一覧に戻る
Networking

Transit Gateway と Network Firewall によるマルチVPC構成

AWS Transit Gateway をハブとし、複数のVPC(Spoke VPC)やオンプレミスと接続しながら、AWS Network Firewall によって安全にトラフィックを集中検査・制御する境界セキュリティ構成です。

構成要素 (AWS Services):

Transit GatewayVPCNetwork FirewallRoute 53IAM

構築される主要リソース (13種):

EC2 Subnet7
EC2 VPC3
EC2 TransitGatewayAttachment3
EC2 TransitGatewayRouteTableAssociation3
EC2 TransitGatewayRouteTable2
EC2 TransitGatewayRouteTablePropagation2
EC2 TransitGateway1
EC2 InternetGateway1
EC2 VPCGatewayAttachment1
NetworkFirewall RuleGroup1
NetworkFirewall FirewallPolicy1
NetworkFirewall Firewall1
EC2 TransitGatewayRoute1

アーキテクチャ図 (Architecture Diagram)

クリックで拡大表示
Transit Gateway と Network Firewall によるマルチVPC構成 アーキテクチャ図

AWS CLI でのデプロイ例

AWS CLIを使用してCloudFormationスタックをデプロイする場合は、以下のコマンドを実行します。

aws cloudformation deploy \
  --template-file transitgateway-secure-hubspoke.yaml \
  --stack-name transitgateway-secure-hubspoke-stack \
  --capabilities CAPABILITY_IAM CAPABILITY_NAMED_IAM
transitgateway-secure-hubspoke.yaml
DL
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'