Bootstrap FreeKB - Amazon Web Services (AWS) - Forward Requests from a Network Load Balancer to an Application Load Balancer using Terraform
Amazon Web Services (AWS) - Forward Requests from a Network Load Balancer to an Application Load Balancer using Terraform


There are a few different types of load balancers.

  • Application Load Balancers
    • Typically used to load balance requests to a web app
    • Typically uses the HTTP and HTTPS protocols
    • Cannot be bound to an Elastic IP address (static IP address)
  • Network Load Balancers
    • Typically used to load balance requests to one or more EC2 Instances, or SQL databases or Application Load Balancers
    • Typically uses the TCP protocol
    • Can be bound to one or more Elastic IP addresses (static IP address)
  • Gateway Load Balancers
  • Classic Load Balancers (deprecated)

It's important to recognize that an Elastic IP address cannot be assigned to an Application Load Balancer. A common approach is to have a Network Load Balancer with an assigned Elastic IP forward requests onto an Application Load Balancer.

 

It is also important to recognize that if your Network Load Balancer will be routing requests to EC2 instances is different subnets / availability zones, the Network Load Balancer will need an Elastic IP for each subnet / availability zone.

 

This assumes you have setup Terraform with the Amazon Web Services (AWS) provider. If not, check out my article Amazon Web Services (AWS) Getting Started with Terraform.

Let's say you have the following files on your Terraform server.

├── required_providers.tf
├── elastic_load_balancers (directory)
│   ├── listeners.tf
│   ├── load_balancers.tf
│   ├── outputs.tf
│   ├── provider.tf
│   ├── register_targets.tf
│   ├── remote_states.tf
│   ├── security_groups.tf
│   ├── target_groups.tf

 

This assume you have already:

 

security_groups.tf could have the following to allow incoming (ingress) requests to the EC2 instances on HTTP port 80.

resource "aws_security_group" "http-security-group" {
  name        = "HTTP security group"
  description = "HTTP security group"
  vpc_id      = data.terraform_remote_state.virtual_private_clouds.outputs.my_vpc.id

  ingress {
    description      = "Allow incoming (ingress) requests on port 80"
    from_port        = 80
    to_port          = 80
    protocol         = "HTTP"
    cidr_blocks      = ["0.0.0.0/0"]
  }

  egress {
    from_port        = 0
    to_port          = 0
    protocol         = "-1"
    cidr_blocks      = ["0.0.0.0/0"]
  }

  tags = {
    Name = "HTTP security group"
  }
}

 

target_groups.tf could have something like this so that there is:

  • a Target Group that will forward request from the Network Load Balancer to the Application Load Balancer 
  • a Target Group that will forward request from the Application Load Balancer to an EC2 Instance
resource "aws_lb_target_group" "nlb-to-alb-target-group" {
  name = "nlb-to-alb-target-group"
  port = 80
  protocol = "TCP"
  vpc_id = data.terraform_remote_state.virtual_private_clouds.outputs.my_vpc.id
  target_type = "alb"

  tags = {
    Name = "nlb-to-alb-target-group"
  }
}

resource "aws_lb_target_group" "alb-target-group" {
  name = "alb-target-group"
  port = 80
  protocol = "HTTP"
  vpc_id = data.terraform_remote_state.virtual_private_clouds.outputs.my_vpc.id

  tags = {
    Name = "alb-target-group"
  }
}

 

listeners.tf could have something like this so that there is:

  • Listener that will listen for requests into the Network Load Balancer on TCP port 80
  • Listener that will listen for requests into the Application Load Balancer on HTTP port 80
resource "aws_lb_listener" "nlb-listener" {

  load_balancer_arn = aws_lb.my-network-load-balancer.arn
  port = 80
  protocol = "TCP"

  default_action {
    type             = "forward"
    target_group_arn = aws_lb_target_group.nlb-to-alb-target-group.arn
  }

  tags = {
    Name = "nlb-listener"
  }
}

resource "aws_lb_listener" "alb-listener" {
  load_balancer_arn = aws_lb.my-application-load-balancer.arn
  port = 80
  protocol = "HTTP"

  default_action {
    type             = "forward"
    target_group_arn = aws_lb_target_group.alb-target-group.arn
  }

  tags = {
    Name = "alb-listener"
  }
}

 

register_targets.tf could have the following to register your EC2 Instance in your Application Load Balance Target Group.

resource "aws_lb_target_group_attachment" "registered-target" {

  for_each = toset([data.terraform_remote_state.ec2_instances.outputs.my_docker1_instance.id, data.terraform_remote_state.ec2_instances.outputs.my_docker2_instance.id])

  target_group_arn = aws_lb_target_group.my-application-load-balancer-target-group.arn
  target_id        = each.key
  port             = 80
}

 




Did you find this article helpful?

If so, consider buying me a coffee over at Buy Me A Coffee



Comments


Add a Comment


Please enter cc9174 in the box below so that we can be sure you are a human.