【AWS 初学者向け】マネジメントコンソールで CloudWatch エージェントを設定して Amazon EC2 のメモリ使用率を取得する
はじめに
Amazon EC2 の標準メトリクスにメモリ使用率は含まれません。取得するには CloudWatch エージェントを入れて、収集する項目を書いた設定が必要です。設定作業はマネジメントコンソールだけで、Session Manager で入れる EC2 にメモリ使用率の取得だけを追加するというシンプルなものが欲しかったです。自分好みな手順が見当たらなかったので作成したものを公開しておきます。
経緯としては本当はこちらの手順が簡単で良かったのですが、ドキュメントを確認するといまだにベータだったので無難な方法の手順を作ることになりました。
検証環境
AmazonSSMManagedInstanceCore 相当の権限を持つ IAM ロールがアタッチ済みの状態から始めます。Session Manager で接続できていれば、この前提条件はほぼ満たしているはずです。
| 項目 | 値 |
|---|---|
| OS | Ubuntu Server 26.04 LTS(x86_64) |
| インスタンスタイプ | t3.small(2 vCPU / 2 GiB) |
| リージョン | ap-northeast-1 |
| CloudWatch エージェントのバージョン | 1.300072.0b1766 |
設定の流れ
そんなに複雑な内容ではないです。いずれもマネジメントコンソールからの作業です。
| # | 実施内容 | AWS の設定画面 |
|---|---|---|
| 1 | EC2 にメトリクス送信の権限を追加する | IAM ロール |
| 2 | CloudWatch Agent をインストールする | Systems Manager の Run Command |
| 3 | 収集する項目を書いた設定を保存する | Systems Manager のパラメータストア |
| 4 | 設定を読み込ませてエージェントを起動する | Systems Manager の Run Command |
IAM ロールに CloudWatchAgentServerPolicy を追加する
対象の EC2 インスタンスにどの IAM ロールが付いているかを確認します。コンソール上部の検索ボックスに「EC2」と入力し、サービスの候補をクリックして開きます。

インスタンス一覧で対象インスタンスにチェックを入れると、画面下部に詳細のペインが開きます。

ペインのタブから「セキュリティ」を開きます。「セキュリティの詳細」の「IAM ロール」にロール名が表示されます。ロール名はリンクになっており、クリックすると IAM の画面へ移動します。このロールに権限を足していきます。

開いたロールの「許可」タブで、「許可を追加」から「ポリシーをアタッチ」を選びます。CloudWatchAgentServerPolicy を検索して選択し、右下の「許可を追加」をクリックします。

アタッチすると「ポリシーがロールに正常にアタッチされました。」と表示されます。今回のロールは AmazonSSMManagedInstanceCore だけが付いた状態だったため、追加後は 2 つのポリシーが付いた IAM ロールとなりました。

IAM ロールへのポリシー追加は再起動なしで反映されますが、反映まで時間がかかりますのでお急ぎの場合は EC2 インスタンスの再起動または、停止・開始を実施してください。
CloudWatch エージェントをインストールする
ここからは Systems Manager を使います。コンソール上部の検索ボックスに「Systems Manager」と入力し、サービスの候補をクリックして開きます。

まずフリートマネージャーで「マネージドノード」を開き、対象インスタンスの Ping ステータスが「オンライン」になっていることを確認します。ここに出ていないインスタンスは Run Command のターゲットに選べません。

Systems Manager の Run Command で「コマンドの実行」を開き、コマンドドキュメントから AWS-ConfigureAWSPackage を選びます。検索は Enter を押さないと絞り込まれません。
「コマンドのパラメータ」で入力するのは Name だけで、AmazonCloudWatchAgent と指定します。ほかは既定のままです。

「ターゲット」では「インスタンスを手動で選択する」を選び、対象インスタンスにチェックを入れます。「出力オプション」の「S3 バケットへの書き込みを有効化する」は既定でオンなので、使わないならチェックを外して進めます。画面最下部の「実行」をクリックします。
右上の更新ボタンでステータスを取り直します。「成功」になれば完了です。

設定をパラメータストアに登録する
Systems Manager のパラメータストアで「パラメータを作成」を開きます。名前に AmazonCloudWatch-linux-mem を入力します。

登録する設定は次の JSON です。
{
"agent": {
"metrics_collection_interval": 60,
"run_as_user": "cwagent"
},
"metrics": {
"namespace": "CWAgent",
"append_dimensions": {
"InstanceId": "${aws:InstanceId}"
},
"metrics_collected": {
"mem": {
"measurement": [
"mem_used_percent",
"mem_available_percent"
]
}
}
}
}
metrics_collected に書いた項目がそのままメトリクスになります。カスタムメトリクスは 1 個ごとの月額課金なので必要なものだけを指定します。append_dimensions は InstanceId だけにしました。InstanceType も含めるとインスタンスタイプを変更したときに項目が分かれ、変更前後のグラフが途切れて見えます。run_as_user の cwagent ユーザーは先ほどのインストールで作られています。
タイプは「文字列」、データ型は text のままにします。値の欄にこの JSON を貼り付けます。入力欄は数行しか表示されませんが、上限は 4096 文字なので今回の設定は収まります。

作成後の詳細画面で、種類が String、データ型が text、バージョンが 1 になっていることを確認します。

設定を適用してエージェントを起動する
もう一度 Run Command の「コマンドの実行」を開きます。検索ボックスに AmazonCloudWatch-ManageAgent を入力して Enter を押します。
入力するのは Optional Configuration Location だけで、先ほど作ったパラメータ名を指定します。Action は configure、Mode は ec2 が既定です。Optional Configuration Source の ssm、Optional Restart の yes も画面の既定値です。 再起動できない状況でしたら Optional Restart はnoに変更してください。

ターゲットの選び方と出力オプションはインストールのときと同じです。実行すると 1 秒ほどで成功します。

メモリ使用率のメトリクスを CloudWatch から確認する
CloudWatch も検索ボックスから開きます。「CloudWatch」と入力し、サービスの候補をクリックします。

メトリクスで「すべてのメトリクス」を開き、「参照」タブを見ると、カスタム名前空間に CWAgent が現れます。カードの数字は CWAgent 名前空間に属するメトリクスの合計で、他のインスタンスの設定分も含みます。今回のアカウントには別の設定が残っていたため 99 と表示されました。

そのため今回作られたメトリクスを確認したいときはインスタンス ID で絞ります。CWAgent を開き、フィルターに対象のインスタンス ID を指定すると、mem_used_percent と mem_available_percent の 2 行が残ります。

2 行にチェックを入れるとグラフで確認できます。「グラフ化したメトリクス」タブの「期間」は既定で 5 分です。60 秒間隔で集めた値が 5 分ごとの平均にまとめられるため、以降のグラフは期間を 1 分に変更しています。表示期間 1 時間のグラフでは、上の線が mem_available_percent、下の線が mem_used_percent です。メモリ使用率は 13% 台、空きが 77% 台で落ち着いていました。

【任意】 動作確認のために負荷をかける
ここまでで設定は完了です。ここから先は設定手順ではありません。取得したメトリクスが実際のメモリの状態を反映しているかを確かめる動作確認なので、値の妥当性を見ておきたい場合に実施してください。
Run Command で AWS-RunShellScript を選び、次のスクリプトを実行しました。stress-ng の導入も同じスクリプトに含めています。
#!/bin/bash
apt-get -o DPkg::Lock::Timeout=180 update
apt-get -o DPkg::Lock::Timeout=180 install -y stress-ng
stress-ng --vm 1 --vm-bytes 1300M --vm-keep --timeout 360s
--vm-bytes 1300M は確保するメモリの量です。t3.small で OS から見えるメモリ約 1.9 GiB の 70% にあたります。
結果の程はというとグラフでは 22:06 過ぎに 2 本の線が入れ替わり、負荷が終わる 22:13 過ぎに元へ戻りました。

1 分ごとの値から負荷前、負荷中のピーク、負荷後を抜き出しました。
| 区間 | 時刻 | mem_used_percent | mem_available_percent | 合計 |
|---|---|---|---|---|
| 負荷前 | 22:06 | 13.486 | 77.536 | 91.02 |
| 負荷中のピーク | 22:09 | 81.729 | 9.644 | 91.37 |
| 負荷後 | 22:17 | 12.009 | 79.378 | 91.39 |
2 つを足しても 100% にはならず、負荷の有無にかかわらず合計は 91% 前後のままでした。mem_used_percent はキャッシュとバッファを使用量に含めない計算です。
Used memory = Total Memory - Free Memory - Cached memory - Buffer memory
一方 mem_available_percent は、スワップを使わずプロセスへ即座に渡せるメモリの割合で回収できるキャッシュを含んでいます。なので、指標と定義の違いがあります。
メモリが逼迫しているかを判断するなら mem_available_percent のほうが読み違えにくいです。キャッシュに左右されず、あとどれだけプロセスへ渡せるかを示すためです。
おわりに
ワークステーションからの移行先だったり、ワークステーションの調達に時間がかかり、移行先としてクラウドを検討するご相談が続き対応していました。EC2 をワークステーションとして使えるか確かめるとき、メモリ使用率が取れていないとサイジングの判断ができません。最低限の下地として取得方法を AWS 初学者向けに案内したくてまとめました。
EC2 のコンソールから設定する方法はこちらで紹介されています。






