Introduction
Cloud Load Balancing is essential for distributing traffic across multiple servers, ensuring high availability, and improving performance. In 2026, businesses demand resilient architectures that handle traffic spikes effectively. This tutorial shows how to deploy an Application Load Balancer (ALB) on AWS with Terraform. You'll learn to create a VPC, subnets, security groups, targets, and the load balancer itself. Each step includes ready-to-use code. The IaC approach guarantees reproducibility and version control for your infrastructure.
Prerequisites
- Terraform 1.8+
- AWS account with IAM permissions
- Basic AWS knowledge (VPC, EC2)
- AWS CLI configured
Provider and Variables Configuration
terraform {
required_version = ">= 1.8"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = var.aws_region
}
variable "aws_region" {
description = "Région AWS"
default = "eu-west-3"
}This file initializes Terraform and configures the AWS provider. It sets the default region to ensure all resources are created in the same location.
Creating the VPC and Subnets
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
enable_dns_hostnames = true
tags = { Name = "lb-vpc" }
}
resource "aws_subnet" "public" {
count = 2
vpc_id = aws_vpc.main.id
cidr_block = "10.0.${count.index}.0/24"
availability_zone = data.aws_availability_zones.available.names[count.index]
tags = { Name = "public-${count.index}" }
}
data "aws_availability_zones" "available" {}We create a VPC with two public subnets in separate availability zones to ensure load balancer redundancy.
Security Groups
resource "aws_security_group" "alb" {
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"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}The security group allows incoming HTTP traffic on port 80 from any source and permits all outgoing traffic, providing the minimal configuration for a public ALB.
Target Group and Instances
resource "aws_lb_target_group" "app" {
name = "app-tg"
port = 80
protocol = "HTTP"
vpc_id = aws_vpc.main.id
health_check {
path = "/health"
interval = 30
healthy_threshold = 2
unhealthy_threshold = 2
}
}The Target Group defines the port and protocol for target instances along with essential health checks to automatically remove failing instances.
Deploying the Load Balancer
resource "aws_lb" "main" {
name = "app-alb"
internal = false
load_balancer_type = "application"
security_groups = [aws_security_group.alb.id]
subnets = aws_subnet.public[*].id
enable_deletion_protection = false
}
resource "aws_lb_listener" "http" {
load_balancer_arn = aws_lb.main.arn
port = 80
protocol = "HTTP"
default_action {
type = "forward"
target_group_arn = aws_lb_target_group.app.arn
}
}This code deploys the public ALB, attaches it to the subnets, and creates an HTTP listener that routes all traffic to the configured Target Group.
Best Practices
- Use subnets in at least two AZs for high availability
- Enable access logging on the load balancer
- Configure health checks suited to your application
- Separate environments using Terraform workspaces
- Always version your IaC code
Common Mistakes to Avoid
- Forgetting to associate subnets across multiple availability zones
- Setting overly permissive security groups
- Ignoring custom health checks
- Not enabling deletion protection in production
Going Further
Explore our advanced courses on cloud infrastructure and Terraform at Learni Group.