Blog by Saw Win Naung

Official

Centralized AWS Ingress with Transit Gateway - Part 2


In yesterday’s post, we built a centralized egress architecture using AWS Transit Gateway. Today, we’re completing the picture by implementing centralized ingress - handling inbound traffic from the internet to your spoke account resources through load balancers in your networking hub.

The Missing Piece: Inbound Traffic

While our Transit Gateway setup handles outbound traffic beautifully, we need to address how external users and services reach applications running in spoke accounts. The solution? Deploy load balancers in the networking VPC that can route traffic to spoke resources via Transit Gateway.

Architecture Overview

Our centralized ingress architecture extends the hub-and-spoke model with load balancers in the networking VPC that can reach spoke account resources:

Centralized Ingress Architecture Figure 1: Centralized ingress architecture with load balancers routing to spoke resources

Ingress Options

Load Balancer TypeBest ForKey Features
Application Load Balancer (ALB)HTTP/HTTPS applicationsLayer 7 routing, SSL termination, WAF integration
Network Load Balancer (NLB)TCP/UDP, high performanceLayer 4 routing, ultra-low latency, static IPs
API Gateway + VPC LinkAPI managementCentralized auth, throttling, API versioning

Implementation: Cross-Account NLB Setup

Let’s walk through implementing a Network Load Balancer in the networking account that routes traffic to an EC2 web server in a spoke account.

Prerequisites

Lab Architecture

Internet → IGW → NLB (Networking VPC) → TGW → EC2 Web Server (Spoke VPC)

The traffic flow:

  1. Internet traffic hits the NLB in networking VPC public subnet
  2. NLB forwards to target group containing spoke EC2 private IP
  3. Traffic routes through TGW attachment to spoke VPC
  4. EC2 responds back through the same path

Step-by-Step Implementation

Step 1: Launch EC2 Web Server in Spoke Account

Set up a test web server in your spoke account:

  1. Launch EC2 instance in spoke account private subnet
  2. Configure security group to allow HTTP traffic from networking VPC CIDR
  3. Install web server (Apache/Nginx) and create a simple test page
  4. Note the private IP address of the instance for target group registration
  5. Test local connectivity to ensure the web server is responding

Step 2: Create IP Target Group in Networking Account

Create a target group that can reference cross-account resources:

  1. Navigate to EC2 Load Balancers in the networking account
  2. Create target group with the following settings:
    • Target type: IP addresses (required for cross-account)
    • Protocol: TCP (for NLB) or HTTP (for ALB)
    • Port: 80 (or your application port)
    • VPC: Networking VPC
    • Health check: TCP or HTTP based on your setup
  3. Configure health check settings with appropriate timeout and interval

Step 3: Register Spoke EC2 Private IP

Add the spoke account EC2 instance to the target group:

  1. Copy the private IP address from the spoke EC2 instance
  2. Go to target group targets tab in networking account
  3. Register targets and enter the spoke EC2 private IP
  4. Specify port (usually 80 for web servers)
  5. Save the registration and wait for health check initialization

Step 4: Create Network Load Balancer

Deploy the NLB in the networking account:

  1. Create load balancer in EC2 console
  2. Select Network Load Balancer type
  3. Choose internet-facing scheme
  4. Select networking VPC and public subnets across multiple AZs
  5. Configure listeners for the required ports (e.g., port 80)
  6. Attach the target group created in Step 2
  7. Add appropriate tags and create the load balancer

Step 5: Configure Security Groups

Set up proper security group rules for cross-account access:

  1. Spoke EC2 security group (in spoke account):
    • Allow inbound TCP port 80 from networking VPC CIDR (10.0.0.0/16)
    • Allow inbound health check traffic from NLB subnets
  2. NLB considerations:
    • Network Load Balancers don’t use security groups
    • Ensure target security groups allow traffic from NLB subnets
    • Verify NACLs permit the required traffic flows

Required Routing Updates

Update Networking VPC Route Tables

The public subnet route table needs routes to spoke CIDRs:

# Add route to spoke CIDR via TGW attachment
aws ec2 create-route \
    --route-table-id rtb-xxxxxxxx \
    --destination-cidr-block 10.1.0.0/16 \
    --transit-gateway-id tgw-xxxxxxxx \
    --profile netw

Update Transit Gateway Route Tables

Ensure the Egress Route Table has spoke routes for return traffic:

# If not already propagated, add static route
aws ec2 create-transit-gateway-route \
    --destination-cidr-block 10.1.0.0/16 \
    --transit-gateway-route-table-id tgw-rtb-xxxxxxxx \
    --transit-gateway-attachment-id tgw-attach-spoke \
    --profile netw

Security Group Configuration

Spoke EC2 Security Group

Allow inbound HTTP from networking VPC CIDR:

aws ec2 authorize-security-group-ingress \
    --group-id sg-xxxxxxxx \
    --protocol tcp \
    --port 80 \
    --cidr 10.0.0.0/16 \

Traffic Flow Analysis

Inbound Request Flow

  1. Internet → IGW → NLB (networking VPC public subnet)
  2. NLB → TGW attachment → Transit Gateway
  3. TGW → spoke attachment → EC2 (spoke VPC private subnet)

Response Flow

  1. EC2 → spoke attachment → Transit Gateway
  2. TGW → networking attachment → NLB
  3. NLB → IGW → Internet

TADA!!! Combined with previous’s egress setup, we now have a complete centralized networking solution that scales across multiple AWS accounts while maintaining security and cost efficiency.

Ready to centralize your ingress traffic? Start with a single service and expand from there!