0

I am trying to describe VPC using terraform, like this article https://networkfirewall.workshop.aws/setup/distributedmodel.html

# VPC
resource "aws_vpc" "eu-central-1" {
  cidr_block = "10.11.0.0/16"
}

resource "aws_subnet" "private_a" {
  vpc_id     = aws_vpc.eu-central-1.id
  cidr_block = "10.11.0.0/20"
  availability_zone = "eu-central-1a"

  tags = {
    Name = "Private A"
  }
}

resource "aws_subnet" "private_b" {
  vpc_id     = aws_vpc.eu-central-1.id
  cidr_block = "10.11.16.0/20"
  availability_zone = "eu-central-1b"

  tags = {
    Name = "Private B"
  }
}

resource "aws_subnet" "public_a" {
  vpc_id     = aws_vpc.eu-central-1.id
  cidr_block = "10.11.64.0/20"
  availability_zone = "eu-central-1a"
  map_public_ip_on_launch = true

  tags = {
    Name = "Public A"
  }
}

resource "aws_subnet" "public_b" {
  vpc_id     = aws_vpc.eu-central-1.id
  cidr_block = "10.11.80.0/20"
  availability_zone = "eu-central-1b"
  map_public_ip_on_launch = true

  tags = {
    Name = "Public B"
  }
}

resource "aws_subnet" "firewall_a" {
  vpc_id     = aws_vpc.eu-central-1.id
  cidr_block = "10.11.255.16/28"
  availability_zone = "eu-central-1a"
  map_public_ip_on_launch = true

  tags = {
    Name = "Firewall A"
  }
}

resource "aws_subnet" "firewall_b" {
  vpc_id     = aws_vpc.eu-central-1.id
  cidr_block = "10.11.255.32/28"
  availability_zone = "eu-central-1b"
  map_public_ip_on_launch = true

  tags = {
    Name = "Firewall B"
  }
}
# Routes
resource "aws_route_table" "private_a" {
  vpc_id = aws_vpc.eu-central-1.id

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

resource "aws_route_table" "private_b" {
  vpc_id = aws_vpc.eu-central-1.id

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

resource "aws_route_table" "public_a" {
  vpc_id = aws_vpc.eu-central-1.id

  route {
    cidr_block = "0.0.0.0/0"
    vpc_endpoint_id = tolist(aws_networkfirewall_firewall.firewall_a.firewall_status[0].sync_states)[0].attachment[0].endpoint_id
  }
}

resource "aws_route_table" "public_b" {
  vpc_id = aws_vpc.eu-central-1.id

  route {
    cidr_block = "0.0.0.0/0"
    vpc_endpoint_id = tolist(aws_networkfirewall_firewall.firewall_b.firewall_status[0].sync_states)[0].attachment[0].endpoint_id
  }
}

resource "aws_route_table" "firewall_all" {
  vpc_id = aws_vpc.eu-central-1.id

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

resource "aws_route_table" "igw" {
  vpc_id = aws_vpc.eu-central-1.id

  route {
    cidr_block = "10.11.80.0/20"
    vpc_endpoint_id = tolist(aws_networkfirewall_firewall.firewall_b.firewall_status[0].sync_states)[0].attachment[0].endpoint_id
  }

  route {
    cidr_block = "10.11.64.0/20"
    vpc_endpoint_id = tolist(aws_networkfirewall_firewall.firewall_a.firewall_status[0].sync_states)[0].attachment[0].endpoint_id
  }
}

resource "aws_route_table_association" "igw" {
  gateway_id     = aws_internet_gateway.gw.id
  route_table_id = aws_route_table.igw.id
}

resource "aws_route_table_association" "private_a" {
  subnet_id      = aws_subnet.private_a.id
  route_table_id = aws_route_table.private_a.id
}

resource "aws_route_table_association" "private_b" {
  subnet_id      = aws_subnet.private_b.id
  route_table_id = aws_route_table.private_b.id
}

resource "aws_route_table_association" "public_a" {
  subnet_id      = aws_subnet.public_a.id
  route_table_id = aws_route_table.public_a.id
}

resource "aws_route_table_association" "public_b" {
  subnet_id      = aws_subnet.public_b.id
  route_table_id = aws_route_table.public_b.id
}

resource "aws_route_table_association" "firewall_a" {
  subnet_id      = aws_subnet.firewall_a.id
  route_table_id = aws_route_table.firewall_all.id
}

resource "aws_route_table_association" "firewall_b" {
  subnet_id      = aws_subnet.firewall_b.id
  route_table_id = aws_route_table.firewall_all.id
}
# Net instances
resource "aws_internet_gateway" "gw" {
  vpc_id = aws_vpc.eu-central-1.id
}

resource "aws_nat_gateway" "nat_gw_a" {
  allocation_id = aws_eip.nat_gw_a.id
  subnet_id     = aws_subnet.public_a.id

  tags = {
    Name = "NAT gw A"
  }
}

resource "aws_nat_gateway" "nat_gw_b" {
  allocation_id = aws_eip.nat_gw_b.id
  subnet_id     = aws_subnet.public_b.id

  tags = {
    Name = "NAT gw B"
  }
}
# firewall
resource "aws_networkfirewall_firewall_policy" "test" {
  name = "test"

  firewall_policy {
    stateless_default_actions          = ["aws:pass"]
    stateless_fragment_default_actions = ["aws:drop"]
  }
}

resource "aws_networkfirewall_firewall" "firewall_a" {
  name                = "firewall-a"
  firewall_policy_arn = aws_networkfirewall_firewall_policy.test.arn
  vpc_id              = aws_vpc.eu-central-1.id
  subnet_mapping {
    subnet_id = aws_subnet.firewall_a.id
  }
}

resource "aws_networkfirewall_firewall" "firewall_b" {
  name                = "firewall-b"
  firewall_policy_arn = aws_networkfirewall_firewall_policy.test.arn
  vpc_id              = aws_vpc.eu-central-1.id
  subnet_mapping {
    subnet_id = aws_subnet.firewall_b.id
  }
}

But when I'm analysing path of packages from "Internet gateway" to EC2 instance in subnet "public_b", I see an error: "Route from 10.11.80.0/20 to gatewayId, in route table rtb-0b6f63fddc7b98f40, cannot transmit the packet because the packet's destination address matches a more specific route."


{
  "explanationCode": "MORE_SPECIFIC_ROUTE",
  "routeTable": {
    "arn": "arn:aws:ec2:eu-central-1:107128487986:route-table/rtb-0b6f63fddc7b98f40",
    "id": "rtb-0b6f63fddc7b98f40"
  },
  "routeTableRoute": {
    "destinationCidr": "10.11.80.0/20",
    "gatewayId": "vpce-008edd7f85458d8b7",
    "origin": "createroute"
  },
  "vpc": {
    "arn": "arn:aws:ec2:eu-central-1:107128487986:vpc/vpc-04a2b379c648fedb0",
    "id": "vpc-04a2b379c648fedb0"
  }
}

And if I delete routes:


  route {
    cidr_block = "10.11.80.0/20"
    vpc_endpoint_id = tolist(aws_networkfirewall_firewall.firewall_b.firewall_status[0].sync_states)[0].attachment[0].endpoint_id
  }

  route {
    cidr_block = "10.11.64.0/20"
    vpc_endpoint_id = tolist(aws_networkfirewall_firewall.firewall_a.firewall_status[0].sync_states)[0].attachment[0].endpoint_id
  }

I see another error:


{
  "destination": {
    "arn": "arn:aws:ec2:eu-central-1:107128487986:internet-gateway/igw-0a78290a9915b1562",
    "id": "igw-0a78290a9915b1562"
  },
  "explanationCode": "NO_ROUTE_TO_DESTINATION",
  "routeTable": {
    "arn": "arn:aws:ec2:eu-central-1:107128487986:route-table/rtb-05eac5e7d51bb9b98",
    "id": "rtb-05eac5e7d51bb9b98"
  },
  "vpc": {
    "arn": "arn:aws:ec2:eu-central-1:107128487986:vpc/vpc-04a2b379c648fedb0",
    "id": "vpc-04a2b379c648fedb0"
  }
}
John Rotenstein
  • 241,921
  • 22
  • 380
  • 470
Roman
  • 1
  • Why do you not have the Route Table for the Internet Gateway routing on `0.0.0.0/0`? – John Rotenstein Dec 06 '21 at 11:22
  • I think Internet Gateways don't need routes 0.0.0.0/0, if it needs, what will be a target? – Roman Dec 06 '21 at 12:03
  • The typical configuration of a Public Subnet is to have a Route Table with a Route configured with a Destination of `0.0.0.0/0` and a Target of the Internet Gateway. This tells the VPC to route any Internet-bound traffic through the Internet Gateway. This is, in fact, what makes a subnet into a "Public Subnet". – John Rotenstein Dec 06 '21 at 22:24
  • Yes, but I want to control all traffic by firewalls. That is why a destination 0.0.0.0/0 in public subnets has a target firewall endpoints. Any ideas? – Roman Dec 07 '21 at 11:33
  • Perhaps [Examples: Middlebox routing - Amazon Virtual Private Cloud](https://docs.aws.amazon.com/vpc/latest/userguide/middlebox-routing-examples.html) or [Deployment models for AWS Network Firewall with VPC routing enhancements | Networking & Content Delivery](https://aws.amazon.com/blogs/networking-and-content-delivery/deployment-models-for-aws-network-firewall-with-vpc-routing-enhancements/). – John Rotenstein Dec 07 '21 at 22:14
  • Thanks! Anyway, I destroyed everything by terraform and applied again, and everything works... – Roman Dec 09 '21 at 07:40

0 Answers0