In this example we are going to show you how you can use a single Application Load Balancer(ALB) for separate ECS’s.
Imagine, you have 30 ECS’s running on Fargate. You want 10 of those to be exposed. If you would use ALB for every single ECS, this would be very inefficient and expensive. To combat this, AWS supports routing traffic on ALB to Target Groups (ECS can be one example of a target group) based on rules. In this way, you can have one ALB which will route traffic to the Target Group (in our example this will be ECS).
Below is one example of how you can do that with comments about specific details.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# First create a target group for each of your services, this is target group to | |
# Docker ECS service running on AWS Fargate | |
resource "aws_lb_target_group" "this" { | |
name = "${local.this_name}-alb-tg" | |
port = var.app_port | |
protocol = "HTTP" | |
vpc_id = var.config.vpc_id | |
target_type = "ip" | |
health_check { | |
healthy_threshold = "3" | |
interval = "120" | |
protocol = "HTTP" | |
matcher = "200-299" | |
timeout = "119" | |
path = var.health_check_path | |
unhealthy_threshold = "2" | |
} | |
tags = { | |
Team = var.config.team | |
Environment = var.config.env | |
Application = var.app_name | |
} | |
} | |
# Then, create ALB. This is the internal ALB. | |
# Hint: *Always use tags. It's much easier to do cost management and resource tracking. | |
resource "aws_lb" "this" { | |
name = "${local.wd_app_name}-alb" | |
internal = true | |
subnets = var.config.lb_subnets_ids | |
load_balancer_type = "application" | |
security_groups = [aws_security_group.lb.id] | |
idle_timeout = 300 | |
tags = { | |
Team = var.config.team | |
Environment = var.config.env | |
Application = local.wd_app_name | |
} | |
} | |
# This is how you route traffic to a specific target group based on the host header. | |
# For each of your services, you need to create specific rules for each target group. | |
# In this example, we have only one target group and one router. | |
resource "aws_lb_listener_rule" "this" { | |
listener_arn = "${aws_lb_listener.this.arn}" | |
action { | |
type = "forward" | |
target_group_arn = "${aws_lb_target_group.this.arn}" | |
} | |
condition { | |
host_header { | |
values = var.aws_lb_listener_rules | |
} | |
} | |
} | |
# This is the security group for ALB. | |
# Be aware, this is a very permissive security group for internal ALB. | |
# Tailor it to your needs. | |
resource "aws_security_group" "lb" { | |
name = "${local.this_name}-lb-sg" | |
description = "Access to the Application Load Balancer (ALB)" | |
vpc_id = var.config.vpc_id | |
ingress { | |
protocol = "tcp" | |
from_port = 443 | |
to_port = 443 | |
cidr_blocks = ["0.0.0.0/0"] # All IP ranges | |
} | |
egress { # All traffic is allowed | |
protocol = "-1" # -1 is equivalent to "All" | |
from_port = 0 | |
to_port = 0 | |
cidr_blocks = ["0.0.0.0/0"] | |
} | |
tags = { | |
Name = "${local.this_name}-lb-sg" | |
Team = var.config.team | |
Environment = var.config.env | |
Application = var.app_name | |
} | |
} |