🌟

EC2に導入したDockerを使って色々検証するための環境構築用にCloudFormationテンプレートを作ってみた

2022/05/23に公開

はじめに

EC2に導入したDockerを使って諸々検証するための一時的な環境なので、毎度手で作っては消しての運用をしてましたが、流石に手間となってきたので一発で環境が作成できるようにCloudFormationテンプレートを作ってみました。

テンプレート

今回は検証にあたって最低限必要となる構成(EC2の構築およびEC2へのDocker、Docker-Composeの導入まで)を作成するところまでを目途に、テンプレート化してみました。

test-template.yml
AWSTemplateFormatVersion: "2010-09-09"
Description: Provision EC2 for Test

# ------------------------------------------------------------#
# Input Parameters
# ------------------------------------------------------------#
Parameters:
  # 環境名
  EnvironmentName:
    Type: String
    Default: testEnv

  # EC2パラメータ
  KeyName:
    Type: "AWS::EC2::KeyPair::KeyName"
    Default: "KeyName"
  InstanceName:
    Type: String
    Default: "test"
  AMIID: 
    Type: String
    Default: "ami-xxxxxxxxxxxxxx"
  InstanceType:
    Type: String
    Default: "t3.large"
  InstanceVolumeSize:
    Type: String
    Default: "30"
  SourceIP:
    Type: String

Resources:
# ------------------------------------------------------------#
# VPC
# ------------------------------------------------------------#
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.0.0.0/16
      EnableDnsSupport: "true"
      EnableDnsHostnames: "true"
      InstanceTenancy: default
      Tags:
        - Key: Name
          Value: !Sub "${EnvironmentName}-vpc"

  InternetGateway: 
    Type: "AWS::EC2::InternetGateway"
    Properties: 
      Tags: 
        - Key: Name
          Value: !Sub "${EnvironmentName}-igw"

  InternetGatewayAttachment: 
    Type: "AWS::EC2::VPCGatewayAttachment"
    Properties: 
      InternetGatewayId: !Ref InternetGateway
      VpcId: !Ref VPC

# ------------------------------------------------------------#
#  Subnet
# ------------------------------------------------------------#
  PublicSubnet: 
    Type: "AWS::EC2::Subnet"
    Properties: 
      AvailabilityZone: "ap-northeast-1a"
      CidrBlock:  "10.0.0.0/24"
      VpcId: !Ref VPC
      Tags: 
        - Key: Name
          Value: !Sub "${EnvironmentName}-public-subnet"

# ------------------------------------------------------------#
#  Route
# ------------------------------------------------------------#
  RouteTable: 
    Type: "AWS::EC2::RouteTable"
    Properties: 
      VpcId: !Ref VPC 
      Tags: 
        - Key: Name
          Value: !Sub "${EnvironmentName}-routeTable"

  Route: 
    Type: "AWS::EC2::Route"
    Properties: 
      RouteTableId: !Ref RouteTable 
      DestinationCidrBlock: "0.0.0.0/0"
      GatewayId: !Ref InternetGateway 

  RouteTableAssociation: 
    Type: "AWS::EC2::SubnetRouteTableAssociation"
    Properties: 
      SubnetId: !Ref PublicSubnet
      RouteTableId: !Ref RouteTable

# ------------------------------------------------------------#
#  SecurityGroup
# ------------------------------------------------------------#
  SecurityGroup:
    Type: "AWS::EC2::SecurityGroup"
    Properties: 
      VpcId: !Ref VPC 
      GroupName: !Sub "${EnvironmentName}-sg"
      GroupDescription: "-"
      Tags:
        - Key: "Name"
          Value: !Sub "${EnvironmentName}-sg"
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          CidrIp: !Ref SourceIP
        - IpProtocol: tcp
          FromPort: 80
          ToPort: 80
          CidrIp: !Ref SourceIP
        - IpProtocol: tcp
          FromPort: 443
          ToPort: 443
          CidrIp: !Ref SourceIP

# ------------------------------------------------------------#
#  IAM
# ------------------------------------------------------------# 
  IAMRole: 
    Type: "AWS::IAM::Role"
    Properties: 
      RoleName: !Sub "${EnvironmentName}-ssm-role" 
      AssumeRolePolicyDocument: 
        Version: "2012-10-17"
        Statement: 
          - Effect: Allow
            Principal: 
              Service: 
                - "ec2.amazonaws.com"
            Action: 
              - "sts:AssumeRole"
      Path: /
      ManagedPolicyArns: 
        - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore

  InstanceProfile: 
    Type: "AWS::IAM::InstanceProfile"
    Properties: 
      Path: "/"
      Roles: 
        - Ref: IAMRole
      InstanceProfileName: !Sub "${EnvironmentName}-EC2InstanceProfile"

# ------------------------------------------------------------#
# EC2
# ------------------------------------------------------------#
  EC2:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: !Ref AMIID
      InstanceType: !Ref InstanceType
      KeyName: !Ref KeyName
      IamInstanceProfile: !Ref InstanceProfile
      BlockDeviceMappings:
        - DeviceName: /dev/xvda
          Ebs:
            DeleteOnTermination: true
            VolumeType: gp3
            VolumeSize: !Ref InstanceVolumeSize
      NetworkInterfaces: 
        - AssociatePublicIpAddress: true
          DeviceIndex: "0"
          SubnetId: !Ref PublicSubnet
          GroupSet:
            - !Ref SecurityGroup
      UserData: !Base64 |
        #!/bin/bash
        yum -y update
        # Docker初期設定
        yum install -y docker
        service docker start
        usermod -a -G docker ec2-user
        # Docker-Compose初期設定
        curl -L https://github.com/docker/compose/releases/download/1.22.0/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose
        chmod +x /usr/local/bin/docker-compose
      Tags:
        - Key: Name
          Value: !Sub "${EnvironmentName}-${InstanceName}-01"

最後に

一度テンプレート化していたお陰で、手動で作成した際に忘れがちだった作成と削除の手間が激減できたかな思ってます。今後も運用を楽にできるような仕組みづくりを引き続きやっていきます。

Discussion