Category: ALB

Elastic Load Balancing automatically distributes your incoming traffic across multiple targets, such as EC2 instances, containers, and IP addresses, in one or more Availability Zones. It monitors the health of its registered targets, and routes traffic only to the healthy targets.

  • How to Create an ALB Listener with Multiple Path Conditions Using Terraform

    When designing modern cloud-native applications, it’s common to host multiple services under a single domain. Application Load Balancers (ALBs) in AWS provide an efficient way to route traffic to different backend services based on URL path conditions. This article will guide you through creating an ALB listener with multiple path-based routing conditions using Terraform, assuming you already have SSL configured.

    Prerequisites

    • AWS Account: Ensure you have access to an AWS account with the necessary permissions to create and manage ALB, EC2 instances, and other AWS resources.
    • Terraform Installed: Terraform should be installed and configured on your machine.
    • SSL Certificate: You should already have an SSL certificate set up and associated with your ALB, as this guide focuses on creating path-based routing rules.

    Step 1: Set Up Path-Based Target Groups

    Before configuring the ALB listener rules, you need to create target groups for the different services that will handle requests based on the URL paths.

    resource "aws_lb_target_group" "service1_target_group" {
      name     = "service1-tg"
      port     = 80
      protocol = "HTTP"
      vpc_id   = aws_vpc.main_vpc.id
    }
    
    resource "aws_lb_target_group" "service2_target_group" {
      name     = "service2-tg"
      port     = 80
      protocol = "HTTP"
      vpc_id   = aws_vpc.main_vpc.id
    }

    In this example, we’ve created two target groups: one for service1 and another for service2. These groups will handle the traffic based on specific URL paths.

    Step 2: Create the HTTPS Listener

    Since we’re focusing on path-based routing, we’ll configure an HTTPS listener that listens on port 443 and uses the SSL certificate you’ve already set up.

    resource "aws_lb_listener" "https_listener" {
      load_balancer_arn = aws_lb.my_alb.arn
      port              = "443"
      protocol          = "HTTPS"
      ssl_policy        = "ELBSecurityPolicy-2016-08"
      certificate_arn   = aws_acm_certificate.cert.arn
    
      default_action {
        type = "fixed-response"
        fixed_response {
          content_type = "text/plain"
          message_body = "404: Not Found"
          status_code  = "404"
        }
      }
    }

    Step 3: Define Path-Based Routing Rules

    Now that the HTTPS listener is set up, you can define listener rules that route traffic to different target groups based on URL paths.

    resource "aws_lb_listener_rule" "path_condition_rule_service1" {
      listener_arn = aws_lb_listener.https_listener.arn
      priority     = 1
    
      action {
        type             = "forward"
        target_group_arn = aws_lb_target_group.service1_target_group.arn
      }
    
      condition {
        path_pattern {
          values = ["/service1/*"]
        }
      }
    }
    
    resource "aws_lb_listener_rule" "path_condition_rule_service2" {
      listener_arn = aws_lb_listener.https_listener.arn
      priority     = 2
    
      action {
        type             = "forward"
        target_group_arn = aws_lb_target_group.service2_target_group.arn
      }
    
      condition {
        path_pattern {
          values = ["/service2/*"]
        }
      }
    }

    In this configuration:

    • The first rule routes traffic with paths matching /service1/* to service1_target_group.
    • The second rule routes traffic with paths matching /service2/* to service2_target_group.

    The priority field ensures that Terraform processes these rules in the correct order, with lower numbers being processed first.

    Step 4: Apply Your Terraform Configuration

    After defining your Terraform configuration, apply the changes to deploy the ALB with path-based routing.

    1. Initialize Terraform:
       terraform init
    1. Review the Plan:
       terraform plan
    1. Apply the Configuration:
       terraform apply

    Conclusion

    By leveraging path-based routing, you can efficiently manage traffic to different services under a single domain, improving the organization and scalability of your application architecture.

    This approach is especially useful in microservices architectures, where different services can be accessed via specific URL paths, all secured under a single SSL certificate. Path-based routing is a powerful tool for ensuring that your ALB efficiently directs traffic to the correct backend services, enhancing both performance and security.

  • Creating an Application Load Balancer (ALB) Listener with Multiple Host Header Conditions Using Terraform

    Application Load Balancers (ALBs) play a crucial role in distributing traffic across multiple backend services. They provide the flexibility to route requests based on a variety of conditions, such as path-based or host-based routing. In this article, we’ll walk through how to create an ALB listener with multiple host_header conditions using Terraform.

    Prerequisites

    Before you begin, ensure that you have the following:

    • AWS Account: You’ll need an AWS account with the appropriate permissions to create and manage ALB, EC2, and other related resources.
    • Terraform Installed: Make sure you have Terraform installed on your local machine. You can download it from the official website.
    • Basic Knowledge of Terraform: Familiarity with Terraform basics, such as providers, resources, and variables, is assumed.

    Step 1: Set Up Your Terraform Configuration

    Start by creating a new directory for your Terraform configuration files. Inside this directory, create a file named main.tf. This file will contain the Terraform code to create the ALB, listener, and associated conditions.

    provider "aws" {
      region = "us-west-2" # Replace with your preferred region
    }
    
    resource "aws_vpc" "main_vpc" {
      cidr_block = "10.0.0.0/16"
    }
    
    resource "aws_subnet" "main_subnet" {
      vpc_id            = aws_vpc.main_vpc.id
      cidr_block        = "10.0.1.0/24"
      availability_zone = "us-west-2a" # Replace with your preferred AZ
    }
    
    resource "aws_security_group" "alb_sg" {
      name   = "alb_sg"
      vpc_id = aws_vpc.main_vpc.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"]
      }
    }
    
    resource "aws_lb" "my_alb" {
      name               = "my-alb"
      internal           = false
      load_balancer_type = "application"
      security_groups    = [aws_security_group.alb_sg.id]
      subnets            = [aws_subnet.main_subnet.id]
    
      enable_deletion_protection = false
    }
    
    resource "aws_lb_target_group" "target_group_1" {
      name     = "target-group-1"
      port     = 80
      protocol = "HTTP"
      vpc_id   = aws_vpc.main_vpc.id
    }
    
    resource "aws_lb_target_group" "target_group_2" {
      name     = "target-group-2"
      port     = 80
      protocol = "HTTP"
      vpc_id   = aws_vpc.main_vpc.id
    }
    
    resource "aws_lb_listener" "alb_listener" {
      load_balancer_arn = aws_lb.my_alb.arn
      port              = "80"
      protocol          = "HTTP"
    
      default_action {
        type = "fixed-response"
        fixed_response {
          content_type = "text/plain"
          message_body = "404: No matching host header"
          status_code  = "404"
        }
      }
    }
    
    resource "aws_lb_listener_rule" "host_header_rule_1" {
      listener_arn = aws_lb_listener.alb_listener.arn
      priority     = 1
    
      action {
        type             = "forward"
        target_group_arn = aws_lb_target_group.target_group_1.arn
      }
    
      condition {
        host_header {
          values = ["example1.com"]
        }
      }
    }
    
    resource "aws_lb_listener_rule" "host_header_rule_2" {
      listener_arn = aws_lb_listener.alb_listener.arn
      priority     = 2
    
      action {
        type             = "forward"
        target_group_arn = aws_lb_target_group.target_group_2.arn
      }
    
      condition {
        host_header {
          values = ["example2.com"]
        }
      }
    }

    Step 2: Define the ALB and Listener

    In the main.tf file, we start by defining the ALB and its associated listener. The listener listens for incoming HTTP requests on port 80 and directs the traffic based on the conditions we set.

    resource "aws_lb_listener" "alb_listener" {
      load_balancer_arn = aws_lb.my_alb.arn
      port              = "80"
      protocol          = "HTTP"
    
      default_action {
        type = "fixed-response"
        fixed_response {
          content_type = "text/plain"
          message_body = "404: No matching host header"
          status_code  = "404"
        }
      }
    }

    Step 3: Add Host Header Conditions

    Next, we create listener rules that define the host header conditions. These rules will forward traffic to specific target groups based on the Host header in the HTTP request.

    resource "aws_lb_listener_rule" "host_header_rule_1" {
      listener_arn = aws_lb_listener.alb_listener.arn
      priority     = 1
    
      action {
        type             = "forward"
        target_group_arn = aws_lb_target_group.target_group_1.arn
      }
    
      condition {
        host_header {
          values = ["example1.com"]
        }
      }
    }
    
    resource "aws_lb_listener_rule" "host_header_rule_2" {
      listener_arn = aws_lb_listener.alb_listener.arn
      priority     = 2
    
      action {
        type             = "forward"
        target_group_arn = aws_lb_target_group.target_group_2.arn
      }
    
      condition {
        host_header {
          values = ["example2.com"]
        }
      }
    }

    In this example, requests with a Host header of example1.com are routed to target_group_1, while requests with a Host header of example2.com are routed to target_group_2.

    Step 4: Deploy the Infrastructure

    Once you have defined your Terraform configuration, you can deploy the infrastructure by running the following commands:

    1. Initialize Terraform: This command initializes the working directory containing the Terraform configuration files.
       terraform init
    1. Review the Execution Plan: This command creates an execution plan, which lets you see what Terraform will do when you run terraform apply.
       terraform plan
    1. Apply the Configuration: This command applies the changes required to reach the desired state of the configuration.
       terraform apply

    After running terraform apply, Terraform will create the ALB, listener, and listener rules with the specified host header conditions.

    Adding SSL to your Application Load Balancer (ALB) in AWS using Terraform involves creating an HTTPS listener, configuring an SSL certificate, and setting up the necessary security group rules. This guide will walk you through the process of adding SSL to the ALB configuration that we created earlier.

    Step 1: Obtain an SSL Certificate

    Before you can set up SSL on your ALB, you need to have an SSL certificate. You can obtain an SSL certificate using AWS Certificate Manager (ACM). This guide assumes you already have a certificate in ACM, but if not, you can request one via the AWS Management Console or using Terraform.

    Here’s an example of how to request a certificate in Terraform:

    resource "aws_acm_certificate" "cert" {
      domain_name       = "example.com"
      validation_method = "DNS"
    
      subject_alternative_names = [
        "www.example.com",
      ]
    
      tags = {
        Name = "example-cert"
      }
    }

    After requesting the certificate, you need to validate it. Once validated, it will be ready for use.

    Step 2: Modify the ALB Security Group

    To allow HTTPS traffic, you need to update the security group associated with your ALB to allow incoming traffic on port 443.

    resource "aws_security_group_rule" "allow_https" {
      type              = "ingress"
      from_port         = 443
      to_port           = 443
      protocol          = "tcp"
      cidr_blocks       = ["0.0.0.0/0"]
      security_group_id = aws_security_group.alb_sg.id
    }

    Step 3: Add the HTTPS Listener

    Now, you can add an HTTPS listener to your ALB. This listener will handle incoming HTTPS requests on port 443 and will forward them to the appropriate target groups based on the same conditions we set up earlier.

    resource "aws_lb_listener" "https_listener" {
      load_balancer_arn = aws_lb.my_alb.arn
      port              = "443"
      protocol          = "HTTPS"
      ssl_policy        = "ELBSecurityPolicy-2016-08"
      certificate_arn   = aws_acm_certificate.cert.arn
    
      default_action {
        type = "fixed-response"
        fixed_response {
          content_type = "text/plain"
          message_body = "404: No matching host header"
          status_code  = "404"
        }
      }
    }

    Step 4: Add Host Header Rules for HTTPS

    Just as we did with the HTTP listener, we need to create rules for the HTTPS listener to route traffic based on the Host header.

    resource "aws_lb_listener_rule" "https_host_header_rule_1" {
      listener_arn = aws_lb_listener.https_listener.arn
      priority     = 1
    
      action {
        type             = "forward"
        target_group_arn = aws_lb_target_group.target_group_1.arn
      }
    
      condition {
        host_header {
          values = ["example1.com"]
        }
      }
    }
    
    resource "aws_lb_listener_rule" "https_host_header_rule_2" {
      listener_arn = aws_lb_listener.https_listener.arn
      priority     = 2
    
      action {
        type             = "forward"
        target_group_arn = aws_lb_target_group.target_group_2.arn
      }
    
      condition {
        host_header {
          values = ["example2.com"]
        }
      }
    }

    Step 5: Update Terraform and Apply Changes

    After adding the HTTPS listener and security group rules, you need to update your Terraform configuration and apply the changes.

    1. Initialize Terraform: If you haven’t done so already.
       terraform init
    1. Review the Execution Plan: This command creates an execution plan to review the changes.
       terraform plan
    1. Apply the Configuration: Apply the configuration to create the HTTPS listener and associated resources.
       terraform apply

    Conclusion

    We walked through creating an ALB listener with multiple host header conditions using Terraform. This setup allows you to route traffic to different target groups based on the Host header of incoming requests, providing a flexible way to manage multiple applications or services behind a single ALB.

    By following these steps, you have successfully added SSL to your AWS ALB using Terraform. The HTTPS listener is now configured to handle secure traffic on port 443, routing it to the appropriate target groups based on the Host header.

    This setup not only ensures that your application traffic is encrypted but also maintains the flexibility of routing based on different host headers. This is crucial for securing web applications and complying with modern web security standards.