CloudWatch AgentをEC2インスタンス(Amazon Linux 2)にインストールしてゲスト内メトリクスとログファイル内データを収集します。本メモは最初の1台目の設定方法です。
前提条件
- AWS CLIがインストールされており、クレデンシャル/リージョンが設定されている。
- JSONファイル検証用にjsonlintがインストールされている。
- ログインできるEC2インスタンス(Linux) が起動されていること。今回はAmazon Linux 2。
- EC2インスタンスがインターネットまたはVPCエンドポイント経由でCloudWatch、CloudWatch Logs、SSMエンドポイントにアクセスできる。
EC2実行用ロールの作成およびEC2インスタンスへの紐付け
RunCommandでCloudWatch Agentをインストール/構成するための"AmazonEC2RoleforSSM"ポリシーおよびCloudWatchAgentのための"CloudWatchAgentAdminPolicy"ポリシーを持つロールを作成します。さらにEC2インスタンスにロールを紐付けるためにインスタンスプロファイルを作成してロールを付与し、インスタンスに紐付けます。
※"CloudWatchAgentAdminPolicy"はCloudWatch Agentのコンフィグを再利用するためSSMパラメータストアに書き込むための権限が含まれるため、コンフィグの書き込み完了以降は"CloudWatchAgentServerPolicy"に変更することが推奨されています。
Assume Role Documentの作成
作業フォルダの作成
ls -d ${HOME}/tmp/
# 存在しない場合
mkdir -p ${HOME}/tmp/
変数の設定
# Assume Role Document ディレクトリ
DIR_IAM_ROLE_DOC="${HOME}/tmp"
# Role名
IAM_ROLE_NAME='CloudWatchAgentInstanceRole'
# 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/CloudWatchAgentInstanceRole.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": "CloudWatchAgentInstanceRole",
"RoleId": "AROAJTMDKBJBF5JL7MNZ6",
"Arn": "arn:aws:iam::xxxxxxxxxxxx:role/CloudWatchAgentInstanceRole",
"CreateDate": "2019-02-02T13:56:13Z",
"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="CloudWatchAgentAdminPolicy"
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",
"CloudWatchAgentAdminPolicy"
]
インスタンスプロファイルの作成
変数の設定
IAM_INSTANCE_PROFILE_NAME='CloudWatchAgentInstanceProfile'
インスタンスプロファイルの作成
aws iam create-instance-profile \
--instance-profile-name ${IAM_INSTANCE_PROFILE_NAME}
{
"InstanceProfile": {
"Path": "/",
"InstanceProfileName": "CloudWatchAgentInstanceProfile",
"InstanceProfileId": "AIPAI37ND6UTLOF7QWRBY",
"Arn": "arn:aws:iam::xxxxxxxxxxxx:instance-profile/CloudWatchAgentInstanceProfile",
"CreateDate": "2019-02-02T14:47:25Z",
"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-00eba20147c23b77e",
"InstanceId": "i-0f6392abb1e0eba21",
"IamInstanceProfile": {
"Arn": "arn:aws:iam::xxxxxxxxxxxx:instance-profile/CloudWatchAgentInstanceProfile",
"Id": "AIPAI37ND6UTLOF7QWRBY"
},
"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-0f6392abb1e0eba21",
"PingStatus": "Online",
"LastPingDateTime": 1549184853.467,
"AgentVersion": "2.3.372.0",
"IsLatestVersion": false,
"PlatformType": "Linux",
"PlatformName": "Amazon Linux",
"PlatformVersion": "2",
"ResourceType": "EC2Instance",
"IPAddress": "172.31.35.234",
"ComputerName": "ip-172-31-35-234.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の設定
設定ファイルの作成
EC2インスタンスにログイン
CloudWatch AgentがインストールされているEC2インスタンスにSSHログインします。
(オプション) 一般的な設定を変更
プロキシ設定、認証情報(IAMロールをつけている場合は不要)などを設定する場合は以下のファイルを編集します。今回は省略。
vi /opt/aws/amazon-cloudwatch-agent/etc/common-config.toml
ウィザードを利用して設定ファイルを作成する
設定ウィザードを起動します。
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-config-wizard
ウィザードに剃ってパラメータを決定していきます。(各パラメータの選択の意図は後日元気のあるときに追記)
=============================================================
= Welcome to the AWS CloudWatch Agent Configuration Manager =
=============================================================
On which OS are you planning to use the agent?
1. linux
2. windows
default choice: [1]:
1
Trying to fetch the default region based on ec2 metadata...
Are you using EC2 or On-Premises hosts?
1. EC2
2. On-Premises
default choice: [1]:
1
Do you want to turn on StatsD daemon?
1. yes
2. no
default choice: [1]:
1
Which port do you want StatsD daemon to listen to?
default choice: [8125]
8125
What is the collect interval for StatsD daemon?
1. 10s
2. 30s
3. 60s
default choice: [1]:
1
What is the aggregation interval for metrics collected by StatsD daemon?
1. Do not aggregate
2. 10s
3. 30s
4. 60s
default choice: [4]:
1
Do you want to monitor metrics from CollectD?
1. yes
2. no
default choice: [1]:
1
Do you want to monitor any host metrics? e.g. CPU, memory, etc.
1. yes
2. no
default choice: [1]:
1
Do you want to monitor cpu metrics per core? Additional CloudWatch charges may apply.
1. yes
2. no
default choice: [1]:
1
Do you want to add ec2 dimensions (ImageId, InstanceId, InstanceType, AutoScalingGroupName) into all of your metrics if the info is available?
1. yes
2. no
default choice: [1]:
1
Would you like to collect your metrics at high resolution (sub-minute resolution)? This enables sub-minute resolution for all metrics, but you can customize for specific metrics in the output json file.
1. 1s
2. 10s
3. 30s
4. 60s
default choice: [4]:
2
Which default metrics config do you want?
1. Basic
2. Standard
3. Advanced
4. None
default choice: [1]:
3
Current config as follows:
{
"metrics": {
"append_dimensions": {
"AutoScalingGroupName": "${aws:AutoScalingGroupName}",
"ImageId": "${aws:ImageId}",
"InstanceId": "${aws:InstanceId}",
"InstanceType": "${aws:InstanceType}"
},
"metrics_collected": {
"collectd": {
"metrics_aggregation_interval": 0
},
"cpu": {
"measurement": [
"cpu_usage_idle",
"cpu_usage_iowait",
"cpu_usage_user",
"cpu_usage_system"
],
"metrics_collection_interval": 10,
"resources": [
"*"
],
"totalcpu": false
},
"disk": {
"measurement": [
"used_percent",
"inodes_free"
],
"metrics_collection_interval": 10,
"resources": [
"*"
]
},
"diskio": {
"measurement": [
"io_time",
"write_bytes",
"read_bytes",
"writes",
"reads"
],
"metrics_collection_interval": 10,
"resources": [
"*"
]
},
"mem": {
"measurement": [
"mem_used_percent"
],
"metrics_collection_interval": 10
},
"netstat": {
"measurement": [
"tcp_established",
"tcp_time_wait"
],
"metrics_collection_interval": 10
},
"statsd": {
"metrics_aggregation_interval": 0,
"metrics_collection_interval": 10,
"service_address": ":8125"
},
"swap": {
"measurement": [
"swap_used_percent"
],
"metrics_collection_interval": 10
}
}
}
}
Are you satisfied with the above config? Note: it can be manually customized after the wizard completes to add additional items.
1. yes
2. no
default choice: [1]:
1
Do you have any existing CloudWatch Log Agent (http://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/AgentReference.html) configuration file to import for migration?
1. yes
2. no
default choice: [2]:
2
Do you want to monitor any log files?
1. yes
2. no
default choice: [1]:
1
Log file path:
/var/log/messages
Log group name:
default choice: [messages]
Log stream name:
default choice: [{instance_id}]
Do you want to specify any additional log files to monitor?
1. yes
2. no
default choice: [1]:
2
Saved config file to /opt/aws/amazon-cloudwatch-agent/bin/config.json successfully.
Current config as follows:
{
"logs": {
"logs_collected": {
"files": {
"collect_list": [
{
"file_path": "/var/log/messages",
"log_group_name": "messages",
"log_stream_name": "{instance_id}"
}
]
}
}
},
"metrics": {
"append_dimensions": {
"AutoScalingGroupName": "${aws:AutoScalingGroupName}",
"ImageId": "${aws:ImageId}",
"InstanceId": "${aws:InstanceId}",
"InstanceType": "${aws:InstanceType}"
},
"metrics_collected": {
"collectd": {
"metrics_aggregation_interval": 0
},
"cpu": {
"measurement": [
"cpu_usage_idle",
"cpu_usage_iowait",
"cpu_usage_user",
"cpu_usage_system"
],
"metrics_collection_interval": 10,
"resources": [
"*"
],
"totalcpu": false
},
"disk": {
"measurement": [
"used_percent",
"inodes_free"
],
"metrics_collection_interval": 10,
"resources": [
"*"
]
},
"diskio": {
"measurement": [
"io_time",
"write_bytes",
"read_bytes",
"writes",
"reads"
],
"metrics_collection_interval": 10,
"resources": [
"*"
]
},
"mem": {
"measurement": [
"mem_used_percent"
],
"metrics_collection_interval": 10
},
"netstat": {
"measurement": [
"tcp_established",
"tcp_time_wait"
],
"metrics_collection_interval": 10
},
"statsd": {
"metrics_aggregation_interval": 0,
"metrics_collection_interval": 10,
"service_address": ":8125"
},
"swap": {
"measurement": [
"swap_used_percent"
],
"metrics_collection_interval": 10
}
}
}
}
Please check the above content of the config.
The config file is also located at /opt/aws/amazon-cloudwatch-agent/bin/config.json.
Edit it manually if needed.
Do you want to store the config in the SSM parameter store?
1. yes
2. no
default choice: [1]:
1
What parameter store name do you want to use to store your config? (Use 'AmazonCloudWatch-' prefix if you use our managed AWS policy)
default choice: [AmazonCloudWatch-linux]
Trying to fetch the default region based on ec2 metadata...
Which region do you want to store the config in the parameter store?
default choice: [ap-northeast-1]
Which AWS credential should be used to send json config to parameter store?
1. ASIATWB6MCKPTDHEQ3IX(From SDK)
2. Other
default choice: [1]:
1
Successfully put config to parameter store AmazonCloudWatch-linux.
Program exits now.
上記のウィザードによってローカルの設定ファイル/opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.toml
に設定が保存されます。
また、パラメータストアに設定ファイルを保存する指定をした場合はそちら(デフォルトパラメータ名はAmazonCloudWatch-linux)にもJson形式で保存されます。これにより、2台目以降はウィザードを実行せずにパラメータストアを参照して構成できます。
collectdのインストール
このままCloudWatch Agentを起動するとcollectdがないと怒られるのでインストールします。
sudo amazon-linux-extras install -y epel
sudo yum install collectd
省略
CloudWatch Agentの構成、起動
SSM経由でCloudWatch Agentを構成、起動します。
変数の設定
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": "91cae632-5469-4917-84f6-a939abda9f97",
"DocumentName": "AmazonCloudWatch-ManageAgent",
(...省略...)
"RequestedDateTime": 1549190668.591,
"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にカスタムメトリクスのmem_used_percentが取得されています。
ログ
CloudWatch Logsに/var/log/messagesのログが取得されています。
Next Step
2台目以降はパラメータストアに保存した設定を簡略化できるためそちらも試す。
"CloudWatchAgentAdminPolicy"は設定ファイル作成/更新時以外は不要のため"CloudWatchAgentServerPolicy"に変更する。
参考
AWS CLIの書き方はJAWS-UG CLI専門支部の過去資料が大変参考になります。
https://jawsug-cli.doorkeeper.jp/