AWS CloudFormationでALBを作成してみました(CLI)

前提

・VPCが作成されていること
※パラメーター(Inputファイル)にサブネットIDをVPCコンソール上でコピペ
・ALBログ出力用のS3バケットが作成されていること
S3バケットバケット名例:cpi-dev-tyo-s3-kby-alblog
・S3バケットバケットポリシーが作成されていること
バケットポリシー例:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AlbLogs",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::582318560864:root"
            },
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::cpi-dev-tyo-s3-kby-alblog/*/268673644828/*"
        }
    ]
}

・ACMに証明書が作成されていること
証明書のARN例:
パラメーター(Inputファイル)に、Certificate Managerコンソール上よりコピペ

arn:aws:acm:ap-northeast-1:268673644828:certificate/e668071b-7ce3-4f10-9e19-03079f8d398f

・AWS CLIがインストールされて、初期設定が完了できていること
・実行OS: Winows

テンプレート

パラメーターを設定して再利用可能なテンプレートを作成します。
ファイル名:ALB-Template.yaml

AWSTemplateFormatVersion: '2010-09-09'
Description: 'ALB'
Parameters:
  Environment:
    Type: String
    Description: "Environment"
  ALBName:
    Type: String
    Description: "ALBName"
  ALBSubnets:
    Type: CommaDelimitedList
    Description: "ALBSubnets"
  ALBlogbucket:
    Type: String
    Description: "ALBlogbucket"
  ALBlogbucketprefix:
    Type: String
    Description: "ALBlogbucketprefix"
# HTTPS
  Certificates:
    Type: String
    Description: "Certificates"
# SorryListenerRule
  SorryListenerContentType:
    Type: String
    Description: "SorryListenerContentType"
  SorryListenerMessageBody:
    Type: String
    Description: "SorryListenerMessageBody"
# Common Parameters
  HealthCheckIntervalSeconds:
    Type: String
    Description: "HealthCheckIntervalSeconds"
  HealthCheckPath:
    Type: String
    Description: "HealthCheckPath"
  HealthCheckTimeoutSeconds:
    Type: String
    Description: "HealthCheckTimeoutSeconds"
  HealthyThresholdCount:
    Type: String
    Description: "HealthyThresholdCount"
  UnhealthyThresholdCount:
    Type: String
    Description: "UnhealthyThresholdCount"
  VpcId:
    Type: String
    Description: "VpcId"
# BlueTargetGroup Parameters
  BlueTargetGroupName:
    Type: String
    Description: "BlueTargetGroupName"
# GreenTargetGroup Parameters
  GreenTargetGroupName:
    Type: String
    Description: "GreenTargetGroupName"
# SecurityGroup Parameters
  SecurityGroupName:
    Type: String
    Description: "SecurityGroupName"
  SecurityGroupDescription:
    Type: String
    Description: "SecurityGroupDescription"
  IngressDescription01:
    Type: String
    Description: "IngressDescription01"
  IngressDescription02:
    Type: String
    Description: "IngressDescription02"

Resources:
# ALB
  ALB:
    Type: AWS::ElasticLoadBalancingV2::LoadBalancer
    Properties:
      Type: application
      IpAddressType: ipv4
      Name: !Ref ALBName
      Scheme: internet-facing
      # Scheme: internal
      SecurityGroups:
        - !Ref SecurityGroup
      Subnets: !Ref ALBSubnets
      LoadBalancerAttributes:
        - Key: access_logs.s3.enabled
          Value: true
        - Key: access_logs.s3.bucket
          Value: !Ref ALBlogbucket
        - Key: access_logs.s3.prefix
          Value: !Ref ALBlogbucketprefix
#        - Key: deletion_protection.enabled
#          Value: true
        - Key: routing.http.drop_invalid_header_fields.enabled
          Value: true
        - Key: routing.http.desync_mitigation_mode
          Value: defensive
        - Key: idle_timeout.timeout_seconds
          Value: 60
      Tags:
        - Key: Name
          Value: !Ref ALBName
        - Key: Env
          Value: !Ref Environment
# HTTP
  HTTPListener:
    Type: AWS::ElasticLoadBalancingV2::Listener
    Properties:
      DefaultActions:
        - Type: redirect
          RedirectConfig:
              StatusCode: HTTP_301
              Protocol: HTTPS
              Port: 443
      LoadBalancerArn: !Ref ALB
      Port: 80
      Protocol: HTTP
# HTTPS
  HTTPSListener:
    Type: AWS::ElasticLoadBalancingV2::Listener
    Properties:
      DefaultActions:
        - Type: forward
          TargetGroupArn: !Ref BlueTargetGroup
      Certificates:
        - CertificateArn: !Ref Certificates
      LoadBalancerArn: !Ref ALB
      Port: 443
      Protocol: HTTPS
# HTTPS ListenerRule Main
  MainListenerRule:
    Type: AWS::ElasticLoadBalancingV2::ListenerRule
    Properties:
      Actions:
        - Type: forward
          ForwardConfig:
              TargetGroups:
                - TargetGroupArn: !Ref BlueTargetGroup
                  Weight: 100
                - TargetGroupArn: !Ref GreenTargetGroup
                  Weight: 0
      Conditions:
        - Field: path-pattern
          PathPatternConfig:
              Values:
                - '*'
      ListenerArn: !Ref HTTPSListener
      Priority: 2
# HTTPS ListenerRule Sorry
  SorryListenerRule:
    Type: AWS::ElasticLoadBalancingV2::ListenerRule
    Properties:
      Actions:
        - Type: fixed-response
          FixedResponseConfig:
              ContentType: !Ref SorryListenerContentType 
# MessageBody
              MessageBody: !Ref SorryListenerMessageBody
              StatusCode: 503
      Conditions:
        - Field: path-pattern
          PathPatternConfig:
              Values:
                - '*'
      ListenerArn: !Ref HTTPSListener
      Priority: 9
# Blue TargetGroup
  BlueTargetGroup:
    Type: AWS::ElasticLoadBalancingV2::TargetGroup
    Properties:
      HealthCheckEnabled: true
      HealthCheckIntervalSeconds: !Ref HealthCheckIntervalSeconds
      HealthCheckPath: !Ref HealthCheckPath
      HealthCheckPort: 80
      HealthCheckProtocol: HTTP
      HealthCheckTimeoutSeconds: !Ref HealthCheckTimeoutSeconds
      HealthyThresholdCount: !Ref HealthyThresholdCount
      Matcher:
        HttpCode: 200
      Name: !Ref BlueTargetGroupName
      Port: 80
      Protocol: HTTP
      TargetType: instance
      UnhealthyThresholdCount: !Ref UnhealthyThresholdCount
      VpcId: !Ref VpcId
      Tags:
      - Key: Name
        Value: !Ref BlueTargetGroupName
      - Key: Env
        Value: !Ref Environment
      - Key: BlueGreen
        Value: Blue
# Green TargetGroup
  GreenTargetGroup:
    Type: AWS::ElasticLoadBalancingV2::TargetGroup
    Properties:
      HealthCheckEnabled: true
      HealthCheckIntervalSeconds: !Ref HealthCheckIntervalSeconds
      HealthCheckPath: !Ref HealthCheckPath
      HealthCheckPort: 80
      HealthCheckProtocol: HTTP
      HealthCheckTimeoutSeconds: !Ref HealthCheckTimeoutSeconds
      HealthyThresholdCount: !Ref HealthyThresholdCount
      Matcher:
        HttpCode: 200
      Name: !Ref GreenTargetGroupName
      Port: 80
      Protocol: HTTP
      TargetType: instance
      UnhealthyThresholdCount: !Ref UnhealthyThresholdCount
      VpcId: !Ref VpcId
      Tags:
      - Key: Name
        Value: !Ref GreenTargetGroupName
      - Key: Env
        Value: !Ref Environment
      - Key: BlueGreen
        Value: Green
# SecurityGroup
  SecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupName: !Ref SecurityGroupName
      GroupDescription: !Ref SecurityGroupDescription
      VpcId: !Ref VpcId
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 80
          ToPort: 80
          CidrIp: 0.0.0.0/0
          Description: !Ref IngressDescription01
        - IpProtocol: tcp
          FromPort: 443
          ToPort: 443
          CidrIp: 0.0.0.0/0
          Description: !Ref IngressDescription02
      Tags:
      - Key: Name
        Value: !Ref SecurityGroupName
      - Key: Env
        Value: !Ref Environment

Outputs:
# Blue TargetGroup
  BlueTargetGroup:
    Value: !Ref BlueTargetGroup
    Export:
      Name: !Ref BlueTargetGroupName
# Green TargetGroup
  GreenTargetGroup:
    Value: !Ref GreenTargetGroup
    Export:
      Name: !Ref GreenTargetGroupName

パラメーター(Inputファイル)

ファイル名:cpi-dev-alb-test01.yaml

StackName: 'cpi-dev-alb-test01'
Parameters:
- ParameterKey: 'Environment'
  ParameterValue: 'cpi-dev'
- ParameterKey: 'ALBName'
  ParameterValue: 'cpi-dev-alb-test01'
- ParameterKey: 'ALBSubnets'
  ParameterValue: 'subnet-0ad5e179c1769a532,subnet-01921a93ba3299d92'
- ParameterKey: 'ALBlogbucket'
  ParameterValue: 'cpi-dev-tyo-s3-kby-alblog'
- ParameterKey: 'ALBlogbucketprefix'
  ParameterValue: 'func01/albname'
- ParameterKey: 'Certificates'
  ParameterValue: 'arn:aws:acm:ap-northeast-1:268673644828:certificate/e668071b-7ce3-4f10-9e19-03079f8d398f'
- ParameterKey: 'SorryListenerContentType'
  ParameterValue: 'text/html'
- ParameterKey: 'SorryListenerMessageBody'
  ParameterValue: |
    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8">
        <title>Sorry</title>
      </head>
      <body>
        <h1>Sorry</h1>
      </body>
    </html>
- ParameterKey: 'HealthCheckIntervalSeconds'
  ParameterValue: '30'
- ParameterKey: 'HealthCheckPath'
  ParameterValue: '/test.html'
- ParameterKey: 'HealthCheckTimeoutSeconds'
  ParameterValue: '5'
- ParameterKey: 'HealthyThresholdCount'
  ParameterValue: '5'
- ParameterKey: 'UnhealthyThresholdCount'
  ParameterValue: '2'
- ParameterKey: 'VpcId'
  ParameterValue: 'vpc-06106967d774bee36'
- ParameterKey: 'BlueTargetGroupName'
  ParameterValue: 'cpi-tyo-tg-blue'
- ParameterKey: 'GreenTargetGroupName'
  ParameterValue: 'cpi-tyo-tg-blue-green'
- ParameterKey: 'SecurityGroupName'
  ParameterValue: 'cpi-tyo-sg-alb-test01'
- ParameterKey: 'SecurityGroupDescription'
  ParameterValue: 'cpi-tyo-sg-alb-test01'
- ParameterKey: 'IngressDescription01'
  ParameterValue: 'HTTP From AnyWhere'
- ParameterKey: 'IngressDescription02'
  ParameterValue: 'HTTPS From AnyWhere'

スタック作成

バッチファイルを作成して実行します。
ファイル名:create_cpi-dev-alb-test01.bat

@echo off
set CFN_PATH=D:\AWS-CPI-DEV\90_Template
set INPUT_PATH=D:\AWS-CPI-DEV\90_Template\InputFiles
set TEMPLATE_NAME=ALB-Template.yaml
set INPUT_NAME=cpi-dev-alb-test01.yaml

aws cloudformation create-stack --template-body file://%CFN_PATH%\%TEMPLATE_NAME% --cli-input-yaml file://%INPUT_PATH%\%INPUT_NAME%

バッチを実行

create_cpi-dev-alb-test01.bat
{
    "StackId": "arn:aws:cloudformation:ap-northeast-1:268673644828:stack/cpi-dev-alb-test01/7f4eafe0-a370-11eb-80ad-0afa5c27f35b"
}

確認

確認1:CloudFormationコンソール上で確認

確認2:EC2コンソール上で確認

まとめ

以前、動作確認のため、AWSコンソール上でリソースを作成したことがあります。検証完了後、リソースの削除漏れがよくあります。CloudFormationでリソースを作成して、検証完了後、スタックを削除すると関連リソースが作成されます。

テンプレートを利用する時、名前やサブネットIDを自分の環境に読み替えでください。少しでもお役に立てれば幸いです。

Last modified: 2021-04-22

Author