CloudFormationでEC2を作成


はじめに

前回はCloudFormationでVPC周りを作ったので、
CloudFormationでも実現するようにしていきたいと思います。

CloudFormationの書き方としてはレイヤ毎に分けて書くのが推奨なので、
SecurityGroup / EC2 の作成のYAMLをそれぞれ書きました。内容についてはコメント記載しています。
みなさんの役に立ったら嬉しいです。

VPC周りのリソースを引っ張って構成しているので、SecrutiyGroupとEC2のデプロイする前にVPCをデプロイしてから実施してください。
VPCの記事はこちらです。

SecurityGroupのYAML

# 最新のテンプレートの形式バージョンは 2010-09-09 であり、現時点で唯一の有効な値です。

AWSTemplateFormatVersion: 2010-09-09

# 本テンプレートの説明です。

Description:
  Security Group Template

# スタック作成時にMyIPを手動で入力します。

Parameters: 
  MyIP:
    Description: IP address allowed to access EC2
    Type: String

# EC2のセキュリティグループ作成
# 許可IPはスタック作成時に設定したMyIP

Resources:
  SecurityGroupEC2:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: SecurityGroupEC2
      GroupName: SecurityGroupEC2
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 80
          ToPort: 80
          CidrIp: !Ref MyIP
        - IpProtocol: tcp
          FromPort: 443
          ToPort: 443
          CidrIp: !Ref MyIP
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          CidrIp: !Ref MyIP
      Tags:
        - Key: Name
          Value: SecurityGroupEC2
      VpcId: !ImportValue nnagashimaVPC

# RDSのセキュリティグループ作成
# Private環境なので許可IPは0.0.0.0/0としている
# postgresqlとmysqlだけを想定したポート許可

  SecurityGroupRDS:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: SecurityGroupRDS
      GroupName: SecurityGroupRDS
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 3306
          ToPort: 3306
          CidrIp: 0.0.0.0/0
        - IpProtocol: tcp
          FromPort: 5432
          ToPort: 5432
          CidrIp: 0.0.0.0/0
      Tags:
        - Key: Name
          Value: SecurityGroupRDS
      VpcId: !ImportValue nnagashimaVPC

# ALBのセキュリティグループ作成
# 443ポートのみを許可

  SecurityGroupALB:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: SecurityGroupALB
      GroupName: SecurityGroupALB
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 443
          ToPort: 443
          CidrIp: 0.0.0.0/0
      Tags:
        - Key: Name
          Value: SecurityGroupALB
      VpcId: !ImportValue nnagashimaVPC

# 最後にCloudFormation上で作成した各セキュリティグループのIDを表示させます。

Outputs:
  SecurityGroupEC2:
    Value: !Ref SecurityGroupEC2
    Export:
      Name: SecurityGroupEC2
  SecurityGroupRDS:
    Value: !Ref SecurityGroupRDS
    Export:
      Name: SecurityGroupRDS
  SecurityGroupALB:
    Value: !Ref SecurityGroupALB
    Export:
      Name: SecurityGroupALB

EC2のYAML

# 最新のテンプレートの形式バージョンは 2010-09-09 であり、現時点で唯一の有効な値です。

AWSTemplateFormatVersion: 2010-09-09

# 本テンプレートの説明です。

Description:
  EC2 Template

# 事前パラメータの定義

Parameters:

# EC2インスタンスの認証キーの指定(デフォルトではnn-ec2を指定)

  KeyName:
    Description: The EC2 Key Pair to allow SSH access to the instance
    Type: "AWS::EC2::KeyPair::KeyName"
    Default: nn-ec2

# 作成できるEC2インスタンスタイプの制限

  InstanceType:
    Description: WebServer EC2 instance type
    Type: String
    Default: t2.micro
    AllowedValues:
    - t2.micro
    - t2.small
    - t3.medium

Resources:

# EIPを新規アサイン

  ElasticIP:
    Type: AWS::EC2::EIP
    Properties:
      Domain: vpc
      Tags:
          - Key: Name
            Value: nn-ec2-test

# EC2インスタンスをデプロイ、AMZ2を起動している。

  EC2: 
    Type: AWS::EC2::Instance
    Properties: 
      ImageId: ami-00d101850e971728d
      KeyName: !Ref KeyName
      InstanceType: !Ref InstanceType
      NetworkInterfaces: 
        - AssociatePublicIpAddress: "true"
          DeviceIndex: "0"
          SubnetId: !ImportValue PublicSubnetD
          GroupSet: 
            - !ImportValue SecurityGroupEC2
      BlockDeviceMappings:
        - DeviceName: '/dev/xvda'
          Ebs:
            VolumeType: 'gp2'
            VolumeSize: 10
      Tags:
          - Key: Name
            Value: nn-ec2-test

# EC2インスタンスをデプロイ、AMZ2を起動している。

  IPAssoc:
    Type: AWS::EC2::EIPAssociation
    Properties:
      InstanceId: !Ref EC2
      EIP: !Ref ElasticIP

# EC2インスタンスをデプロイした結果を出力

Outputs:
  InstanceId:
    Value: !Ref EC2
    Export:
       Name: InstanceId
  AZ:
    Value:
      Fn::GetAtt:
      - EC2
      - AvailabilityZone
    Export:
       Name: AZ
  PublicIP:
    Value:
      Fn::GetAtt:
      - EC2
      - PublicIp
    Export:
      Name: PublicIp

最後に

ここまでコード管理できるようになると最初の準備がとても楽で、且つ上物の構築するだけになるので工数がだいぶ下がるようになると思います。
なにより構成管理が楽になるのがメリットです。
ただ既存のリソースを書き換える時だけは変更箇所をよくみてやらないと痛い目に合うので、注意が必要ですね。
これを機にもっと極めてCloudFormationだけで作れるようになっていきたいと思います。