aws-tgw-peering-routes-to-peer

explicit aws emits RoutesTo

match (record)

{ "field": "State", "resource_type": "AWS::EC2::TransitGatewayPeeringAttachment" }

where

peering_attachment.State == 'available'

emit

source typeTransitGateway
target typeNetwork
source<local TransitGateway node (RequesterTgwInfo.TransitGatewayId)>
target<peer VirtualNetwork (AccepterTgwInfo.TransitGatewayId's attached VPCs — modeled as a Network placeholder until peer account facts are available)>
conditionsnetwork_reachability
state logicACTIVE when peering_attachment.State == 'available' (both TGW owners have accepted). CONDITIONAL(service_state) when State == 'pendingAcceptance' (peer TGW owner has not yet accepted). Omit for State in [rejected, failed, deleted]. Routes across the peering are ONLY present if the respective TGW route tables have been updated to include the peer CIDR — annotate CONDITIONAL(network_reachability) for the linchpin to evaluate.

Narrative

TGW {local_tgw.name} (account {requester_account}) has an active peering attachment to TGW {peer_tgw_id} (account {accepter_account}). This is a routing topology fact - routes must be added to each TGW's route tables for traffic to flow across the peering (CONDITIONAL(network_reachability)).

Raw rule rules/explicit/aws-tgw.yaml

id: aws-tgw-peering-routes-to-peer
emits: RoutesTo
applies_to:
- aws
match_record:
  resource_type: AWS::EC2::TransitGatewayPeeringAttachment
  field: State
where:
- peering_attachment.State == 'available'
emit:
  source_type: TransitGateway
  target_type: Network
  source: <local TransitGateway node (RequesterTgwInfo.TransitGatewayId)>
  target: "<peer VirtualNetwork (AccepterTgwInfo.TransitGatewayId's attached VPCs \u2014 modeled as a\
    \ Network placeholder until peer account facts are available)>"
  api_source: ec2:DescribeTransitGatewayPeeringAttachments
  evidence_field: TransitGatewayPeeringAttachment.AccepterTgwInfo + RequesterTgwInfo + State
  conditions:
  - network_reachability
  state_logic: "ACTIVE when peering_attachment.State == 'available' (both TGW owners have accepted). CONDITIONAL(service_state)\
    \ when State == 'pendingAcceptance' (peer TGW owner has not yet accepted). Omit for State in [rejected,\
    \ failed, deleted]. Routes across the peering are ONLY present if the respective TGW route tables\
    \ have been updated to include the peer CIDR \u2014 annotate CONDITIONAL(network_reachability) for\
    \ the linchpin to evaluate."
  false_positive_note: Peering attachment creation (ec2:CreateTransitGatewayPeeringAttachment) does NOT
    automatically add routes between the peer TGWs; static routes must be added to each TGW's route table
    after the peering is established. Without those route table entries, the peering does not create reachability.
    Emit CONDITIONAL(network_reachability) and note that route table entries are required. Cross-account
    peering (AccepterTgwInfo.OwnerId != RequesterTgwInfo.OwnerId) is an additional cross-account reachability
    fact; the CrossAccountTrust for the RAM share (if used) is separate (see /rules/explicit/aws-ram.yaml).
  narrative: "TGW {local_tgw.name} (account {requester_account}) has an active peering attachment to TGW\
    \ {peer_tgw_id} (account {accepter_account}). This is a routing topology fact \u2014 routes must be\
    \ added to each TGW's route tables for traffic to flow across the peering (CONDITIONAL(network_reachability))."
move · open · esc close