Code Snip: This sites VPC Terraform

Sunday, Feb 1, 2026

Code Snip: The Terraform configuration the VPC

Part of the Terraform for this site This Website

resource "aws_vpc" "ecs_vpc" {
  cidr_block = "10.0.0.0/16"
  enable_dns_hostnames = true
  enable_dns_support = true

  tags = {
    Name = "ECSWebServerVPC"
  }
}

resource "aws_subnet" "public_subnets" {
  count = 2

  vpc_id = aws_vpc.ecs_vpc.id
  map_public_ip_on_launch = true
  availability_zone = data.aws_availability_zones.available_zones.names[count.index]
  cidr_block = "10.0.${count.index + 1}.0/24"
  tags = {
    Name = "ecs_public_subnet_alb_${count.index + 1}"
  }

  lifecycle {
    create_before_destroy = true
  }
}

resource "aws_subnet" "private_subnets" {
  count = 3

  vpc_id = aws_vpc.ecs_vpc.id
  map_public_ip_on_launch = false
  availability_zone = data.aws_availability_zones.available_zones.names[count.index]
  cidr_block = "10.0.${count.index + 10}.0/24"
  tags = {
    Name = "ecs_private_subnet_${count.index + 10}"
  }

  lifecycle {
    create_before_destroy = true
  }
}

resource "aws_internet_gateway" "ecs_igw" {
  vpc_id = aws_vpc.ecs_vpc.id
  tags = {
    Name = "ECSWebServerIGW"
  }
}

resource "aws_eip" "nat_ip_address" {
  domain = "vpc"

  depends_on = [aws_internet_gateway.ecs_igw]
}

resource "aws_nat_gateway" "nat_gateway_for_private_subnets" {
  allocation_id = aws_eip.nat_ip_address.id
  subnet_id = aws_subnet.public_subnets[0].id
}

resource "aws_route_table" "public" {
  vpc_id = aws_vpc.ecs_vpc.id

  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.ecs_igw.id
  }

  tags = {
    Name = "webserver-public-rt"
  }
}

resource "aws_route_table_association" "public" {
  count          = length(aws_subnet.public_subnets)
  subnet_id      = aws_subnet.public_subnets[count.index].id
  route_table_id = aws_route_table.public.id
}

resource "aws_route_table" "private" {
  count  = length(aws_subnet.private_subnets)
  vpc_id = aws_vpc.ecs_vpc.id

  route { 
    cidr_block = "0.0.0.0/0"
    nat_gateway_id = aws_nat_gateway.nat_gateway_for_private_subnets.id
  }

  tags = {
    Name = "private-rt-${count.index + 1}"
  }
}

resource "aws_route_table_association" "private" {
  count = length(aws_subnet.private_subnets)

  subnet_id      = aws_subnet.private_subnets[count.index].id
  route_table_id = aws_route_table.private[count.index].id
}

resource "aws_vpc_endpoint" "s3" {
  vpc_id            = aws_vpc.ecs_vpc.id
  service_name      = "com.amazonaws.${aws_vpc.ecs_vpc.region}.s3"
  vpc_endpoint_type = "Gateway"
  route_table_ids   = [for rt in aws_route_table.private : rt.id]
  tags = { Name = "s3-gateway-endpoint" }

  lifecycle {
    create_before_destroy = true
    replace_triggered_by = [aws_subnet.private_subnets]
  }

  depends_on = [aws_subnet.private_subnets]
}