アクセスキーを使わずオンプレの Mac mini を CloudWatch で監視する

# はじめに
オンプレの Mac mini のリソース監視で Prometheus を使用しており、これを CloudWatch に変更した際の記録。
やる前は「EC2 と同じようにただエージェントを入れてちょこっと設定するだけじゃん。楽勝。」と思っていたのだが、考えてみると「AWS 管理外のサーバーを対象にするなら絶対アクセスキー使うじゃん」という少し嫌な予感がしていた。
ただ AWS はこの辺りもちゃんと対応法を用意してくれていて、さすがだなと嬉しくなったのでシェアさせていただく。

参考にしたのは以下。
※今回は主に Mac OS 特有であったり個人的に気になった部分についてのみ触れるため、その他基本的な部分については以下参照

https://dev.classmethod.jp/articles/tsnote-hybrid-activation-cloudwatch-agent-using-iam-role-001/

# 各種エージェントのインストール
#### CloudWatch エージェントのインストール
```bash
sudo curl -o amazon-cloudwatch-agent.pkg https://amazoncloudwatch-agent-ap-northeast-1.s3.ap-northeast-1.amazonaws.com/darwin/amd64/latest/amazon-cloudwatch-agent.pkg
```

```bash
sudo installer -pkg amazon-cloudwatch-agent.pkg -target /
```

#### SSM エージェントインストール・起動
```bash
sudo curl -o amazon-ssm-agent.pkg https://s3.ap-northeast-1.amazonaws.com/amazon-ssm-ap-northeast-1/latest/darwin_amd64/amazon-ssm-agent.pkg
```

```bash
sudo installer -pkg amazon-ssm-agent.pkg -target /
```

※ AWS の公式ドキュメントでは `wget` を使用してインストールしているが、`wget` が入っていない -> OS のバージョンが古く、`Homebrew` が使えない -> `wget` が入れらないという状況だったので `curl` で実行している。

https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/download-cloudwatch-agent-commandline.html

# ハイブリッドアクティベーションを作成し、Mac Mini をマネージドノードとして登録
Systems Manager のコンソール画面左メニューから「ハイブリッドアクティベーション」を選択し、アクティベーションを作成していく。
基本的には特に入力内容に悩むことはないと思うが、以下スクショ部分について少し補足をすると、「アクティベーションの有効期限」は、オンプレのインスタンスをマネージドノードとして**登録可能な有効期限**を指している。
そのため、これを過ぎたからといって登録済みのインスタンスに何か影響を及ぼすわけではない。
注意書きとしてちゃんと書いてあるが、個人的に少し気になったポイントだったので補足。

![スクリーンショット 2024-12-07 14.53.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1131391/d81394de-f0df-09a6-9b77-fcf697808f34.png)

また、「デフォルトのインスタンス名」については、例えば以下のように Run Command でインスタンスに対し操作をする場合にインスタンスを識別するための名前となる。

![スクリーンショット 2024-12-07 14.50.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1131391/8f9ccd50-53c1-785e-dcd7-3acdaf70ea23.png)

作成が完了するとアクティベーション一覧画面に戻り、画面上部に `Activation Code` と `Activation ID` が表示される。（スクショにあるコードは削除済みのため無効）
これは一度しか表示されないため、必ずどこかに控えておく必要がある。

![スクリーンショット 2024-12-07 14.55.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1131391/213e5eca-5b87-d1ca-7dd5-fc3bbc831cff.png)

あとはこのコードを使用してインスタンスの中でコマンドを実行すると、マネージドノードとして登録される。

```bash
/opt/aws/ssm/bin/amazon-ssm-agent -register -code "<Activation Code>" -id "<Activation ID>" -region "ap-northeast-1"
```

アクティベーションを確認し、「登録済みインスタンス」が1になっていれば無事成功。

![スクリーンショット 2024-12-07 15.46.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1131391/67e1ce57-d344-b91e-0e66-74d596b63c2b.png)

# CloudWatch エージェントの認証設定
CloudWatch エージェントをインストールすると自動で作成される `common-config.toml` を修正する。
おそらく全てコメントアウトされているので、以下部分のコメントアウトを外し、`profile` 名と `credential` ファイルのパスを記載する。
尚、ここで指定する `profile` 名や `credential` ファイルのパスは各自環境に合わせる。
おそらく Mac OS では、SSM エージェントによって生成される認証情報は `/var/root/.aws/credentials` に保管されると思われる。

```bash
[credentials]
   shared_credential_profile = "default"
   shared_credential_file = "/var/root/.aws/credentials"
```

続いて、`config` にリージョンの指定を追記する。

```bash
cat <<EOF > /var/root/.aws/config
[default]
region = ""ap-northeast-1""
EOF
```

これで CloudWatch エージェントを起動する準備 OK。

# 監視内容を設定する
CloudWatch エージェントを起動する前に、何をどのように監視するのかを決める必要がある。
ここでは Parameter Store に JSON で定義し、起動時にそこから設定を読み込む方式がおすすめ。
これは、外部からどのような設定になっているか一目で確認できるため。

まずお作法として、Parameter の名前は `AmazonCloudWatch-` で始める必要がある。
これは、CloudWatch エージェントを使用する際に必要となる IAM ポリシーの `CloudWatchAgentServerPolicy` で以下のように `Resource` を指定しているため。

```json
{
    "Sid": "CWASSMServerPermissions",
    "Effect": "Allow",
    "Action": [
        "ssm:GetParameter"
    ],
    "Resource": "arn:aws:ssm:*:*:parameter/AmazonCloudWatch-*"
}
```

以下ドキュメントにも記載がある。

https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/create-iam-roles-for-cloudwatch-agent.html

続いて Parameter の中身だが、以下のような形式。

```json
{
    "agent": {
        "metrics_collection_interval": 60,
        "run_as_user": "root"
    },
    "metrics": {
        "metrics_collected": {
            "cpu": {
                "measurement": [
                    "usage_iowait",
                    "usage_idle"
                ],
                "metrics_collection_interval": 60,
                "resources": [
                    "*"
                ],
                "totalcpu": true
            },
            "mem": {
                "measurement": [
                    "mem_used_percent"
                ],
                "metrics_collection_interval": 60
            }
        }
    }
}
```

今回はメモリと CPU のみ収集できれば良かったのでかなり簡易的な設定となっている。
disk や Load Average など他にも色々収集したい場合は以下のようになる。（以下は EC2 インスタンスの設定）

```json
{
	"agent": {
		"metrics_collection_interval": 60,
		"run_as_user": "root"
	},
	"metrics": {
		"aggregation_dimensions": [
			[
				"AutoScalingGroupName"
			]
		],
		"append_dimensions": {
			"AutoScalingGroupName": "${aws:AutoScalingGroupName}",
			"InstanceId": "${aws:InstanceId}"
		},
		"metrics_collected": {
			"collectd": {
				"collectd_security_level":"encrypt",
				"collectd_auth_file":"/etc/collectd.d/auth_file",
				"metrics_aggregation_interval": 60
			},
			"cpu": {
				"measurement": [
					"usage_iowait"
				],
				"metrics_collection_interval": 60,
				"resources": [
					"*"
				],
				"totalcpu": true
			},
			"disk": {
				"measurement": [
					"used_percent",
					"inodes_used",
					"inodes_total",
					"inodes_free"
				],
				"metrics_collection_interval": 60,
				"resources": [
					"/"
				]
			},
			"mem": {
				"measurement": [
					"used_percent"
				],
				"metrics_collection_interval": 60
			}
		}
	}
}
```

CloudWatch エージェントによって収集可能なメトリクスは以下参考。

https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/metrics-collected-by-CloudWatch-agent.html

Collectd を使用した Load Average の取得法は以下参考。（CloudWatch エージェントでは Load Average は収集できない）

https://blog.serverworks.co.jp/tech/2020/03/30/collectd/

https://take-engineer.com/cloudwatch-ec2-loadaverage/


Mac OS における Collectd 使用時の注意で参考にしたのは以下。（Collectd のインストールパスの差異）

https://qiita.com/yamada_yuki/items/a24a98d8a5448aafc579#cloudwatchagent%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB

# Run Command によって CloudWatch エージェントを起動する
これは以下ドキュメントの通り実行するだけ。
「Optional Configuration Location」で先ほど作成した Parameter Store の名前を指定してやる。

https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/install-CloudWatch-Agent-on-premise.html#start-CloudWatch-Agent-on-premise-SSM-onprem

余談だが、Run Command は中々便利なもので、サーバーに接続せずとも外からスクリプトを実行したりすることもできる。

https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/walkthrough-cli.html#walkthrough-cli-run-scripts

最後にインストールしたパッケージファイルをお掃除して完了。

```bash
rm amazon-*.pkg
```

以上でオンプレの Mac Mini が CloudWatch で監視できるようになった。
大クラウド時代しか生きていないため、オンプレのサーバーに触るのは初めてだったので良い経験になった。