Amazon EKS — TargetGroupBinding

1 minute read

TargetGroupBinding binds existing AWS ALB/NLB target groups to Kubernetes Services. This is useful when load balancers are managed by Terraform and you need Kubernetes to manage only the target registration.


Use Case

Typical scenario:

  • Terraform creates: VPC, ALB, listeners, target groups
  • Kubernetes manages: Pod endpoints registered to the target group

This separation gives infrastructure teams control over the ALB configuration while application teams manage deployments.


How It Works

apiVersion: elbv2.k8s.aws/v1beta1
kind: TargetGroupBinding
metadata:
  name: web-app-tgb
  namespace: production
spec:
  serviceRef:
    name: web-app        # Kubernetes Service
    port: 80
  targetGroupARN: arn:aws:elasticloadbalancing:us-east-1:123456789:targetgroup/my-tg/abc123
  targetType: ip          # ip or instance

The AWS Load Balancer Controller watches the TargetGroupBinding and registers/deregisters pod IPs as endpoints change.


Configuration with Health Checks

apiVersion: elbv2.k8s.aws/v1beta1
kind: TargetGroupBinding
metadata:
  name: api-tgb
  namespace: production
spec:
  serviceRef:
    name: api-service
    port: 8080
  targetGroupARN: arn:aws:elasticloadbalancing:us-east-1:123456789:targetgroup/api-tg/def456
  targetType: ip
  networking:
    ingress:
      - from:
          - securityGroup:
              groupID: sg-0123456789abcdef0   # ALB security group
        ports:
          - port: 8080
            protocol: TCP

Multi-Cluster Load Balancing

TargetGroupBinding enables a single ALB to route to pods across multiple EKS clusters:

ALB → Target Group → Cluster A pods (via TGB in Cluster A)
                   → Cluster B pods (via TGB in Cluster B)

Both clusters create a TargetGroupBinding pointing to the same target group ARN. The controller registers pods from each cluster.


Terraform + TargetGroupBinding Pattern

# Terraform manages the ALB and target group
resource "aws_lb" "main" {
  name               = "eks-alb"
  load_balancer_type = "application"
  subnets            = module.vpc.public_subnets
  security_groups    = [aws_security_group.alb.id]
}

resource "aws_lb_target_group" "app" {
  name        = "app-tg"
  port        = 80
  protocol    = "HTTP"
  target_type = "ip"
  vpc_id      = module.vpc.vpc_id

  health_check {
    path                = "/healthz"
    port                = "traffic-port"
    healthy_threshold   = 2
    unhealthy_threshold = 3
  }
}

resource "aws_lb_listener" "https" {
  load_balancer_arn = aws_lb.main.arn
  port              = 443
  protocol          = "HTTPS"
  ssl_policy        = "ELBSecurityPolicy-TLS13-1-2-2021-06"
  certificate_arn   = aws_acm_certificate.main.arn

  default_action {
    type             = "forward"
    target_group_arn = aws_lb_target_group.app.arn
  }
}

Then in Kubernetes:

apiVersion: elbv2.k8s.aws/v1beta1
kind: TargetGroupBinding
metadata:
  name: app-tgb
  namespace: production
spec:
  serviceRef:
    name: web-app
    port: 80
  targetGroupARN: arn:aws:elasticloadbalancing:us-east-1:123456789:targetgroup/app-tg/abc123
  targetType: ip

Best Practices

  1. Use TargetGroupBinding when Terraform manages the ALB — clear separation of concerns
  2. Set targetType: ip for direct pod routing
  3. Configure security group ingress — the ALB security group must reach pod IPs
  4. Use for multi-cluster patterns — shared ALB across clusters
  5. Don’t mix Ingress and TargetGroupBinding for the same target group

Updated: