ネストされた ALB/NLB/EC2 を CloudFormation で構築
[履歴] [最終更新] (2017/10/20 20:58:02)
1
作品
369
技術情報
最近の投稿
ここは
趣味の電子工作を楽しむ人のためのハードウェア情報共有サイト

技術情報や作品の投稿機能、リアルタイム遠隔操作 API をご利用いただけます。
新着作品

概要

AWS ELB に ALBNLB が追加され、こちらのページで使用方法を把握した従来の ELB は CLB (Classic Load Balancer) とよばれるようになりました。本ページでは CloudFormation の基本的な使い方を把握する目的で ALB/NLB/EC2 スタックを作成するテンプレートを YAML で記述します。その際、共通部分は別テンプレートに分離してスタックをネストさせます。

テンプレートを記述する際は、以下のようなドキュメントを参照します。

EC2 インスタンス用のテンプレート (ALB/NLB 共通部分)

以下のような設定で EC2 インスタンスを一つだけ起動します。

  • 事前に作成した VPC、Subnet、SSH 鍵 をスタック作成時に引数として指定
  • 事前に作成した AMI をスタックを作成するリージョンに応じて指定
  • SSH/HTTP ポートのみ開放
  • ルートボリューム以外に EBS 32 GB をアタッチ
  • インスタンスタイプ t2.micro
  • 固定 EIP を付与

ec2.yaml

AWSTemplateFormatVersion: 2010-09-09
Description: Launch EC2 Instance
Parameters:
  MyVpcId:
    Type: AWS::EC2::VPC::Id
  MySubnetId:
    Type: AWS::EC2::Subnet::Id
  MyKeyName:
    Type: AWS::EC2::KeyPair::KeyName
Mappings:
  MyRegionMap: # Amazon Linux AMI 2017.09.0 (HVM), SSD Volume Type
    us-east-1: # US East (N. Virginia)
      AMI: ami-8c1be5f6
    us-east-2: # US East (Ohio)
      AMI: ami-c5062ba0
    us-west-1: # US West (N. California)
      AMI: ami-02eada62
    us-west-2: # US West (Oregon)
      AMI: ami-e689729e
    ca-central-1: # Canada (Central)
      AMI: ami-fd55ec99
    eu-west-1: # EU (Ireland)
      AMI: ami-acd005d5
    eu-west-2: # EU (London)
      AMI: ami-1a7f6d7e
    eu-central-1: # EU (Frankfurt)
      AMI: ami-c7ee5ca8
    ap-southeast-1: # Asia Pacific (Singapore)
      AMI: ami-0797ea64
    ap-southeast-2: # Asia Pacific (Sydney)
      AMI: ami-8536d6e7
    ap-northeast-1: # Asia Pacific (Tokyo)
      AMI: ami-2a69be4c
    ap-northeast-2: # Asia Pacific (Seoul)
      AMI: ami-9bec36f5
    ap-south-1: # Asia Pacific (Mumbai)
      AMI: ami-4fc58420
    sa-east-1: # South America (São Paulo)
      AMI: ami-f1344b9d
Resources:
  MyEc2SecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Allow incoming SSH/HTTP connections.
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          CidrIp: 0.0.0.0/0
        - IpProtocol: tcp
          FromPort: 80
          ToPort: 80
          CidrIp: 0.0.0.0/0
      VpcId: !Ref MyVpcId
  MyEc2Instance:
    Type: AWS::EC2::Instance
    Properties:
      BlockDeviceMappings:
        - DeviceName: /dev/sdf
          Ebs:
            DeleteOnTermination: false
            VolumeSize: 32
            VolumeType: gp2
      ImageId: !FindInMap [ MyRegionMap, !Ref 'AWS::Region', AMI ]
      InstanceType: t2.micro
      KeyName: !Ref MyKeyName
      SecurityGroupIds:
        - !Ref MyEc2SecurityGroup
      SubnetId: !Ref MySubnetId
      Tags:
        - Key: Name
          Value: my-ec2-instance
  MyEip:
    Type: AWS::EC2::EIP
    Properties:
      InstanceId: !Ref MyEc2Instance
      Domain: vpc
Outputs:
  MyOutputEc2Instance:
    Value: !Ref MyEc2Instance

ALB/NLB 用のテンプレート

以下のような設定で ALB/NLB および EC2 インスタンスを起動します。内部的に EC2 インスタンス用のテンプレートを利用します。TCP や HTTP についてはこちらのページもご参照ください。

  • 事前に作成した VPC、Subnet 二つ、SSH 鍵、テンプレート URL をスタック作成時に引数として指定
    • EC2 インスタンス用のテンプレートは S3 にアップロードしたものを指定
  • EC2 インスタンスは二つのサブネットでそれぞれで一つずつ起動
  • ALB 経由では HTTP ポートのみ待ち受け
    • EC2 インスタンスの HTTP ポートにリバースプロキシ
    • EC2 インスタンスの HTTP ポートのパス /status でヘルスチェック
  • NLB 経由では TCP 80 番ポートのみ待ち受け
    • EC2 インスタンスの TCP 80 番ポートにリバースプロキシ
    • EC2 インスタンスの HTTP ポートのパス /status でヘルスチェック
  • DefaultActions 以外のアクション設定が不要なため AWS::ElasticLoadBalancingV2::ListenerRule 未設定

alb-nlb-ec2.yaml

AWSTemplateFormatVersion: 2010-09-09
Description: Create ALB (or NLB) and attached EC2 instances.
Parameters:
  MyVpcId:
    Type: AWS::EC2::VPC::Id
  MySubnetId1:
    Type: AWS::EC2::Subnet::Id
  MySubnetId2:
    Type: AWS::EC2::Subnet::Id
  MyKeyName:
    Type: AWS::EC2::KeyPair::KeyName
  MyEc2StackTemplateURL:
    Type: String
    AllowedPattern: ^https://s3.amazonaws.com/.+$
Resources:
  MyEc2Stack1:
    Type: AWS::CloudFormation::Stack
    Properties:
      Parameters:
        MyVpcId: !Ref MyVpcId
        MySubnetId: !Ref MySubnetId1
        MyKeyName: !Ref MyKeyName
      TemplateURL: !Ref MyEc2StackTemplateURL
  MyEc2Stack2:
    Type: AWS::CloudFormation::Stack
    Properties:
      Parameters:
        MyVpcId: !Ref MyVpcId
        MySubnetId: !Ref MySubnetId2
        MyKeyName: !Ref MyKeyName
      TemplateURL: !Ref MyEc2StackTemplateURL
  MyLbSecurityGroup:  # NLB では削除します。
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupName: MyLbSecurityGroup
      GroupDescription: Allow incoming HTTP connections.
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 80
          ToPort: 80
          CidrIp: 0.0.0.0/0
      VpcId: !Ref MyVpcId
  MyTargetGroup:
    Type: AWS::ElasticLoadBalancingV2::TargetGroup
    Properties:
      HealthCheckIntervalSeconds: 30
      HealthCheckPath: /status
      HealthCheckPort: 80
      HealthCheckProtocol: HTTP
      HealthCheckTimeoutSeconds: 10  # NLB では削除します。
      HealthyThresholdCount: 4
      Matcher:  # NLB では削除します。
        HttpCode: 200
      Name: MyTargetGroup
      Port: 80
      Protocol: HTTP  # NLB では `TCP` に変更します。
      Targets:
        - Id: !GetAtt MyEc2Stack1.Outputs.MyOutputEc2Instance
          Port: 80
        - Id: !GetAtt MyEc2Stack2.Outputs.MyOutputEc2Instance
          Port: 80
      UnhealthyThresholdCount: 3  # NLB では `HealthyThresholdCount` と同じ値にします。
      VpcId: !Ref MyVpcId
  MyLb:
    Type: AWS::ElasticLoadBalancingV2::LoadBalancer
    Properties:
      Name: MyLbName
      Scheme: internet-facing
      SecurityGroups:  # NLB では削除します。
        - !Ref MyLbSecurityGroup
      Subnets:
        - !Ref MySubnetId1
        - !Ref MySubnetId2
      Type: application  # NLB では `network` に変更します。
  MyListener:
    Type: AWS::ElasticLoadBalancingV2::Listener
    Properties:
      DefaultActions:
        - TargetGroupArn: !Ref MyTargetGroup
          Type: forward
      LoadBalancerArn: !Ref MyLb
      Port: 80
      Protocol: HTTP  # NLB では `TCP` に変更します。

成功すれば以下のように root stack と nested stack が作られます。インスタンスに SSH ログインして nginx 等をインストールした後 /status で 200 を返すように設定すれば ALB 経由でインターネットから HTTP 接続できるようになります。

Uploaded Image