Creating Target Group and Application Load Balancer Using Terraform

By Łukasz Kallas
Picture of the author
Published on
terraform image

Why Use an Application Load Balancer?

An ALB automatically distributes incoming application traffic across multiple targets, such as EC2 instances, containers, and IP addresses. It operates at the application layer (Layer 7) and can make routing decisions based on content, offering advanced request routing and web application firewall integration.

What is a Target Group?

A Target Group is a logical grouping of targets that receive traffic routed by the load balancer. It helps in organizing the resources and applying specific configurations, like health checks, to them. Target Groups support different types of targets, including IP addresses, instances, and Lambda functions.

Prerequisites

  1. AWS Account
  2. Terraform installed and configured on your local machine
  3. Existing VPC and subnets

Setting Up an ALB and Target Group Using Terraform

  1. Define the Target Group
resource "aws_lb_target_group" "nginx_tg" {
  name     = "nginx-tg"
  port     = 80
  protocol = "HTTP"
  vpc_id   = aws_vpc.main_vpc.id

  health_check {
    path                = "/"
    interval            = 30
    timeout             = 5
    healthy_threshold   = 3
    unhealthy_threshold = 3
  }
}
  1. Create an Application Load Balancer (ALB)
resource "aws_lb" "main_alb" {
  name               = "nginx-alb"
  internal           = false
  load_balancer_type = "application"
  security_groups    = [aws_security_group.allow_http.id]
  subnets            = [aws_subnet.public_subnet_1.id, aws_subnet.public_subnet_2.id]

  enable_deletion_protection = false

  tags = {
    Name = "nginx-alb"
  }
}
  1. Create a Listener
resource "aws_lb_listener" "alb_listener" {
  load_balancer_arn = aws_lb.main_alb.arn
  port              = "80"
  protocol          = "HTTP"

  default_action {
    type             = "forward"
    target_group_arn = aws_lb_target_group.nginx_tg.arn
  }
}
  1. Launching EC2 into Target Group
variable "server_count" {
  default = 4
}

resource "aws_instance" "nginx_instance" {
  count = var.server_count

  ami           = "ami-066784287e358dad1"
  instance_type = "t3.micro"
  subnet_id     = element(concat([aws_subnet.public_subnet_1.id], [aws_subnet.public_subnet_2.id]), count.index % 2)
  security_groups = [aws_security_group.allow_http.id]


  tags = {
    Name = "nginx-server-${count.index}"
  }

  user_data = <<-EOF
              #!/bin/bash
              yum update -y
              yum install -y nginx
              INSTANCE_NUMBER=${count.index}
              echo "<h1>Instance Number: $INSTANCE_NUMBER</h1>" > /usr/share/nginx/html/index.html
              systemctl start nginx
              systemctl enable nginx
              EOF

  associate_public_ip_address = true
}

resource "aws_lb_target_group_attachment" "tg_attachment" {
  count            = var.server_count
  target_group_arn = aws_lb_target_group.nginx_tg.arn
  target_id        = aws_instance.nginx_instance[count.index].id
  port             = 80
}

output "alb_dns_name" {
  description = "The DNS name of the ALB"
  value       = aws_lb.main_alb.dns_name
}

Stay Tuned

Want to learn?
The best articles, links and news related to software development delivered once a week to your inbox.