FortiGate Firewall Security Hub on AWS

Deploy a FortiGate NGFW to inspect all inter-VPC traffic via Transit Gateway.

Introduction

30 Second Summary

When companies run multiple applications in the cloud, they often spread them across separate networks to keep things organized and isolated. But without a security checkpoint in the middle, traffic flows freely between those networks and threats can move laterally from one environment to another.

In this project, you will deploy a Fortinet FortiGate next-generation firewall on AWS as a centralized security hub that inspects and controls all traffic flowing between isolated network environments.

What You'll Build

A secure hub-and-spoke network architecture on AWS where a FortiGate-VM firewall inspects and controls all inter-VPC traffic routed through AWS Transit Gateway.

By the end of this project, you'll have:

  • A Security VPC with a FortiGate-VM next-generation firewall running FortiOS and inspecting all traffic.
  • Two spoke VPCs connected via AWS Transit Gateway in a hub-and-spoke architecture with proper route table segregation.
  • FortiGate firewall policies and IPS (Intrusion Prevention System) actively detecting and blocking threats between spokes.
  • Secret Mission: Configure a site-to-site IPSec VPN from FortiGate to a simulated on-premises network, extending your security hub to a hybrid environment.

Are there any prerequisites?

You need an AWS account with admin permissions and the AWS CLI installed and configured on Windows. This project uses the FortiGate-VM PAYG listing on AWS Marketplace, which includes a 30-day free trial for the firewall license.

Before We Start...

Before you begin the hands-on work, take a moment to lock in what you are building and why it matters.

Before We Start

Prepare Your AWS Environment

Enterprises running multiple VPCs on AWS face a fundamental security challenge. Traffic between VPCs can bypass security controls unless you route it through a centralized inspection point.

In this project, you will deploy a Fortinet FortiGate next-generation firewall as that inspection point. Before building anything, you need to subscribe to the FortiGate VM on AWS Marketplace, verify your CLI tools, and plan your network addressing.

In this step, get ready to:
  • Subscribe to FortiGate VM on AWS Marketplace.
  • Verify your AWS CLI configuration.
  • Plan your network CIDR ranges.
Subscribe to FortiGate VM on AWS Marketplace

The FortiGate-VM is available as a pay-as-you-go (PAYG) product on AWS Marketplace with a 30-day free trial for the firewall license. You need an active subscription before you can launch the FortiGate instance later.

  • Open your web browser and navigate to the AWS Marketplace.
  • Search for Fortinet FortiGate VM Next-Generation Firewall in the search bar.
  • Click on the listing titled Fortinet FortiGate VM Next-Generation Firewall (the PAYG version).
  • Click Continue to Subscribe on the product page.
  • Review the pricing information and the End User License Agreement (EULA).
  • Click Accept Terms to activate the 30-day free trial.
  • Wait for the subscription status to change to Effective. This may take one to two minutes.

What does the free trial cover?

The 30-day free trial waives the FortiGate software license cost. Standard EC2 compute charges still apply when you launch the instance in a later step. After 30 days, the trial auto-converts to a paid subscription unless you cancel.

Do not click Continue to Configuration yet

You only need the subscription active for now. You will launch the FortiGate instance manually in a later step with specific networking requirements.

Subscription stuck on pending?

If the status does not change to Effective after a few minutes, try refreshing the page. Ensure your AWS account has a valid payment method on file. AWS Marketplace subscriptions require a payment method even for free trials.

help me troubleshoot my FortiGate VM AWS Marketplace subscription

Verify your AWS CLI configuration

Before creating any resources, confirm that your AWS CLI is properly configured and can authenticate with your AWS account.

  • Open your terminal (PowerShell on Windows) and verify your identity by running this command:
aws sts get-caller-identity

What does this command do?

This command calls the AWS Security Token Service to confirm which AWS account and IAM identity your CLI is using. It returns your account ID, user ARN, and user ID. If it works, your CLI has valid credentials.

You should see a JSON response with your Account, Arn, and UserId fields.

Seeing an error or empty response?

If you see a credentials error, your AWS CLI is not configured or your credentials have expired. Run aws configure and enter your Access Key ID, Secret Access Key, default region (e.g. us-east-1), and output format (json).

help me fix my AWS CLI credentials configuration

Plan your network CIDR ranges

A hub-and-spoke architecture needs carefully planned IP address ranges. Each VPC gets its own CIDR block, and the blocks must not overlap.

Here is the network plan you will use throughout this project:

  • Security VPC: 10.0.0.0/16 (where the FortiGate firewall lives).
  • Spoke A VPC: 10.1.0.0/16 (first workload environment).
  • Spoke B VPC: 10.2.0.0/16 (second workload environment).
  • TGW subnet within Security VPC: 10.0.3.0/24 (for Transit Gateway attachment).

Why these specific ranges?

Each VPC uses a /16 block from the 10.x.0.0 private range, giving 65,536 addresses per VPC. The ranges are sequential (10.0, 10.1, 10.2) so they are easy to remember and route.

The TGW subnet (10.0.3.0/24) is a dedicated subnet inside the Security VPC specifically for the Transit Gateway attachment. Keeping it separate from the FortiGate's interfaces simplifies routing later.

What is a hub-and-spoke architecture?

In a hub-and-spoke network, a central hub (your Security VPC with FortiGate) connects to multiple spokes (workload VPCs). All traffic between spokes must pass through the hub for inspection. AWS Transit Gateway is the AWS service that connects these VPCs together.

Your subscription is active, your CLI is verified, and your network plan is set. Next up, you will create the Security VPC and deploy the FortiGate-VM instance into it.

Create the Security VPC and Deploy FortiGate-VM

With your FortiGate marketplace subscription active and your CIDR plan ready, it's time to build the Security VPC. This VPC is the heart of your hub-and-spoke architecture.

The FortiGate firewall will live inside this VPC, inspecting all traffic that flows between your spoke networks. You'll create the VPC, set up three purpose-built subnets, and then launch the FortiGate-VM itself.

In this step, get ready to:
  • Create the Security VPC with an Internet Gateway and three subnets.
  • Launch a FortiGate-VM instance from the Marketplace AMI with two network interfaces.
  • Access the FortiGate web GUI and complete initial configuration.
Create the Security VPC with subnets and an Internet Gateway

The Security VPC needs three subnets, each serving a distinct purpose in the firewall architecture. The public subnet hosts FortiGate's external-facing interface, the private subnet hosts its internal interface, and the TGW subnet provides the attachment point for Transit Gateway.

  • In the AWS Management Console, open the VPC service by typing VPC in the top search bar and selecting VPC.
  • On the VPC dashboard, click Create VPC.
  • For Resources to create, select VPC only.
  • Enter Security-VPC in the Name tag field.
  • For IPv4 CIDR block, enter 10.0.0.0/16.
  • Leave all other settings at their defaults and click Create VPC.

Now create the three subnets inside the Security VPC.

  • In the left navigation pane, click Subnets.
  • Click Create subnet.
  • Select Security-VPC from the VPC ID dropdown.
  • For the first subnet, enter Security-Public as the Subnet name and 10.0.1.0/24 as the IPv4 subnet CIDR block.
  • Click Add new subnet to add a second subnet. Enter Security-Private as the name and 10.0.2.0/24 as the CIDR block.
  • Click Add new subnet again. Enter Security-TGW as the name and 10.0.3.0/24 as the CIDR block.
  • Click Create subnet.

Next, attach an Internet Gateway so the FortiGate can reach the internet.

  • In the left navigation pane, click Internet gateways.
  • Click Create internet gateway.
  • Enter Security-IGW as the Name tag and click Create internet gateway.
  • On the success banner at the top of the page, click Attach to a VPC.
  • Select Security-VPC and click Attach internet gateway.

Finally, update the public subnet's route table so it can reach the internet.

  • In the left navigation pane, click Route tables.
  • Select the route table associated with Security-VPC (it was created automatically with the VPC).
  • Click the Routes tab, then click Edit routes.
  • Click Add route. Enter 0.0.0.0/0 as the Destination and select your Security-IGW internet gateway as the Target.
  • Click Save changes.
  • Click the Subnet associations tab, then click Edit subnet associations.
  • Select the Security-Public subnet and click Save associations.

Why three subnets?

Each subnet isolates a different type of traffic. The public subnet lets FortiGate's management interface reach the internet. The private subnet carries inspected traffic between FortiGate and the Transit Gateway. The TGW subnet is where AWS Transit Gateway attaches to this VPC.

Keeping them separate lets you assign different route tables and security group rules to each. This is a production best practice for network segmentation.

Don't see your subnets after creating them?

Make sure you selected Security-VPC in the VPC ID dropdown before creating subnets. If they ended up in the wrong VPC, delete them and recreate them in the correct VPC.

help me find my subnets in the VPC console

Launch the FortiGate-VM instance from the Marketplace AMI

Now you'll launch the actual FortiGate firewall as an EC2 instance. The FortiGate-VM needs two Elastic Network Interfaces (ENIs): port1 in the public subnet for management access, and port2 in the private subnet for internal traffic inspection.

  • Navigate to the EC2 service by typing EC2 in the top search bar and selecting EC2.
  • Click Launch instances.
  • Enter FortiGate-VM in the Name field.
  • Under Application and OS Images, click Browse more AMIs.
  • Click the AWS Marketplace AMIs tab on the left.
  • Search for FortiGate and select the Fortinet FortiGate VM Next-Generation Firewall PAYG listing.
  • Click Continue on the pricing information page.
  • For Instance type, select t3.xlarge.
  • For Key pair, select an existing key pair or click Create new key pair to generate one. Save the key file securely.

Why t3.xlarge?

Fortinet recommends at least 4 GB of RAM for proper FortiGate-VM operation, especially when IPS and unified threat management are enabled. The t3.xlarge instance type provides 4 vCPUs and 16 GB RAM, giving comfortable headroom for production-grade inspection.

Now configure the network settings for the instance.

  • Under Network settings, click Edit.
  • Select Security-VPC as the VPC.
  • Select Security-Public as the subnet (this becomes port1).
  • For Auto-assign public IP, select Disable (you'll assign an Elastic IP instead for a permanent address).
  • Under Firewall (security groups), select Create security group.
  • Name it FortiGate-SG.
  • Add an inbound rule: Type HTTPS, Port 443, Source My IP.
  • Add another inbound rule: Type SSH, Port 22, Source My IP.

Add a second network interface for FortiGate's internal port.

  • Scroll down to Advanced network configuration and expand it.
  • Under Network interfaces, you'll see Network interface 1 already configured for the public subnet.
  • Click Add network interface.
  • For Network interface 2, select the Security-Private subnet (10.0.2.0/24). This becomes port2.
  • For the security group on this interface, create or select a group that allows All traffic from source 10.0.0.0/8.
  • Click Launch instance.

Wait for the instance state to show Running and both status checks to pass. This can take 2-3 minutes.

Now assign an Elastic IP to port1 so you have a permanent address for the FortiGate GUI.

  • In the EC2 left navigation, click Elastic IPs under Network & Security.
  • Click Allocate Elastic IP address, then click Allocate.
  • Select the newly allocated Elastic IP.
  • Click Actions, then Associate Elastic IP address.
  • For Resource type, select Network interface.
  • In the Network interface field, select the ENI in the Security-Public subnet (port1/eth0 of your FortiGate instance).
  • Click Associate.

How do I identify the correct network interface?

Go back to EC2 Instances, select your FortiGate-VM, and look at the Networking tab. You'll see two interfaces listed. The one in the Security-Public subnet (10.0.1.0/24) is port1. Copy its interface ID and use it when associating the Elastic IP.

One final critical step: disable Source/Destination Check on both ENIs so the FortiGate can forward traffic.

  • In the EC2 left navigation, click Network interfaces under Network & Security.
  • Select the first FortiGate ENI (port1 in the public subnet).
  • Click Actions, then Change source/dest. check.
  • Uncheck Enable and click Save.
  • Repeat for the second ENI (port2 in the private subnet).

Why disable Source/Destination Check?

By default, AWS drops traffic on an ENI if the instance is not the source or destination. A firewall forwards traffic between other hosts, so it needs this check disabled to function as an inline inspection device.

Instance stuck in Initializing?

FortiGate-VM can take 3-5 minutes for both status checks to pass on first boot. Wait for the 2/2 checks passed status before proceeding.

help me troubleshoot my FortiGate EC2 instance that isn't passing status checks

Connect to the FortiGate web GUI and complete initial setup

Your FortiGate-VM is running. Now you'll access its web-based management interface, change the default password, and confirm it has a valid license with active FortiGuard services.

  • Copy the Elastic IP address you associated with port1 in the previous substep.
  • Open a new browser tab and navigate to https:// followed by your Elastic IP (for example, https://3.92.45.123).

Seeing a certificate warning? That's expected.

The FortiGate uses a self-signed certificate by default. Your browser will show a security warning. Click Advanced (or Show Details on Safari) and proceed to the site. This is safe for initial configuration.

  • On the FortiGate login page, enter admin as the username.
  • For the password, enter your EC2 instance ID (find it on the EC2 Instances page, e.g. i-0abc123def456789a).
  • Click Login.
  • FortiGate immediately prompts you to change the admin password. Enter a new, strong password and confirm it.
  • Click OK to save the new password.

What are the default credentials?

FortiGate-VM on AWS uses admin as the username and the AWS instance ID as the initial password. You must change this password on first login. Keep your new password in a secure location.

After logging in, verify FortiGate is licensed and connected to FortiGuard.

  • On the FortiGate dashboard, look at the License Information widget. It should show your FortiGate license as valid.
  • Check the FortiGuard section. The services (AV, IPS, Web Filtering) should show green checkmarks indicating they are connected and receiving updates.

FortiGuard services showing as disconnected?

FortiGate PAYG requires internet connectivity to validate its license and download FortiGuard databases. Verify that your Security Group allows outbound traffic on port 443 and that the public subnet route table has the 0.0.0.0/0 route pointing to the Internet Gateway.

help me troubleshoot FortiGuard connectivity on my FortiGate-VM

Your Security VPC is built and your FortiGate firewall is online. Next, you'll create the spoke VPCs with test instances that your firewall will protect.

Create Spoke VPCs and Launch Test Instances

Your Security VPC is live and FortiGate is ready to inspect traffic. Now you need something to actually protect.

In this step, you will create two isolated spoke VPCs that simulate separate workload environments. Each spoke gets a test EC2 instance that can only communicate through the FortiGate firewall once routing is configured in later steps.

In this step, get ready to:
  • Create Spoke A and Spoke B VPCs with private and TGW subnets.
  • Launch a test EC2 instance in each spoke's private subnet.
  • Set up Session Manager access so you can connect without public IPs.
Create the spoke VPCs and subnets

Each spoke VPC represents a separate workload environment. In production, these might be different business units or application tiers that must be isolated from each other.

  • In the AWS Management Console, open the VPC console by searching for VPC in the top search bar and selecting it.
  • In the left navigation pane, click Your VPCs.
  • Click Create VPC.
  • For Resources to create, choose VPC only.
  • For Name tag, enter SpokeA-VPC.
  • For IPv4 CIDR, enter 10.1.0.0/16.
  • Leave all other settings as default and click Create VPC.

Now create the subnets for Spoke A. Each spoke needs a private subnet for workloads and a TGW subnet for the Transit Gateway attachment.

  • In the left navigation pane, click Subnets.
  • Click Create subnet.
  • For VPC ID, select SpokeA-VPC.
  • For the first subnet, set Subnet name to SpokeA-Private and IPv4 subnet CIDR block to 10.1.1.0/24.
  • Click Add new subnet.
  • For the second subnet, set Subnet name to SpokeA-TGW and IPv4 subnet CIDR block to 10.1.2.0/24.
  • Click Create subnet.

Repeat the same process for Spoke B.

  • Click Your VPCs in the left navigation, then Create VPC.
  • For Resources to create, choose VPC only.
  • For Name tag, enter SpokeB-VPC.
  • For IPv4 CIDR, enter 10.2.0.0/16.
  • Click Create VPC.

Now create subnets for Spoke B.

  • Go to Subnets and click Create subnet.
  • For VPC ID, select SpokeB-VPC.
  • For the first subnet, set Subnet name to SpokeB-Private and IPv4 subnet CIDR block to 10.2.1.0/24.
  • Click Add new subnet.
  • For the second subnet, set Subnet name to SpokeB-TGW and IPv4 subnet CIDR block to 10.2.2.0/24.
  • Click Create subnet.

Why two subnets per spoke?

The private subnet hosts actual workloads (EC2 instances). The TGW subnet is dedicated to the Transit Gateway attachment. Separating them gives you precise routing control over traffic that enters and exits via the Transit Gateway.

You should now see both spoke VPCs and their subnets listed in the VPC console.

Don't see your new VPCs?

Check the region selector in the top-right corner of the console. Make sure you are in the same region where you created the Security VPC.

help me find my spoke VPCs in the AWS console

Launch test EC2 instances in each spoke

These lightweight instances simulate the workloads that your FortiGate will eventually protect. They sit in private subnets with no public IP addresses, which is exactly how production workloads are deployed in enterprise environments.

Before launching instances, you need to create a security group for each spoke that allows the test traffic you will use later.

  • In the VPC console left navigation, click Security groups.
  • Click Create security group.
  • For Security group name, enter SpokeA-SG.
  • For Description, enter Allow ICMP and SSH from internal.
  • For VPC, select SpokeA-VPC.
  • Under Inbound rules, click Add rule. Set Type to All ICMP - IPv4 and Source to 10.0.0.0/8.
  • Click Add rule again. Set Type to SSH and Source to 10.0.0.0/8.
  • Click Create security group.

Repeat for Spoke B.

  • Click Create security group again.
  • For Security group name, enter SpokeB-SG.
  • For Description, enter Allow ICMP and SSH from internal.
  • For VPC, select SpokeB-VPC.
  • Add the same two inbound rules: All ICMP - IPv4 from 10.0.0.0/8 and SSH from 10.0.0.0/8.
  • Click Create security group.

Why 10.0.0.0/8 as the source?

The CIDR 10.0.0.0/8 covers all three VPCs in your architecture (10.0.x.x, 10.1.x.x, 10.2.x.x). This allows the spoke instances to accept ICMP pings and SSH from any other instance in your hub-and-spoke network, which is what you need for testing.

Now launch the Spoke A test instance.

  • Open the EC2 console by searching for EC2 in the top search bar.
  • Click Launch instance.
  • For Name, enter SpokeA-Test.
  • Under Application and OS Images, select Amazon Linux 2023 (it should be the default).
  • For Instance type, select t3.micro.
  • For Key pair, select Proceed without a key pair (you will use Session Manager instead of SSH).
  • Under Network settings, click Edit.
  • For VPC, select SpokeA-VPC.
  • For Subnet, select SpokeA-Private (10.1.1.0/24).
  • For Auto-assign public IP, select Disable.
  • For Firewall (security groups), select Select existing security group and choose SpokeA-SG.
  • Expand Advanced details. For IAM instance profile, select the SSM role you will create in the next substep (leave this for now and continue reading).

Before clicking launch, you need the IAM instance profile. You will create it next and then come back to finish launching both instances.

Set up Session Manager access and launch the instances

AWS Systems Manager Session Manager lets you connect to EC2 instances without opening SSH ports to the internet or managing key pairs. The instances just need an IAM role with the right policy attached.

  • Open the IAM console by searching for IAM in the top search bar.
  • In the left navigation, click Roles.
  • Click Create role.
  • For Trusted entity type, choose AWS service.
  • Under Use case, choose EC2, then click Next.
  • On the Add permissions page, search for AmazonSSMManagedInstanceCore.
  • Select the checkbox next to AmazonSSMManagedInstanceCore and click Next.
  • For Role name, enter SSMInstanceProfile.
  • Click Create role.

What is AmazonSSMManagedInstanceCore?

This is an AWS managed policy that grants EC2 instances the permissions needed to communicate with AWS Systems Manager. It enables Session Manager connections, inventory collection, and patch management.

By attaching this policy via an instance profile, your spoke instances become "managed nodes" that you can access through the console without needing public IPs or SSH keys.

Now return to the EC2 console to finish launching your instances.

  • Navigate back to the EC2 console and click Launch instance.
  • For Name, enter SpokeA-Test.
  • Select Amazon Linux 2023 AMI and t3.micro instance type.
  • For Key pair, select Proceed without a key pair.
  • Under Network settings, click Edit. Select SpokeA-VPC, subnet SpokeA-Private, Auto-assign public IP set to Disable.
  • For Firewall (security groups), choose Select existing security group and pick SpokeA-SG.
  • Expand Advanced details. For IAM instance profile, select SSMInstanceProfile.
  • Click Launch instance.

Repeat for Spoke B.

  • Click Launch instance again.
  • For Name, enter SpokeB-Test.
  • Select Amazon Linux 2023 AMI and t3.micro instance type.
  • For Key pair, select Proceed without a key pair.
  • Under Network settings, click Edit. Select SpokeB-VPC, subnet SpokeB-Private, Auto-assign public IP set to Disable.
  • For Firewall (security groups), choose Select existing security group and pick SpokeB-SG.
  • Expand Advanced details. For IAM instance profile, select SSMInstanceProfile.
  • Click Launch instance.

Wait for both instances to reach the Running state. You can check this in the EC2 Instances dashboard.

To verify Session Manager access, navigate to AWS Systems Manager in the console, click Session Manager in the left pane, then click Start session. You should see both spoke instances listed as available targets.

What if my instances don't appear in Session Manager?

It can take 3-5 minutes for new instances to register with Systems Manager. If they still don't appear after 5 minutes, confirm the IAM instance profile SSMInstanceProfile is attached by checking the instance details in the EC2 console under Security tab.

The AmazonSSMManagedInstanceCore policy requires outbound internet access for the SSM agent to phone home. Since these instances are in private subnets with no NAT gateway, Session Manager access will fully work only after Transit Gateway routing is configured in the next steps.

Instance launch failed?

If you see a capacity error, try launching in a different Availability Zone by going back to subnet creation and using a different AZ. If you see a permissions error, confirm your AWS account has EC2 launch permissions.

help me troubleshoot my EC2 instance launch failure

Your spoke workloads are deployed and isolated. Next up, you will connect all three VPCs with AWS Transit Gateway so that traffic can flow between them through FortiGate for inspection.

Deploy AWS Transit Gateway and Attach VPCs

Your three VPCs are ready, but they are completely isolated from each other. Traffic from Spoke A cannot reach Spoke B, and neither spoke can reach the FortiGate in the Security VPC.

To solve this, you need a central router that connects all three VPCs together. AWS Transit Gateway acts as that router. By attaching each VPC to the Transit Gateway and segmenting the route tables, you control exactly how traffic flows between your spokes and your firewall.

In this step, get ready to:
  • Create an AWS Transit Gateway with custom route table settings.
  • Attach all three VPCs to the Transit Gateway.
  • Create separate route tables for Security and Spoke traffic segmentation.
Create the Transit Gateway

The Transit Gateway is the backbone of your hub-and-spoke network. You will disable the default route table settings so you can manually control which attachments share routes with each other.

  • In the AWS Management Console, open the VPC console by searching for VPC in the top search bar.
  • In the left navigation pane, click Transit Gateways.
  • Click Create transit gateway.
  • For Name tag, enter FortiGate-Security-TGW.
  • Leave the Amazon side ASN at its default value.
  • Deselect Default route table association.
  • Deselect Default route table propagation.
  • Leave all other settings at their defaults.
  • Click Create transit gateway.

Why disable default route table association and propagation?

By default, Transit Gateway automatically associates all attachments with a single shared route table and propagates routes between them. This means every VPC can talk to every other VPC directly.

For a security hub, you need separate route tables so that spoke traffic is forced through the FortiGate for inspection. Disabling the defaults gives you full control over traffic segmentation.

  • Wait for the Transit Gateway State to change from Pending to Available. This takes 1-2 minutes. Refresh the page if needed.

Transit Gateway stuck in Pending?

The Transit Gateway typically takes 1-2 minutes to become available. If it stays in Pending for longer than 5 minutes, confirm your IAM user has EC2 full access permissions.

Help me troubleshoot my Transit Gateway creation

Create TGW VPC attachments

With the Transit Gateway available, you can now connect each VPC to it. Each attachment uses a dedicated TGW subnet you created earlier.

  • In the left navigation pane, click Transit Gateway Attachments.
  • Click Create transit gateway attachment.
  • For Name tag, enter Security-VPC-Attachment.
  • For Transit gateway ID, select the FortiGate-Security-TGW you just created.
  • For Attachment type, select VPC.
  • For VPC ID, select your Security VPC (10.0.0.0/16).
  • For Subnet IDs, select the TGW subnet (10.0.3.0/24).
  • Click Create transit gateway attachment.

Now repeat this process for both spoke VPCs.

  • Click Create transit gateway attachment again.
  • For Name tag, enter SpokeA-VPC-Attachment.
  • For Transit gateway ID, select FortiGate-Security-TGW.
  • For Attachment type, select VPC.
  • For VPC ID, select Spoke A VPC (10.1.0.0/16).
  • For Subnet IDs, select the TGW subnet (10.1.2.0/24).
  • Click Create transit gateway attachment.
  • Click Create transit gateway attachment one more time.
  • For Name tag, enter SpokeB-VPC-Attachment.
  • For Transit gateway ID, select FortiGate-Security-TGW.
  • For Attachment type, select VPC.
  • For VPC ID, select Spoke B VPC (10.2.0.0/16).
  • For Subnet IDs, select the TGW subnet (10.2.2.0/24).
  • Click Create transit gateway attachment.
  • Wait for all three attachments to show State as Available. This takes 2-3 minutes per attachment.

What is a TGW VPC attachment?

A VPC attachment connects a VPC to the Transit Gateway. The TGW places a network interface inside the subnet you select, which serves as the entry and exit point for all transit traffic.

This is why you created dedicated TGW subnets earlier. They exist solely for the Transit Gateway interface and keep transit traffic separate from your workload subnets.

Attachment stuck in Pending or Failed?

Confirm that the Transit Gateway itself is in the Available state before creating attachments. Attachments cannot be created against a TGW that is still pending.

If the attachment fails, verify your IAM user has permissions to create service-linked roles for Transit Gateway.

Help me troubleshoot my TGW attachment issue

Create TGW route tables and associate attachments

Route tables determine where the Transit Gateway sends traffic. You need two separate route tables to enforce the security hub pattern: one for the Security VPC and one for the spokes.

  • In the left navigation pane, click Transit Gateway Route Tables.
  • Click Create transit gateway route table.
  • For Name tag, enter Security.
  • For Transit gateway ID, select FortiGate-Security-TGW.
  • Click Create transit gateway route table.
  • Click Create transit gateway route table again.
  • For Name tag, enter Spokes.
  • For Transit gateway ID, select FortiGate-Security-TGW.
  • Click Create transit gateway route table.

Now associate each attachment with the correct route table.

  • Select the Security route table from the list.
  • In the lower panel, click the Associations tab.
  • Click Create association.
  • Select the Security-VPC-Attachment and click Create association.
  • Select the Spokes route table from the list.
  • In the lower panel, click the Associations tab.
  • Click Create association.
  • Select the SpokeA-VPC-Attachment and click Create association.
  • Click Create association again.
  • Select the SpokeB-VPC-Attachment and click Create association.

What do these route table associations accomplish?

The Security route table controls where traffic from the Security VPC (and FortiGate) goes. The Spokes route table controls where traffic from both spoke VPCs goes.

In the next step, you will add routes to the Spokes table that send all traffic to the Security VPC attachment. This forces spoke traffic through the FortiGate for inspection before it can reach another spoke.

  • Verify your associations by clicking each route table and checking the Associations tab shows the correct attachment(s).

Association shows as Disassociated?

Each attachment can only be associated with one route table at a time. If an attachment was previously associated with a different route table (including a default one), you need to disassociate it first before creating a new association.

Help me fix my TGW route table association

Transit Gateway costs

Transit Gateway charges $0.05 per VPC attachment per hour. With three attachments, that is $0.15/hr ($3.60/day). Data processing through the TGW costs $0.02 per GB.

Remember to clean up these resources in the Before You Go section when you are finished with the project.

Your Transit Gateway is now connecting all three VPCs with properly segmented route tables. Next up, you will configure the routing rules that force all spoke traffic through the FortiGate for inspection.

Configure Transit Gateway Routing for Inspection

Your Transit Gateway is connected to all three VPCs, but traffic has no instructions on where to go. Without routes, packets from Spoke A destined for Spoke B will simply be dropped.

In this step, you will program the routing logic that forces all inter-spoke traffic through your Security VPC for inspection by FortiGate. You will configure both the TGW route tables and the VPC-level route tables to create a complete end-to-end traffic path.

In this step, get ready to:
  • Configure the Spokes TGW route table to force all traffic through the Security VPC.
  • Configure the Security TGW route table to return inspected traffic to the correct spoke.
  • Update VPC subnet route tables to complete the traffic flow path.
Add routes to the Spokes TGW route table

The Spokes route table controls where traffic from Spoke A and Spoke B goes next. You need a default route that sends all spoke traffic to the Security VPC attachment, where FortiGate can inspect it.

  • In the VPC console, choose Transit Gateway Route Tables in the navigation pane.
  • Select the Spokes route table you created earlier.
  • Choose Actions, then Create static route.
  • Enter 0.0.0.0/0 as the CIDR block.
  • Choose Active.
  • Select the Security VPC attachment from the dropdown.
  • Choose Create static route.

Why a default route to the Security VPC?

This default route (0.0.0.0/0) sends ALL traffic from the spokes to the Security VPC attachment. The FortiGate in that VPC then inspects the traffic before forwarding it to its final destination.

This is the foundation of the hub-and-spoke security model. No traffic escapes the firewall.

Next, you need to add blackhole routes to prevent direct spoke-to-spoke routing within the TGW.

  • With the Spokes route table still selected, choose Actions, then Create static route.
  • Enter 10.1.0.0/16 as the CIDR block.
  • Choose Blackhole.
  • Choose Create static route.
  • Repeat the process to add a second blackhole route for 10.2.0.0/16.

What are blackhole routes?

A blackhole route drops traffic that matches the CIDR. Without these, the TGW could potentially route spoke-to-spoke traffic directly using more specific routes that bypass the Security VPC.

With the blackhole routes in place, only the 0.0.0.0/0 default route applies, guaranteeing all traffic goes through FortiGate.

  • Click the Routes tab on the Spokes route table to verify your three routes are listed.

You should see three routes: 0.0.0.0/0 pointing to the Security VPC attachment, and 10.1.0.0/16 and 10.2.0.0/16 both marked as blackhole.

Don't see three routes?

Make sure you selected the correct Spokes route table, not the Security route table. If a route is missing, repeat the static route creation steps for the missing CIDR.

help me troubleshoot my Transit Gateway Spokes route table

Add routes to the Security TGW route table

The Security route table tells the TGW how to send inspected traffic back to the correct spoke. Without these return routes, FortiGate can inspect traffic but cannot deliver it to its final destination.

  • Select the Security route table in Transit Gateway Route Tables.
  • Choose Actions, then Create static route.
  • Enter 10.1.0.0/16 as the CIDR block.
  • Choose Active.
  • Select the Spoke A VPC attachment from the dropdown.
  • Choose Create static route.
  • Repeat the process to add a route for 10.2.0.0/16 pointing to the Spoke B VPC attachment.
  • Click the Routes tab on the Security route table to verify both routes appear.

You should see 10.1.0.0/16 pointing to the Spoke A attachment and 10.2.0.0/16 pointing to the Spoke B attachment.

How does this complete the traffic loop?

When Spoke A sends traffic to Spoke B, the Spokes route table sends it to the Security VPC attachment. FortiGate inspects and forwards it. The Security route table then delivers it to the Spoke B attachment.

This two-table design creates a mandatory inspection hop without allowing spokes to bypass the firewall.

Update VPC subnet route tables

The TGW route tables only control traffic within the Transit Gateway itself. You also need to tell each VPC's subnets to send traffic to the TGW in the first place, and to send traffic from the TGW to FortiGate's network interface.

You will update four route tables across three VPCs.

  • In the VPC console, choose Route tables in the navigation pane.
  • Select the route table associated with Spoke A's private subnet (10.1.1.0/24).
  • Choose Actions, then Edit routes.
  • Choose Add route.
  • For Destination, enter 0.0.0.0/0.
  • For Target, select Transit Gateway and choose your TGW ID.
  • Choose Save changes.
  • Repeat the same steps for Spoke B's private subnet (10.2.1.0/24) route table, adding 0.0.0.0/0 to the TGW.

Why default routes on the spoke subnets?

Each spoke's private subnet now sends all non-local traffic to the Transit Gateway. The TGW then applies the Spokes route table rules you configured earlier, directing everything to the Security VPC for inspection.

Now update the Security VPC's TGW subnet route table to point spoke traffic at FortiGate's private interface.

  • Select the route table associated with the Security VPC's TGW subnet (10.0.3.0/24).
  • Choose Actions, then Edit routes.
  • Choose Add route.
  • For Destination, enter 10.1.0.0/16.
  • For Target, select Network Interface and choose FortiGate's port2 ENI (the private subnet interface).
  • Choose Add route again.
  • For Destination, enter 10.2.0.0/16.
  • For Target, select the same FortiGate port2 ENI.
  • Choose Save changes.

Why does the TGW subnet point to an ENI?

When traffic arrives from the Transit Gateway into the Security VPC, it lands in the TGW subnet. The route table for that subnet tells the traffic where to go next inside the VPC.

By pointing spoke CIDRs at FortiGate's port2 network interface, traffic flows directly to the firewall for inspection before being routed onward.

Finally, update the Security VPC's private subnet route table so FortiGate can send inspected traffic back to the TGW.

  • Select the route table associated with the Security VPC's private subnet (10.0.2.0/24).
  • Choose Actions, then Edit routes.
  • Choose Add route.
  • For Destination, enter 10.1.0.0/16. For Target, select Transit Gateway and choose your TGW.
  • Choose Add route again.
  • For Destination, enter 10.2.0.0/16. For Target, select the same TGW.
  • Choose Save changes.

What does this route table do?

FortiGate's port2 sits in the private subnet. After inspecting traffic, FortiGate forwards it out port2. The private subnet route table then sends it back to the TGW, which uses the Security route table to deliver it to the correct spoke.

Not sure which route table belongs to which subnet?

In the VPC console, choose Subnets in the navigation pane. Select any subnet, then check the Route table tab at the bottom of the page to see its associated route table.

help me identify which VPC route table belongs to which subnet

Your routing is fully configured. Next up, you will configure FortiGate's own interfaces and firewall policies so it knows how to handle the traffic flowing through it.

Configure FortiGate Firewall Policies and IPS

Your AWS routing is complete. Every packet leaving a spoke VPC now gets forwarded through the Transit Gateway to your Security VPC.

The FortiGate itself does not yet know how to reach the spoke networks. Without static routes and a firewall policy, the FortiGate will drop traffic that arrives from the TGW subnet. In this step, you will configure the FortiGate's internal interface, add routes to the spokes, and create a firewall policy with IPS enabled to inspect all inter-spoke traffic.

In this step, get ready to:
  • Configure FortiGate port2 and add static routes to both spoke CIDRs.
  • Create a firewall policy allowing and logging spoke-to-spoke traffic.
  • Enable the default IPS sensor for real-time threat detection.
Configure port2 and add static routes to the spokes

Traffic from the spoke VPCs arrives at the FortiGate on port2 (the private interface in the 10.0.2.0/24 subnet). The FortiGate needs static routes telling it to send spoke-bound traffic back through the TGW subnet gateway.

  • Return to the FortiGate web GUI at https://your FortiGate Elastic IP.
  • In the left sidebar, navigate to Network > Interfaces.
  • Find port2 in the list and double-click it (or select it and click Edit).
  • Confirm the IP/Network Mask matches the private subnet IP assigned by AWS (for example, 10.0.2.x/24). If it shows 0.0.0.0/0.0.0.0, set it to the correct IP from the ENI in the AWS console.
  • Click OK to save the interface settings.

Now add the static routes so FortiGate knows how to reach each spoke network.

  • Navigate to Network > Static Routes.
  • Click Create New.
  • Set Destination to Subnet and enter 10.1.0.0/255.255.0.0.
  • Set Gateway Address to 10.0.3.1.
  • Set Interface to port2.
  • Click OK.
  • Click Create New again and repeat for Spoke B: destination 10.2.0.0/255.255.0.0, gateway 10.0.3.1, interface port2.
  • Click OK.

Why 10.0.3.1 as the gateway?

The TGW subnet is 10.0.3.0/24. AWS reserves the first usable IP in every subnet (.1) as the VPC router. Traffic sent to 10.0.3.1 gets picked up by the VPC routing table, which forwards it to the Transit Gateway attachment.

This is the bridge between FortiGate and the TGW. Without this route, FortiGate would not know where to send inspected traffic headed for the spokes.

Verify both routes appear in the static routes list. You should see two entries: 10.1.0.0/16 and 10.2.0.0/16, both with gateway 10.0.3.1 on port2.

Routes not showing up?

Make sure you selected Subnet (not Named Address or Internet Service) in the Destination type. Double-check the subnet mask is 255.255.0.0 (a /16 mask) and not 255.255.255.0.

If the gateway field is greyed out, confirm you selected port2 as the interface first.

Why aren't my FortiGate static routes saving?

Create a firewall policy for inter-spoke traffic

With routing in place, the FortiGate can now receive and forward spoke traffic. But FortiGate blocks all traffic by default unless a firewall policy explicitly allows it. You need a policy that permits spoke-to-spoke communication on port2 while logging every session.

  • In the left sidebar, navigate to Policy & Objects > Firewall Policy.
  • Click Create New.
  • Enter a Name for the policy, such as Spoke-to-Spoke-Allow.
  • Set Incoming Interface to port2.
  • Set Outgoing Interface to port2.
  • Set Source to all (or create address objects for 10.1.0.0/16 and 10.2.0.0/16 for tighter control).
  • Set Destination to all (or the same spoke address objects).
  • Set Schedule to always.
  • Set Service to ALL.
  • Set Action to ACCEPT.
  • Scroll down to the Logging Options section and select All Sessions.
  • Expand the Security Profiles section, enable IPS, and select the default sensor.
  • Click OK to save the policy.

What does this policy do?

This policy matches any traffic arriving on port2 and leaving on port2. Since spoke traffic enters and exits through the same internal interface (routed via the TGW subnet), setting both interfaces to port2 captures all inter-spoke flows.

Logging all sessions means every connection between the spokes will appear in FortiGate's traffic log. The default IPS sensor applies Fortinet's full intrusion prevention signature set to this traffic, detecting and blocking known attacks in real time.

Can't set incoming and outgoing interface to the same port?

Some older FortiOS versions block same-interface policies by default. If you see this restriction, go to System > Settings (or System > Feature Visibility) and ensure Allow Subnet Overlap and intra-zone traffic are enabled. In most PAYG marketplace deployments this is already allowed.

My FortiGate won't let me set the same interface for both incoming and outgoing on a firewall policy.

Verify IPS is active and signatures are up to date

The firewall policy you just created references the default IPS sensor. Now confirm the sensor is active and the signature database is current.

  • Navigate to Security Profiles > Intrusion Prevention.
  • Confirm the default sensor is listed and enabled.
  • Check the FortiGuard IPS signature database version displayed on this page. It should show a recent date.
  • If the database shows as out of date, navigate to FortiGuard > Settings and click Update Now to pull the latest signatures.

What is the IPS sensor doing?

The Intrusion Prevention System inspects every packet matching your firewall policy against thousands of known attack signatures. If a packet matches a threat signature (like a buffer overflow exploit or known malware pattern), FortiGate blocks it and logs the event.

FortiGuard continuously updates the signature database so your FortiGate recognizes newly discovered threats without manual intervention.

Your FortiGate is now fully configured as a security inspection hub. Every packet flowing between Spoke A and Spoke B passes through port2, gets evaluated against your firewall policy, and is scanned by the IPS engine.

Your security hub is now armed with firewall policies and intrusion prevention. Next up, you will test the full traffic path by pinging between spokes and verifying FortiGate's logs prove every packet is being inspected.

Verify Traffic Inspection and Test the Security Hub

In the previous step, you configured FortiGate with firewall policies and IPS to inspect all inter-spoke traffic. The policies are in place and the routing is set, but you have no proof yet that traffic is actually flowing through your firewall.

In this step, you will generate real traffic between spokes and confirm that FortiGate is actively inspecting, logging, and enforcing policies on that traffic. This is the final validation that your security hub architecture works end-to-end.

In this step, get ready to:
  • Test connectivity between spoke instances through FortiGate.
  • Verify that FortiGate logs inter-VPC traffic.
  • Create and test a deny policy to prove enforcement.
Ping from Spoke A to Spoke B via Session Manager

The simplest way to prove traffic flows through FortiGate is to send ICMP ping packets from one spoke to the other. If the ping succeeds, it means the packets traversed the Transit Gateway, entered the Security VPC, passed through FortiGate inspection, and returned.

  • Open the EC2 console in the AWS Management Console.
  • In the left navigation pane, click Instances.
  • Select your Spoke A test instance.
  • Click Connect at the top of the page.
  • Choose the Session Manager tab.
  • Click Connect to open a browser-based shell session on the Spoke A instance.

What is Session Manager?

Session Manager is a fully managed AWS Systems Manager capability. It gives you an interactive shell on an EC2 instance without needing SSH keys, bastion hosts, or open inbound ports. You set this up in a previous step with the AmazonSSMManagedInstanceCore IAM policy.

  • Once connected, ping the Spoke B instance's private IP address by running this command:
ping 10.2.1.x -c 4

What private IP should I use?

Replace 10.2.1.x with the actual private IP address of your Spoke B test instance. You can find this on the EC2 console by selecting the Spoke B instance and checking the Private IPv4 address field in the Details tab.

You should see four successful ping replies, confirming that ICMP traffic flowed from Spoke A through FortiGate to Spoke B and back.

Ping not getting replies?

If you see 100% packet loss, check these common causes:

  • Verify that the Spoke B security group allows ICMP from 10.0.0.0/8.
  • Confirm the spoke VPC route tables have a 0.0.0.0/0 route pointing to the Transit Gateway.
  • Check that FortiGate's firewall policy allows traffic from port2 to port2 for the spoke CIDRs.
  • Verify the FortiGate static routes for 10.1.0.0/16 and 10.2.0.0/16 point to the gateway 10.0.3.1.

Help me troubleshoot why my ping between spoke VPCs is failing through the FortiGate Transit Gateway hub.

Confirm traffic is logged in FortiGate

A successful ping proves connectivity, but you also need to confirm that FortiGate is actively inspecting and recording this traffic. The Forward Traffic log is where FortiGate records every session that matches a firewall policy.

  • Switch back to the FortiGate web GUI in your browser.
  • In the left navigation menu, expand Log & Report.
  • Click Forward Traffic.
  • Look for log entries showing ICMP traffic with source and destination IPs matching your spoke instances (in the 10.1.1.0/24 and 10.2.1.0/24 ranges).
  • Verify that the Action column shows accept for these entries.

What do these log entries prove?

Each log entry in Forward Traffic represents a session that FortiGate actively inspected. The source interface (port2), destination interface (port2), source IP, destination IP, and protocol fields confirm the traffic path.

The presence of these log entries is your proof that traffic between spokes is not bypassing the firewall. Every packet passed through FortiGate's inspection engine, including the IPS sensor you configured.

Not seeing log entries?

  • Logs may take 30-60 seconds to appear. Click the refresh button at the top of the log page.
  • Check that your firewall policy has Log Allowed Traffic set to All Sessions (not just Security Events).
  • Confirm the log source is set to Memory or Disk at the top of the Forward Traffic page.

Help me figure out why FortiGate Forward Traffic logs are not showing inter-spoke ICMP traffic.

Test policy enforcement with a deny rule

Logging proves inspection, but a true security hub must also enforce policies. You will now create a deny rule that blocks a specific type of traffic. Then you will attempt that traffic and confirm FortiGate stops it.

  • In the FortiGate GUI, navigate to Policy & Objects in the left menu.
  • Click Firewall Policy.
  • Click Create New to add a new policy.
  • Set the Name to Block-HTTP-SpokeA-to-SpokeB.
  • Set Incoming Interface to port2.
  • Set Outgoing Interface to port2.
  • Set Source to the Spoke A subnet (10.1.0.0/16).
  • Set Destination to the Spoke B subnet (10.2.0.0/16).
  • Set Service to HTTP (TCP port 80).
  • Set Action to Deny.
  • Enable Log Violation Traffic so denied sessions appear in the logs.
  • Click OK to save the policy.

Why does policy order matter?

FortiGate evaluates firewall policies from top to bottom. A packet matches the first policy whose criteria it meets. Your new deny rule must appear above the existing allow-all policy in the policy list.

After saving, drag the Block-HTTP-SpokeA-to-SpokeB policy above your general allow policy in the list. If the deny rule is below the allow rule, HTTP traffic will still match the allow policy first and pass through.

  • Make sure the deny policy is positioned above the allow policy in the policy list by dragging it into position.

Now test the deny rule from your Spoke A session.

  • Switch back to your Session Manager shell on the Spoke A instance.
  • Attempt an HTTP connection to the Spoke B instance's private IP by running:
curl -m 5 http://10.2.1.x

What does this command do?

The curl command attempts to make an HTTP request (TCP port 80) to the Spoke B instance. The -m 5 flag sets a 5-second timeout so you do not wait indefinitely if the connection is blocked.

Replace 10.2.1.x with the same Spoke B private IP you used earlier for the ping test.

The curl command should fail with a connection timeout or connection refused error. This confirms FortiGate is actively blocking HTTP traffic from Spoke A to Spoke B.

  • Verify the ping still works to confirm only HTTP is blocked:
ping 10.2.1.x -c 2

The ping should still succeed. This proves your deny rule is specific to TCP port 80 while other traffic continues to flow through the allow policy.

  • Switch back to the FortiGate GUI.
  • Navigate to Log & Report > Forward Traffic.
  • Look for a log entry showing a denied HTTP session from the Spoke A IP to the Spoke B IP with the action deny.

What does this end-to-end test prove?

You have now validated three things: traffic between spokes flows through FortiGate (ping succeeds), FortiGate inspects and logs all traffic (Forward Traffic entries appear), and FortiGate enforces policies by blocking specific traffic (HTTP denied, logged as deny).

This is exactly how enterprise security teams validate a centralized firewall deployment. Your FortiGate security hub is production-ready.

HTTP curl not being blocked?

  • Check that your deny policy is positioned above the allow policy in the firewall policy list.
  • Verify the Source and Destination address objects match the correct spoke CIDRs.
  • Confirm the Service is set to HTTP (port 80) specifically.

Help me figure out why my FortiGate deny policy for HTTP is not blocking traffic between my spoke VPCs.

Secret mission

Configure a Site-to-Site IPSec VPN

Your security hub is protecting inter-VPC traffic, but enterprise networks don't stop at AWS. Extend your FortiGate firewall to a simulated on-premises environment by building an IPSec VPN tunnel with production-grade encryption settings.

Clean Up Your Resources

Clean Up Your Resources

Decide whether to keep your resources running, pause them to come back later, or delete them entirely. This project uses paid AWS resources that cost approximately $8-10/day if left running.

Cost warning

Your FortiGate-VM (t3.xlarge) incurs EC2 compute costs even during the 30-day free trial for the FortiGate license. The Transit Gateway costs $0.05 per VPC attachment per hour ($0.15/hr for 3 attachments). If you leave everything running, expect to pay approximately $8-10/day.

If you are not actively using this environment, choose Pause or Delete below to avoid unexpected charges.

Resources you used:

  • FortiGate-VM EC2 instance (t3.xlarge) with Elastic IP.
  • Simulated on-premises VPN endpoint (second FortiGate-VM or AWS VGW/CGW).
  • Spoke A test EC2 instance (t3.micro) and Spoke B test EC2 instance (t3.micro).
  • AWS Transit Gateway with 3 VPC attachments and 2 route tables.
  • Security VPC (10.0.0.0/16), Spoke A VPC (10.1.0.0/16), and Spoke B VPC (10.2.0.0/16) with subnets, route tables, and Internet Gateway.
  • IAM instance profiles (AmazonSSMManagedInstanceCore) on spoke instances.
  • FortiGate PAYG Marketplace subscription.

Keep everything running

No action needed. Choose this if you are still actively building or testing your security hub architecture.

  • Monitor your AWS billing dashboard daily. The Transit Gateway alone costs $3.60/day with 3 attachments.
  • The FortiGate 30-day free trial covers the software license only. EC2 compute charges for the t3.xlarge instance still apply.
  • Your Elastic IP is free while the FortiGate instance is running. It incurs a small charge if you stop the instance without releasing the IP.

Pause - I'll come back to this later

Shut down compute instances to save on hourly costs. Note that the Transit Gateway still incurs hourly charges while it exists, even with no traffic.

  • In the AWS Console, go to **EC2** > **Instances**.
  • Select all four EC2 instances (FortiGate-VM, simulated on-prem endpoint, Spoke A test instance, Spoke B test instance).
  • Click **Instance state** > **Stop instance**.
  • Be aware that your Elastic IP will cost $0.005/hr while the FortiGate instance is stopped. The Transit Gateway continues at $0.15/hr (3 attachments at $0.05 each).
  • When you return, start the instances and verify FortiGate connectivity. You may need to update the Elastic IP association if it was released.

Delete - I don't want to use this again

Remove all project resources completely. Follow this order carefully. Dependent resources must be deleted before the resources they attach to.

Terminate all EC2 instances
  • In the AWS Console, go to **EC2** > **Instances**.
  • Select all four instances: the FortiGate-VM, the simulated on-prem VPN endpoint, Spoke A test instance, and Spoke B test instance.
  • Click **Instance state** > **Terminate instance**. Confirm the termination.
  • Wait for all instances to reach the **Terminated** state.
Release the Elastic IP
  • Go to **EC2** > **Elastic IPs**.
  • Select the Elastic IP that was associated with FortiGate port1.
  • Click **Actions** > **Release Elastic IP address**. Confirm the release.
Delete Transit Gateway attachments and the Transit Gateway
  • Go to **VPC** > **Transit Gateway Attachments**.
  • Select all three TGW attachments (Security VPC, Spoke A, Spoke B). Click **Actions** > **Delete transit gateway attachment**.
  • Wait for all attachments to reach the **Deleted** state.
  • Go to **VPC** > **Transit Gateway Route Tables**. Delete both the Security and Spokes route tables.
  • Go to **VPC** > **Transit Gateways**. Select your Transit Gateway, click **Actions** > **Delete transit gateway**. Confirm the deletion.
Delete VPCs and associated resources

Repeat the following steps for each VPC: Security VPC (10.0.0.0/16), Spoke A VPC (10.1.0.0/16), Spoke B VPC (10.2.0.0/16), and the simulated on-prem VPC if you created a separate one.

  • Go to **VPC** > **Your VPCs**.
  • Select the VPC. Click **Actions** > **Delete VPC**.
  • AWS will prompt you to delete associated resources (subnets, route tables, security groups, internet gateways, network interfaces). Confirm the deletion.
  • If deletion fails due to a remaining network interface, go to **EC2** > **Network Interfaces**, find any ENIs still attached to the VPC, and delete them first.
Remove IAM instance profiles
  • Go to **IAM** > **Roles**.
  • Find and delete the role you created with the AmazonSSMManagedInstanceCore policy for the spoke instances.
Cancel the FortiGate Marketplace subscription
  • Go to **AWS Marketplace** > **Manage subscriptions**.
  • Find the "Fortinet FortiGate VM Next-Generation Firewall" subscription.
  • Click **Manage**, then **Cancel subscription**. Confirm the cancellation.
  • This prevents any charges after the 30-day free trial expires.

Nice Work!

Nice Work!

You just built a production-grade centralized security architecture on AWS using Fortinet FortiGate as your next-generation firewall.

This is the same hub-and-spoke inspection pattern that Fortinet's own professional services team deploys for enterprise customers. You now have the skills to secure multi-VPC AWS environments using industry-leading NGFW technology.

You've learned how to:

  • Deploy a FortiGate-VM next-generation firewall from AWS Marketplace and design a hub-and-spoke network using AWS Transit Gateway with proper route table segregation.
  • Configure firewall policies to control inter-VPC traffic flow and enable IPS (Intrusion Prevention System) for real-time threat detection on all inter-spoke traffic.
  • Validate end-to-end traffic inspection by testing spoke-to-spoke connectivity, reviewing FortiGate logs, and enforcing deny rules to prove policy enforcement.
  • Extended the architecture with a site-to-site IPSec VPN for hybrid cloud connectivity to a simulated on-premises network.

Ready to quiz yourself?