Logo Teamwork

AWS Transit Gateway Policy-Based Routing: Smart Routing

Published on
Authors
Version audio
Chargement...
AWS Transit Gateway Policy-Based Routing - Guide Sylvain BRUAS


Network routing on AWS has long been constrained by a simple logic: traffic is routed based on the destination IP address. Full stop. For network architects used to the advanced features of on-premise equipment (Cisco, Juniper, Palo Alto), this limitation was frustrating. AWS has just closed this gap with the announcement of the general availability of Policy-Based Routing (PBR) on AWS Transit Gateway.

This feature, announced on July 30, 2026, now makes it possible to make routing decisions based on a combination of attributes: source IP address, destination IP address, ports, and protocol. It is a fundamental change in the way we design network architectures on AWS.

What is Policy-Based Routing?

Policy-Based Routing is a mechanism that lets you direct network traffic according to policies defined by the administrator, rather than relying solely on the classic destination-based routing table. In other words, you can now say: "all HTTPS traffic coming from the application subnet destined for port 443 must go through my inspection appliance, while SSH traffic from the operations team can take a direct path."

On AWS Transit Gateway, PBR works with a concept of policy table that you associate with a Transit Gateway attachment. In this table, you define an ordered set of rules. Each rule classifies traffic according to the following criteria:

  • Source IP address: where the traffic comes from
  • Destination IP address: where the traffic goes
  • Source and destination ports: which service is used
  • Protocol: TCP, UDP, ICMP, etc.

Rules are evaluated in order with first-match-wins logic: the first rule that matches the traffic determines which route table the packet will be directed to. If no rule matches, the traffic is silently dropped (implicit deny). This behavior, similar to that of Security Groups, means you must always provide a catch-all rule if you want to avoid unintended drops.

Why is this a game-changer?

Before PBR: architectural complexity

Before this announcement, network architects who needed to direct traffic in a granular way had to build complex multi-VPC architectures with additional routing hops. In concrete terms, this meant:

  • Multiplying inspection VPCs: a dedicated VPC for each type of traffic to inspect differently
  • Adding Gateway Load Balancers: to distribute traffic to third-party appliances
  • Creating routing chains: with multiple interconnected Transit Gateway route tables
  • Managing rising costs: each additional hop generates data processing charges

This complexity translated into significant operational overhead, increased latency, and a high risk of configuration error.

With PBR: regained simplicity

PBR eliminates much of this complexity by extending the native routing capabilities of the Transit Gateway. No more need to add intermediate layers: you classify and direct traffic directly at the Transit Gateway level, in a single step.

Concrete use cases

PBR opens the door to many scenarios that network and security teams have been waiting for.

Selective traffic inspection

This is probably the most requested use case. Rather than routing all traffic through AWS Network Firewall or a third-party appliance (which generates cost and latency), you can now route only sensitive traffic to inspection. For example:

  • Traffic destined for databases (port 3306, 5432) goes through inspection
  • Internal traffic between microservices on known application ports can bypass inspection
  • Traffic to specific external destinations is systematically inspected

Source-based routing for hybrid connectivity

For enterprises using AWS Direct Connect and AWS VPN in parallel, PBR makes it possible to direct traffic to the right path based on its source or protocol:

  • Critical traffic (databases, ERP) takes the Direct Connect to benefit from low latency and guaranteed bandwidth
  • Less sensitive traffic (updates, synchronization) can use the VPN as a secondary path
  • Failover can be managed more finely based on applications

Environment isolation

PBR makes it possible to isolate production and development environments in separate routing domains, thereby limiting lateral movement. Even if two environments share similar IP ranges or common attachments, PBR rules ensure that development traffic can never reach production resources, and vice versa.

Configuration and setup

Fundamental constraint: policy table OR route table, never both

This is the most important point to understand before getting started: a Transit Gateway attachment can only be associated with a policy table OR a route table, never both simultaneously. There is no hybrid mode. In concrete terms:

  • If your VPC attachment is currently associated with a classic route table, you must first disassociate that route table before you can associate a policy table
  • During the disassociation/association window, traffic for that attachment will be interrupted
  • An empty policy table (with no rules) causes all inbound traffic to be dropped on that attachment — this is the implicit deny

This exclusivity means that PBR completely replaces the classic routing logic for a given attachment. It is a binary architectural choice per attachment.

The setup steps

Configuring PBR is done in four steps:

  1. Create the target route tables: each PBR rule points to a TGW route table that contains the actual routes
  2. Create a policy table: you define a policy table associated with your Transit Gateway
  3. Define the rules: you create an ordered set of rules (numbered from 1 to 50,000) with the classification criteria and the target route table
  4. Disassociate the existing route table then associate the policy table with the attachment

PBR is configurable via the AWS Console, the AWS CLI, and the AWS SDKs. The dedicated CLI commands (create-transit-gateway-policy-table, create-transit-gateway-policy-table-entry, associate-transit-gateway-policy-table) are available now.

Concrete example: HTTP/HTTPS and SSH filtering

Here is a complete setup example via AWS CLI, which implements the scenario described in the introduction: HTTPS traffic is inspected, SSH traffic takes a direct path.

# 1. Create the policy table
aws ec2 create-transit-gateway-policy-table \
  --transit-gateway-id tgw-0bc994abffEXAMPLE \
  --tag-specifications 'ResourceType=transit-gateway-policy-table,Tags=[{Key=Name,Value=app-security-policy}]'
# Returns: tgw-ptb-0ca78a549EXAMPLE

# 2. Rule 100: HTTPS traffic (port 443) from the application subnet → firewall inspection
aws ec2 create-transit-gateway-policy-table-entry \
  --transit-gateway-policy-table-id tgw-ptb-0ca78a549EXAMPLE \
  --policy-rule-number 100 \
  --policy-rule '{"SourceCidrBlock":"10.1.10.0/24","Protocol":"6","DestinationPortRange":"443"}' \
  --target-route-table-id tgw-rtb-0a823edbdeEXAMPLE

# 3. Rule 200: HTTP traffic (port 80) → same inspection
aws ec2 create-transit-gateway-policy-table-entry \
  --transit-gateway-policy-table-id tgw-ptb-0ca78a549EXAMPLE \
  --policy-rule-number 200 \
  --policy-rule '{"SourceCidrBlock":"10.1.10.0/24","Protocol":"6","DestinationPortRange":"80"}' \
  --target-route-table-id tgw-rtb-0a823edbdeEXAMPLE

# 4. Rule 300: SSH traffic (port 22) from the ops team → direct routing (no inspection)
#    Only matches if this traffic actually enters via the attachment associated with the policy table
aws ec2 create-transit-gateway-policy-table-entry \
  --transit-gateway-policy-table-id tgw-ptb-0ca78a549EXAMPLE \
  --policy-rule-number 300 \
  --policy-rule '{"SourceCidrBlock":"10.1.50.0/24","Protocol":"6","DestinationPortRange":"22"}' \
  --target-route-table-id tgw-rtb-0b91f2c3d4EXAMPLE

# 5. Rule 40000: catch-all → default routing (avoids the implicit deny)
#    An empty policy-rule matches everything: all conditions default to *
aws ec2 create-transit-gateway-policy-table-entry \
  --transit-gateway-policy-table-id tgw-ptb-0ca78a549EXAMPLE \
  --policy-rule-number 40000 \
  --policy-rule '{}' \
  --target-route-table-id tgw-rtb-0f5e4d3c2bEXAMPLE

# 6. Check the entries before switching the attachment over
aws ec2 get-transit-gateway-policy-table-entries \
  --transit-gateway-policy-table-id tgw-ptb-0ca78a549EXAMPLE

# 7. Disassociate the existing route table from the source attachment
#    An attachment can only be associated with a route table OR a policy table
aws ec2 disassociate-transit-gateway-route-table \
  --transit-gateway-attachment-id tgw-attach-0def6EXAMPLE \
  --transit-gateway-route-table-id tgw-rtb-0c7d8e9f01EXAMPLE

# 8. Wait for the disassociation to complete: associating too early will fail the request
while :; do
  STATE=$(aws ec2 get-transit-gateway-route-table-associations \
    --transit-gateway-route-table-id tgw-rtb-0c7d8e9f01EXAMPLE \
    --filters "Name=transit-gateway-attachment-id,Values=tgw-attach-0def6EXAMPLE" \
    --query 'Associations[0].State' --output text)
  # "None": the association has disappeared from the list
  if [ "$STATE" = "None" ] || [ "$STATE" = "disassociated" ]; then
    break
  fi
  sleep 5
done

# 9. Associate the policy table with the attachment
aws ec2 associate-transit-gateway-policy-table \
  --transit-gateway-policy-table-id tgw-ptb-0ca78a549EXAMPLE \
  --transit-gateway-attachment-id tgw-attach-0def6EXAMPLE

# 10. Confirm the association
aws ec2 get-transit-gateway-policy-table-associations \
  --transit-gateway-policy-table-id tgw-ptb-0ca78a549EXAMPLE

With this configuration, traffic is handled as follows:

  • TCP:443 packet from 10.1.10.x → inspected by the firewall (rule 100)
  • TCP:80 packet from 10.1.10.x → inspected by the firewall (rule 200)
  • TCP:22 packet from 10.1.50.x → direct routing without inspection (rule 300)
  • Any other traffic → default routing (rule 40000 catch-all)

Considerations and best practices

Like any advanced network feature, PBR requires a structured approach:

  • Start simple: first deploy one or two rules on a non-critical attachment to validate the behavior
  • Document your policies: the first-match-wins logic can become complex with many rules. Maintain clear documentation of the order and intent of each rule
  • Monitor metrics: use Amazon CloudWatch to monitor hits on each rule and identify unused rules. The PacketDropCountNoPolicy metric alerts you when traffic is dropped due to no matching rule
  • Always provide a catch-all rule: unless you explicitly want Zero Trust behavior (deny-all), add a high-numbered rule (e.g. 40000) that captures the remaining traffic
  • Leave gaps between rule numbers: use 100, 200, 300… so you can insert new rules without renumbering everything
  • Test failover scenarios: validate that your PBR rules behave correctly in case a target attachment fails
  • Watch out for BGP: associating a policy table with a VPN (Site-to-Site) or Connect attachment stops BGP advertisements to the peer. Direct Connect is not affected (it uses the allowed-prefixes list)

Impact on network latency

A legitimate question: does PBR add latency to traffic transit?

The answer is no. PBR rule evaluation is performed at the Transit Gateway data plane level, at the same decision point as the classic routing table. There is no additional network hop, no intermediate component added to the path. The decision is made "inline" as the packet transits.

In reality, PBR can even reduce the overall latency of your architecture:

  • Before PBR: to selectively inspect traffic, you had to send everything to an inspection VPC (an additional hop) then filter at the appliance level. Even "clean" traffic went through the traversal.
  • With PBR: only the traffic that actually requires inspection is directed to the appliance. The rest takes the direct path, saving one or more network hops.

Bandwidth quotas are not affected either: each VPC attachment retains its 100 Gbps capacity per Availability Zone in each direction.

Limits and quotas

Like any AWS service, PBR has its limits that you should know before designing your architecture:

ResourceLimitAdjustable
Policy tables per Transit Gateway20No
Policy entries (customer-managed) per TGW, across all tables200Yes
Rule numbers1 to 50,000—
Supported attachment typesVPC, VPN, Direct Connect, Connect, Peering (except Cloud WAN)—

Other important constraints:

  • Absolute exclusivity: an attachment is associated with a policy table OR a route table, never both
  • No PBR on Cloud WAN peerings: only system-managed entries (managed by Cloud WAN) apply on these attachments
  • Ports limited to TCP/UDP: port filtering only works for TCP (6) and UDP (17) protocols. For ICMP, GRE or "Any", ports are automatically set to *
  • Empty policy table = blackhole: associating a policy table with no rules to an attachment causes all traffic to be silently dropped
  • Referenced route table not deletable: a route table used as a target by a policy entry cannot be deleted as long as the reference exists

Migration: moving from a route table to PBR without downtime

Migration to PBR is the question that concerns production network teams the most. Let's be clear: there is an unavoidable micro-interruption during the switchover, because the disassociation of the route table and the association of the policy table are not atomic.

Here is the recommended strategy to minimize the impact:

  1. Prepare everything upfront: create the policy table, define all the rules, and create the target route tables with the necessary routes — all without any impact on existing traffic
  2. Start with a non-critical attachment: choose a development or test VPC to validate the behavior
  3. Include a catch-all rule that replicates the current behavior: your high-numbered rule must point to a route table that exactly reproduces the current routing. This way, even if your specific rules have a bug, traffic continues to transit
  4. Plan a maintenance window: disassociating the route table followed by associating the policy table generally takes a few seconds, but plan for 30 to 60 seconds of potential micro-outage
  5. Switch over: disassociate the route table, then immediately associate the policy table
  6. Validate: check the flows with GetTransitGatewayPolicyTableEntries and monitor the PacketDropCountNoPolicy metric
  7. Iterate: once validated, repeat on the production attachments

What happens during the switchover

[Route table associated] ──disassociation──▶ [No association] ──association──▶ [Policy table associated]
                                              │
                                    Traffic dropped during
                                    this window (seconds)

During the window where the attachment has neither a route table nor a policy table, inbound traffic is dropped. Established TCP connections will be cut and will need to be re-established. For stateless protocols (UDP, ICMP), recovery is transparent as soon as the policy table is active.

Mitigation strategies

  • Tolerant applications: most applications with retry mechanisms (HTTP, gRPC) survive an interruption of a few seconds without visible user impact
  • Critical traffic: for flows that tolerate no loss, consider a migration scheme using attachment duplication — create a second VPC attachment (in a dedicated subnet), migrate it to PBR, then switch the application traffic to this new subnet
  • DNS failover: if you have a DNS failover mechanism (Route 53 health checks), you can temporarily switch traffic to an alternate path for the duration of the migration
  • Multi-AZ coordination: migrate one AZ at a time if your architecture allows it (separate attachments per AZ)

Rollback

In case of a problem, rollback is simple: disassociate the policy table and re-associate the old route table. The same micro-interruption applies in the other direction. This is why it is essential to not delete the old route table until the migration is validated in production.

Availability and pricing

Policy-Based Routing for AWS Transit Gateway is available in all commercial AWS regions where Transit Gateway is available. Important point: PBR incurs no additional cost beyond the standard Transit Gateway charges (per-attachment charges + data processing charges). There is no per-rule or per-evaluation pricing. This is excellent news because it means that adoption will not be held back by budget considerations.

Conclusion

For network architects and security teams, this is a feature that will considerably simplify existing architectures while opening up new possibilities.

My advice: if you currently have complex multi-VPC architectures solely to handle conditional routing, now is the time to review your design. PBR can potentially allow you to reduce the number of intermediate components, lower latency, and simplify your daily operations.

Start by identifying your most critical traffic flows that require differentiated handling, then test PBR on a limited scope before extending it to your entire organization.

Share this article

XBlueskyReddit