I got the following setup to create the networking requirements for a Fargate setup:
resource "aws_vpc" "main" {
cidr_block = var.cidr
tags = {
Environment = var.environment
DO_NOT_DELETE = true
CreatedBy = "terraform"
}
}
resource "aws_internet_gateway" "main" {
vpc_id = aws_vpc.main.id
tags = {
Environment = var.environment
CreatedBy = "terraform"
Vpc = aws_vpc.main.id
}
}
data "aws_availability_zones" "region_azs" {
state = "available"
}
locals {
az_count = length(data.aws_availability_zones.region_azs.names)
}
resource "aws_subnet" "private" {
vpc_id = aws_vpc.main.id
cidr_block = cidrsubnet(aws_vpc.main.cidr_block, 4, count.index)
availability_zone = data.aws_availability_zones.region_azs.names[count.index]
count = local.az_count
tags = {
Name = "public-subnet-${data.aws_availability_zones.region_azs.names[count.index]}"
AvailabilityZone = data.aws_availability_zones.region_azs.names[count.index]
Environment = var.environment
CreatedBy = "terraform"
Vpc = aws_vpc.main.id
Type = "private"
DO_NOT_DELETE = true
}
}
resource "aws_subnet" "public" {
vpc_id = aws_vpc.main.id
cidr_block = cidrsubnet(aws_vpc.main.cidr_block, 4, count.index + local.az_count )
availability_zone = data.aws_availability_zones.region_azs.names[count.index]
count = local.az_count
map_public_ip_on_launch = true
tags = {
Environment = var.environment
CreatedBy = "terraform"
Vpc = aws_vpc.main.id
DO_NOT_DELETE = true
Type = "public"
}
}
resource "aws_route_table" "public" {
vpc_id = aws_vpc.main.id
tags = {
Environment = var.environment
CreatedBy = "terraform"
Vpc = aws_vpc.main.id
Type = "public"
}
}
resource "aws_route" "public" {
route_table_id = aws_route_table.public.id
destination_cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.main.id
}
resource "aws_route_table_association" "public" {
count = local.az_count
subnet_id = element(aws_subnet.public.*.id, count.index)
route_table_id = aws_route_table.public.id
}
resource "aws_nat_gateway" "main" {
count = local.az_count
allocation_id = element(aws_eip.nat.*.id, count.index)
subnet_id = element(aws_subnet.public.*.id, count.index)
depends_on = [aws_internet_gateway.main]
tags = {
Environment = var.environment
CreatedBy = "terraform"
Vpc = aws_vpc.main.id
}
}
resource "aws_eip" "nat" {
count = local.az_count
vpc = true
tags = {
CreatedBy = "terraform"
Vpc = aws_vpc.main.id
}
}
resource "aws_route_table" "private" {
count = local.az_count
vpc_id = aws_vpc.main.id
tags = {
Environment = var.environment
CreatedBy = "terraform"
Type = "private"
Vpc = aws_vpc.main.id
}
}
resource "aws_route" "private" {
count = local.az_count
route_table_id = element(aws_route_table.private.*.id, count.index)
destination_cidr_block = "0.0.0.0/0"
nat_gateway_id = element(aws_nat_gateway.main.*.id, count.index)
}
resource "aws_route_table_association" "private" {
count = local.az_count
subnet_id = element(aws_subnet.private.*.id, count.index)
route_table_id = element(aws_route_table.private.*.id, count.index)
}
resource "aws_security_group" "alb" {
name = "${var.resources_name_prefix}-alb-sg"
vpc_id = aws_vpc.main.id
ingress {
protocol = "tcp"
from_port = 80
to_port = 80
cidr_blocks = ["0.0.0.0/0"]
ipv6_cidr_blocks = ["::/0"]
}
ingress {
protocol = "tcp"
from_port = 443
to_port = 443
cidr_blocks = ["0.0.0.0/0"]
ipv6_cidr_blocks = ["::/0"]
}
egress {
protocol = "-1"
from_port = 0
to_port = 0
cidr_blocks = ["0.0.0.0/0"]
ipv6_cidr_blocks = ["::/0"]
}
tags = {
Environment = var.environment
CreatedBy = "terraform"
Vpc = aws_vpc.main.id
}
}
resource "aws_security_group" "ecs_tasks" {
name = "${var.resources_name_prefix}-ecs-sg"
vpc_id = aws_vpc.main.id
ingress {
protocol = "tcp"
from_port = 3000
to_port = 3000
cidr_blocks = ["0.0.0.0/0"]
ipv6_cidr_blocks = ["::/0"]
}
egress {
protocol = "-1"
from_port = 0
to_port = 0
cidr_blocks = ["0.0.0.0/0"]
ipv6_cidr_blocks = ["::/0"]
}
tags = {
Environment = var.environment
CreatedBy = "terraform"
Vpc = aws_vpc.main.id
}
}
This is been working great for a couple availability zones, but now that I'm dynamically creating subnets for running tasks in every AZ per region, I'm reaching the limit of Elastic IP's per region.
So I'm getting this erorr while trying to create the stack:
Error creating EIP: AddressLimitExceeded: The maximum number of addresses has been reached.
status code: 400
I'm wodering if the following part:
resource "aws_nat_gateway" "main" {
count = local.az_count
allocation_id = element(aws_eip.nat.*.id, count.index)
subnet_id = element(aws_subnet.public.*.id, count.index)
depends_on = [aws_internet_gateway.main]
tags = {
Environment = var.environment
CreatedBy = "terraform"
Vpc = aws_vpc.main.id
}
}
resource "aws_eip" "nat" {
count = local.az_count
vpc = true
tags = {
CreatedBy = "terraform"
Vpc = aws_vpc.main.id
}
}
Could be structured to use a single EIP and routing internally, if this makes sense.