0
0
TerraformHow-ToBeginner · 4 min read

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, and load_balancer_type = "application".
  • aws_lb_target_group: Define backend targets with port, protocol, and vpc_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.