How to Register an Application Load Balancer as a Target for a Terraform Target Group

To register an AWS Application Load Balancer (ALB) as a target in Terraform, use the aws_lb_target_group_attachment resource and supply the ALB's ARN as the target_id, ensuring you first create the ALB with aws_lb and the target group with aws_lb_target_group.

When configuring multi-layer load balancing architectures with the hashicorp/terraform-provider-aws, you can chain load balancers by registering an Application Load Balancer as a target in another target group. This setup enables complex traffic flows—such as gateway load balancers forwarding to internal ALBs—managed entirely through Terraform's AWS provider resources.

Core Resources for ALB Target Registration

Terraform implements ALB target registration through three distinct resources in the AWS provider. Understanding the role of each resource—and its corresponding source file—ensures you configure dependencies correctly.

aws_lb – Provisioning the Application Load Balancer

The aws_lb resource creates the Application Load Balancer that will serve as the target. According to the provider source code in internal/service/lb/resource_lb.go, this resource manages the ALB's ARN, subnets, security groups, and internal/external accessibility. The ARN output (aws_lb.example.arn) becomes the critical identifier used during target registration.

aws_lb_target_group – Defining Traffic Destinations

Before attaching any target, you must define the target group using aws_lb_target_group. As implemented in internal/service/lb/resource_lb_target_group.go, this resource specifies the protocol, port, VPC ID, and health-check settings. The target group must reside in the same VPC as the targets it will receive.

aws_lb_target_group_attachment – The Registration Mechanism

The actual registration occurs in internal/service/lb/resource_lb_target_group_attachment.go. This resource handles the API calls that associate a specific target—whether an EC2 instance, IP address, Lambda function, or ALB—with the target group. The implementation accepts an ALB ARN as a valid target_id, enabling load-balancer chaining.

Step-by-Step Implementation

Follow this resource creation order to avoid dependency errors during terraform apply.

1. Create the Application Load Balancer

Define the ALB using the aws_lb resource. Ensure you export the ARN for the attachment step.

resource "aws_lb" "frontend_alb" {
  name               = "frontend-alb"
  internal           = false
  load_balancer_type = "application"
  subnets            = var.public_subnets
  security_groups    = [aws_security_group.alb_sg.id]
}

2. Define the Target Group

Create a target group that specifies the protocol and port on which the ALB will receive traffic. The vpc_id must match the ALB's VPC.

resource "aws_lb_target_group" "backend_tg" {
  name     = "backend-targets"
  port     = 80
  protocol = "HTTP"
  vpc_id   = var.vpc_id

  health_check {
    path                = "/"
    interval            = 30
    timeout             = 5
    healthy_threshold   = 3
    unhealthy_threshold = 3
    matcher             = "200-299"
  }
}

3. Register the ALB Using Target Group Attachment

Use aws_lb_target_group_attachment to register the ALB. Set target_id to the ALB's ARN and match the port to the listener port you configured.

resource "aws_lb_target_group_attachment" "alb_target" {
  target_group_arn = aws_lb_target_group.backend_tg.arn
  target_id        = aws_lb.frontend_alb.arn
  port             = 80
}

Terraform automatically resolves the implicit dependency chain—creating the ALB and target group before attempting the attachment—without requiring explicit depends_on meta-arguments.

Source Code Implementation Details

The underlying behavior of these resources is defined in the provider's internal service package for load balancing:

These files demonstrate that Terraform treats the ALB ARN as a first-class target identifier, passing it directly to AWS's RegisterTargets API call.

Summary

  • Use aws_lb_target_group_attachment to register an ALB as a target, setting the ALB's ARN as the target_id.
  • Create resources in dependency order: aws_lbaws_lb_target_groupaws_lb_target_group_attachment.
  • Terraform's implicit reference resolution handles the creation sequence automatically; explicit depends_on is rarely necessary.
  • The provider implementation resides in internal/service/lb/resource_lb_target_group_attachment.go, which validates ALB ARNs as legitimate target identifiers.

Frequently Asked Questions

What value should I use for the target_id when registering an ALB?

You must use the ALB's ARN (Amazon Resource Name), not its DNS name or resource ID. Pass the ARN output from the aws_lb resource—for example, aws_lb.frontend_alb.arn—to the target_id argument of the aws_lb_target_group_attachment resource.

Is explicit depends_on required between the ALB and the target group attachment?

No. Terraform automatically detects dependencies through resource references. When you set target_id = aws_lb.frontend_alb.arn, Terraform knows to create the ALB before attempting the attachment. Explicit depends_on is only needed if resources are not directly referenced in the configuration.

Can I register an ALB as a target if the target group uses a different VPC?

No. According to the aws_lb_target_group implementation, the target group defines the VPC in which targets must reside. Both the ALB and the target group must exist in the same VPC for the attachment to succeed.

Can I attach the same ALB to multiple target groups?

Yes. Create multiple aws_lb_target_group_attachment resources, each referencing a different target_group_arn while using the same ALB ARN as the target_id. This pattern supports architectures where a single ALB receives traffic from multiple frontend load balancers or listeners.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →