のぴぴのメモ

自分用のLinuxとかの技術メモ

Amazon Linux2にCloudWatchエージェントを設定する手順(ユーザデータでの手順あり)

はじめに

Amazon Linux2にCloudWatchエージェントをセットアップする手順をまとめました。ドキュメントではSSMから操作する手順をメインにしていますが、AutoScalingなどでUserDataにセットアップ手順を埋め込むことを考慮し全てコマンドラインでセットアップが完結するように手順を整理しています。

ポイントは以下の4点です。

  1. エージェントの操作はamazon-cloudwatch-agent-ctlを利用する
  2. Wizardや手動作成した設定ファイルはフェッチしないと有効化されない
  3. OS自動起動amazon-cloudwatch-agent-ctlからのエージェント起動時に自動設定される
  4. collectdを未使用時でも、Wizardではデフォルトcollectdを有効化するためcollectdパケージをインストールしておくほうが無難

なおCloudWatchエージェントの標準のカスタムメトリクスとログ取得の範囲で利用している場合は、collectdとStatsDは必要ありません。

CloudWatchエージェントとは*1

CloudWatchエージェントは、EC2やオンプレのLinux/Windowsで稼働し、OSやアプリケーションの情報をCloudWatchに送信するエージェントソフトウェアです。
具体的には以下の情報をCloudWatchに送信することができます。

  • OSの稼働情報(CPU/メモリ/ディスクなど)を取得し、カスタムメトリクスとしてCloudWatchへ送信する
  • (Option)CloudWatch エージェントで定義されていない稼働情報は、collectdプロトコルStatsDプロトコルを介して取得することでカスタムメトリクスとしてCloudWatchへ送信する事が可能
  • (Option)指定したログファイルをCloudWatch Logsへ送信する

f:id:nopipi:20220212130803p:plain:w600

なおcollectdStatsDの要否は以下の通りです。
CloudWatchエージェントの標準のカスタムメトリクスとログ取得の範囲で利用している場合は、どちらの機能も不要となります。

  • collectd: CloudWatchエージェントで準備されているメトリクス(CPU/メモリ/ディスク)以外に追加のメトリクスを独自取得したい場合に利用する
  • StatsD: ユーザアプリケーションから出力される稼働データをCloudWatchエージェントからカスタムメトリクスとして送信したい場合(ユーザアプリでStatsDプロトコルでの送信の実装が必要)

CloudWatchエージェント設定手順概要

CloudWatchエージェントは、Amazon Linux2の場合/opt/aws/amazon-cloudwatch-agentにインストールされ、操作用のコマンドは/opt/aws/amazon-cloudwatch-agent/binに配置されます。主に利用するコマンドは、(1)設定ファイル生成用ウィザードのamazon-cloudwatch-agent-config-wizardと、(2)操作用のamazon-cloudwatch-agent-ctl、の2つになります。

CloudWatchエージェントを利用するための手順概要は以下の通りです。

  1. CloudWatchエージェントのインストール
  2. 設定ファイルの作成(手動またはamazon-cloudwatch-agent-config-wizardによる作成)
  3. 設定ファイルのフェッチ
  4. CloudWatchエージェントの起動

f:id:nopipi:20220212135002p:plain:w600


CloudWatchエージェントの初期設定手順

Amazon Linux2のEC2インスタンスを作成しCloudWatchエージェントをインストール&セットアップする手順です。

(事前準備) IAMロール&EC2インスタンスの作成

既にIAMロールとEC2インスタンスの準備ができている人はこの項目はスキップして下さい。

  • 前提
    • AWS CLIとIAMとEC2の変更権限があるプロファイルがあること
    • PublicSubnetがあるVPC
    • ssh接続用のキーペア(SSM接続の場合は不要。その場合EC2インスタンス作成時に--key-nameオプションを除外すること)
PROFILE="<作業用のプロファイルを指定。デフォルトのプロファイルを利用する場合はdefaultを指定>"
REGION="<EC2インスタンスを作成したいリージョン>"

#動作テスト(以下のコマンドが通ればOK)
aws --profile "${PROFILE}" --region "${REGION}" ec2 describe-instances
  • IAMロールの作成
#IAMロールの作成
POLICY='{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "Service": "ec2.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}'
aws --profile ${PROFILE} --region ${REGION}\
    iam create-role \
        --role-name "EC2-CloudWatchAgent" \
        --assume-role-policy-document "${POLICY}" \
        --max-session-duration 43200

#IAMポリシーアタッチ(CloudWatchAgentServerPolicy)
aws --profile ${PROFILE} --region ${REGION} \
    iam attach-role-policy \
        --role-name "EC2-CloudWatchAgent" \
        --policy-arn "arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy"

#EC2インスタンス用のプロファイル作成
aws --profile ${PROFILE} \
    iam create-instance-profile \
        --instance-profile-name "EC2-CloudWatchAgent";

aws --profile ${PROFILE} \
    iam add-role-to-instance-profile \
        --instance-profile-name "EC2-CloudWatchAgent" \
        --role-name "EC2-CloudWatchAgent" ;
#設定
SubnetId="<インスタンスを配置したいサブネットのID>"
SgId="<インスタンスにアタッチするサブネットグループのID>"
KEYNAME="<SSH接続時のキーペア名を指定。SSM接続の場合は設定不要>"
InstanceType="t2.micro"

#Amazon Linux2の最新AMIのID取得
AMZ2_AMIID=$(aws --profile "${PROFILE}" --region "${REGION}" --output text \
    ec2 describe-images \
        --owners amazon \
        --filters 'Name=name,Values=amzn2-ami-kernel-5.10-hvm-2.0.????????.?-x86_64-gp2' \
                      'Name=state,Values=available' \
    --query 'reverse(sort_by(Images, &CreationDate))[:1].ImageId' ) ;
echo "AMZ2_AMIID = ${AMZ2_AMIID}"

#EC2インスタンスの作成
>|sh|
TAGJSON='
[
    {
        "ResourceType": "instance",
        "Tags": [
            {
                "Key": "Name",
                "Value": "CLW-Agent-Test"
            }
        ]
    }
]'

# EC2インスタンス起動
aws --profile "${PROFILE}" --region "${REGION}" \
    ec2 run-instances \
        --image-id "${AMZ2_AMIID}" \
        --instance-type "${InstanceType}" \
        --iam-instance-profile "Name=EC2-CloudWatchAgent" \
        --key-name "${KEYNAME}" \
        --subnet-id "${SubnetId}" \
        --security-group-ids "${SgId}" \
        --associate-public-ip-address \
        --tag-specifications "${TAGJSON}"

CloudWatchエージェントのインストール

CloudWatchエージェントをセットアップしたいインスタンスSSHやSSMなどでログインして作業を行います。

  • collectdのインストール
    • 注意事項1: CloudWactchエージェントでcollectdを有効化しない場合はインストール不要です。ただコンフィグレーションWizardではデフォルトでcollectdを有効化するのでインストールしておくほうが無難です。なお未インストールでcollectdを有効化するとエージェント起動が失敗します。*2
    • 注意事項2: Amazon Linux2の最新パッケージではextraリポジトリからcollectdをセットアップ可能です*3
sudo amazon-linux-extras enable collectd
sudo yum clean metadata
sudo yum -y install collectd
  • CloudWatchエージェントインストール*4
sudo yum -y install amazon-cloudwatch-agent

CloudWatch設定ファイル作成

  • Wizardでの作成
    • Wizardで作成された設定ファイルは/opt/aws/amazon-cloudwatch-agent/bin/config.jsonに出力されます。
    • ここではデフォルト設定とするため、Wizardでは基本リターンを押し続けて下さい。ただ以下の項目は個別に選択して下さい。
      • Do you want to monitor any log files?
        • ログ設定の要否です。スキップするため、2. noを選択して下さい。
      • Do you want to store the config in the SSM parameter store?
        • 設定をParameter Storeに保管するかの確認です。スキップするため、2. noを選択して下さい。
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-config-wizard

#Wizardで作成したコンフィルが以下に生成されるため確認します。
cat /opt/aws/amazon-cloudwatch-agent/bin/config.json
  • 手動での作成

CloudWatchエージェントのドキュメントを参考にコンフィルファイルを作成して下さい。ファイル名は任意で問題ありません。
ただ最初はWizardで作成して、後からカスタマイズする方が効率的と思います。

CloudWatch設定ファイルのフェッチ

  • 作成したコンフィルファイルをフェッチし、実際にCloudWatchエージェントのデーモンが読み込む設定ファイルに反映します。
    • file:<ファイルパス>で作成したコンフィルファイルを指定します。以下の手順はWizardでコンフィル生成した場合のコマンドになります。コンフィグを手動作成した場合は、フィルパスを適切に修正ください。
#Wizardでコンフィグ生成した場合
#手動の場合は"/opt/aws/amazon-cloudwatch-agent/bin/config.json"を作成したコンフィグファイルパスに適時置き換える
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -c file:/opt/aws/amazon-cloudwatch-agent/bin/config.json

CloudWatchエージェントの起動*5

  • CloudWatchエージェントを起動します
#CloudWatchエージェントの起動
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a start
  • CloudWatchエージェントを起動します。
#CloudWatchエージェントの状態確認
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a status

{
  "status": "running",    <= runningと表記されれば起動成功
  "starttime": "2022-02-12T06:17:30+0000",
  "configstatus": "configured",
  "cwoc_status": "stopped",
  "cwoc_starttime": "",
  "cwoc_configstatus": "not configured",
  "version": "1.247347.4"
}

補足

設定フェッチと再起動を1コマンドで実行する

設定ファイルフェッチ時に-sオプションを付与することで、設定ファイルのフェッチ後にエージェントのスタート/リスタートを合わせて実行してくれます。

#設定ファイルフェッチと再起動を同時に行う場合の実行例
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -s -c file:/opt/aws/amazon-cloudwatch-agent/bin/config.json
CloudWatchエージェントのログファイル

CloudWatchエージェントが起動しない場合などトラブル時切り分けのために利用するログファイルは以下にあります。

  • /opt/aws/amazon-cloudwatch-agent/logs/amazon-cloudwatch-agent.log : エージェントのログ
  • /opt/aws/amazon-cloudwatch-agent/logs/configuration-validation.log : コンフィルフェッチ処理時のログ

Systems Manager Parameter Storeで設定を配布する場合

多数のサーバにCloudWatchエージェントの設定を配布し起動する場合は、Parameter Storeに定義ファイルを格納することができます。
この場合は各サーバでParameter Storeからコンフィグを取得しフェッチ&エージェント起動するというやり方になります。
以下に Parameter Storeを利用した場合のCloudWatchエージェントの操作手順を整理します。

Parameter Storeへの設定ファイル格納

作成した設定ファイルをParameter Storeへ格納します。Parameter Storeの構成条件は以下の通りとなります。

  • Parameter Storeの構成条件
    • Parameter Store名称: AmazonCloudWatch-で始まる名前である必要があります*6
    • タイプ: String

先の手順で作成した設定ファイルをParameter Storeへの格納ができる権限があるAWS CLI環境(例えば、IAMロールやEC2インスタンスを作成した環境)にコピーして、以下のコマンドで格納します。
ここではParameter Storeの名称をAmazonCloudWatch-SampleConfig、CloudWatchエージェントのコンフィグファイルをconfig.jsonとしています。

PROFILE="<作業用のプロファイルを指定。デフォルトのプロファイルを利用する場合はdefaultを指定>"
REGION="<EC2インスタンスを作成したいリージョン>"

aws --profile "${PROFILE}" --region "${REGION}" \
    ssm put-parameter \
        --name "AmazonCloudWatch-SampleConfig" \
        --type "String" \
        --value file://config.json

格納したParameter Storeのデータを確認します。

aws --profile "${PROFILE}" --region "${REGION}" \
    ssm get-parameter \
        --name "AmazonCloudWatch-SampleConfig"
CloudWatchエージェントを稼働させるAmazon Linux2サーバでの操作
  • 新しいEC2インスタンスの作成: 先の手順を参考にCloudWatchエージェントが稼働できるEC2インスタンスを新規作成してOSにログインします。
  • CloudWatchエージェントのインストール: 先の手順を参考にCloudWatchエージェントをインストールします
  • コンフィグファイルのフェッチとエージェント起動
#SSMから設定ファイルを取得しフェッチする
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -c ssm:AmazonCloudWatch-SampleConfig

#エージェントの起動
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a start

#エージェントの状態確認
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a status

ユーザデータでCloudWatchエージェントを設定する

AutoScalingやCloudFormationなどでEC2のユーザデータでインスタンスの初期起動時にCloudWatchエージェントを設定する場合は、以下の手順をユーザデータに追加します。
この手順ではParameter StoreからCloudWatchエージェントの設定ファイルを取得して起動する前提で書いています。

# Setup AWS CLI
REGION=$(TOKEN=`curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"` \
    && curl -H "X-aws-ec2-metadata-token: $TOKEN" -s http://169.254.169.254/latest/meta-data/placement/availability-zone | sed -e 's/.$//')
aws configure set region ${!REGION}
aws configure set output json

# Setup CloudWatch Agent
sudo amazon-linux-extras enable collectd
sudo yum clean metadata
sudo yum -y install collectd
sudo yum -y install amazon-cloudwatch-agent

sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -s -c ssm:AmazonCloudWatch-ForwardProxy