EC2 Image BuilderでCloudwatch Agent構築したAMIを作成してみた #reinvent

EC2 Image Builderを利用してCloudwatch Agentをインストールしたゴールデンイメージを作成してみたいと思います。Image Builderに関連する用語等を整理しながら実施してみたいと思います。
2019.12.11

re:Invent 2019で発表されたEC2 Image Builderを利用し、Cloudwatch Agentをインストールしたゴールデンイメージを作成してみたいと思います。すでに多くのやってみた系の記事がありますが、改めてEC2 Image Builderに関連する用語等を整理しながら実施してみたいと思います。

EC2 Image Bullderとは?

ゴールデンイメージを作成できるサービスです。手動や、サードパーティ製ツールを使って実装する必要があったイメージ更新、自動化〜テストが、このサービスひとつで対応することができます。詳細については、以下の記事を参照ください。

やってみた

前提

  • CloudWatch Agentの設定ファイルがSSMパラメータストア(ここでは、test-cloudwatch-agent)に格納されていること

事前準備

CloudWatch Agentインストール(及び、起動チェック)をスクリプトで行いたいと思います。 コマンドを並べただけで簡易的ですが、こちらのスクリプトは後ほど作成するコンポーネントと紐付け、ゴールデンイメージを作成するパイプラインの中で実行されます。

以下のスクリプトを作成し、S3にPUTしました。

インストールスクリプト(install_cloudwatch_agent.sh)

#!/bin/bash
INSTANCE_ID=`curl http://169.254.169.254/latest/meta-data/instance-id`
DOWN_LOAD_LINK="https://s3.amazonaws.com/amazoncloudwatch-agent/amazon_linux/amd64/latest/amazon-cloudwatch-agent.rpm"
PARAMETER_NAME=test-cloudwatch-agent

# Cloudwathc Agent インストール
wget $DOWN_LOAD_LINK
rpm -U ./amazon-cloudwatch-agent.rpm

# Cloudwathc Agent 設定
aws ssm send-command \
  --document-name "AmazonCloudWatch-ManageAgent" \
  --targets "Key=instanceids,Values=${INSTANCE_ID}" \
  --parameters "action=configure, mode=ec2, optionalConfigurationSource=ssm, \
    optionalConfigurationLocation=${PARAMETER_NAME}, optionalRestart=yes" \
  --timeout-seconds 600 --max-concurrency "50" --max-errors "0" --region ap-northeast-1

※Run Commandが非同期のため簡易的にこのようなつくりにしました

起動チェックスクリプト(check_cloudwatch_agent.sh)

#!/bin/bash
# Cloudwathc Agent ステータスチェック
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"
  exit 0
else
  echo "Cloudwathc Agent is not running"
  exit 1
fi

PUT確認

$ aws s3 ls s3://test-ec2-image-builder-script
2019-12-10 22:23:38        305 check_cloudwatch_agent.sh
2019-12-10 22:23:38        733 install_cloudwatch_agent.sh

CloudWatch Agentのインストールについては、以下ドキュメントが参考になります。

コンポーネント作成

コンポーネントは、ソフトウェアのインストールやスクリプトの実行を定義します。コンポーネントの種別は、ビルドコンポーネント及び、テストコンポーネントがあります。

ビルドコンポーネント

Image Builderコンソールより[Components] - [Create component]をクリックします。

以下を設定しました。

  • Image operating system (OS)…Linux
  • Component name…Install-Cloudwatch-Agent
  • Component version…0.0.0

Content(定義ドキュメント)

name: Install Cloudwatch Agent
description: This is Cloudwatch Agent Install and Setting document.
schemaVersion: 1.0
phases:
  - name: build
    steps:
      - name: DownloadFile
        action: S3Download
        inputs:
            - source: s3://test-ec2-image-builder-script/install_cloudwatch_agent.sh
              destination: /tmp/install_cloudwatch_agent.sh
      - name: InstallCloudWatchAgent
        action: ExecuteBash
        inputs:
          commands:
            - 'chmod 777 {{build.DownloadFile.inputs[0].destination}}'
            - '{{build.DownloadFile.inputs[0].destination}}'

ドキュメント定義の補足です。

phases

phasesstepsの論理的なグループです。ドキュメントには多くのphasesを定義することができ、buildvalidatetestから指定します。

steps

stepsは各フェーズの個々の作業単位です。stepsは順番に実行され、入力と出力の両方を後続のstepsの入力として使用することができます。

action

動作を定義しています。「DownloadFile」のアクションモジュールではS3Downloadを利用し、S3からオブジェクトをダウンロードしています。「InstallCloudWatchAgent」ではExecuteBashアクションを利用してスクリプトを実行しています。

コンポーネントの書式、利用可能なアクションについては、以下が参考になります。

テスト用コンポーネント

テストコンポーネントは、イメージパイプラインによって作成されたイメージ(AMI)上で動作するコンポーネントです。以下を設定しました。

  • Image operating system (OS)…Linux
  • Component name…Check-Cloudwatch-Agent
  • Component version…0.0.0

Content(定義ドキュメント)

name: Check Cloudwatch Agent
description: This is Cloudwatch Agent Check document.
schemaVersion: 1.0
phases:
  - name: test
    steps:
      - name: DownloadFile
        action: S3Download
        maxAttempts: 1
        inputs:
            - source: s3://test-ec2-image-builder-script/check_cloudwatch_agent.sh
              destination: /tmp/check_cloudwatch_agent.sh
      - name: CheckCloudWatchAgent
        action: ExecuteBash
        inputs:
          commands:
            - 'chmod 777 {{test.DownloadFile.inputs[0].destination}}'
            - '{{test.DownloadFile.inputs[0].destination}}'

書式はビルドコンポーネントと同一です。

イメージパイプライン作成

ゴールデンイメージを作成する一連の定義をイメージパイプラインで指定します。Image Builderコンソールより[Image pipelines] - [Create image pipeline]をクリックします。

レシピ作成

まずは、レシピを作成します。レシピはゴールデンイメージの元となるイメージを指定し、コンポーネントと紐付けます。以下を設定しました。

  • Image operating system (OS)…Amazon Linux
  • Select image…Select managed images
  • Select managed images…Amazon Linux 2 x86 | Version 2019.11.21
  • Build components…Install-Cloudwatch-Agent(先程作成したコンポーネント)
  • Tests…Check-Cloudwatch-Agent(先程作成したコンポーネント)

パイプライン作成

パイプラインでは以下を設定しました。

  • Name…test-img-builder-pipeline
  • IAM role…test-role
    • ここではCloudWatch Agent、SSMの権限が必要です
  • Instance type…t3.micro
  • Subnet ID…public-subnet
    • ここではインターネットへのアクセスが必要です

以降の追加定義は行わず、パイプラインを作成しました。

実行

作成したパイプラインを選択し、[Actions] - [Run pipeline]をクリックします。

パイプラインのステータスがBuildingに変わりました。

指定したVPCにEC2が起動しました。

しばらくすると、EC2が停止しAMIの取得がはじまりました。

AMIの取得が完了すると、EC2が削除されました。

EC2が削除されると、パイプラインのステータスがTestingに変わりました。

パイプラインで作成されたイメージでEC2が新たに起動されました。

しばらくすると(テストコンポーネントの実行されると)EC2が削除されました。

パイプラインのステータスがAvailableに変わり、処理が完了しました。

作成されたゴールデンイメージより、CloudWatch Agentがインストールされていることを確認しました。

$ sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -m ec2 -a status
{
  "status": "running",
  "starttime": "2019-12-10T14:13:52+0000",
  "version": "1.231221.0"
}

さいごに

AWSのマネージドサービスとして提供されているので、SNS連携等で強力になりそうですね。シンプルな構成で直感的に利用することができましたので、イメージの更新に時間がかかっている方は利用を検討してみてはいかがでしょうか。ごにょごにょしている中で気がついたのですが、テストコンポーネント未設定でも、パイプラインで作成されたEC2(Test instance~)は起動されるようですね。