CloudFront+InternalALBの構成をCloudFormation Templateにしてみた

# 追記
どうやらCloudFrontのVPC Originを作成しないとInternalALBへの接続はできないようです。
CloudFormationが対応したら追記します。

# 背景
つい先日、CloudFrontが直接PrivateのALBと接続できるというアップデートがありました。これにより、ALBにPublic IPを持たせることなく接続できます。

https://aws.amazon.com/jp/blogs/aws/introducing-amazon-cloudfront-vpc-origins-enhanced-security-and-streamlined-operations-for-your-applications/

そこで、CloudFormationのTemplateでCloudFront+InternalALBの構成を作成してみました。

# テンプレート
テンプレートでは実際にIPをターゲットとして機能するかどうかを検証していません。検証ができ次第追記します。また、この構成ではCloudFrontカスタムヘッダー + ManagedPrefixListの構成がまだ反映されていません。カスタムヘッダーとManagedPrefixListを利用した構成においても作成でき次第追記します。

```yaml
AWSTemplateFormatVersion: '2010-09-09'
Description: 'CloudFront + ALB(ip)'
Mappings:
# リージョンごとのCloudFrontのPrefixListのID
  RegionMap:
    ap-south-1:
      CloudFrontPrefixListId: pl-9aa247f3
    eu-north-1:
      CloudFrontPrefixListId: pl-fab65393
    eu-west-3:
      CloudFrontPrefixListId: pl-75b1541c
    eu-west-2:
      CloudFrontPrefixListId: pl-93a247fa
    eu-west-1:
      CloudFrontPrefixListId: pl-4fa04526
    ap-northeast-3:
      CloudFrontPrefixListId: pl-31a14458
    ap-northeast-2:
      CloudFrontPrefixListId: pl-22a6434b
    ap-northeast-1:
      CloudFrontPrefixListId: pl-58a04531
    ca-central-1:
      CloudFrontPrefixListId: pl-38a64351
    sa-east-1:
      CloudFrontPrefixListId: pl-5da64334
    ap-southeast-1:
      CloudFrontPrefixListId: pl-31a34658
    ap-southeast-2:
      CloudFrontPrefixListId: pl-b8a742d1
    eu-central-1:
      CloudFrontPrefixListId: pl-a3a144ca
    us-east-1:
      CloudFrontPrefixListId: pl-3b927c52
    us-east-2:
      CloudFrontPrefixListId: pl-b6a144df
    us-west-1:
      CloudFrontPrefixListId: pl-4ea04527
    us-west-2:
      CloudFrontPrefixListId: pl-82a045eb

Resources:
########## Network ##########
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.0.0.0/16
      EnableDnsSupport: 'true'
      EnableDnsHostnames: 'true'
      Tags:
       - Key: Name
         Value: hogehoge-VPC

  ALBSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: 10.0.0.0/24
      AvailabilityZone: !Select [0, !GetAZs ''] 
      Tags:
      - Key: Name
        Value: hogehoge-ALBSubnet-1

  ALBSubnet2:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: 10.0.1.0/24
      AvailabilityZone: !Select [1, !GetAZs ''] 
      Tags:
      - Key: Name
        Value: hogehoge-ALBSubnet-2

  ApplicationSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: 10.0.2.0/24
      AvailabilityZone: !Select [0, !GetAZs ''] 
      Tags:
      - Key: Name
        Value: hogehoge-ApplicationSubnet-1

  ApplicationSubnet2:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: 10.0.3.0/24
      AvailabilityZone: !Select [1, !GetAZs ''] 
      Tags:
      - Key: Name
        Value: hogehoge-ApplicationSubnet-2

  ALBRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId:  
        Ref: VPC
      Tags:
      - Key: Name
        Value: hogehoge-ALBRouteTable
        
  ALBRouteTableAssociation1:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId:
        Ref: ALBSubnet1
      RouteTableId:
        Ref: ALBRouteTable
        
  ALBRouteTableAssociation2:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId:
        Ref: ALBSubnet2
      RouteTableId:
        Ref: ALBRouteTable
        
  ApplicationRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId:  
        Ref: VPC
      Tags:
      - Key: Name
        Value: hogehoge-ApplicationRouteTable

  ApplicationRouteTableAssociation1:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId:
        Ref: ApplicationSubnet1
      RouteTableId:
        Ref: ApplicationRouteTable
        
  ApplicationRouteTableAssociation2:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId:
        Ref: ApplicationSubnet2
      RouteTableId:
        Ref: ApplicationRouteTable

  ALBSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: "hogehoge-InternalALB use this." 
      GroupName: hogehoge-InternalALB-SecurityGroup
      SecurityGroupEgress: 
        - CidrIp: 0.0.0.0/0
          FromPort: -1
          IpProtocol: -1
          ToPort: -1
      SecurityGroupIngress: 
        - SourcePrefixListId: !FindInMap [RegionMap, !Ref "AWS::Region", CloudFrontPrefixListId]
          FromPort: 80
          IpProtocol: tcp
          ToPort: 80
      VpcId: !Ref VPC


######### ALB ##########
  ApplicationTargetGroup:
    Type: AWS::ElasticLoadBalancingV2::TargetGroup
    Properties:
      Name: hogehoge-ApplicationTargetGroup
      Port: 80
      Protocol: HTTP
      TargetType: ip
      VpcId: !Ref VPC

  InternalALB:
    Type: AWS::ElasticLoadBalancingV2::LoadBalancer
    Properties:
      Name: hogehoge-InternalALB
      Scheme: internal
      SecurityGroups: 
        - !Ref ALBSecurityGroup
      Subnets: 
        - !Ref ALBSubnet1
        - !Ref ALBSubnet2
      Type: application
  
  CloudFront:
    Type: AWS::CloudFront::Distribution
    Properties: 
      DistributionConfig:
        Comment: "hogehoge 2.0"
        Enabled: true
        PriceClass: PriceClass_All
        Origins:
          - DomainName: !GetAtt InternalALB.DNSName
            Id: hogehoge-InternalALB
            CustomOriginConfig: 
              HTTPPort: 80
              HTTPSPort: 443
              OriginProtocolPolicy: http-only
              OriginSSLProtocols: 
                - TLSv1.2
              OriginReadTimeout: 30
              OriginKeepaliveTimeout: 5
            ConnectionAttempts: 3
            ConnectionTimeout: 10
            OriginShield:
              Enabled: false
        DefaultCacheBehavior: 
          AllowedMethods:
            - GET
            - HEAD
            - OPTIONS
            - PUT
            - POST
            - PATCH
            - DELETE
          CachePolicyId: 4135ea2d-6df8-44a3-9df3-4b5a84be39ad
          OriginRequestPolicyId: b689b0a8-53d0-40ab-baf2-68738e2966ac
          ResponseHeadersPolicyId: 5cc3b908-e619-4b99-88e5-2cf7f45965bd
          TargetOriginId: hogehoge-InternalALB
          ViewerProtocolPolicy: https-only
```