How to Create an Application Load Balancer (ALB) with Terraform
To create an AWS Application Load Balancer (ALB) with
Terraform, define the aws_lb resource specifying the load balancer's name, subnets, and security groups. Then configure listeners and target groups using aws_lb_listener and aws_lb_target_group resources to route traffic properly.Syntax
The main Terraform resource to create an ALB is aws_lb. You specify the load balancer's name, subnets where it will run, and security groups to control access. You also create aws_lb_target_group to define where traffic is sent, and aws_lb_listener to listen for incoming requests on specific ports.
- aws_lb: Defines the ALB itself.
- aws_lb_target_group: Defines backend targets like EC2 instances.
- aws_lb_listener: Defines how the ALB listens for traffic and forwards it.
terraform
resource "aws_lb" "example" { name = "example-alb" internal = false load_balancer_type = "application" security_groups = [aws_security_group.alb_sg.id] subnets = [aws_subnet.subnet1.id, aws_subnet.subnet2.id] } resource "aws_lb_target_group" "example_tg" { name = "example-tg" port = 80 protocol = "HTTP" vpc_id = aws_vpc.main.id } resource "aws_lb_listener" "example_listener" { load_balancer_arn = aws_lb.example.arn port = 80 protocol = "HTTP" default_action { type = "forward" target_group_arn = aws_lb_target_group.example_tg.arn } }
Example
This example creates a public ALB in two subnets, a target group for HTTP traffic on port 80, and a listener that forwards requests to the target group.
terraform
provider "aws" { region = "us-east-1" } resource "aws_vpc" "main" { cidr_block = "10.0.0.0/16" } resource "aws_subnet" "subnet1" { vpc_id = aws_vpc.main.id cidr_block = "10.0.1.0/24" availability_zone = "us-east-1a" } resource "aws_subnet" "subnet2" { vpc_id = aws_vpc.main.id cidr_block = "10.0.2.0/24" availability_zone = "us-east-1b" } resource "aws_security_group" "alb_sg" { name = "alb-sg" description = "Allow HTTP inbound" vpc_id = aws_vpc.main.id ingress { from_port = 80 to_port = 80 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] } } resource "aws_lb" "example" { name = "example-alb" internal = false load_balancer_type = "application" security_groups = [aws_security_group.alb_sg.id] subnets = [aws_subnet.subnet1.id, aws_subnet.subnet2.id] } resource "aws_lb_target_group" "example_tg" { name = "example-tg" port = 80 protocol = "HTTP" vpc_id = aws_vpc.main.id } resource "aws_lb_listener" "example_listener" { load_balancer_arn = aws_lb.example.arn port = 80 protocol = "HTTP" default_action { type = "forward" target_group_arn = aws_lb_target_group.example_tg.arn } }
Output
Apply complete! Resources: 7 added, 0 changed, 0 destroyed.
Common Pitfalls
Common mistakes when creating an ALB with Terraform include:
- Not specifying the correct subnets in different availability zones, which can cause the ALB to be unhealthy or unavailable.
- Forgetting to attach a security group that allows inbound traffic on the listener port (usually 80 or 443).
- Misconfiguring the target group protocol or port, causing requests to fail.
- Not associating the listener with the correct target group ARN.
Always validate your VPC, subnet, and security group IDs before applying.
terraform
/* Wrong: Missing security group allowing inbound HTTP */ resource "aws_lb" "wrong_alb" { name = "wrong-alb" internal = false load_balancer_type = "application" subnets = [aws_subnet.subnet1.id, aws_subnet.subnet2.id] } /* Right: Security group allows inbound HTTP */ resource "aws_security_group" "alb_sg" { name = "alb-sg" vpc_id = aws_vpc.main.id ingress { from_port = 80 to_port = 80 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } } resource "aws_lb" "correct_alb" { name = "correct-alb" internal = false load_balancer_type = "application" security_groups = [aws_security_group.alb_sg.id] subnets = [aws_subnet.subnet1.id, aws_subnet.subnet2.id] }
Quick Reference
- aws_lb: Create ALB with
name,subnets,security_groups, andload_balancer_type = "application". - aws_lb_target_group: Define backend targets with
port,protocol, andvpc_id. - aws_lb_listener: Listen on ports like 80 or 443 and forward to target groups.
- Always use multiple subnets in different availability zones for high availability.
- Security groups must allow inbound traffic on listener ports.
Key Takeaways
Use the aws_lb resource with subnets and security groups to create an ALB.
Create aws_lb_target_group to define where the ALB sends traffic.
Configure aws_lb_listener to listen on ports and forward requests.
Always specify multiple subnets in different availability zones.
Ensure security groups allow inbound traffic on listener ports.