Review workload exposure through Kubernetes Ingress

Verify that the actual Ingress path, authentication and TLS configuration match service requirements.

Description

Ingress routes HTTP and HTTPS requests to cluster services through a supporting controller. Its presence alone does not establish internet exposure; the controller, endpoint and network configuration determine that. Unintentionally publishing an internal workload can increase the attack surface.

Potential impact

  • External requests can reach sensitive administration functions or internal services.
  • Incorrect authentication, TLS or backend connections can cause data exposure or service disruption.

Remediation

  • Connect only required services to Ingress and verify target Service names and ports. Use private controllers or endpoints and appropriate network restrictions for internal services.
  • Apply suitable authentication and TLS to public services and test actual external access. Replacing a literal Service name with a Terraform reference does not by itself restrict exposure or permissions.

Examples

These legacy excerpts use the removed older Ingress API. For Kubernetes 1.22 and later, use a supported Ingress API and kubernetes_ingress_v1 syntax. The controller, path interpretation and actual Service backends are configured separately.

Before

hcl
resource "kubernetes_service" "example" {
  metadata {
    name = "ingress-service"
  }

  spec {
    port {
      port        = 80
      target_port = 80
      protocol    = "TCP"
    }

    type = "NodePort"
  }
}

resource "kubernetes_ingress" "example" {
  metadata {
    name = "example"
  }

  spec {
    rule {
      http {
        path {
          path = "/*"

          backend {
            service_name = "example"
            service_port = 80
          }
        }
      }
    }
  }
}

After

hcl
resource "kubernetes_service" "example" {
  metadata {
    name = "ingress-service"
  }

  spec {
    port {
      port        = 80
      target_port = 80
      protocol    = "TCP"
    }

    type = "NodePort"
  }
}

resource "kubernetes_ingress" "example" {
  metadata {
    name = "example"
  }

  spec {
    rule {
      http {
        path {
          path = "/*"

          backend {
            service_name = kubernetes_service.example.metadata.0.name
            service_port = 80
          }
        }
      }
    }
  }
}

Explanation:

  • Before: The backend name example differs from the declared Service name ingress-service. Without a separate Service named example, it will not connect.
  • After: The declared Service name is referenced. This fixes the name relationship without changing exposure or authentication.

References