AWS Transit Gateway Policy-Based Routing: Implementation and Migration Guide
AWS Transit Gateway forwarding used to answer one main question: which route best matches the destination IP address? On July 30, 2026, AWS added Policy-Based Routing (PBR), allowing a transit gateway to classify packets by source and destination addresses, ports, and protocol before choosing a route table. That is a meaningful change for inspection, hybrid routing, and environment isolation.
The feature removes several architectures that existed only to manufacture a different routing decision. A security team can steer selected application flows through AWS Network Firewall without forcing all traffic into the same inspection path. A network team can prefer Direct Connect for one class of traffic and VPN for another. Production and development attachments can share a transit hub while landing in separate routing domains.
PBR also introduces a policy engine into a place where operators are accustomed to longest-prefix routing. Rule order now matters. Overlap can silently send traffic to the wrong route table. Stateful inspection still requires symmetry. This guide focuses on those operational details: policy-table design, migration, validation, failure isolation, Terraform readiness, and rollback.
If Transit Gateway route tables and attachment propagation are new to you, start with the hub-and-spoke Transit Gateway guide. PBR extends that model; it does not replace the underlying route tables.
What the forwarding path now looks like
AWS describes the feature as an ordered set of rules associated through a policy table with a Transit Gateway attachment. Each rule matches packet attributes and directs matching traffic to a specified Transit Gateway route table. Evaluation is first-match-wins.
Packet enters attachment
|
v
Associated PBR policy table
|
+-- rule 10 matches? -> target route table A
|
+-- rule 20 matches? -> target route table B
|
+-- default/fallback -> normal attachment route-table behavior
The AWS launch announcement lists source IP, destination IP, source or destination port, and protocol as classifiers. The target is not an ENI or firewall endpoint. It is another Transit Gateway route table, which then performs normal destination routing toward an attachment.
That two-stage decision matters:
- The policy decides which routing domain evaluates the packet.
- The selected route table decides which attachment receives it.
PBR therefore cannot compensate for a missing route in the target table. A rule can match perfectly and still black-hole traffic because the chosen table lacks the destination prefix.

PBR versus the existing tools
| Mechanism | Matches | Selects | Best use |
|---|---|---|---|
| VPC route table | Destination prefix | ENI, gateway, or attachment | Subnet-local egress decision |
| Transit Gateway route table | Destination prefix | Transit Gateway attachment | Regional hub-and-spoke routing |
| Transit Gateway PBR | Source, destination, port, protocol | Transit Gateway route table | Per-flow routing-domain selection |
| Security group | Identity and five-tuple-related rules | Allow or deny | Stateful workload access control |
| Network firewall policy | Packet/session attributes and signatures | Allow, drop, alert, reject | Stateful inspection and threat prevention |
PBR is not a firewall. It chooses a path; the appliance on that path performs inspection. It is also not a substitute for segmentation. A target route table with broad propagation can reintroduce connectivity the policy was intended to restrict.
For rule-based global route advertisement, AWS Cloud WAN has a different routing-policy model. The Cloud WAN routing-policy guide explains route propagation policies. Transit Gateway PBR evaluates traffic forwarding, not BGP route distribution.
Design the route tables before the policy
Begin with explicit routing domains. A centralized inspection design often needs at least:
rt-spoke: routes from application VPCs toward inspection;rt-inspection: routes from the firewall VPC back to each spoke and toward egress or hybrid links;rt-direct: approved traffic that can bypass the inspection service;rt-quarantine: only remediation and management destinations.
Document every target table with its accepted sources, reachable prefixes, propagation sources, blackholes, and owner. A PBR rule should never point at an unlabeled “shared” table whose contents change independently.
| Route table | Intended traffic | Propagation policy | Failure behavior |
|---|---|---|---|
| Inspection | Sensitive or untrusted flows | Explicit application and firewall attachments | Fail closed if firewall path disappears |
| Direct | Latency-sensitive approved flows | Narrow application and destination routes | Fall back only by deliberate policy change |
| Hybrid-DX | Corporate data over Direct Connect | On-premises prefixes from DX | VPN table used only by tested rule change |
| Quarantine | Suspected workload | Security tooling and update repositories | No lateral VPC propagation |
The centralized Network Firewall pattern covers appliance-mode attachments and return routing. Keep those mechanics. PBR simplifies classification, but stateful firewalls still need both directions of a flow to traverse compatible endpoints.
For hybrid paths, the Client VPN attachment guide shows another attachment type whose route domain should be documented before policy association.
Write a policy worksheet, not ad hoc rules
AWS exposes PBR through the console, CLI, and SDK. At launch, tooling versions and infrastructure providers may not expose identical schemas immediately. Before translating rules to a specific API, keep a provider-neutral worksheet under version control.
policy: application-steering-v1
attachment_class: application-vpc
rules:
- priority: 10
description: production database traffic through inspection
source_cidrs: [10.20.0.0/16]
destination_cidrs: [10.80.0.0/16]
protocol: tcp
destination_ports: [5432]
target_route_table: rt-inspection
- priority: 20
description: approved backup stream over Direct Connect domain
source_cidrs: [10.20.40.0/24]
destination_cidrs: [172.20.0.0/16]
protocol: tcp
destination_ports: [443]
target_route_table: rt-hybrid-dx
- priority: 900
description: remaining production traffic through inspection
source_cidrs: [10.20.0.0/16]
target_route_table: rt-inspection
This is a design artifact, not an AWS API payload. Its job is to make overlap review possible. Translate it only after checking the current Transit Gateway documentation and CLI model used by your deployment pipeline.
Use priority gaps of 10 or 100. You will need to insert an emergency rule without renumbering the entire policy. Put narrow rules before broad ones. A /24 and port-specific rule belongs before a /16 catch-all.
Build an overlap test
First-match-wins policies need unit tests. At minimum, create representative flows and expected target tables:
tests:
- name: prod-postgres-is-inspected
source_ip: 10.20.5.10
destination_ip: 10.80.8.25
protocol: tcp
destination_port: 5432
expect: rt-inspection
- name: backup-uses-direct-connect
source_ip: 10.20.40.12
destination_ip: 172.20.5.5
protocol: tcp
destination_port: 443
expect: rt-hybrid-dx
- name: dev-cannot-enter-production
source_ip: 10.30.9.9
destination_ip: 10.80.8.25
protocol: tcp
destination_port: 5432
expect: no-route
A small offline evaluator can parse CIDRs, protocols, and port ranges, sort by priority, and report the first match. Add negative cases. Test IPv4 and IPv6 separately when both are enabled. Most incidents come from an overly broad earlier rule, not a typo in the narrow rule everyone reviewed.
Preserve symmetric routing
Suppose an application packet enters from a spoke attachment, matches a rule, and uses the inspection route table. The firewall creates state. The return packet enters Transit Gateway from the inspection attachment, so it evaluates the policy associated with that different attachment. If that rule sends the response directly to the spoke through another domain, the path may bypass the stateful device or select a different firewall endpoint.
Draw both directions:
forward: spoke -> TGW PBR -> inspection RT -> firewall -> destination
return: destination -> TGW PBR -> inspection RT -> firewall -> spoke
Enable appliance mode where the architecture requires it, keep the firewall subnets and route tables aligned by Availability Zone, and test established TCP sessions during policy changes. The Transit Gateway appliance-mode enhancement improves AZ-aware selection, but it does not repair a policy that chooses the wrong domain.
The more recent container-aware Network Firewall guide adds workload context at the firewall. PBR and workload-aware policy are complementary: PBR gets traffic to inspection; the firewall decides what that workload may do.
Migrate in four controlled stages
Stage 1: observe the existing path
Capture Transit Gateway Flow Logs, VPC Flow Logs, firewall logs, Direct Connect metrics, and application latency for at least one representative business cycle. Record source/destination pairs, ports, bytes, accepted/rejected outcomes, and current route table.
Do not infer the traffic contract from route tables alone. Unused routes and undocumented flows are common.
Stage 2: create target route tables
Build the new domains without associating a PBR policy. Populate explicit routes, propagations, and blackholes. Use Network Manager Route Analyzer where it supports the path and verify with controlled probes. The Route Analyzer introduction explains the workflow.
Stage 3: canary one attachment
Choose a non-critical application attachment with representative traffic. Associate the policy table only there. Validate DNS, TCP connection establishment, large transfers, idle sessions, return traffic, MTU-sensitive traffic, and failure of the preferred next hop.
Stage 4: expand by attachment class
Move one category at a time: development, internal production, internet-facing production, then hybrid. Hold after each group. Compare flow distribution and firewall throughput to the baseline. Do not batch every attachment because the policy itself is centrally managed.
Define rollback before association
Rollback should be one bounded change: disassociate the PBR policy table from the affected attachment and restore its known route-table association. Preserve the prior associations and routes as code. Do not delete them during the first migration window.
| Symptom | Likely cause | Immediate action |
|---|---|---|
| All traffic from one attachment fails | Policy association or fallback route missing | Disassociate canary policy and re-test |
| Only one protocol fails | Port/protocol match or firewall policy | Inspect first matching rule and firewall logs |
| Connections establish but reset | Asymmetric return path | Trace both attachments and appliance mode |
| Direct Connect flow uses VPN | Earlier overlapping rule or DX route absent | Verify priority and selected target table |
| Cross-AZ cost rises | Inspection endpoint/AZ path changed | Compare flow logs by AZ and route-table target |
Set an operational kill condition before rollout, such as more than 1% connection failures, p99 latency exceeding the baseline by a fixed threshold, missing firewall logs for steered traffic, or any production-to-development reachability.
Infrastructure as code without provider surprises
The launch supports AWS CLI and SDK configuration. Terraform and CloudFormation support can lag a same-day service release. Do not work around missing native resources with an unreviewed local-exec in the production pipeline.
Use this order:
- Pin a CLI/SDK version that contains the PBR API model.
- Capture the exact console-created resource through describe calls.
- Confirm idempotency and replacement behavior in a sandbox Transit Gateway.
- Prefer a native provider resource when available.
- If a custom resource is necessary, give it explicit create, update, delete, and drift tests.
Always run terraform plan or a CloudFormation change set and attach the policy worksheet plus overlap-test results to the change. Route policy is code with a network-wide blast radius.
Monitor decisions, not only availability
Transit Gateway metrics can show packets moving while the wrong domain carries them. Build dashboards around intent:
- bytes and flows per source attachment and selected domain;
- accepted and rejected firewall sessions for PBR-steered traffic;
- Direct Connect versus VPN bytes for hybrid classes;
- cross-AZ bytes through the inspection VPC;
- policy changes, associations, and route-table modifications from CloudTrail;
- synthetic probes for every high-risk rule.
Tag policy tables, route tables, and attachments with environment, owner, data classification, and change ticket. Export the effective rules and associations nightly. Alert when production attachments use an unapproved policy version.
Test the actual packet matrix
Offline rule tests prove only the first matching policy rule. A production-like network test must prove the complete path: source subnet route, PBR selection, target Transit Gateway route table, attachment, appliance endpoint, destination route, and return direction.
Create small canary instances or container tasks in representative source and destination VPCs. Use TCP listeners on approved test ports and emit a unique correlation ID. For each policy class, test:
- connection allowed on the matching port;
- adjacent port follows its intended fallback;
- response returns through the expected inspection domain;
- long-lived connection survives ordinary route updates;
- IPv4 and IPv6 behavior where dual stack is enabled;
- packets larger than the normal MTU and path-MTU discovery;
- failure of Direct Connect, VPN, or a firewall endpoint;
- DNS resolution and return traffic from shared services.
Combine VPC Flow Logs, Transit Gateway Flow Logs, Network Firewall logs, and application logs by five-tuple and time. A successful curl proves reachability, not that the packet used the required inspection path. Require an inspection log for flows whose policy says rt-inspection.
Use Reachability Analyzer where the resource combination is supported, but do not treat a static reachability result as proof of stateful symmetry. Only a bidirectional live connection exercises appliance state.
Account for controls outside Transit Gateway
PBR does not override security groups, network ACLs, VPC route tables, firewall rules, endpoint policies, or the target service’s authorization. Troubleshooting should move hop by hop.
| Layer | Typical mistake after PBR change |
|---|---|
| Source subnet route | Destination still points to NAT or another attachment |
| Security group | Return or destination access not allowed |
| Network ACL | Ephemeral return ports blocked |
| PBR rule | Broad earlier rule wins |
| Target TGW route table | Destination route absent or propagated from wrong attachment |
| Appliance mode | Return flow selects incompatible endpoint/AZ |
| Firewall | New source range or protocol not allowed |
| Destination VPC route | Return prefix points to another gateway |
Check the selected Region and address family. An IPv4 rule does not automatically express the IPv6 policy. If the initial release or current API does not support a required address-family match, document the fallback instead of assuming parity.
Security group referencing through Transit Gateway can simplify identity rules between VPCs, but outbound references and attachment support have their own limits. PBR chooses a routing table; it does not make the referenced security group valid on every path.
Control changes and emergency overrides
Require two-person review for production policy-table association and rule-order changes. The reviewer should receive a rendered rule table with overlap, unreachable-rule, and default-path analysis. Raw JSON or console screenshots make priority mistakes hard to spot.
Every policy release needs:
policy_version: 2026-07-30.3
target_attachments:
- tgw-attach-0123456789abcdef0
previous_policy_version: 2026-07-22.5
test_suite_digest: sha256:...
expected_inspection_percent: 82-86
rollback: disassociate policy and restore rt-spoke association
owner: network-platform
change_window_end: 2026-07-31T02:00:00Z
An emergency override should be a higher-priority, narrow, expiring rule, not an edit to the broad default. Record the incident, source/destination scope, reason, approver, and expiration. Alert if the rule remains after the window. Remove it through the same reviewed deployment path.
Do not make automatic failover by rewriting dozens of rules during an outage. Predefine the alternate route domain and test one controlled association or rule change. Automation should act on a known state transition, not synthesize network policy under pressure.
Know when not to use PBR
Use PBR when the route-table decision genuinely depends on source, port, or protocol and when eliminating extra routing hops improves the design. Keep ordinary destination routing when one route table already expresses the requirement. Avoid a rule for every application; that recreates a fragile firewall policy inside the network hub.
| Requirement | Best fit |
|---|---|
| Send all spoke egress through one inspection VPC | Normal Transit Gateway route tables |
| Inspect only selected source and port combinations | Transit Gateway PBR |
| Allow or deny workloads based on identity and state | Security groups and firewall policy |
| Control global route propagation and BGP attributes | Cloud WAN routing policies |
| Select application endpoint by HTTP path or hostname | Layer 7 proxy or load balancer |
Hand operations a flow-level runbook
The first incident question should be concrete: “Where should this five-tuple go?” Record source attachment, source and destination CIDRs, source and destination ports, protocol, expected matching rule, selected route table, next hop, and expected return path. That packet-level record prevents a vague “the network is broken” investigation from bouncing among application, firewall, and platform teams.
The runbook should then check policy association, ordered-rule match, selected route table, route state, attachment state, appliance health, and return symmetry. Capture Transit Gateway metrics, VPC Flow Logs, firewall logs, and the deployed policy version under one incident timestamp. Route Analyzer can verify topology, but it does not replace evidence from the exact flow.
Finally, define who owns each decision boundary. The network platform owns classification and route domains; the security team owns firewall policy; the application team owns the requested destination and port. Clear ownership matters because PBR makes the forwarding choice more expressive, not because it makes every downstream control one team’s responsibility.
PBR is most valuable when it makes the architecture smaller. If the proposed policy has hundreds of application-specific rules, stop and check whether segmentation, service networking, or a Layer 7 gateway owns the problem more cleanly.
Transit Gateway PBR replaces topology tricks with an explicit policy. That is progress. Treat the policy as production code: model both directions, test first-match behavior, canary one attachment, retain the previous route domain, and measure where traffic actually went.
Sources
- AWS Transit Gateway PBR launch announcement
- AWS Transit Gateway product page
- How AWS Transit Gateway works
- Centralized inspection with Gateway Load Balancer and Transit Gateway
- Transit Gateway appliance-mode routing improvements
- Transit Gateway Network Manager Route Analyzer
- AWS Transit Gateway pricing
Comments