CloudWatch Agentを起動済みのEC2インスタンス(Amazon Linux 2)にインストールしてゲスト内メトリクスとログファイル内データを収集します。本メモは2台目以降の設定方法です。
前提条件
- AWS CLIがインストールされており、クレデンシャル/リージョンが設定されている。
- JSONファイル検証用にjsonlintがインストールされている。
- ログインできるEC2インスタンス(Linux) が起動されていること。今回はAmazon Linux 2。
- EC2インスタンスがインターネットまたはVPCエンドポイント経由でCloudWatch、CloudWatch Logs、SSMエンドポイントにアクセスできる。
- CloudWatch Agnentの1台目の構築時に、設定をSSMパラメータストアに保存している。
EC2実行用ロールの作成およびEC2インスタンスへの紐付け
RunCommandでCloudWatch Agentをインストール/構成するための"AmazonEC2RoleforSSM"ポリシーおよびCloudWatchAgentのための"CloudWatchAgentServerPolicy"ポリシーを持つロールを作成します。さらにEC2インスタンスにロールを紐付けるためにインスタンスプロファイルを作成してロールを付与し、インスタンスに紐付けます。
*"CloudWatchAgentAdminPolicy"はCloudWatch Agentのコンフィグを再利用するためSSMパラメータストアに書き込むための権限が含まれるため2台目以降は使用しない。
Assume Role Documentの作成
作業フォルダの作成
ls -d ${HOME}/tmp/
# 存在しない場合
mkdir -p ${HOME}/tmp/
変数の設定
# Assume Role Document ディレクトリ
DIR_IAM_ROLE_DOC="${HOME}/tmp"
# Role名
IAM_ROLE_NAME='CloudWatchAgentInstanceServerRole'
# Principle名
IAM_PRINCIPAL='ec2.amazonaws.com'
ファイル名の設定
FILE_IAM_ROLE_DOC="${DIR_IAM_ROLE_DOC}/${IAM_ROLE_NAME}.json" \
&& echo ${FILE_IAM_ROLE_DOC}
/Users/xxxxx/tmp/CloudWatchAgentInstanceServerRole.json
Assume Role Documentの作成
cat << EOF > ${FILE_IAM_ROLE_DOC}
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": "${IAM_PRINCIPAL}"
},
"Effect": "Allow",
"Sid": ""
}
]
}
EOF
cat ${FILE_IAM_ROLE_DOC}
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Effect": "Allow",
"Sid": ""
}
]
}
jsonlintでjsonファイルが壊れていないかチェックします。問題なければ何も出力されません。
jsonlint -q ${FILE_IAM_ROLE_DOC}
IAMロールの作成
aws iam create-role \
--role-name ${IAM_ROLE_NAME} \
--assume-role-policy-document file://${FILE_IAM_ROLE_DOC}
{
"Role": {
"Path": "/",
"RoleName": "CloudWatchAgentInstanceServerRole",
"RoleId": "AROAJBP27QT6327XBN3VQ",
"Arn": "arn:aws:iam::xxxxxxxxxxxx:role/CloudWatchAgentInstanceServerRole",
"CreateDate": "2019-02-09T08:53:09Z",
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Effect": "Allow",
"Sid": ""
}
]
}
}
}
IAMポリシーのアタッチ
AmazonEC2RoleforSSM
変数の設定
IAM_POLICY_NAME="AmazonEC2RoleforSSM"
IAM_POLICY_ARN=$( \
aws iam list-policies \
--scope AWS \
--max-items 1000 \
--query "Policies[?PolicyName==\`${IAM_POLICY_NAME}\`].Arn" \
--output text \
) \
&& echo "${IAM_POLICY_ARN}"
arn:aws:iam::aws:policy/service-role/AmazonEC2RoleforSSM
ポリシーをロールへアタッチ
aws iam attach-role-policy \
--role-name ${IAM_ROLE_NAME} \
--policy-arn ${IAM_POLICY_ARN}
出力なし
CloudWatchAgentAdminPolicy
変数の設定
IAM_POLICY_NAME="CloudWatchAgentServerPolicy"
IAM_POLICY_ARN=$( \
aws iam list-policies \
--scope AWS \
--max-items 1000 \
--query "Policies[?PolicyName==\`${IAM_POLICY_NAME}\`].Arn" \
--output text \
) \
&& echo "${IAM_POLICY_ARN}"
arn:aws:iam::aws:policy/CloudWatchAgentAdminPolicy
ポリシーをロールへアタッチ
aws iam attach-role-policy \
--role-name ${IAM_ROLE_NAME} \
--policy-arn ${IAM_POLICY_ARN}
出力なし
アタッチされたポリシーの確認
aws iam list-attached-role-policies \
--role-name ${IAM_ROLE_NAME} \
--query "AttachedPolicies[].PolicyName"
[
"AmazonEC2RoleforSSM",
"CloudWatchAgentServerPolicy"
]
インスタンスプロファイルの作成
変数の設定
IAM_INSTANCE_PROFILE_NAME='CloudWatchAgentInstanceServerProfile'
インスタンスプロファイルの作成
aws iam create-instance-profile \
--instance-profile-name ${IAM_INSTANCE_PROFILE_NAME}
{
"InstanceProfile": {
"Path": "/",
"InstanceProfileName": "CloudWatchAgentInstanceServerProfile",
"InstanceProfileId": "AIPAJJIV2ATCBNDDRTQXS",
"Arn": "arn:aws:iam::xxxxxxxxxxxx:instance-profile/CloudWatchAgentInstanceServerProfile",
"CreateDate": "2019-02-09T08:55:37Z",
"Roles": []
}
インスタンスプロファイルへのロールのアタッチ
aws iam add-role-to-instance-profile \
--instance-profile-name ${IAM_INSTANCE_PROFILE_NAME} \
--role-name ${IAM_ROLE_NAME}
出力なし
EC2インスタンスへのインスタンスプロファイルのアタッチ
変数の設定
INSTANCE_ID="インスタンスプロファイルを紐付けるインスタンスID"
インスタンスへのアタッチ
aws ec2 associate-iam-instance-profile \
--iam-instance-profile "Name=${IAM_INSTANCE_PROFILE_NAME}" \
--instance-id ${INSTANCE_ID}
{
"IamInstanceProfileAssociation": {
"AssociationId": "iip-assoc-086fefee2bcb2a5ac",
"InstanceId": "i-0ae3a2e7317e5e8d0",
"IamInstanceProfile": {
"Arn": "arn:aws:iam::xxxxxxxxxxxx:instance-profile/CloudWatchAgentInstanceServerProfile",
"Id": "AIPAJJIV2ATCBNDDRTQXS"
},
"State": "associating"
}
}
確認
aws ec2 describe-iam-instance-profile-associations \
--query "IamInstanceProfileAssociations[?InstanceId==\`${INSTANCE_ID}\`].State"
[
"associated"
]
Systems Manager(SSM)からCloudWatch Agentをインストールする
マネージドインスタンスの登録確認
マネージドインスタンスとして登録されているかを確認します。今回はAmazon Linux 2を使用しているため初めからSSMエージェントがインストールされており、マネージドインスタンスとして認識されます。インストールされないOSの場合やバージョンが古い場合は別途インストール/アップデートが必要です。
aws ssm describe-instance-information \
--query "InstanceInformationList[?InstanceId==\`${INSTANCE_ID}\`]"
[
{
"InstanceId": "i-0ae3a2e7317e5e8d0",
"PingStatus": "Online",
"LastPingDateTime": 1549703111.672,
"AgentVersion": "2.3.372.0",
"IsLatestVersion": false,
"PlatformType": "Linux",
"PlatformName": "Amazon Linux",
"PlatformVersion": "2",
"ResourceType": "EC2Instance",
"IPAddress": "172.31.30.106",
"ComputerName": "ip-172-31-30-106.ap-northeast-1.compute.internal"
}
]
CloudWatch Agentのインストール
変数の設定
INSTANCE_ID="インストール先のインスタンスID"
SSM_COMMAND_DOCUMENT_NAME="AWS-ConfigureAWSPackage"
SSM_COMMAND_TARGETS="Key=instanceids,Values=${INSTANCE_ID}"
SSM_COMMAND_PARAMETERS="action=Install, name=AmazonCloudWatchAgent, version=latest"
Run CommandでCloudWatch Agentをインストール
aws ssm send-command \
--document-name ${SSM_COMMAND_DOCUMENT_NAME} \
--targets ${SSM_COMMAND_TARGETS} \
--parameters "${SSM_COMMAND_PARAMETERS}"
{
"Command": {
"CommandId": "3c303421-1328-4613-9602-d041533b24b1",
"DocumentName": "AWS-ConfigureAWSPackage",
(...省略...)
"RequestedDateTime": 1549185898.031,
"Status": "Pending",
"StatusDetails": "Pending",
(...省略...)
}
確認
SSM_COMMAND_ID="3c303421-1328-4613-9602-d041533b24b1" #上記の結果からコピー
aws ssm list-command-invocations \
--command-id ${SSM_COMMAND_ID} \
--instance-id ${INSTANCE_ID} \
--query "CommandInvocations[].Status" \
--output text
Success
CloudWatch Agentの設定
collectdのインストール
このままCloudWatch Agentを起動するとcollectdがないと怒られるので、collectdをSSM RunCommandの"AWS-RunShellScript"ドキュメントを使用していインストールします。
変数の設定
INSTANCE_ID="インストール先のインスタンスID"
SSM_COMMAND_DOCUMENT_NAME="AWS-RunShellScript"
SSM_COMMAND_TARGETS="Key=instanceids,Values=${INSTANCE_ID}"
SSM_COMMAND_PARAMETERS="commands=sudo amazon-linux-extras install -y epel && sudo yum -y install collectd"
RunCommandでcollectdをインストール
aws ssm send-command \
--document-name ${SSM_COMMAND_DOCUMENT_NAME} \
--targets ${SSM_COMMAND_TARGETS} \
--parameters "${SSM_COMMAND_PARAMETERS}"
{
"Command": {
"CommandId": "da0bb8b3-9c9a-466f-a7e2-f4543ef11c49",
"DocumentName": "AWS-RunShellScript",
(...省略...)
"RequestedDateTime": 1549185898.031,
"Status": "Pending",
"StatusDetails": "Pending",
(...省略...)
}
確認
SSM_COMMAND_ID="da0bb8b3-9c9a-466f-a7e2-f4543ef11c49" #上記の結果からコピー
aws ssm list-command-invocations \
--command-id ${SSM_COMMAND_ID} \
--instance-id ${INSTANCE_ID} \
--query "CommandInvocations[].Status" \
--output text
Success
CloudWatch Agentの構成、起動
SSM経由でCloudWatch Agentを構成、起動します。1台目を構築した際に設定がSSMパラメータストアに"AmazonCloudWatch-linux"というキーで保存されているためそちらを利用できます。
変数の設定
INSTANCE_ID="インストール先のインスタンスID"
SSM_CONFIG_PARAMETER_NAME="AmazonCloudWatch-linux"
SSM_COMMAND_DOCUMENT_NAME="AmazonCloudWatch-ManageAgent"
SSM_COMMAND_TARGETS="Key=instanceids,Values=${INSTANCE_ID}"
SSM_COMMAND_PARAMETERS="action=configure, mode=ec2, optionalConfigurationSource=ssm, optionalConfigurationLocation=${SSM_CONFIG_PARAMETER_NAME}, optionalRestart=yes"
Run CommandでCloudWatch Agentを起動
aws ssm send-command \
--document-name ${SSM_COMMAND_DOCUMENT_NAME} \
--targets ${SSM_COMMAND_TARGETS} \
--parameters "${SSM_COMMAND_PARAMETERS}"
{
"Command": {
"CommandId": "813175eb-8e52-4ffb-a833-d258eb3e7064",
"DocumentName": "AmazonCloudWatch-ManageAgent",
(...省略...)
"RequestedDateTime": 1549190668.591,
"Status": "Pending",
"StatusDetails": "Pending",
(...省略...)
}
確認
SSM_COMMAND_ID="813175eb-8e52-4ffb-a833-d258eb3e7064" #上記の結果からコピー
aws ssm list-command-invocations \
--command-id ${SSM_COMMAND_ID} \
--instance-id ${INSTANCE_ID} \
--query "CommandInvocations[].Status" \
--output text
Success
取得されたメトリクス/ログの確認
メトリクス
CloudWatchにカスタムメトリクスのmem_used_percentが取得されています。
ログ
CloudWatch Logsに/var/log/messagesのログが取得されています。
まとめ
今回はすでに起動済みのEC2インスタンスに対してCloudWatch Agentをインストールしましたが、EC2インスタンス起動時にインストールするにはUserDataを利用するのが良いでしょう。
参考: 新しいCloudWatch Agentを有効化したEC2オートスケール環境をCloudFormationで設定してみた
AMIに仕込む場合はログストリーム名がAMIを作成したインスタンスIDとなってしまうため起動時に再構成が必要後なるようです。
参考:CloudWatch Agent 仕込み済み AMI からEC2インスタンスを作成するときの注意
参考
AWS CLIの書き方はJAWS-UG CLI専門支部の過去資料が大変参考になります。
https://jawsug-cli.doorkeeper.jp/