ちょっと話題の記事

(初心者向け)EC2に CloudWatch エージェントをインストールして SSM で起動する

はじめての CloudWatch エージェント
2020.08.07

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

コンサル部@大阪オフィスのYui(@MayForBlue)です。

今回は EC2 に CloudWatch エージェントをインストールして SSM ( AWS Systems Manager ) を使って起動する方法をご紹介します。
わりと初歩的な内容かな?と思うのですが、個人的にハマりどころが多かったので手順を残しておきたいと思います。

構成


今回はパブリックサブネットに構築したEC2インスタンスにCloudWatchエージェントをインストールします。
EC2 インスタンスからインターネットゲートウェイを経由して CloudWatch にログをプッシュします。

なお、EC2 インスタンスから CloudWatch にログをプッシュするためにはアウトバウンドのインターネット接続が必要になります。

やってみる

前提条件

EC2インスタンス、インターネットゲートウェイは構築済みとします。
また、今回EC2のOSは Amazon Linux 2 を使用しています。

EC2インスタンスに割り当てるIAMロールを作成する

今回のEC2に必要な権限を与えたIAMロールを作成します。
EC2から CloudWatch にログをプッシュするための権限と、今回エージェントの設定を SSM ( AWS Systems Manager ) に保存するので、そのための権限を付与します。

IAM のダッシュボードの左側メニューから「ポリシー」を選択し、「ロールの作成」をクリックします。

信頼されたエンティティの種類で AWSサービス -> EC2 を選択し、「アクセス権限」をクリックします。

必要な権限を選択します。今回は以下を選択しました。なお、必要な権限はそれぞれの用途に合ったものを適宜選択してください。

  • CloudWatchAgentAdminPolicy
  • CloudWatchAgentServerPolicy

タグが必要な場合は設定し(今回は設定しませんでした)、「確認」をクリックします。

ロール名を入力し、内容に問題がなければ「ロールの作成」をクリックします。

IAMロールをEC2インスタンスに割り当てる

作成したIAMロールをEC2に割り当てます。

EC2のダッシュボードの左側メニューから「インスタンス」を選択します。
対象のインスタンスを選択し、「アクション」の「インスタンスの設定」から「IAMロールの割り当て/置換」をクリックします。

作成したロールを選択し、「適用」をクリックします。

EC2インスタンスに CloudWatch エージェントをインストールする

インスタンスにCloudWatch エージェントをインストールします。

インスタンスにSSH接続して、以下のコマンドで CloudWatch エージェントをダウンロードします。
(東京リージョン以外の場合はap-northeast-1を該当のリージョンIDに書き換えてください)

wget https://s3.ap-northeast-1.amazonaws.com/amazoncloudwatch-agent-ap-northeast-1/amazon_linux/amd64/latest/amazon-cloudwatch-agent.rpm

以下のコマンドでパッケージをインストールします。

sudo rpm -U ./amazon-cloudwatch-agent.rpm

インストールが完了したら以下のコマンドを使用してエージェントの設定ファイルを作成していきます。

sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-config-wizard

上記のコマンドを叩くと設定ファイルを構成するための質問が出てくるので、該当する内容を答えていきます。
ちなみに私は以下のように設定しました。
(基本はデフォルト値のまま設定し、★をつけたところのみ任意の値を設定しました。)

$ 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
Which user are you planning to run the agent?
1. root
2. cwagent
3. others
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]:
4
Do you want to monitor metrics from CollectD? ★
1. yes
2. no
default choice: [1]:
2
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]:
4
Which default metrics config do you want?
1. Basic
2. Standard
3. Advanced
4. None
default choice: [1]:
1
Current config as follows:
{
	"agent": {
		"metrics_collection_interval": 60,
		"run_as_user": "root"
	},
	"metrics": {
		"append_dimensions": {
			"AutoScalingGroupName": "${aws:AutoScalingGroupName}",
			"ImageId": "${aws:ImageId}",
			"InstanceId": "${aws:InstanceId}",
			"InstanceType": "${aws:InstanceType}"
		},
		"metrics_collected": {
			"disk": {
				"measurement": [
					"used_percent"
				],
				"metrics_collection_interval": 60,
				"resources": [
					"*"
				]
			},
			"mem": {
				"measurement": [
					"mem_used_percent"
				],
				"metrics_collection_interval": 60
			},
			"statsd": {
				"metrics_aggregation_interval": 60,
				"metrics_collection_interval": 10,
				"service_address": ":8125"
			}
		}
	}
}
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]
messages
Log stream name:
default choice: [{instance_id}]
{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:
{
	"agent": {
		"metrics_collection_interval": 60,
		"run_as_user": "root"
	},
	"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": {
			"disk": {
				"measurement": [
					"used_percent"
				],
				"metrics_collection_interval": 60,
				"resources": [
					"*"
				]
			},
			"mem": {
				"measurement": [
					"mem_used_percent"
				],
				"metrics_collection_interval": 60
			},
			"statsd": {
				"metrics_aggregation_interval": 60,
				"metrics_collection_interval": 10,
				"service_address": ":8125"
			}
		}
	}
}
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]
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]
ap-northeast-1
Which AWS credential should be used to send json config to parameter store?
1. ASIA35DMWNLMOWIF53HY(From SDK)
2. Other
default choice: [1]:
1
Successfully put config to parameter store AmazonCloudWatch-linux.
Program exits now.

なお、collectd を使用する場合は別途インストールが必要になりますのでご注意ください。
詳細については以下のブログ、公式ドキュメントをご覧ください。

collectd を使用したカスタムメトリクスの取得

また、この方法は質問に回答して適切な設定ファイルを作成する方法になりますが、手動で作成することも可能です。
方法については以下の公式ドキュメントをご参照ください。
CloudWatch エージェント設定ファイルを手動で作成または編集する

SSMからエージェントを起動する

インスタンスでのエージェントの設定が完了したら、SSM の Run Command でエージェントを起動します。

SSM のダッシュボードの左側メニューから「Run Command」を選択し、「Run Command」のボタンをクリックします。

以下を設定します。(他はデフォルト値のまま行いました。)

  • コマンドドキュメント: AmazonCloudWatch-ManageAgent
  • Optional Configuration Location: AmazonCloudWatch-linux
  • ターゲット: 「インスタンスを手動で選択する」をクリックし、対象のインスタンスにチェックをいれる
  • 出力オプション: S3 バケットへの書き込みを有効化する(こちらは任意でOKです)

設定が完了したら「実行」をクリックします。

以下の画面になればコマンドの実行が成功し、エージェントが起動しているはずです。

確認する

CloudWatch Logs にログがプッシュされていることを確認します。

今回は以下にログが保存されているはずなので、CloudWatch のダッシュボードからアクセスします。

  • ロググループ: messages
  • ログストリーム: インスタンスID

対象の階層の配下にログイベントが保存されていることが確認できました!

さいごに

EC2インスタンスに CloudWatch エージェントをインストールして起動する方法をご紹介しました。
IAMロールの設定や SSM でのエージェント起動の方法など、知っておくべきことが多いなと思ったので記事にまとめました。
(最初にやったときはIAMロールの権限が足りない、起動の方法がわからないなどでかなりハマりました・・・)

この方法がどなたかのお役に立てば幸いです。

以上、コンサル部@大阪オフィスのYui(@MayForBlue)でしたっ(`・ω・´)

参考リンク

CloudWatch エージェントを使用して Amazon EC2 インスタンスとオンプレミスサーバーからメトリクスとログを収集する