DEV Community

Ragul.M
Ragul.M

Posted on

Deploying a Scalable AWS Infrastructure with VPC, ALB, and Target Groups Using Terraform

Introduction
In this blog, we will walk through the process of deploying a scalable AWS infrastructure using Terraform. The setup includes:

  • A VPC with public and private subnets
  • An Internet Gateway for public access
  • Application Load Balancers (ALBs) for distributing traffic
  • Target Groups and EC2 instances for handling incoming requests
  • By the end of this guide, you’ll have a highly available setup with proper networking, security, and load balancing.

Step 1: Creating a VPC with Public and Private Subnets
The first step is to define our Virtual Private Cloud (VPC) with four subnets (two public, two private) spread across multiple Availability Zones.
Terraform Code: vpc.tf

resource "aws_vpc" "main_vpc" {
  cidr_block = "10.0.0.0/16"
}
# Public Subnet 1 - ap-south-1a
resource "aws_subnet" "public_subnet_1" {
  vpc_id            = aws_vpc.main_vpc.id
  cidr_block        = "10.0.1.0/24"
  availability_zone = "ap-south-1a"
  map_public_ip_on_launch = true
}
# Public Subnet 2 - ap-south-1b
resource "aws_subnet" "public_subnet_2" {
  vpc_id            = aws_vpc.main_vpc.id
  cidr_block        = "10.0.2.0/24"
  availability_zone = "ap-south-1b"
  map_public_ip_on_launch = true
}
# Private Subnet 1 - ap-south-1a
resource "aws_subnet" "private_subnet_1" {
  vpc_id            = aws_vpc.main_vpc.id
  cidr_block        = "10.0.3.0/24"
  availability_zone = "ap-south-1a"
}
# Private Subnet 2 - ap-south-1b
resource "aws_subnet" "private_subnet_2" {
  vpc_id            = aws_vpc.main_vpc.id
  cidr_block        = "10.0.4.0/24"
  availability_zone = "ap-south-1b"
}
# Internet Gateway for Public Access
resource "aws_internet_gateway" "igw" {
  vpc_id = aws_vpc.main_vpc.id
}
# Public Route Table
resource "aws_route_table" "public_rt" {
  vpc_id = aws_vpc.main_vpc.id
}
resource "aws_route" "internet_access" {
  route_table_id         = aws_route_table.public_rt.id
  destination_cidr_block = "0.0.0.0/0"
  gateway_id             = aws_internet_gateway.igw.id
}
resource "aws_route_table_association" "public_assoc_1" {
  subnet_id      = aws_subnet.public_subnet_1.id
  route_table_id = aws_route_table.public_rt.id
}
resource "aws_route_table_association" "public_assoc_2" {
  subnet_id      = aws_subnet.public_subnet_2.id
  route_table_id = aws_route_table.public_rt.id
}
Enter fullscreen mode Exit fullscreen mode

This configuration ensures that our public subnets can access the internet, while our private subnets remain isolated.

Step 2: Setting Up Security Groups
Next, we define security groups to control access to our ALBs and EC2 instances.
Terraform Code: security_groups.tf

resource "aws_security_group" "alb_sg" {
  vpc_id = aws_vpc.main_vpc.id
  # Allow HTTP and HTTPS traffic to ALB
  ingress {
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }
  ingress {
    from_port   = 443
    to_port     = 443
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }
  # Allow outbound traffic
  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}
Enter fullscreen mode Exit fullscreen mode

This allows public access to the ALB but restricts other traffic.

Step 3: Creating the Application Load Balancers (ALB)
Now, let’s define two ALBs—one public and one private.
Terraform Code: alb.tf

# Public ALB
resource "aws_lb" "public_alb" {
  name               = "public-alb"
  internal           = false
  load_balancer_type = "application"
  security_groups    = [aws_security_group.alb_sg.id]
  subnets           = [aws_subnet.public_subnet_1.id, aws_subnet.public_subnet_2.id]
}
# Private ALB
resource "aws_lb" "private_alb" {
  name               = "private-alb"
  internal           = true
  load_balancer_type = "application"
  security_groups    = [aws_security_group.alb_sg.id]
  subnets           = [aws_subnet.private_subnet_1.id, aws_subnet.private_subnet_2.id]
}
Enter fullscreen mode Exit fullscreen mode

This ensures redundancy and distributes traffic across different subnets.

Step 4: Creating Target Groups for EC2 Instances
Each ALB needs target groups to route traffic to EC2 instances.
Terraform Code: target_groups.tf

resource "aws_lb_target_group" "public_tg" {
  name     = "public-tg"
  port     = 80
  protocol = "HTTP"
  vpc_id   = aws_vpc.main_vpc.id
}
resource "aws_lb_target_group" "private_tg" {
  name     = "private-tg"
  port     = 80
  protocol = "HTTP"
  vpc_id   = aws_vpc.main_vpc.id
}
Enter fullscreen mode Exit fullscreen mode

These target groups allow ALBs to forward requests to backend EC2 instances.

Step 5: Launching EC2 Instances
Finally, we deploy EC2 instances and register them with the target groups.
Terraform Code: ec2.tf

resource "aws_instance" "public_instance" {
  ami           = "ami-0abcdef1234567890" # Replace with a valid AMI ID
  instance_type = "t2.micro"
  subnet_id     = aws_subnet.public_subnet_1.id
}
resource "aws_instance" "private_instance" {
  ami           = "ami-0abcdef1234567890" # Replace with a valid AMI ID
  instance_type = "t2.micro"
  subnet_id     = aws_subnet.private_subnet_1.id
}
Enter fullscreen mode Exit fullscreen mode

These instances will serve web requests.

Step 6: Registering Instances to Target Groups

resource "aws_lb_target_group_attachment" "public_attach" {
  target_group_arn = aws_lb_target_group.public_tg.arn
  target_id        = aws_instance.public_instance.id
}
resource "aws_lb_target_group_attachment" "private_attach" {
  target_group_arn = aws_lb_target_group.private_tg.arn
  target_id        = aws_instance.private_instance.id
}
Enter fullscreen mode Exit fullscreen mode

This registers our EC2 instances as backend servers.

Final Step: Terraform Apply!
Run the following command to deploy everything:

terraform init
terraform apply -auto-approve
Enter fullscreen mode Exit fullscreen mode

Once completed, you’ll get ALB DNS names, which you can use to access your deployed infrastructure.

Conclusion
This guide covered how to deploy a highly available AWS infrastructure using Terraform, including VPC, subnets, ALBs, security groups, target groups, and EC2 instances. This setup ensures a secure and scalable architecture.

Follow for more and happy learning :)

Top comments (0)