AWSのCloudFormationでSSL+LAMP環境を構築してみた

ここ最近、AWSのCloudFormationについて色々調べています。
CloudFormationはAWSのほぼすべてのリソースの構築を自動化するというサービスです。あらかじめ用意したテンプレートを元に少しのパラメータ入力と少しのボタンクリックだけでクラウド環境が構築できてしまうというやつ。
ネットで探して見つかるVPCやAutoScalingを組み込んだものと比べるとビギナーもいいとこですがひとまず目的とした環境構築ができるようになったので記事としてまとめてみました。


今回はCloudFormationのデフォルトで選択可能なサンプルテンプレート「LAMP Stack」をベースにLet’s EncryptのSSL証明書をインストールするところまでを自動化してみました。流れとしては以下のようになります。

  1. スタック作成以前にEIP(vpc)を用意しておく
  2. SSL証明書を発行する際に使用するドメイン名のDNSレコードをEIPに向けておく
  3. CloudFormationの管理画面からスタック作成

Let’s Encryptのインストールは作成したEC2インスタンスにec2-userで初回ログインしたときに行っています。これはEC2インスタンスが立ち上がる時点EIPが紐付いていないため(たぶん循環依存っていう状態?)。
具体的にはEIPAssociationの後にLet’s EncryptをインストールするスクリプトをEC2内で実行する必要があるのですがCloudFormationのテンプレート内でどう構築すればいいのかわかりませんでした。EC2インスタンスにec2-userで初回ログインしたときに読み込まれる.bash_profileからLet’s Encryptをインストールする/tmp/certbot-configure.shスクリプトを呼び出すことでひとまず半自動化のような状態となっています。
.bash_profile自体はログインするたびに読み込まれるため、/tmp/certbot-configure.sh実行時に自身を.bash_profileから削除したり、/tmp/certbot-configure.shの全行をコメントアウトするといったことをスクリプト内で行っています。


以下は具体的な手順をまとめたキャプチャになります。

テンプレートの種類で「テンプレートをS3にアップロードを選択」

パラメータを入力します。
DBName~DBUserは今回は直接関係しないので適当に入力。
EIPAllocateIdにあらかじめ用意したEIPのアロケートIDを入力します。
DomainNameにEIPのIPアドレスにレコード設定を向けてあるドメインを入力します。
EMailAddressはメールアドレスを入力。Let’s Encryptの通知用アドレスとして使用します。
InstanceType他は適当に入力。

オプションの入力画面は特に変更せずに次へボタンをクリックします。クリックするとスタックの作成が開始されます。ちなみにタグとしてNameタグを設定すると、作成されるリソース全てに同じ値が入るようでした。

スタックの作成が完了した状態です。
EC2の画面では作成されたEC2インスタンスやセキュリティグループが確認できます。

EC2にSSHログインしたときの様子です。ec2-userでログインすると.bash_profileが読み込まれた際に自動でLet’s Encryptのインストールと設定が行われます。
自動実行されたスクリプトは2回目以降は読み込まれないよう設定してあります。
また、自動実行された際のログをec2-userのホームディレクトリにcertbot-configure.logという名前で出力しています。

構築した環境にブラウザでアクセスしたときの様子です。証明書のエラーが出ないことや認証局がLet’s Encryptになっていることを確認できます。


上記であげた環境構築を行えるテンプレートが以下になります。LAMP環境を構築するテンプレートをベースにしているのでMySQLのパラメータ入力など今回の目的とは直接関係ない箇所が多く含まれています。

AWSTemplateFormatVersion: 2010-09-09
Description: >-
  AWS CloudFormation Sample Template LAMP_Single_Instance: Create a LAMP stack
  using a single EC2 instance and a local MySQL database for storage. This
  template demonstrates using the AWS CloudFormation bootstrap scripts to
  install the packages and files necessary to deploy the Apache web server, PHP
  and MySQL at instance launch time. **WARNING** This template creates an Amazon
  EC2 instance. You will be billed for the AWS resources used if you create a
  stack from this template.
Parameters:
  KeyName:
    Description: Name of an existing EC2 KeyPair to enable SSH access to the instance
    Type: 'AWS::EC2::KeyPair::KeyName'
    ConstraintDescription: must be the name of an existing EC2 KeyPair.
  DBName:
    Default: MyDatabase
    Description: MySQL database name
    Type: String
    MinLength: '1'
    MaxLength: '64'
    AllowedPattern: '[a-zA-Z][a-zA-Z0-9]*'
    ConstraintDescription: must begin with a letter and contain only alphanumeric characters.
  DBUser:
    NoEcho: 'true'
    Description: Username for MySQL database access
    Type: String
    MinLength: '1'
    MaxLength: '16'
    AllowedPattern: '[a-zA-Z][a-zA-Z0-9]*'
    ConstraintDescription: must begin with a letter and contain only alphanumeric characters.
  DBPassword:
    NoEcho: 'true'
    Description: Password for MySQL database access
    Type: String
    MinLength: '1'
    MaxLength: '41'
    AllowedPattern: '[a-zA-Z0-9]*'
    ConstraintDescription: must contain only alphanumeric characters.
  DBRootPassword:
    NoEcho: 'true'
    Description: Root password for MySQL
    Type: String
    MinLength: '1'
    MaxLength: '41'
    AllowedPattern: '[a-zA-Z0-9]*'
    ConstraintDescription: must contain only alphanumeric characters.
  InstanceType:
    Description: WebServer EC2 instance type
    Type: String
    Default: t2.small
    AllowedValues:
      - t1.micro
      - t2.nano
      - t2.micro
      - t2.small
      - t2.medium
      - t2.large
      - m1.small
      - m1.medium
      - m1.large
      - m1.xlarge
      - m2.xlarge
      - m2.2xlarge
      - m2.4xlarge
      - m3.medium
      - m3.large
      - m3.xlarge
      - m3.2xlarge
      - m4.large
      - m4.xlarge
      - m4.2xlarge
      - m4.4xlarge
      - m4.10xlarge
      - c1.medium
      - c1.xlarge
      - c3.large
      - c3.xlarge
      - c3.2xlarge
      - c3.4xlarge
      - c3.8xlarge
      - c4.large
      - c4.xlarge
      - c4.2xlarge
      - c4.4xlarge
      - c4.8xlarge
      - g2.2xlarge
      - g2.8xlarge
      - r3.large
      - r3.xlarge
      - r3.2xlarge
      - r3.4xlarge
      - r3.8xlarge
      - i2.xlarge
      - i2.2xlarge
      - i2.4xlarge
      - i2.8xlarge
      - d2.xlarge
      - d2.2xlarge
      - d2.4xlarge
      - d2.8xlarge
      - hi1.4xlarge
      - hs1.8xlarge
      - cr1.8xlarge
      - cc2.8xlarge
      - cg1.4xlarge
    ConstraintDescription: must be a valid EC2 instance type.
  SSHLocation:
    Description: ' The IP address range that can be used to SSH to the EC2 instances'
    Type: String
    MinLength: '9'
    MaxLength: '18'
    Default: 0.0.0.0/0
    AllowedPattern: '(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/(\d{1,2})'
    ConstraintDescription: must be a valid IP CIDR range of the form x.x.x.x/x.
  EIPAllocateId:
    Description: Please enter the allocation ID of the existing EIP
    Type: String
    AllowedPattern: '[a-zA-Z0-9\-]*'
    ConstraintDescription: only alphanumeric characters.
  DomainName:
    Description: Please enter the domain associated with EIP
    Type: String
    AllowedPattern: '[a-zA-Z0-9\-\.]*'
    ConstraintDescription: only domain characters.
  EMailAddress:
    Description: Please enter the email address
    Type: String
    AllowedPattern: '^[\x20-\x45]?[\w-\+]+(\.[\w]+)*@[\w-]+(\.[\w]+)*(\.[a-z]{2,})$'
    ConstraintDescription: must be a valid email address.
Mappings:
  AWSInstanceType2Arch:
    t1.micro:
      Arch: HVM64
    t2.nano:
      Arch: HVM64
    t2.micro:
      Arch: HVM64
    t2.small:
      Arch: HVM64
    t2.medium:
      Arch: HVM64
    t2.large:
      Arch: HVM64
    m1.small:
      Arch: HVM64
    m1.medium:
      Arch: HVM64
    m1.large:
      Arch: HVM64
    m1.xlarge:
      Arch: HVM64
    m2.xlarge:
      Arch: HVM64
    m2.2xlarge:
      Arch: HVM64
    m2.4xlarge:
      Arch: HVM64
    m3.medium:
      Arch: HVM64
    m3.large:
      Arch: HVM64
    m3.xlarge:
      Arch: HVM64
    m3.2xlarge:
      Arch: HVM64
    m4.large:
      Arch: HVM64
    m4.xlarge:
      Arch: HVM64
    m4.2xlarge:
      Arch: HVM64
    m4.4xlarge:
      Arch: HVM64
    m4.10xlarge:
      Arch: HVM64
    c1.medium:
      Arch: HVM64
    c1.xlarge:
      Arch: HVM64
    c3.large:
      Arch: HVM64
    c3.xlarge:
      Arch: HVM64
    c3.2xlarge:
      Arch: HVM64
    c3.4xlarge:
      Arch: HVM64
    c3.8xlarge:
      Arch: HVM64
    c4.large:
      Arch: HVM64
    c4.xlarge:
      Arch: HVM64
    c4.2xlarge:
      Arch: HVM64
    c4.4xlarge:
      Arch: HVM64
    c4.8xlarge:
      Arch: HVM64
    g2.2xlarge:
      Arch: HVMG2
    g2.8xlarge:
      Arch: HVMG2
    r3.large:
      Arch: HVM64
    r3.xlarge:
      Arch: HVM64
    r3.2xlarge:
      Arch: HVM64
    r3.4xlarge:
      Arch: HVM64
    r3.8xlarge:
      Arch: HVM64
    i2.xlarge:
      Arch: HVM64
    i2.2xlarge:
      Arch: HVM64
    i2.4xlarge:
      Arch: HVM64
    i2.8xlarge:
      Arch: HVM64
    d2.xlarge:
      Arch: HVM64
    d2.2xlarge:
      Arch: HVM64
    d2.4xlarge:
      Arch: HVM64
    d2.8xlarge:
      Arch: HVM64
    hi1.4xlarge:
      Arch: HVM64
    hs1.8xlarge:
      Arch: HVM64
    cr1.8xlarge:
      Arch: HVM64
    cc2.8xlarge:
      Arch: HVM64
  AWSInstanceType2NATArch:
    t1.micro:
      Arch: NATHVM64
    t2.nano:
      Arch: NATHVM64
    t2.micro:
      Arch: NATHVM64
    t2.small:
      Arch: NATHVM64
    t2.medium:
      Arch: NATHVM64
    t2.large:
      Arch: NATHVM64
    m1.small:
      Arch: NATHVM64
    m1.medium:
      Arch: NATHVM64
    m1.large:
      Arch: NATHVM64
    m1.xlarge:
      Arch: NATHVM64
    m2.xlarge:
      Arch: NATHVM64
    m2.2xlarge:
      Arch: NATHVM64
    m2.4xlarge:
      Arch: NATHVM64
    m3.medium:
      Arch: NATHVM64
    m3.large:
      Arch: NATHVM64
    m3.xlarge:
      Arch: NATHVM64
    m3.2xlarge:
      Arch: NATHVM64
    m4.large:
      Arch: NATHVM64
    m4.xlarge:
      Arch: NATHVM64
    m4.2xlarge:
      Arch: NATHVM64
    m4.4xlarge:
      Arch: NATHVM64
    m4.10xlarge:
      Arch: NATHVM64
    c1.medium:
      Arch: NATHVM64
    c1.xlarge:
      Arch: NATHVM64
    c3.large:
      Arch: NATHVM64
    c3.xlarge:
      Arch: NATHVM64
    c3.2xlarge:
      Arch: NATHVM64
    c3.4xlarge:
      Arch: NATHVM64
    c3.8xlarge:
      Arch: NATHVM64
    c4.large:
      Arch: NATHVM64
    c4.xlarge:
      Arch: NATHVM64
    c4.2xlarge:
      Arch: NATHVM64
    c4.4xlarge:
      Arch: NATHVM64
    c4.8xlarge:
      Arch: NATHVM64
    g2.2xlarge:
      Arch: NATHVMG2
    g2.8xlarge:
      Arch: NATHVMG2
    r3.large:
      Arch: NATHVM64
    r3.xlarge:
      Arch: NATHVM64
    r3.2xlarge:
      Arch: NATHVM64
    r3.4xlarge:
      Arch: NATHVM64
    r3.8xlarge:
      Arch: NATHVM64
    i2.xlarge:
      Arch: NATHVM64
    i2.2xlarge:
      Arch: NATHVM64
    i2.4xlarge:
      Arch: NATHVM64
    i2.8xlarge:
      Arch: NATHVM64
    d2.xlarge:
      Arch: NATHVM64
    d2.2xlarge:
      Arch: NATHVM64
    d2.4xlarge:
      Arch: NATHVM64
    d2.8xlarge:
      Arch: NATHVM64
    hi1.4xlarge:
      Arch: NATHVM64
    hs1.8xlarge:
      Arch: NATHVM64
    cr1.8xlarge:
      Arch: NATHVM64
    cc2.8xlarge:
      Arch: NATHVM64
  AWSRegionArch2AMI:
    us-east-1:
      HVM64: ami-0ff8a91507f77f867
      HVMG2: ami-0a584ac55a7631c0c
    us-west-2:
      HVM64: ami-a0cfeed8
      HVMG2: ami-0e09505bc235aa82d
    us-west-1:
      HVM64: ami-0bdb828fd58c52235
      HVMG2: ami-066ee5fd4a9ef77f1
    eu-west-1:
      HVM64: ami-047bb4163c506cd98
      HVMG2: ami-0a7c483d527806435
    eu-west-2:
      HVM64: ami-f976839e
      HVMG2: NOT_SUPPORTED
    eu-west-3:
      HVM64: ami-0ebc281c20e89ba4b
      HVMG2: NOT_SUPPORTED
    eu-central-1:
      HVM64: ami-0233214e13e500f77
      HVMG2: ami-06223d46a6d0661c7
    ap-northeast-1:
      HVM64: ami-06cd52961ce9f0d85
      HVMG2: ami-053cdd503598e4a9d
    ap-northeast-2:
      HVM64: ami-0a10b2721688ce9d2
      HVMG2: NOT_SUPPORTED
    ap-northeast-3:
      HVM64: ami-0d98120a9fb693f07
      HVMG2: NOT_SUPPORTED
    ap-southeast-1:
      HVM64: ami-08569b978cc4dfa10
      HVMG2: ami-0be9df32ae9f92309
    ap-southeast-2:
      HVM64: ami-09b42976632b27e9b
      HVMG2: ami-0a9ce9fecc3d1daf8
    ap-south-1:
      HVM64: ami-0912f71e06545ad88
      HVMG2: ami-097b15e89dbdcfcf4
    us-east-2:
      HVM64: ami-0b59bfac6be064b78
      HVMG2: NOT_SUPPORTED
    ca-central-1:
      HVM64: ami-0b18956f
      HVMG2: NOT_SUPPORTED
    sa-east-1:
      HVM64: ami-07b14488da8ea02a0
      HVMG2: NOT_SUPPORTED
    cn-north-1:
      HVM64: ami-0a4eaf6c4454eda75
      HVMG2: NOT_SUPPORTED
    cn-northwest-1:
      HVM64: ami-6b6a7d09
      HVMG2: NOT_SUPPORTED
Resources:
  WebServerInstance:
    Type: 'AWS::EC2::Instance'
    Metadata:
      'AWS::CloudFormation::Init':
        configSets:
          InstallAndRun:
            - Install
            - Configure
        Install:
          packages:
            yum:
              mysql: []
              mysql-server: []
              mysql-libs: []
              httpd: []
              php: []
              php-mysql: []
          files:
            /var/www/html/index.php:
              content: !Join 
                - ''
                - - |
                    <html>
                  - |2
                      <head>
                  - |2
                        <title>AWS CloudFormation PHP Sample</title>
                  - |2
                        <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
                  - |2
                      </head>
                  - |2
                      <body>
                  - |2
                        <h1>Welcome to the AWS CloudFormation PHP Sample</h1>
                  - |2
                        <p/>
                  - |2
                        <?php
                  - |2
                          // Print out the current data and time
                  - |2
                          print "The Current Date and Time is: <br/>";
                  - |2
                          print date("g:i A l, F j Y.");
                  - |2
                        ?>
                  - |2
                        <p/>
                  - |2
                        <?php
                  - |2
                          // Setup a handle for CURL
                  - |2
                          $curl_handle=curl_init();
                  - |2
                          curl_setopt($curl_handle,CURLOPT_CONNECTTIMEOUT,2);
                  - |2
                          curl_setopt($curl_handle,CURLOPT_RETURNTRANSFER,1);
                  - |2
                          // Get the hostname of the intance from the instance metadata
                  - |2
                          curl_setopt($curl_handle,CURLOPT_URL,'http://169.254.169.254/latest/meta-data/public-hostname');
                  - |2
                          $hostname = curl_exec($curl_handle);
                  - |2
                          if (empty($hostname))
                  - |2
                          {
                  - |2
                            print "Sorry, for some reason, we got no hostname back <br />";
                  - |2
                          }
                  - |2
                          else
                  - |2
                          {
                  - |2
                            print "Server = " . $hostname . "<br />";
                  - |2
                          }
                  - |2
                          // Get the instance-id of the intance from the instance metadata
                  - |2
                          curl_setopt($curl_handle,CURLOPT_URL,'http://169.254.169.254/latest/meta-data/instance-id');
                  - |2
                          $instanceid = curl_exec($curl_handle);
                  - |2
                          if (empty($instanceid))
                  - |2
                          {
                  - |2
                            print "Sorry, for some reason, we got no instance id back <br />";
                  - |2
                          }
                  - |2
                          else
                  - |2
                          {
                  - |2
                            print "EC2 instance-id = " . $instanceid . "<br />";
                  - |2
                          }
                  - |2
                          $Database   = "localhost";
                  - '      $DBUser     = "'
                  - !Ref DBUser
                  - |
                    ";
                  - '      $DBPassword = "'
                  - !Ref DBPassword
                  - |
                    ";
                  - |2
                          print "Database = " . $Database . "<br />";
                  - |2
                          $dbconnection = mysql_connect($Database, $DBUser, $DBPassword)
                  - |2
                                          or die("Could not connect: " . mysql_error());
                  - |2
                          print ("Connected to $Database successfully");
                  - |2
                          mysql_close($dbconnection);
                  - |2
                        ?>
                  - |2
                        <h2>PHP Information</h2>
                  - |2
                        <p/>
                  - |2
                        <?php
                  - |2
                          phpinfo();
                  - |2
                        ?>
                  - |2
                      </body>
                  - |
                    </html>
              mode: '000600'
              owner: apache
              group: apache
            /tmp/setup.mysql:
              content: !Join 
                - ''
                - - 'CREATE DATABASE '
                  - !Ref DBName
                  - |
                    ;
                  - 'GRANT ALL ON '
                  - !Ref DBName
                  - .* TO '
                  - !Ref DBUser
                  - '''@localhost IDENTIFIED BY '''
                  - !Ref DBPassword
                  - |
                    ';
              mode: '000400'
              owner: root
              group: root
            /etc/cfn/cfn-hup.conf:
              content: !Join 
                - ''
                - - |
                    [main]
                  - stack=
                  - !Ref 'AWS::StackId'
                  - |+

                  - region=
                  - !Ref 'AWS::Region'
                  - |+

              mode: '000400'
              owner: root
              group: root
            /etc/cfn/hooks.d/cfn-auto-reloader.conf:
              content: !Join 
                - ''
                - - |
                    [cfn-auto-reloader-hook]
                  - |
                    triggers=post.update
                  - >
                    path=Resources.WebServerInstance.Metadata.AWS::CloudFormation::Init
                  - 'action=/opt/aws/bin/cfn-init -v '
                  - '         --stack '
                  - !Ref 'AWS::StackName'
                  - '         --resource WebServerInstance '
                  - '         --configsets InstallAndRun '
                  - '         --region '
                  - !Ref 'AWS::Region'
                  - |+

                  - |
                    runas=root
              mode: '000400'
              owner: root
              group: root
            /tmp/certbot-configure.sh:
              content: !Join 
                - ''
                - - |
                    #!/bin/bash -xe
                  - >
                    curl https://dl.eff.org/certbot-auto -o
                    /usr/bin/certbot-auto
                  - |
                    chmod 700 /usr/bin/certbot-auto
                  - >-
                    yes | certbot-auto certonly --agree-tos --debug --webroot -w
                    /var/www/html/ -d 
                  - !Ref DomainName
                  - ' --email '
                  - !Ref EMailAddress
                  - |2
                     --non-interactive
                  - |+

                  - >-
                    sed -i -e "s:^SSLCertificateFile
                    /etc/pki/tls/certs/localhost.crt:SSLCertificateFile
                    /etc/letsencrypt/live/
                  - !Ref DomainName
                  - |
                    /cert.pem:" /etc/httpd/conf.d/ssl.conf
                  - >-
                    sed -i -e "s:^SSLCertificateKeyFile
                    /etc/pki/tls/private/localhost.key:SSLCertificateKeyFile
                    /etc/letsencrypt/live/
                  - !Ref DomainName
                  - |
                    /privkey.pem:" /etc/httpd/conf.d/ssl.conf
                  - >-
                    sed -i -e "s:^#SSLCertificateChainFile
                    /etc/pki/tls/certs/server-chain.crt:SSLCertificateChainFile
                    /etc/letsencrypt/live/
                  - !Ref DomainName
                  - |
                    /chain.pem:" /etc/httpd/conf.d/ssl.conf
                  - |+

                  - |
                    /etc/init.d/httpd restart
                  - |+

                  - >
                    sed -i -e "s:^sudo /tmp/certbot-configure.sh 2>&1 | tee
                    certbot-configure.log::" /home/ec2-user/.bash_profile
                  - |
                    sed -i -e "s:^:#:" /tmp/certbot-configure.sh
              mode: '000500'
              owner: root
              group: root
            /home/ec2-user/.bash_profile:
              content: !Join 
                - ''
                - - |
                    # .bash_profile
                  - |+

                  - |
                    # Get the aliases and functions
                  - |
                    if [ -f ~/.bashrc ]; then
                  - |2
                            . ~/.bashrc
                  - |
                    fi
                  - |+

                  - |
                    # User specific environment and startup programs
                  - |+

                  - |
                    PATH=$PATH:$HOME/.local/bin:$HOME/bin
                  - |+

                  - |
                    export PATH
                  - |+

                  - >
                    sudo /tmp/certbot-configure.sh 2>&1 | tee
                    certbot-configure.log
              mode: '000644'
              owner: ec2-user
              group: ec2-user
          services:
            sysvinit:
              mysqld:
                enabled: 'true'
                ensureRunning: 'true'
              httpd:
                enabled: 'true'
                ensureRunning: 'true'
              cfn-hup:
                enabled: 'true'
                ensureRunning: 'true'
                files:
                  - /etc/cfn/cfn-hup.conf
                  - /etc/cfn/hooks.d/cfn-auto-reloader.conf
        Configure:
          commands:
            01_set_mysql_root_password:
              command: !Join 
                - ''
                - - mysqladmin -u root password '
                  - !Ref DBRootPassword
                  - ''''
              test: !Join 
                - ''
                - - '$(mysql '
                  - !Ref DBName
                  - ' -u root --password='''
                  - !Ref DBRootPassword
                  - ''' >/dev/null 2>&1 </dev/null); (( $? != 0 ))'
            02_create_database:
              command: !Join 
                - ''
                - - mysql -u root --password='
                  - !Ref DBRootPassword
                  - ''' < /tmp/setup.mysql'
              test: !Join 
                - ''
                - - '$(mysql '
                  - !Ref DBName
                  - ' -u root --password='''
                  - !Ref DBRootPassword
                  - ''' >/dev/null 2>&1 </dev/null); (( $? != 0 ))'
    Properties:
      ImageId: !FindInMap 
        - AWSRegionArch2AMI
        - !Ref 'AWS::Region'
        - !FindInMap 
          - AWSInstanceType2Arch
          - !Ref InstanceType
          - Arch
      InstanceType: !Ref InstanceType
      SecurityGroups:
        - !Ref WebServerSecurityGroup
      KeyName: !Ref KeyName
      UserData: !Base64 
        'Fn::Join':
          - ''
          - - |
              #!/bin/bash -xe
            - |
              yum update -y aws-cfn-bootstrap
            - |
              # Install the files and packages from the metadata
            - '/opt/aws/bin/cfn-init -v '
            - '         --stack '
            - !Ref 'AWS::StackName'
            - '         --resource WebServerInstance '
            - '         --configsets InstallAndRun '
            - '         --region '
            - !Ref 'AWS::Region'
            - |+

            - |
              # Signal the status from cfn-init
            - '/opt/aws/bin/cfn-signal -e $? '
            - '         --stack '
            - !Ref 'AWS::StackName'
            - '         --resource WebServerInstance '
            - '         --region '
            - !Ref 'AWS::Region'
            - |+

    CreationPolicy:
      ResourceSignal:
        Timeout: PT5M
  WebServerSecurityGroup:
    Type: 'AWS::EC2::SecurityGroup'
    Properties:
      GroupDescription: Enable HTTP access via port 80
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: '80'
          ToPort: '80'
          CidrIp: 0.0.0.0/0
        - IpProtocol: tcp
          FromPort: '443'
          ToPort: '443'
          CidrIp: 0.0.0.0/0
        - IpProtocol: tcp
          FromPort: '22'
          ToPort: '22'
          CidrIp: !Ref SSHLocation
  ElasticIPAssociation:
    Type: 'AWS::EC2::EIPAssociation'
    Properties:
      AllocationId: !Ref EIPAllocateId
      InstanceId: !Ref WebServerInstance
Outputs:
  WebsiteURL:
    Description: URL for newly created LAMP stack
    Value: !Join 
      - ''
      - - 'http://'
        - !GetAtt 
          - WebServerInstance
          - PublicDnsName

yaml形式です。
EC2のInit内のコマンドを書く際はjsonのほうが作業しやすかったと思います。デザイナーの画面で相互変換できるのでyamlでコピペ→json変換→jsonで作業→yamlに戻すといった作業を行いました。


上記テンプレートによってSSL+LAMP環境が5分くらいで構築できるようになりました。
ELBやスケーリングなどは使用していないEC2だけの単純な構成なのでコストは低そうです。
まだCloudFormation自体に慣れていないのでJava+Tomcat+SSLの自動化の構築などを行いつつ、AutoScalingやELBなどのリソースを含めたクラウド!って感じのする環境構築を勉強していこうと思います。

スポンサーリンク
GoogleAdsense



GoogleAdsense



シェアする