プライベート環境のEC2からCloudWatch エージェントでログを収集したい

## はじめに
[アイレット株式会社 22新卒 Advent Calendar 2022](https://qiita.com/advent-calendar/2022/iret-22)に投稿される10日目の記事になります。

https://qiita.com/advent-calendar/2022/iret-22

本記事はプライベートサブネット内のEC2にCloudWatchエージェントを導入し、Windowsイベントログの収集を行う方法についてまとめたものです。

背景として、2023年6月28日までにAWSサービスへの通信で利用されるTLSバージョンの最小要件が 1.2 になるのに伴い、TLS1.1の通信を一部行っていたCloudWatch Logs エージェントをCloudWatch エージェントに移行することになり、新人のエンジニアとしては少し苦労したのでその際に調べた方法についてまとめました。

## 構成
今回の構成は以下の通りです。
VPC Endpointを使用し、CloudWatchにログを送信します。
EC2はMicrosoft Windows Server 2016 BaseのAMIを使用しています。
![スクリーンショット 2022-12-05 4.23.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2959129/4e6836f2-0c9c-07ff-8ead-1f6f247de81b.png)


## EC2インスタンスに権限を付与
Agentをインストールする前にEC2インスタンスにCloudWatchとSystem Managerを使用する権限を付与する必要があるため、下記のポリシーを付与した2つのロールを作成します。
|No|ロール名(任意)|許可ポリシー|備考|
| --- | --- | --- | --- |
|1|CloudWatchAgentServerRole|CloudWatchAgentServerPolicy|CloudWatchへの書き込み権限|
|2|CloudWatchAgentAdminRole|CloudWatchAgentAdminPolicy <br> AmazonSSMManagedInstanceCore|CloudWatch エージェントのインストールや設定に必要な権限|

作成後、No.2のロールをインスタンスにアタッチします。

## エンドポイントを作成
プライベートサブネット内からCloudWatchへメトリクスやログを送信する場合、そのままだと送信ができないためVPCに下記のエンドポイントを設定する必要があります。
なお、ログだけの収集でもmonitoringのエンドポイントは必要になります

1. com.amazonaws.ap-northeast-1.logs
2. com.amazonaws.ap-northeast-1.monitoring

### エンドポイントポリシー
VPCエンドポイントのアクセス制御のためにエンドポイントポリシーを設定します。
本記事ではAWSの公式ドキュメントを参考に設定します。
#### com.amazonaws.ap-northeast-1.logs
```
{
  "Statement": [
    {
      "Sid": "PutOnly",
      "Principal": "*",
      "Action": [
        "cloudwatch:PutMetricData"
      ],
      "Effect": "Allow",
      "Resource": "*"
    }
  ]
}
```
参考：https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/cloudwatch-and-interface-VPC.html
#### com.amazonaws.ap-northeast-1.monitoring
```
{
  "Statement": [
    {
      "Sid": "PutOnly",
      "Principal": "*",
      "Action": [
        "logs:CreateLogStream",
        "logs:PutLogEvents"
      ],
      "Effect": "Allow",
      "Resource": "*"
    }
  ]
}
```
参考：https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/logs/cloudwatch-logs-and-interface-VPC.html

### セキュリティグループ
エンドポイントポリシーとは別にvpcからのアクセスをセキュリティグループで許可します。
|プロトコル|ソース|
| --- | --- |
|HTTPS|VPCのCIDR|

## SSM Agent のバージョン確認
CloudWatch エージェントを使用するにはバージョン 2.2.93.0 以降のSSM Agentが必要なため、インストールもしくはアップデートを行います。
要件を満たしている場合は特に何もしなくて大丈夫です。
### インストール
インスタンスにRDPで接続を行い、PowerShellで下記のコマンドを実行し、インストールを行います。
```
$progressPreference = 'silentlyContinue'
Invoke-WebRequest `
    https://s3.amazonaws.com/ec2-downloads-windows/SSMAgent/latest/windows_amd64/AmazonSSMAgentSetup.exe `
    -OutFile $env:USERPROFILE\Desktop\SSMAgent_latest.exe
```
### アップデート
1. AWSコンソールにログイン

2. Systems Manager → Run Command → Run Command をクリック

3. コマンドのドキュメントから「AWS-UpdateSSMAgent」を選択

4. ドキュメントのバージョンを「ランタイムの最新バージョン」を選択

5. ターゲットから対象のインスタンスを選択

6. 実行 をクリック

コマンド実行画面に遷移し、しばらくするとステータスが 成功 に変わりアップデートが完了します。

### バージョン確認
下記のコマンドをPowerShellで実行し、要件を満たしていたらOKです。
```
& "C:\Program Files\Amazon\SSM\amazon-ssm-agent.exe" -version
```

## CloudWatch エージェントをインストール
1. AWSコンソールにログイン

2. Systems Manager → Run Command → Run Command をクリック

3. コマンドのドキュメントから AWS-ConfigureAWSPackage を選択

3. ドキュメントのバージョンを ランタイムの最新バージョン を選択

3. コマンドのパラメータ の Name に AmazonCloudWatchAgent と入力

4. ターゲットから対象のインスタンスを選択

5. 実行 をクリック

コマンド実行画面に遷移し、しばらくするとステータスが 成功 に変わりインストールが完了します。

## 設定ファイル作成
ウィザードを使用し、cloud エージェントの設定ファイルを作成します。
インスタンスにRDPで接続を行い、コマンドプロントで下記のコマンドを実行し、ウィザードを実行します。
```
cd "C:\Program Files\Amazon\AmazonCloudWatchAgent"
amazon-cloudwatch-agent-config-wizard.exe
```
ウィザードが実行されたら対話形式で設定を行い、作成した設定ファイルをパラメータストアに保存します。

1.エージェントを使用するOS
```
On which OS are you planning to use the agent?
1. linux
2. windows
3. darwin
default choice: [2]:
2
```
2.EC2かオンプレミスのホストを使用しているか
```
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
```
3.StatsDデーモンを有効にするか
 StatsDを有効にすると、アプリケーションやサービスから追加のカスタムメトリクスを取得できます。
```
Do you want to turn on StatsD daemon?
1. yes
2. no
default choice: [1]:
2
```
4.インポートする既存のCloudWatch Log Agentの設定ファイルはあるか
CloudWatch Log Agentの設定ファイルをインポートするとCloudWatch エージェントに同じ設定をすることができます。
```
Do you have any existing CloudWatch Log Agent configuration file to import for migration?
1. yes
2. no
default choice: [2]:
2
```
5.ホストのメトリクスを監視するか
```
Do you want to monitor any host metrics? e.g. CPU, memory, etc.
1. yes
2. no
default choice: [1]:
2
```
6.カスタマイズされたログファイルを監視するか
```
Do you want to monitor any customized log files?
1. yes
2. no
default choice: [1]:
2
```
7.Windowsのイベントログを監視するか
```
Do you want to monitor any Windows event log?
1. yes
2. no
default choice: [1]:
1
```
8.監視するイベント名
イベント名は下記の手順からFull Nameを入力します
イベントビューア― → 収集するイベントログを右クリック → プロパティ → Full Name
```
Windows event log name:
default choice: [System]
Microsoft-Windows-TerminalServices-LocalSessionManager/Operational
```
9.監視するイベントレベル
イベントレベル詳細
|レベル名|レベル ID|イベント ログでの表示|説明|
| --- | --- | --- | --- |
|Critical Error|30|重大|システム管理者がすぐに対処する必要があるイベント。一般的には、システムまたはアプリケーションなど、グローバル (システム全体) レベルで指定されます。また、アプリケーションまたはシステムが、失敗あるいは停止したことを示すこともできます。|
|Error|40|エラー|問題を示すイベント。ただし、このカテゴリのイベントはすぐに対処する必要はありません。|
|Warning|50|警告|潜在的な問題について事前に警告するイベント。実際のエラーに対する応答ではありませんが、コンポーネントまたはアプリケーションが理想的な状態ではないこと、また、さらなるアクションを実行すると重大なエラーにつながる可能性があることを警告します。|
|Information|80|情報|重大ではない情報を管理者に提供するイベント。"参考までに" というメモと同様の役割を果たします。|
|Verbose|100|情報|進行状況または成功のメッセージなど、状態に関する詳細情報です。|

参照：https://learn.microsoft.com/ja-jp/previous-versions/office/developer/sharepoint-2010/ff604025(v=office.14)
```
Do you want to monitor VERBOSE level events for Windows event log Microsoft-Windows-TerminalServices-LocalSessionManager/Operational ?
1. yes
2. no
default choice: [1]:
2
Do you want to monitor INFORMATION level events for Windows event log Microsoft-Windows-TerminalServices-LocalSessionManager/Operational ?
1. yes
2. no
default choice: [1]:
1
Do you want to monitor WARNING level events for Windows event log Microsoft-Windows-TerminalServices-LocalSessionManager/Operational ?
1. yes
2. no
default choice: [1]:
1
Do you want to monitor ERROR level events for Windows event log Microsoft-Windows-TerminalServices-LocalSessionManager/Operational ?
1. yes
2. no
default choice: [1]:
1
Do you want to monitor CRITICAL level events for Windows event log Microsoft-Windows-TerminalServices-LocalSessionManager/Operational ?
1. yes
2. no
default choice: [1]:
2

```
10.CloudWatch Logs に表示されるロググループ名
```
Log group name:
default choice: [Microsoft-Windows-TerminalServices-LocalSessionManager/Operational]
```
11. CloudWatch Logs に表示されるログストリーム名
```
Log stream name:
default choice: [{instance_id}]
```
12.CloudWatch Logsに保存する形式
```
In which format do you want to store windows event to CloudWatch Logs?
1. XML: XML format in Windows Event Viewer
2. Plain Text: Legacy CloudWatch Windows Agent (SSM Plugin) Format
default choice: [1]:
2
```
12.ロググループを保存する日にち
-1に関しては無制限での保存になります。
```
Log Group Retention in days
1. -1
2. 1
3. 3
4. 5
5. 7
6. 14
7. 30
8. 60
9. 90
10. 120
11. 150
12. 180
13. 365
14. 400
15. 545
16. 731
17. 1827
18. 2192
19. 2557
20. 2922
21. 3288
22. 3653
default choice: [1]:
2
```
13.監視するWindowsイベントログを追加で指定するか
```
Do you want to specify any additional Windows event log to monitor?
1. yes
2. no
default choice: [1]:
2
```
14.この内容でSSMパラメータストアに保存するか
必要であれば手動で編集してください。
```
Saved config file to config.json successfully.
Current config as follows:
{
        "logs": {
                "logs_collected": {
                        "windows_events": {
                                "collect_list": [
                                        {
                                                "event_format": "text",
                                                "event_levels": [
                                                        "INFORMATION",
                                                        "WARNING",
                                                        "ERROR"
                                                ],
                                                "event_name": "Microsoft-Windows-TerminalServices-LocalSessionManager/Operational",
                                                "log_group_name": "Microsoft-Windows-TerminalServices-LocalSessionManager/Operational",
                                                "log_stream_name": "{instance_id}",
                                                "retention_in_days": 1
                                        }
                                ]
                        }
                }
        }
}
Please check the above content of the config.
The config file is also located at 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
```
15.設定を保存するパラメータストア名を指定
```
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-windows]
```
16.保存するリージョン
```
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]
```
17.パラメータストアに送信するために必要なクレデンシャル
```
Which AWS credential should be used to send json config to parameter store?
1. XXXXXXXXXXXXX(From SDK)
2. Other
default choice: [1]:
1
```

## EC2インスタンスへ適用
1. AWSコンソールにログイン

2. Systems Manager → Run Command → Run Command をクリック

3. コマンドのドキュメントから AmazonCloudWatch-ManageAgent を選択

4. コマンドのパラメータ の Optional Configuration Location にパラメータストアに格納したパラメータストア名を入力

4. ターゲットから対象のインスタンスを選択

5. 実行 をクリック

コマンド実行画面に遷移し、しばらくするとステータスが 成功 に変わり適用が完了します。

## 確認
AWSコンソールの CloudWatch → ロググループから設定したログが取得されていることを確認できたら設定の完了になります。
また、現在インスタンスにアタッチしているロールだと設定完了後は必要ない権限が含まれているので、同時に作成したNo.1のロールに変更してください。

## おわりに
調べている時はいろいろなドキュメントや記事を苦労して漁っていましたが、
こうしてまとめてみるとそんなに難しいことはやってなかったかなという印象でした。

また、記事をまとめているうちに内容の理解が深まったので、今後もこうしたアウトプットをしていきたいなと思いました！