Run Commandで複数のEC2インスタンスのカスタムメトリクスを一括設定

2017.10.30

こんにちは、AWS事業部の佐伯です。

Amazon Linux AMI 2017.09 がリリースされました!でも取り上げられていますが、SSMエージェントがAmazon Linuxにデフォルトでインストール済みとなりました。

今回はRun Commandで複数のAmazon Linuxにディスク使用率とメモリ使用率のカスタムメトリクスを取得する設定コマンドを実行します。なお、Windows Serverについては複数のWindows Serverにカスタムメトリクスを一括設定する方法の記事を参照ください。

大まかな手順

  • IAMロールを作成
    • EC2サービスを信頼
    • AmazonEC2RoleforSSMポリシーをアタッチ
  • EC2インスタンスを作成
    • 作成したIAMロールを設定
    • タグの設定
  • Run Commandを実行

やってみた

今回は5つのEC2インスタンス(Amazon Linux AMI 2017.09)にRun Commandを実行します。
タグはcustom-metrics:enableとしています。

amazon-linux-put-custom-metrics-with-run-command_001a

IAMロールの作成

今回は、以下のようなEC2サービスを信頼したIAMロールにAmazonEC2RoleforSSMポリシーをアタッチ、作成したIAMロールをEC2インスタンスにアタッチしています。

amazon-linux-put-custom-metrics-with-run-command_002a

amazon-linux-put-custom-metrics-with-run-command_003b

コマンドの実行

コマンドのドキュメントはAWS-RunShellScriptを選択し、EC2インスタンスに設定したタグ名、タグ値を指定し実行します。

amazon-linux-put-custom-metrics-with-run-command_004

コマンドの内容

実行するコマンドですが、シェルスクリプトをヒアドキュメントで無理やり作成します。シェルスクリプトは以下ページからパクらせていただきました。

# ディレクトリ作成
mkdir /opt/cw-monitoring

# ユーザー作成
useradd cw-mon

# メモリ使用率カスタムメトリクス送信スクリプト作成
tee /opt/cw-monitoring/memoryUsage.sh << "EOF" > /dev/null
#!/bin/bash

log() {
  echo $1 | logger -t cw-monitoring
}

aws=$(which aws)
usage=$(free | head -n 3 | tail -n 1 | awk '{a = $3/($3 + $4)*100; print a}')
instanceId=$(curl -s http://169.254.169.254/latest/meta-data/instance-id)
region=$(curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone | sed -e 's/.$//')

cw_opts="--namespace CustomMetrics/EC2"
cw_opts=${cw_opts}" --metric-name MemoryUtilization"
cw_opts=${cw_opts}" --dimensions InstanceId=${instanceId}"
cw_opts=${cw_opts}" --unit Percent"
cw_opts=${cw_opts}" --region ${region}"
cw_opts=${cw_opts}" --value ${usage}"

# wait for 0 - 15 seconds to disperse API request.
sleep $(($RANDOM % 15))

counter=0
MAX_RETRY=3

while :; do
  # Error Retry
  ${aws} cloudwatch put-metric-data ${cw_opts}
  if [ $? -ne 0 ]; then
    if [ "${counter}" -ge "${MAX_RETRY}" ]; then
      log "failed to put metrics of memory usage."
      exit 1
    fi
  else
    break
  fi

  counter=$((counter + 1))
  sleep 10
done

exit 0
EOF

# ディスク使用率カスタムメトリクス送信スクリプト作成
tee /opt/cw-monitoring/diskUsage.sh << "EOF" >> /dev/null
#!/bin/bash

log() {
  echo $1 | logger -t cw-monitoring
}

aws=$(which aws)
usage=$(df | sed -e 1d -e 's/%//' | awk '{print $5}' | sort -nr | head -n 1)
instanceId=$(curl -s http://169.254.169.254/latest/meta-data/instance-id)
region=$(curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone | sed -e 's/.$//')

cw_opts="--namespace CustomMetrics/EC2"
cw_opts=${cw_opts}" --metric-name DiskUsage"
cw_opts=${cw_opts}" --dimensions InstanceId=${instanceId}"
cw_opts=${cw_opts}" --unit Percent"
cw_opts=${cw_opts}" --region ${region}"
cw_opts=${cw_opts}" --value ${usage}"

# wait for 0 - 15 seconds to disperse API request.
sleep $(($RANDOM % 15))

counter=0
MAX_RETRY=3

while :; do
  # Error Retry
  ${aws} cloudwatch put-metric-data ${cw_opts}
  if [ $? -ne 0 ]; then
    if [ "${counter}" -ge "${MAX_RETRY}" ]; then
      log "failed to put metrics of disk usage."
      exit 1
    fi
  else
    break
  fi

  counter=$((counter + 1))
  sleep 10
done

exit 0
EOF

# オーナー、グループ、パーミッション設定
chown -R cw-mon:cw-mon /opt/cw-monitoring
chmod 744 /opt/cw-monitoring/*Usage.sh

# cron設定
tee /var/spool/cron/cw-mon << EOF > /dev/null
*/5 * * * * /opt/cw-monitoring/memoryUsage.sh
*/5 * * * * /opt/cw-monitoring/diskUsage.sh
EOF

実行結果出力

エラーがなければなにも出力されません。

amazon-linux-put-custom-metrics-with-run-command_005

CloudWatchメトリクスを確認

各EC2インスタンスのメモリ使用率およびディスク使用率のカスタムメトリクスが取得できていました。

amazon-linux-put-custom-metrics-with-run-command_006

amazon-linux-put-custom-metrics-with-run-command_007

まとめ

Amazon LinuxもSSMエージェントがデフォルトでインストール済みとなったことで、マネジメントコンソールから簡単に一括操作できるのはいいですね。
Ansibleなどのプロビジョニングツールの代替とまではいきませんが、簡単な操作であればRun Commandを利用してみるのも手かもしれません。