EC2 Image Builder で MT の AMI を構築

これまでは、Movable Type AMI 版 を使っていましたが、個人無償版 + AWS な構成に変更することに。

Movable Type 環境構築の手間もあって AMI 版だったわけですが、EC2 Image Builder で AMI を作るパイプラインを作ったので、MT のアップデートに合わせて新しい AMI を作っていけばOK。

EC2-Image-Builder-Image-Recipe.png

EC2 Image Builder のコンポーネントを準備

Movable Type 環境の構築には大体次のコンポーネントが必要になるわけですが

  1. Web サーバー
  2. DB、DB クライアント、DB ドライバー
  3. イメージプロセッサーライブラリ
  4. MT 本体

これらをそれぞれ EC2 Image Builder のコンポーネントにしていきます。

Nginx

Web サーバーとしては、Nginx を採用。これは、amazon-linux-extra にあるのでそれを入れます。

phases:
  - name: build
    steps:
      - name: InstallNginx
        action: ExecuteBash
        inputs:
          commands:
            - sudo amazon-linux-extras install nginx1 -y
            - sudo systemctl enable nginx
            - sudo systemctl start nginx

  - name: validate
    steps:
      - name: CheckNginx
        action: ExecuteBash
        inputs:
          commands:
            - rpm -qi nginx

  - name: test
    steps:
      - name: TestNginx
        action: ExecuteBash
        inputs:
          commands:
            - curl localhost

ファイルアップロードで Permission Denied が出ることある。のでうまい具合に直す

DB

DB には MySQL を利用するので、RDS for MySQL を利用することに。DB を外部にすることで EC2 を使い捨てにするためですね。

DB クライアント

MariaDB のクライアントが入れられるのでそのまま使います。

phases:
  - name: build
    steps:
      - name: InstallMariaDB
        action: ExecuteBash
        inputs:
          commands:
            - sudo yum install mariadb -y

  - name: validate
    steps:
      - name: CheckMariaDB
        action: ExecuteBash
        inputs:
          commands:
            - rpm -qi mariadb

  - name: test
    steps:
      - name: TestMariaDB
        action: ExecuteBash
        inputs:
          commands:
            - mysql --version

ImageMagick

ImageMagick は、yum で入れられるのでそのまま使います。そのために、開発ツール一式を入れてます。

- name: InstallBuildEssentials
  action: ExecuteBash
    inputs:
      commands:
        - sudo yum group install "Development Tools" -y

- name: InstallImageMagick
  action: ExecuteBash
    inputs:
      commands:
        - sudo yum install -y ImageMagick
        - sudo yum install -y ImageMagick-devel
        - sudo yum install -y ImageMagick-perl

- name: validate
  steps:
    - name: CheckImageMagick
      action: ExecuteBash
      inputs:
        commands:
          - rpm -qi ImageMagick

- name: test
  steps:
    - name: TestImageMagick
      action: ExecuteBash
      inputs:
        commands:
          - identify --version

Perl モジュール群

yum で入れられるものはそのまま。ないものは、cpanm を入れてから。

phases:
  - name: build
    steps:
      - name: InstallLibrariesAndHeaders
        action: ExecuteBash
        inputs:
          commands:
            - sudo yum install -y openssl-devel
            - sudo yum install -y libxml2-devel
            - sudo yum install -y expat-devel
      - name: InstallPerlModulesByYum
        action: ExecuteBash
        inputs:
          commands:
            - sudo yum install -y perl-App-cpanminus
            - sudo yum install -y perl-DBI
            - sudo yum install -y perl-DBD-MySQL
            - sudo yum install -y perl-Archive-Tar
            - sudo yum install -y perl-Archive-Zip
            - sudo yum install -y perl-YAML-Syck
            - sudo yum install -y perl-libwww-perl
            - sudo yum install -y perl-Net-SSLeay
            - sudo yum install -y perl-Test-Warn
            - sudo yum install -y perl-CGI
            - sudo yum install -y perl-HTTP-Daemon
            - sudo yum install -y perl-Net-Server
            - sudo yum install -y perl-LWP-Protocol-https
            - sudo yum install -y perl-XML-LibXML
      - name: InstallPerlModulesByCpanm
        action: ExecuteBash
        inputs:
          commands:
            - sudo cpanm Plack
            - sudo cpanm CGI::PSGI
            - sudo cpanm CGI::Parse::PSGI
            - sudo cpanm CGI::Compile
            - sudo cpanm Mozilla::CA
            - sudo cpanm XML::SAX::ExpatXS
            - sudo cpanm Authen::SASL
            - sudo cpanm Digest::SHA1
            - sudo cpanm Env
            - sudo cpanm File::Which
            - sudo cpanm Crypt::DSA
            - sudo cpanm Cache::File
            - sudo cpanm XML::SAX::Expat
            - sudo cpanm XMLRPC::Transport::HTTP::Plack --notest
            - sudo cpanm Starman --notest

CloudWatch Agent

ログの転送と内部メトリクスの転送に CloudWatch Agent をセットアップ。設定は、SSM パラメータストアに保存ずみ。これで、ログ関係も外出し完了。

phases:
  - name: build
    steps:
      - name: InstallCollectd
        action: ExecuteBash
        inputs:
          commands:
            - sudo amazon-linux-extras install collectd -y

      - name: InstallCloudWatchAgent
        action: ExecuteBash
        inputs:
          commands:
            - sudo yum install amazon-cloudwatch-agent -y

      - name: StartCloudWatchAgent
        action: ExecuteBash
        inputs:
          commands:
            - sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -s -c ssm:AmazonCloudWatch-linux

  - name: test
    steps:
      - name: RunningCloudWatchAgent
        action: ExecuteBash
        inputs:
          commands:
            - |
              CWA_STATUS=`sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -m ec2 -a status`
              if [[ "${CWA_STATUS}" =~ running ]]; then
                echo "Cloudwathc Agent is running"
              else
                echo "Cloudwathc Agent is not running"
                exit 1
              fi

ロケール周り

Amazon Linux 2 を標準で起動すると、UTC-0 / en-us な環境になるので、各種設定。

phases:
  - name: build
    steps:
      - name: SetTimezone
        action: ExecuteBash
        inputs:
          commands:
            - timedatectl set-timezone Asia/Tokyo
      - name: SetLocale
        action: ExecuteBash
        inputs:
          commands:
            - localectl set-locale LANG=ja_JP.UTF-8
      - name: SetKeymap
        action: ExecuteBash
        inputs:
          commands:
            - localectl set-keymap LANG=jp106

Movable Type

Movable Type は、S3 バケットに置いておき、ファイルを展開して設置する。

- name: DownloadMTFiles
  action: S3Download
    maxAttempts: 3
    inputs:
      - source: s3://my-mt-bucket/*
        destination: /tmp

- name: ExtractPackage
  action: ExecuteBash
    inputs:
      commands:
        - sudo unzip app/MT7*

- name: CopyingAppFiles
  action: ExecuteBash
    inputs:
      commands:
        - sudo cp -Rf MT7*/* /app/mt/

EFS

構築済みファイルや、mt-static などは EFS に配置してる。これで、データファイルも外出し完了。

- name: InstallEfsUtils
  action: ExecuteBash
    inputs:
      commands:
        - sudo yum install amazon-efs-utils -y
- name: MountEFS
  action: ExecuteBash
    inputs:
      commands:
        - sudo echo "fs-xxxxxxx:/ /data efs defaults,_netdev 0 0"  >> /etc/fstab
        - sudo mount -t efs -o tls fs-xxxxxxxx:/ /data

あとは、nginx や MT の各種設定ファイルを好きなところから持ってきて設置。

EC2 Image Builder でイメージレシピ作成

用意したコンポーネントを利用するようにイメージレシピを作成します。 ビルド用インスタンスには、S3 へのアクセス、CloudWatch へのアクセス許可が必要です。また、割り当てるセキュリティグループからの通信を EFS 側のセキュリティグループで許可することを忘れてはいけない。

出来上がった AMI をもとに EC2 インスタンスを起動して、動作を確認すれば完成。

出来上がった AMI から起動テンプレートを作成して、Auto Scaling グループに割り当ててあげれば Auot Healing 対応な Movable Type 環境の出来上がりです。

EC2 の中には、プログラム関連しか入っていなから使い捨てられます。ということで、t3.small なスポットインスタンス 100% で用意してコストも t2.micro より下がりました。