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:
- Initialize Terraform: This command initializes the working directory containing the Terraform configuration files.
terraform init
- 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
- 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.
- Initialize Terraform: If you haven’t done so already.
terraform init
- Review the Execution Plan: This command creates an execution plan to review the changes.
terraform plan
- 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.