Skip to content

creates a central egress vpc using nat gateway and aws network firewall for transit gateway

Notifications You must be signed in to change notification settings

fortunecookiezen/aws-tf-egress-vpc-tgw-nwf

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

42 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

AWS Central Egress VPC with Network Firewall

Description

Terraform code to create a central egress vpc using nat gateway and aws network firewall as documented by aws in Building a Scalable and Secure Multi-VPC AWS Network Infrastructure

The module creates a default firewall policy and firewall rule groups that allow output HTTP and HTTPS traffic only to a list of configurable ports.

Credit to the following authors and projects for providing helpful examples:

Diagram

Diagram

Why did you build this?

Truthfully, I wanted a stack as simple to deploy as Checkpoint's CloudGuard Transit Gateway Auto Scaling Group, but utilizing aws services. I work with a firewall team that has little experience with aws and a strong preference for Checkpoint and this is a demonstration of how aws services can perform the same functionality.

Usage

module "egress_vpc" {
  source              = "../"
  name                = "egress"
  prefix              = "fncz"
  cidr                = "10.1.1.0/24" # cidr shouldn't be bigger than /24
  home_net            = "10.0.0.0/8"
  firewall_policy_arn = aws_networkfirewall_firewall_policy.egress.arn

  # /24 can scale to 4 AZ
  #   public_subnets          = ["10.1.1.64/27", "10.1.1.96/27", "10.1.1.128/27", "10.1.1.160/27"]
  #   firewall_subnets        = ["10.1.1.0/28", "10.1.1.16/28", "10.1.1.32/28", "10.1.1.48/28"]
  #   transit_gateway_subnets = ["10.1.1.192/28", "10.1.1.208/28", "10.1.1.224/28", "10.1.1.240/28"]

  http_ports              = ["80"]
  tls_ports               = ["443"]
  public_subnets          = ["10.1.1.64/27", "10.1.1.96/27"]
  firewall_subnets        = ["10.1.1.0/28", "10.1.1.16/28"] # these should not be larger than /28. nothing else should live here.
  transit_gateway_subnets = ["10.1.1.192/28", "10.1.1.208/28"]
  availability_zone_names = ["us-east-1a", "us-east-1b"]
  transit_gateway_id      = "tgw-080381551298c8919"
  vpc_flow_logs           = "CLOUDWATCH"

  tags = var.tags

  firewall_policy_tags = {
    Name = "default-egress-policy"
  }

  firewall_tags = {
    vpc = "egress-vpc"
  }
}

# How to add local resources and override the default egress policy
# and rules the module creates by specifying your own policy and rules

resource "aws_networkfirewall_firewall_policy" "egress" {
  name = "egress-policy"

  firewall_policy {
    stateless_default_actions          = ["aws:forward_to_sfe"]
    stateless_fragment_default_actions = ["aws:forward_to_sfe"]

    stateful_rule_group_reference {
      resource_arn = aws_networkfirewall_rule_group.domainlist.arn
    }

    stateless_rule_group_reference {
      priority     = 10
      resource_arn = aws_networkfirewall_rule_group.drop.arn
    }
  }
  tags = merge(
    {},
    var.tags
  )
}

resource "aws_networkfirewall_rule_group" "domainlist" {
  capacity = 1000
  name     = "domain-white-list"
  type     = "STATEFUL"

  rule_group {
    rule_variables {
      ip_sets {
        key = "HOME_NET"
        ip_set {
          definition = ["10.0.0.0/8"]
        }
      }
    }
    rules_source {
      rules_source_list {
        generated_rules_type = "ALLOWLIST"
        target_types = [
          "HTTP_HOST",
          "TLS_SNI"
        ]
        targets = [
          ".amazon.com",
          ".amazonaws.com",
          ".awsstatic.com",
          ".aws.dev",
          ".auth0.com",
          ".google.com",
          ".okta.com",
          "pypi.python.org",
          ".pypi.org",
          ".pythonhosted.org",
          "slashdot.org"
        ]
      }
    }
  }
  tags = merge(
    {},
    var.tags
  )
}

variable "tags" {
  type = map(string)
  default = {
    costcenter = "12345"
  }
}

resource "aws_networkfirewall_rule_group" "drop" {
  capacity    = 10
  name        = "egress-drop"
  description = "stateless rule group that forwards http/s outbound traffic to stateful rules for inspection and drops all other traffic"
  type        = "STATELESS"

  rule_group {
    rules_source {
      stateless_rules_and_custom_actions {
        stateless_rule {
          priority = 10
          rule_definition {
            actions = ["aws:forward_to_sfe"]
            match_attributes {
              source {
                address_definition = "10.0.0.0/8"
              }
              source_port {
                from_port = 0
                to_port   = 65535
              }
              destination {
                address_definition = "0.0.0.0/0"
              }
              destination_port {
                from_port = 80
                to_port   = 80
              }
              destination_port {
                from_port = 443
                to_port   = 443
              }
              protocols = [6]
            }
          }
        }
        stateless_rule {
          priority = 100
          rule_definition {
            actions = ["aws:drop"]
            match_attributes {
              source {
                address_definition = "10.0.0.0/8"
              }
              destination {
                address_definition = "0.0.0.0/0"
              }
            }
          }
        }
      }
    }
  }
  tags = merge(
    {},
    var.tags
  )
}

# Provided as an example of accessing the anfw vpce assigned to a specific az

output "anwf-vpce-us-east-1a" {
  value = lookup(module.egress_vpc.vpce_lookup, "us-east-1a")
}

output "anwf-vpce-us-east-1b" {
  value = lookup(module.egress_vpc.vpce_lookup, "us-east-1b")
}

Requirements

No requirements.

Providers

Name Version
aws n/a

Modules

No modules.

Inputs

Name Description Type Default Required
availability_zone_names list of availability zones for subnet coverage, like us-east-1a, us-east-1b, etc. This module will create a set of three subnets (public, firewall, transit gateway) per availability zone list(string)
[
"us-east-1a"
]
no
bucket_tags A map of tags to add to s3 buckets map(string) {} no
cidr cidr block for this vpc. It really doesn't need to be larger than /24. string n/a yes
enable_dns_hostnames Should be true to enable DNS hostnames in the VPC bool true no
enable_dns_support Should be true to enable DNS support in the VPC bool true no
firewall_acl_tags Additional tags for the firewall subnets network ACL map(string) {} no
firewall_log_group_name name of the cloudwatch log group for firewall logs. Defaults to "Firewall". string "firewall" no
firewall_policy_arn arn of the firewall policy. Overrides default policy of any -> any string "" no
firewall_policy_tags Additional tags for the firewall policy map(string) {} no
firewall_subnet_route_table_tags Additional tags for the firewall subnet route tables map(string) {} no
firewall_subnet_suffix Suffix to append to firewall subnet name string "network-firewall" no
firewall_subnet_tags Additional tags for the firewall subnets map(string) {} no
firewall_subnets A list of firewall subnet cidr blocks inside the VPC. Firewall subnets should not be larger than /28. Nothing else can live in these subnets. list(string) [] no
firewall_tags Additional tags for the firewall map(string) {} no
flow_log_bucket_arn Optional arn of s3 bucket destination for flow logs. If not specified, a bucket will be created. string "" no
home_net summary cidr block for all resources behind this egress vpc string "10.0.0.0/8" no
http_ports Destination ports for HTTP traffic list(string)
[
"80"
]
no
igw_tags Additional tags for the internet gateway map(string) {} no
kms_master_key_id AWS KMS master key id used for bucket and log storage encryption. If empty, this module will use the default AWS-managed kms service key. string "" no
log_retention_days Number of days to retain cloudwatch logs, default is 90 number 90 no
name Name to be used on all the resources as identifier string "anwf" no
nat_eip_tags Additional tags for the NAT EIP map(string) {} no
nat_gateway_tags Additional tags for the NAT gateways map(string) {} no
prefix prefix prepended to certain resource names for organizational clarity string "fncz" no
private_route_table_routes Configuration block of routes. See https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/default_route_table#route list(map(string)) [] no
public_acl_tags Additional tags for the public subnets network ACL map(string) {} no
public_subnet_route_table_tags Additional tags for the public subnet route tables map(string) {} no
public_subnet_suffix Suffix to append to public subnet name string "public" no
public_subnet_tags Additional tags for the public subnets map(string) {} no
public_subnets A list of public subnet cidr blocks inside the VPC list(string) [] no
s3_log_bucket Name of s3 bucket for s3 bucket access logs string "" no
s3_logs send firewall logs to s3 bucket. If unset, logs will not be sent. Allowed values are "ALERT" and "FLOW". string "" no
tags A map of tags to add to all resources map(string) {} no
tls_ports Destination ports for TLS traffic list(string)
[
"443"
]
no
transit_gateway_acl_tags Additional tags for the transit gateway subnets network ACL map(string) {} no
transit_gateway_id id of the transit gateway for tgw subnet attachment string n/a yes
transit_gateway_subnet_route_table_tags Additional tags for the transit gateway subnet route tables map(string) {} no
transit_gateway_subnet_suffix Suffix to append to transit gateway subnet name string "transit-gateway" no
transit_gateway_subnet_tags Additional tags for the transit gateway subnets map(string) {} no
transit_gateway_subnets A list of transit gateway attached subnet cidr blocks inside the VPC list(string) [] no
vpc_flow_logs Log vpc traffic flows. If unset, vpc traffic flows will not be logged. If set, all vpc traffic will be logged. Allowed values are "CLOUDWATCH" and "S3". string "" no
vpc_tags Additional tags for the VPC map(string) {} no

Resources

Name Type
aws_cloudwatch_log_group.alert resource
aws_cloudwatch_log_group.egress_vpc resource
aws_cloudwatch_log_group.flow resource
aws_default_network_acl.default resource
aws_default_security_group.default resource
aws_ec2_transit_gateway_vpc_attachment.egress resource
aws_eip.nat resource
aws_flow_log.egress_vpc resource
aws_iam_role.flow_log resource
aws_iam_role_policy.flow_log resource
aws_internet_gateway.this resource
aws_nat_gateway.this resource
aws_network_acl.firewall resource
aws_network_acl.public resource
aws_network_acl.transit_gateway resource
aws_networkfirewall_firewall.egress resource
aws_networkfirewall_firewall_policy.default resource
aws_networkfirewall_logging_configuration.cloudwatch resource
aws_networkfirewall_rule_group.stateful-egress resource
aws_networkfirewall_rule_group.stateless-egress resource
aws_route.firewall_subnet_default_route resource
aws_route.firewall_subnet_home_net_route resource
aws_route.public_home_net resource
aws_route.public_internet_gateway resource
aws_route.transit_gateway_subnet_default_route resource
aws_route_table.firewall_subnet resource
aws_route_table.public_subnet resource
aws_route_table.transit_gateway_subnet resource
aws_route_table_association.firewall resource
aws_route_table_association.public_subnet resource
aws_route_table_association.transit_gateway_subnet resource
aws_s3_bucket.flow_logs resource
aws_s3_bucket_logging.flow_logs resource
aws_s3_bucket_public_access_block.block resource
aws_s3_bucket_server_side_encryption_configuration.crypto resource
aws_s3_bucket_versioning.versioning resource
aws_subnet.firewall resource
aws_subnet.public resource
aws_subnet.transit_gateway resource
aws_vpc.egress resource
aws_availability_zones.azs data source
aws_caller_identity.current data source
aws_ec2_transit_gateway.this data source
aws_region.current data source

Outputs

Name Description
firewall_attachments output used to inspect firewall endpoint ids for route creation
network_firewall_endpoint_id Created Network Firewall endpoint id
transit_gateway_subnet_ids transit gateway subnet ids
vpce_lookup Provided for troubleshooting so you can access per-az maps of anwf enis

About

creates a central egress vpc using nat gateway and aws network firewall for transit gateway

Topics

Resources

Stars

Watchers

Forks

Packages

No packages published