Single gateway on AWS — Terraform / CloudFormation
A minimal, production-shaped landing zone for the Enforza NVA — one VPC, one firewall in a public subnet, and two private workload subnets whose internet-bound traffic is routed through the firewall for secure NAT and Layer-7 egress filtering. Deploy it with Terraform or CloudFormation (including a click-by-click console upload if you’d rather not touch a command line) — both build the identical architecture.
Architecture
Section titled “Architecture” Internet (0.0.0.0/0) │ Internet Gateway │ VPC · enforza-single-gateway · 10.0.0.0/16 ┌────────────────────────────────────────────────────────┐ │ Public subnet · 10.0.0.0/24 · AZ 0 │ │ enforza-fw (NVA) · c6i.large · src/dest check OFF │ │ SNAT egress · L7 filtering · Elastic IP │ │ public-rt: 0.0.0.0/0 → IGW │ │ │ │ Private subnet A Private subnet B │ │ 10.0.1.0/24 · AZ 0 10.0.2.0/24 · AZ 1 │ │ workloads (no public IP) workloads (no public IP) │ │ private-rt-a: private-rt-b: │ │ 0.0.0.0/0 → firewall ENI 0.0.0.0/0 → firewall ENI │ └────────────────────────────────────────────────────────┘What it deploys
Section titled “What it deploys”- One VPC (
10.0.0.0/16) and one Internet Gateway. - One public subnet (
10.0.0.0/24, AZ 0) hosting the Enforza firewall with an Elastic IP; public IPs auto-assign at launch so the box has outbound internet for its first-boot bootstrap. - Two private workload subnets (
10.0.1.0/24AZ 0,10.0.2.0/24AZ 1). - One EC2 instance (default
c6i.large) on a stock base AMI, source/destination check disabled, that bootstraps the engine at boot. - A public route table (
0.0.0.0/0 → IGW) and two private route tables (0.0.0.0/0 → the firewall's network interface).
All resources are tagged Project=enforza and
Scenario=01-single-gateway-deployment-key.
How the first-boot bootstrap works
Section titled “How the first-boot bootstrap works”- The instance boots from a stock base AMI — no Enforza software baked in.
cloud-initruns the user-data script, which fetches the public installer and passes it your deployment key.- The installer sets up prerequisites and the Enforza engine, which registers with the Enforza cloud using the key.
- The key is consumed (one-time use), and the firewall appears in the console, ready to claim.
The installer targets prod (https://dl.neon.efz.io/install.sh). The networking is
identical to the Marketplace variant; only the image and first-boot bootstrap
differ.
Prerequisites
Section titled “Prerequisites”- An Enforza deployment (registration) key — one per firewall.
- An AWS account, a region, and credentials configured.
- Terraform ≥ 1.5 (AWS provider
~> 5.0) or the AWS CLI / Console for CloudFormation.
Get a deployment key
Section titled “Get a deployment key”Console (CCX): sidebar → Onboard Firewall → Deployment Keys →
Generate a key → choose Single-use (one firewall per key). Copy it — it
looks like efz_xxxxxxxxxxxxxxxx.
This is the same key used in the AWS Lab guide (Part 3). The engine swaps it for a long-lived licence at first boot, so the key is spent once used. Mint one key per firewall — a single-use key is consumed by the first engine that registers with it.
Option A — Deploy with Terraform
Section titled “Option A — Deploy with Terraform”Work in the terraform/ directory and pass your deployment key as a variable:
cd terraformterraform initterraform plan -var deployment_key=efz_xxxxxxxxxxxxxxxxterraform apply -var deployment_key=efz_xxxxxxxxxxxxxxxxinit downloads the AWS provider, plan shows exactly what will be created, and
apply builds it. The whole VPC, subnets, route tables, firewall instance and
Elastic IP come up together; the firewall bootstraps itself on first boot with the
key you passed.
Optional overrides — append any of these -var flags:
-var base_ami_id=ami-xxxxxxxx # pin a base image-var instance_type=c6i.xlarge-var ssh_key_name=my-key# CIDRs: vpc_cidr, public_subnet_cidr, private_subnet_a_cidr, private_subnet_b_cidrOption B — Deploy with CloudFormation (CLI)
Section titled “Option B — Deploy with CloudFormation (CLI)”One self-contained template builds the identical architecture. Pass your key as a parameter override:
aws cloudformation deploy \ --template-file cloudformation/template.yaml \ --stack-name enforza-single-gateway-deployment-key \ --parameter-overrides DeploymentKey=efz_xxxxxxxxxxxxxxxx \ --capabilities CAPABILITY_NAMED_IAMCAPABILITY_NAMED_IAM is required because the stack creates a named IAM role for
the instance. Optional parameters: BaseAmiId, InstallUrl, InstanceType,
SshKeyName, and the CIDR parameters (VpcCidr, PublicSubnetCidr,
PrivateSubnetACidr, PrivateSubnetBCidr).
Prefer clicking to typing? Upload the template in the AWS Console
Section titled “Prefer clicking to typing? Upload the template in the AWS Console”- Download the template — grab
cloudformation/template.yamlfrom the deployment artifacts bundle. - Open CloudFormation → Create stack → With new resources (standard).
- Choose the template → Template is ready → Upload a template file → select
template.yaml→ Next. - Name it and set parameters — Stack name
enforza-single-gateway-deployment-key; pasteDeploymentKey = efz_xxxxxxxxxxxxxxxx; leave the rest at defaults (or setInstanceType,SshKeyName,InstallUrl, CIDRs) → Next. - Stack options — nothing required → Next.
- Acknowledge IAM & submit — tick “I acknowledge that AWS CloudFormation might create IAM resources with custom names” → Submit.
- Watch it build — the Events tab streams to
CREATE_COMPLETE; the Outputs tab showsFirewallInstanceId— the instance you’ll claim in the console.
The IAM acknowledgement is the console’s equivalent of the CLI’s
--capabilities CAPABILITY_NAMED_IAM.
Claim the firewall, and how traffic flows
Section titled “Claim the firewall, and how traffic flows”Once the engine has registered (a minute or two after boot), it appears in the
Enforza console under Firewalls, where you can claim and manage it. The
firewall_instance_id / FirewallInstanceId output identifies the instance.
End-to-end path:
- A workload in a private subnet sends traffic to the internet.
- Its private route table sends
0.0.0.0/0to the firewall’s network interface — not to an IGW or NAT gateway. - The engine inspects and filters the egress at Layer 7, then SNATs the packet to the firewall’s Elastic IP.
- The public route table sends
0.0.0.0/0to the Internet Gateway, and the packet leaves. - Return traffic follows the reverse path back through the firewall to the workload.
Teardown — stop the meter
Section titled “Teardown — stop the meter”Remove everything when you’re done, then delete the firewall from the Enforza console.
# Terraformcd terraformterraform destroy -var deployment_key=efz_xxxxxxxxxxxxxxxx
# CloudFormationaws cloudformation delete-stack --stack-name enforza-single-gateway-deployment-keyTo scale out, add private subnets and point their route tables at the same firewall ENI, or deploy another gateway with a fresh key.