26
20

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

AWS CloudFormationでEC2にミドルまでセットアップする

Last updated at Posted at 2018-09-30

AWS CloudFormationでEC2にミドルまでセットアップする

CloudFormationでインフラのコード化だと言いつつ、EC2立てた後のミドルのセットアップはAnsibleあたりが必要なのだろうか、とかアプリのデプロイとはスクリプト分けたいよねとか、モヤモヤしてたらCloudFormationで出来るようなので試してみました。

参考

だいたい公式のチュートリアル通りでOK。
https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/deploying.applications.html

UserData プロパティ

ここにEC2のプロビジョニングで実行できるシェルスクリプトが書けます。
極論これだけで全部賄うことも可能ですが、UpdateStackへの対応や、メンテやデバッグがしんどくなるので、cfn-init ヘルパースクリプトを使って実行内容をメタデータに記載する方法をとります。

Resources:
  WebServerInstance:
    Type: AWS::EC2::Instance
    #(...)
    Properties:
      ImageId: ami-08847abae18baa040 # Amazon Linux 2 AMI (HVM), SSD Volume Type
      #(...)
      UserData: !Base64
        Fn::Sub: |
          #!/bin/bash
          yum -y update
          amazon-linux-extras install php7.2

          yum -y install aws-cfn-bootstrap
          # Install the files and packages from the metadata
          # https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/cfn-init.html
          /opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resource WebServerInstance --region ${AWS::Region}
          # Signal the status from cfn-init
          # https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/cfn-signal.html
          /opt/aws/bin/cfn-signal -e $? --stack ${AWS::StackName} --resource WebServerInstance --region ${AWS::Region} 
    CreationPolicy:
      ResourceSignal:
        Timeout: PT5M

変数展開のためにFn:Subを使用。
ついでにyum updateamazon-linux-extrasで管理されているリポジトリの有効化もやっておく。

あとはヘルパースクリプトのインストール、cfn-initによるデプロイ、cfn-signalで結果の通知。
何故かチュートリアルには#!/bin/bash -xeのオプションが付いていたため、エラー発生時にcfn-signalが実行されずにタイムアウト待ちになったため外しておきます。詳細をログに出したければ -xは残してもいいかも。

Metadata プロパティ

cfn-initを実行すると、ここに記載するAWS::CloudFormation::Initリソースの内容がデプロイされます。

Resources:
  WebServerInstance:
    Type: AWS::EC2::Instance
    Metadata:
      # https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-init.html
      AWS::CloudFormation::Init:
        config:
          packages:
            rpm:
              mysql57-community-release: http://dev.mysql.com/get/mysql57-community-release-el7-10.noarch.rpm
            yum:
              httpd: []
              mysql-community-client: []
              php: []
          files:
            # https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/cfn-hup.html
            /etc/cfn/cfn-hup.conf:
              content: !Sub |
                [main]
                stack=${AWS::StackId}
                region=${AWS::Region}
              mode: '000400'
              owner: root
              group: root
            /etc/cfn/hooks.d/cfn-auto-reloader.conf:
              content: !Sub |
                [cfn-auto-reloader-hook]
                triggers=post.update
                path=Resources.WebServerInstance.Metadata.AWS::CloudFormation::Init
                action=/opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resource WebServerInstance --region ${AWS::Region}
                runas=root
              mode: '000400'
              owner: root
              group: root
          commands:
            01_set_timezone:
              command: timedatectl set-timezone Asia/Tokyo
              ignoreErrors: false
            02_install_composer:
              command: /usr/bin/curl -s https://getcomposer.org/installer | /usr/bin/php && mv composer.phar /usr/local/bin/composer
              env:
                HOME: /root
              cwd: '~'
              test: test ! -e /usr/local/bin/composer
              ignoreErrors: false
          services:
            sysvinit:
              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
    Properties:
      #(...)

configSetsを使うと複数のconfigを記載できるようです。依存関係のコントロール用?今回は必要ないのでconfigを使用。

packagesでyumのパッケージをインストール。rpmで野良パッケージや追加リポジトリのインストールも可能です。

filesで設定ファイルの作成ができます。ここではUpdateStack用のcfn-hupサービスに関する設定を追加。

commandsで任意のコマンドを実行できます。実行順はキー名の昇順になります。testを書くと判定がtrueの場合のみ実行できます。コマンド実行時は環境変数が殆ど設定されていないので注意。envに記載可能です。

servicesに起動したいサービスを記載します。

UserDataのログは /var/log/cloud-init-output.logに、cfn-initcfn-hupのログは/var/log/cfn-*.logに出力されているので、うまくいかない場合は参照しましょう。

UpdateStack時

AWS::CloudFormation::Init:の内容に変更があった場合、UpdateStack時にcfn-hupサービスが検知して、cfn-auto-reloader.confの内容(cfn-init)を実行してくれる...ハズなんですが、実行してくれる時としてくれない時があって良くわかりませんでした。

2018-11-02追記
/var/log/cfn-hup.logを眺めていたら、どうやら変更監視は15分間隔で実施されているようでした。
UpdateStack後に次回のチェックを待つとちゃんと実行されました。

実行されなかった場合は、EC2にログインしてactionの内容を手動で実行すれば反映できます。

sudo /opt/aws/bin/cfn-init -v --stack yourstackname --resource WebServerInstance --region ap-northeast-1 # Tokyo

おわり

AWSの公式ドキュメントは必要なことは全部書いてあるはずなのに、実際やると結構苦労しますね。

26
20
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
26
20

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?