LoginSignup
1
2

More than 5 years have passed since last update.

CloudWatch Agentをインストールしてゲスト内メトリクスとログファイルデータを収集する (最初の1台目)

Last updated at Posted at 2019-02-03

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}
Output例
/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}
Output例
{
  "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}
Output例
{
    "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}"
Output例
arn:aws:iam::aws:policy/service-role/AmazonEC2RoleforSSM

ポリシーをロールへアタッチ

コマンド
aws iam attach-role-policy \
  --role-name ${IAM_ROLE_NAME} \
  --policy-arn ${IAM_POLICY_ARN}
Output例
出力なし

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}"
Output例
arn:aws:iam::aws:policy/CloudWatchAgentAdminPolicy

ポリシーをロールへアタッチ

コマンド
aws iam attach-role-policy \
  --role-name ${IAM_ROLE_NAME} \
  --policy-arn ${IAM_POLICY_ARN}
Output例
出力なし

アタッチされたポリシーの確認

コマンド
aws iam list-attached-role-policies \
    --role-name ${IAM_ROLE_NAME} \
    --query "AttachedPolicies[].PolicyName"
Output例
[
    "AmazonEC2RoleforSSM",
    "CloudWatchAgentAdminPolicy"
]

インスタンスプロファイルの作成

変数の設定

コマンド
IAM_INSTANCE_PROFILE_NAME='CloudWatchAgentInstanceProfile'

インスタンスプロファイルの作成

コマンド
aws iam create-instance-profile \
  --instance-profile-name ${IAM_INSTANCE_PROFILE_NAME}
Output例
{
    "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}
Output例
出力なし

EC2インスタンスへのインスタンスプロファイルのアタッチ

変数の設定

INSTANCE_ID="インスタンスプロファイルを紐付けるインスタンスID"

インスタンスへのアタッチ

コマンド
aws ec2 associate-iam-instance-profile \
    --iam-instance-profile "Name=${IAM_INSTANCE_PROFILE_NAME}" \
    --instance-id ${INSTANCE_ID}
Output例
{    "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"
Output例
[
    "associated"
]

Systems Manager(SSM)からCloudWatch Agentをインストールする

マネージドインスタンスの登録確認

マネージドインスタンスとして登録されているかを確認します。今回はAmazon Linux 2を使用しているため初めからSSMエージェントがインストールされており、マネージドインスタンスとして認識されます。インストールされないOSの場合やバージョンが古い場合は別途インストール/アップデートが必要です。

コマンド
aws ssm describe-instance-information \
    --query "InstanceInformationList[?InstanceId==\`${INSTANCE_ID}\`]"
Output例
    {
        "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}"
Output例
{
    "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
Output例
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
Output例
省略

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}"
Output例
{
    "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
Output例
Success

取得されたメトリクス/ログの確認

メトリクス

CloudWatchにカスタムメトリクスのmem_used_percentが取得されています。
image.png

ログ

CloudWatch Logsに/var/log/messagesのログが取得されています。
image.png

Next Step

2台目以降はパラメータストアに保存した設定を簡略化できるためそちらも試す。
"CloudWatchAgentAdminPolicy"は設定ファイル作成/更新時以外は不要のため"CloudWatchAgentServerPolicy"に変更する。

参考

AWS CLIの書き方はJAWS-UG CLI専門支部の過去資料が大変参考になります。
https://jawsug-cli.doorkeeper.jp/

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2