Search code examples
terraform-provider-awsamazon-vpc

Trouble Adding AWS Network Firewall Endpoint as a Route using Terraform


I have been trying to add my Network Firewall as a vpc endpoint route. But its not working.

resource "aws_route_table" "Inspection_VPC_IGW_Ingress_RT" {
  vpc_id = aws_vpc.Inspection_VPC.id
  
  # Send inbound packets to the FW endpoint in the FW subnet.
  route {
    cidr_block      = "172.0.0.0/8"
    vpc_endpoint_id = aws_networkfirewall_firewall.Transit_FW.firewall_status.sync_states.attachment.endpoint_id
  }

  tags = {
    Name = "Inspection_VPC_RT_IGW"
  }
}

Here is the error I keep getting

│ Error: Unsupported attribute
│
│   on transit_networking.tf line 89, in resource "aws_route_table" "Inspection_VPC_Public_RT":│   89:     vpc_endpoint_id = aws_networkfirewall_firewall.Transit_FW.firewall_status.sync_states.attachment.endpoint_id
│
│ Can't access attributes on a list of objects. Did you mean to access attribute "sync_states" 
│ for a specific element of the list, or across all elements of the list?

Is there an alternative to this, I am curious how I can grab the ENI of the created network firewall endpoint and use a network_interface_id = "" attribute in my route block instead.


Solution

  • I've fixed it!

    When a Network Firewall is deployed two key/value tags are added.

    Firewall = aws_networkfirewall_firewall.Transit_FW.arn
    AWSNetworkFirewallManaged = "true"
    

    So I decided to filter for the endpoint using a data source. I also made sure the state of the endpoint is available too.

    data "aws_vpc_endpoint" "Transit_FW" {
      vpc_id = aws_vpc.Inspection_VPC.id
      state  = "available"
    
      tags = {
        Firewall                  = aws_networkfirewall_firewall.Transit_FW.arn
        AWSNetworkFirewallManaged = "true"
      }
    }
    

    I realized that I can't associate my endpoint with my route table. This is because it is a gateway load balancer service type. But the tricky part is that this load balancer isn't visible on the console or API.

    Next, I used the local source to specify the interface ID of the VPC endpoint as a string so it can be used anywhere in the code.

    locals {
      key = join(",", data.aws_vpc_endpoint.Transit_FW.network_interface_ids)
    }
    

    Then, I read the data of the VPC Endpoint, specifically the interface ID

    data "aws_network_interface" "ENI_0" {
      id = local.key
    }
    

    Lastly, I pass the ID of the interface ID data source to my route table.

    resource "aws_route_table" "Inspection_VPC_IGW_Ingress_RT" {
      vpc_id = aws_vpc.Inspection_VPC.id
    
      # Send inbound packets to the FW endpoint in the FW subnet.
      route {
        cidr_block           = "172.0.0.0/8"
        network_interface_id = data.aws_network_interface.ENI_0.id
      }
    
      tags = {
        Name = "Inspection_VPC_RT_IGW"
      }
    }