code coding computer cyberspace

AWS Three-Tier VPC with ALB in Terraform

This AWS Three-Tier VPC with ALB in Terraform is the second part of AWS Three-Tier VPC network with Terraform. In the first post I had created many of the VPC components; such as the VPC, app subnets, web subnets, data subnets, route tables for each subnet, internet and NAT gateways, NACLs for each subnet, and a generic security group. In this post I’ll reveal the Terraform code for creating an Elastic Load Balancer, specifically the Application Load Balancer (ALB). The ALB will require a listener, so I’ll add that too. For simplicity purposes the listener will monitor a non-secure port 80. Remember to use certificates and port 443 in production!

Cost

Charges may occur on various resources created using this module. The load balancers have a low hourly price set.

The design

Here’s the original diagram from the previous post.

three-tier vpc diagram

ALB (Application Load Balancer)

The ALB diagram. The ALB does a health check on port 80 on every instance in the target group. Whichever instance is healthy it will use that. In this drawing there’s only one web server; your production should have at least two that are in different availability zones.

alb diagram
The ALB

ALB Terraform Code

# ALB for the web servers
resource "aws_lb" "web_servers" {
  name               = format("%s-alb", var.vpc_name)
  internal           = false
  load_balancer_type = "application"
  security_groups    = [aws_security_group.web.id]
  subnets            = aws_subnet.public.*.id
  enable_http2       = false
  enable_deletion_protection = true

  tags = {
    Name = format("%s-alb", var.vpc_name)
  }
}

This is an example of an external ALB. Note the “internal = false” statement. The load balancer type is what makes this an application load balancer. The other options are network or gateway. Since this is an ALB, it does require a security group. This external load balancer will be required to be in public subnets so outside users can reach the web servers which are hosted in private subnets. That’s one of the design features that makes this a three-tier VPC! See the Terraform documentation on more options.

Target Groups

Let’s make the ALB useful by creating a target group and a load balancer listener.

# Target group for the web servers
resource "aws_lb_target_group" "web_servers" {
  name     = "sharepoint-web-servers-tg"
  port     = 80
  protocol = "HTTP"
  vpc_id   = aws_vpc.this.id
}

resource "aws_lb_listener" "front_end" {
  load_balancer_arn = aws_lb.web_servers.arn
  port              = "80"
  protocol          = "HTTP"

  default_action {
    type             = "forward"
    target_group_arn = aws_lb_target_group.web_servers.arn
  }
}

An empty target group is not useful either. From now on when you launch a new EC2 web server be sure to add it to the target group like this.

# Find the target group
data "aws_lb_target_group" "web_servers" {
  name = "sharepoint-web-servers-tg"
}

# Attach an EC2 instance to the target group on port 80
resource "aws_lb_target_group_attachment" "web" {
  target_group_arn = aws_lb_target_group.arn
  target_id        = aws_instance.web.id
  port             = 80
}
target group registered targets
EC2 added to a target group

Notice the URL is using the ALB’s DNS record to reach the Nginx web server.

website
Nginx website using the ALB URL

Here’s the complete terraform module code: https://github.com/masterwali/tf-module-aws-three-tier-network-vpc

Here’s an example on how to call or reference the module.

module "sharepoint_network" {
  source = "git@github.com:masterwali/tf-module-aws-three-tier-network-vpc.git"
  
  aws_cli_profile = var.aws_cli_profile
  additional_tags = var.additional_tags
}

Subscribe to the newsletter for more tutorials!

Full Disclosure: I am an AWS employee, this post is opinion of my own.