AWS Transit Gateway をハブとし、複数のVPC(Spoke VPC)やオンプレミスと接続しながら、AWS Network Firewall によって安全にトラフィックを集中検査・制御する境界セキュリティ構成です。
AWS CLIを使用してCloudFormationスタックをデプロイする場合は、以下のコマンドを実行します。
aws cloudformation deploy \ --template-file transitgateway-secure-hubspoke.yaml \ --stack-name transitgateway-secure-hubspoke-stack \ --capabilities CAPABILITY_IAM CAPABILITY_NAMED_IAM
AWSTemplateFormatVersion: '2010-09-09'
Description: 'Multi-VPC Hub and Spoke Architecture using AWS Transit Gateway and AWS Network Firewall.'
Parameters:
Environment:
Type: String
Default: dev
AllowedValues:
- dev
- prod
Description: Environment name
Resources:
# 1. AWS Transit Gateway
TransitGateway:
Type: AWS::EC2::TransitGateway
Properties:
Description: 'Transit Gateway for Hub and Spoke routing control'
AutoAcceptSharedAttachments: enable
DefaultRouteTableAssociation: disable
DefaultRouteTablePropagation: disable
Tags:
- Key: Name
Value: !Sub 'hub-spoke-tgw-${Environment}'
# TGW Route Tables
SpokeRouteTable:
Type: AWS::EC2::TransitGatewayRouteTable
Properties:
TransitGatewayId: !Ref TransitGateway
Tags:
- Key: Name
Value: !Sub 'spoke-tgw-rt-${Environment}'
HubRouteTable:
Type: AWS::EC2::TransitGatewayRouteTable
Properties:
TransitGatewayId: !Ref TransitGateway
Tags:
- Key: Name
Value: !Sub 'hub-tgw-rt-${Environment}'
# 2. Hub VPC (Inspection & Egress VPC)
HubVPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.0.0.0/16
EnableDnsHostnames: true
EnableDnsSupport: true
Tags:
- Key: Name
Value: !Sub 'hub-vpc-${Environment}'
InternetGateway:
Type: AWS::EC2::InternetGateway
Properties:
Tags:
- Key: Name
Value: !Sub 'hub-igw-${Environment}'
VPCGatewayAttachment:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
VpcId: !Ref HubVPC
InternetGatewayId: !Ref InternetGateway
# Hub VPC Subnets
PublicSubnet:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref HubVPC
CidrBlock: 10.0.1.0/24
AvailabilityZone: !Select [0, !GetAZs '']
MapPublicIpOnLaunch: true
Tags:
- Key: Name
Value: !Sub 'hub-public-subnet-${Environment}'
InspectionSubnet:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref HubVPC
CidrBlock: 10.0.2.0/24
AvailabilityZone: !Select [0, !GetAZs '']
Tags:
- Key: Name
Value: !Sub 'hub-inspection-subnet-${Environment}'
TgwSubnet:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref HubVPC
CidrBlock: 10.0.3.0/24
AvailabilityZone: !Select [0, !GetAZs '']
Tags:
- Key: Name
Value: !Sub 'hub-tgw-subnet-${Environment}'
# 3. AWS Network Firewall in Hub VPC
FirewallRuleGroup:
Type: AWS::NetworkFirewall::RuleGroup
Properties:
RuleGroupName: !Sub 'egress-rules-${Environment}'
Type: STATEFUL
Capacity: 100
RuleGroup:
RulesSource:
StatefulRules:
- Action: DROP
Header:
Destination: any
DestinationPort: any
Direction: ANY
Protocol: HTTP
Source: any
SourcePort: any
RuleOptions:
- Name: sid
Value: '1'
- Name: msg
Value: '"Drop HTTP cleartext traffic"'
FirewallPolicy:
Type: AWS::NetworkFirewall::FirewallPolicy
Properties:
FirewallPolicyName: !Sub 'inspection-policy-${Environment}'
FirewallPolicy:
StatelessDefaultActions:
- 'aws:forward_to_sfe'
StatelessFragmentDefaultActions:
- 'aws:forward_to_sfe'
StatefulRuleGroupReferences:
- ResourceArn: !Ref FirewallRuleGroup
NetworkFirewall:
Type: AWS::NetworkFirewall::Firewall
Properties:
FirewallName: !Sub 'inspection-fw-${Environment}'
FirewallPolicyArn: !Ref FirewallPolicy
VpcId: !Ref HubVPC
SubnetMappings:
- SubnetId: !Ref InspectionSubnet
# 4. Spoke VPC 1 (App VPC)
SpokeVPC1:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.1.0.0/16
EnableDnsHostnames: true
EnableDnsSupport: true
Tags:
- Key: Name
Value: !Sub 'spoke-vpc1-${Environment}'
Spoke1AppSubnet:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref SpokeVPC1
CidrBlock: 10.1.1.0/24
AvailabilityZone: !Select [0, !GetAZs '']
Tags:
- Key: Name
Value: !Sub 'spoke1-app-subnet-${Environment}'
Spoke1TgwSubnet:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref SpokeVPC1
CidrBlock: 10.1.2.0/24
AvailabilityZone: !Select [0, !GetAZs '']
Tags:
- Key: Name
Value: !Sub 'spoke1-tgw-subnet-${Environment}'
# 5. Spoke VPC 2 (Db VPC)
SpokeVPC2:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.2.0.0/16
EnableDnsHostnames: true
EnableDnsSupport: true
Tags:
- Key: Name
Value: !Sub 'spoke-vpc2-${Environment}'
Spoke2DbSubnet:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref SpokeVPC2
CidrBlock: 10.2.1.0/24
AvailabilityZone: !Select [0, !GetAZs '']
Tags:
- Key: Name
Value: !Sub 'spoke2-db-subnet-${Environment}'
Spoke2TgwSubnet:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref SpokeVPC2
CidrBlock: 10.2.2.0/24
AvailabilityZone: !Select [0, !GetAZs '']
Tags:
- Key: Name
Value: !Sub 'spoke2-tgw-subnet-${Environment}'
# 6. Transit Gateway Attachments
HubAttachment:
Type: AWS::EC2::TransitGatewayAttachment
Properties:
TransitGatewayId: !Ref TransitGateway
VpcId: !Ref HubVPC
SubnetIds:
- !Ref TgwSubnet
Tags:
- Key: Name
Value: !Sub 'hub-tgw-attachment-${Environment}'
Spoke1Attachment:
Type: AWS::EC2::TransitGatewayAttachment
Properties:
TransitGatewayId: !Ref TransitGateway
VpcId: !Ref SpokeVPC1
SubnetIds:
- !Ref Spoke1TgwSubnet
Tags:
- Key: Name
Value: !Sub 'spoke1-tgw-attachment-${Environment}'
Spoke2Attachment:
Type: AWS::EC2::TransitGatewayAttachment
Properties:
TransitGatewayId: !Ref TransitGateway
VpcId: !Ref SpokeVPC2
SubnetIds:
- !Ref Spoke2TgwSubnet
Tags:
- Key: Name
Value: !Sub 'spoke2-tgw-attachment-${Environment}'
# 7. Transit Gateway Routing Associations & Propagations
Spoke1Association:
Type: AWS::EC2::TransitGatewayRouteTableAssociation
Properties:
TransitGatewayRouteTableId: !Ref SpokeRouteTable
TransitGatewayAttachmentId: !Ref Spoke1Attachment
Spoke2Association:
Type: AWS::EC2::TransitGatewayRouteTableAssociation
Properties:
TransitGatewayRouteTableId: !Ref SpokeRouteTable
TransitGatewayAttachmentId: !Ref Spoke2Attachment
HubAssociation:
Type: AWS::EC2::TransitGatewayRouteTableAssociation
Properties:
TransitGatewayRouteTableId: !Ref HubRouteTable
TransitGatewayAttachmentId: !Ref HubAttachment
# Propagate routes so Spoke traffic routes back
Spoke1Propagation:
Type: AWS::EC2::TransitGatewayRouteTablePropagation
Properties:
TransitGatewayRouteTableId: !Ref HubRouteTable
TransitGatewayAttachmentId: !Ref Spoke1Attachment
Spoke2Propagation:
Type: AWS::EC2::TransitGatewayRouteTablePropagation
Properties:
TransitGatewayRouteTableId: !Ref HubRouteTable
TransitGatewayAttachmentId: !Ref Spoke2Attachment
# Route from Spokes to Hub (Default Egress via Hub Inspection)
SpokeDefaultRoute:
Type: AWS::EC2::TransitGatewayRoute
Properties:
TransitGatewayRouteTableId: !Ref SpokeRouteTable
DestinationCidrBlock: 0.0.0.0/0
TransitGatewayAttachmentId: !Ref HubAttachment
Outputs:
TransitGatewayId:
Description: Transit Gateway ID
Value: !Ref TransitGateway
Export:
Name: !Sub '${AWS::StackName}-TGW-ID'
InspectionFWName:
Description: Network Firewall Name
Value: !Ref NetworkFirewall
Export:
Name: !Sub '${AWS::StackName}-FW-Name'