S3 に新規バケットが作成されたら教えてほしい！ - AWS CloudTrail, Amazon CloudWatch による S3 バケットの構成管理 -

# はじめに

本記事は `プロもくチャット Adevent Calendar 2023` の 22 日目です！！

https://qiita.com/advent-calendar/2023/puromoku


# この記事のゴール
- `AWS S3` に新規バケットが作成された時、通知を受け取ることができるようになります。
- `AWS CloudTrail` により証跡情報を監視することができるようになります。
- `Amazon CloudWatch` でカスタムメトリクスを作成できるようになります。
- `Amazon CloudWatch Alerm` を作成できるようになります。


# 背景

AWS のリソースを扱うハンズオンを実施していると、いつの間にか S3 バケットが作成されていることがあり、後々「何のためのバケットなのかわからなくなる」という事態に直面しました。
これを回避するため、S3 バケットが新規作成されたら僕のメールアドレスに通知されるようにしたいと考えた次第です。
なお、通知を受け取るだけでは根本的な回避策にはならないため、今後実装を深掘りしたいと考えています。（「今後の展望」を参照のこと）


# 前提条件
- 利用端末 : `MacBook Air` `Apple M1` `macOS Sonoma 14.2`
- AWS アカウントにて、 IAM ユーザーを作成済み

::: note info
もしまだ IAM ユーザーを作成されていない方は、こちらの記事を参照ください（宣伝🙄）
[Notion の利用情報を Slack に定期送信したいんだ！ - AWS CDK, Amazon EventBridge, AWS Lambda でつくるバッチ処理アプリケーション -](https://qiita.com/ko-uema2/items/79de6452dc764da04078)
:::


# やることサマリ
1. `AWS CloudTrail` にて AWS アカウントのアクティビティを監視する証跡を作成
2. 証跡情報を記録するロググループにて、S3 バケットの作成イベントを監視するカスタムメトリクスを作成
3. カスタムメトリクスをもとに SNS トピックをトリガーする `CloudWatch Alerm` を作成
4. 動作確認


# 手順詳細


## 1. `AWS CloudTrail` にて AWS アカウントのアクティビティを監視する証跡を作成


公式ドキュメントはこちら。

https://docs.aws.amazon.com/ja_jp/awscloudtrail/latest/userguide/cloudtrail-create-a-trail-using-the-console-first-time.html

**1. 「証跡」をクリック**
今回は東京リージョンで作成します。

![スクリーンショット 2023-12-18 21.02.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3332694/10248937-1890-9a96-78ba-d801d3f47b28.png)

**2. 「証跡の作成」をクリック**

![スクリーンショット 2023-12-18 21.12.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3332694/25b01e47-c4a0-5537-aaa8-a07c9ab2405f.png)

**3. 「証跡名」を入力**

![スクリーンショット 2023-12-18 21.14.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3332694/8956b3ce-44fa-ce5a-0e2c-c53550eef214.png)

今回、チェックボックス「組織内のすべてのアカウントについて有効化」は選択しません。
複数の AWS アカウントを横断して証跡情報を監視したいわけではないので。

**4. 証跡ログを保存するバケットを選択**

![スクリーンショット 2023-12-18 21.18.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3332694/b448dc85-7247-87cd-2953-c5eba542b488.png)

今回は本記事のためのバケットを新規作成しました。
もちろん、既存の S3 バケットを使用することもできます。
ただ、既存のバケットを使用する場合、当該バケットのバケットポリシーを編集して、`AWS CloudTrail` のアクセスを許可する必要があると思います。

そのため、変に躓きたくなければ新しくバケットを作成してしまうのが無難かと思います。

*僕の勘違いだったらすみません。。*
*多分ここで一回躓いたので、合っていると思うのですが。*
*指摘等ございましたらコメント頂けますと幸いです。*

**5. ログファイルの暗号化を設定**

![スクリーンショット 2023-12-18 21.28.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3332694/2a7d8d30-3a7e-4d36-d401-ed96c098de65.png)

S3 バケットに保存されるログファイルの暗号化設定を指定します。
今回は暗号化を有効に設定しました。
その場合は暗号化に利用する KMS キーを指定する必要があります。
今回は本記事のために「cloudtrail-logs-qiita-tutorial」というキーを新規作成するようにしています。
もちろん、既存の KMS キーを指定することも可能です。
ただ、S3 バケットと同様に、`AWS CloudTrail` が KMS キーを利用できるようキーポリシーを編集する必要があると思います。

そのため、変に躓きたくなければ新しく KMS キーをさくs..(省略)


**6. `AWS CloudWatch Logs` の指定**

![スクリーンショット 2023-12-18 21.37.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3332694/a8efc322-9155-8a22-307c-e560f0241b88.png)

チェックボックス「有効」を選択し、`CloudWatch Logs` を有効にします。


**7. 本証跡のために利用するロググループを設定**

![スクリーンショット 2023-12-18 21.43.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3332694/95c0dbe7-dd99-c211-88e0-6fa9351f41a2.png)


本証跡でキャプチャされた情報を記録するロググループを指定します。
今回は「aws-cloudtrail-logs-qiita-tutorial」という新規ロググループを指定しました。
もちろん、既存のロググループを指定することもできます。

*今回は既存のロググループでも躓くことはないと思っているのですが、試してはいません*🫣
*なお、許可設定はこの後の IAM ロール設定で実施するため、そこで躓く可能性があるのではないかと考えています。*



**8. `AWS CloudTrail` にアタッチする IAM ロールを設定**

![スクリーンショット 2023-12-19 17.46.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3332694/295b2d88-fd5d-ab34-18d4-dd870774b2aa.png)

ここでも既存の IAM ロールを使用することができます。
ただ、信頼ポリシーと IAM ポリシーが適切に設定されていることを確認する必要があります。

そのため、変に躓きたくなけれb..(省略)


**9. ベージ最下部の「次へ」をクリック**


**10. 監視するログイベントを選択**

![スクリーンショット 2023-12-19 17.51.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3332694/c33efd11-b380-c957-55f7-fbb689a6132e.png)

S3 バケットの新規作成イベントを監視するためには、「管理イベント」を選択する必要があります。
今回は当該イベント監視専用の証跡を作成する想定で、「管理イベント」のみ選択しました。


**11. 記録する API アクティビティを選択**

![スクリーンショット 2023-12-19 17.57.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3332694/36d4b259-c47c-42b2-c9b5-c095d177cd6e.png)

S3 バケットの新規作成イベントを監視するためには、「書き込み」を選択する必要があります。
(S3 バケットの新規作成が「書き込み」イベントであることは後々確認できます！）
なお、 `AWS KMS` イベント、`Amazon RDS` イベントは今回必要ないので除外設定を選択しました。

::: note info
`AWS CloudTrail` によって記録される `Amazon S3` のバケットレベルのイベントはこちらを参照。
[CloudTrail ログ記録によって追跡される Amazon S3 バケットレベルのアクション](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/cloudtrail-logging-s3-info.html)
:::


**12. ページ最下部にて「次へ」をクリック**


**13. 確認画面にて「証跡の作成」をクリック**


## 2. 証跡情報を記録するロググループにて、S3 バケットの作成イベントを監視するカスタムメトリクスを作成

**1. `Amazon CloudWatch` にて「ロググループ」をクリック**

![スクリーンショット 2023-12-20 20.28.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3332694/32d621cd-c803-8a8b-ffc7-8210ad296c47.png)

**2. 今回作成したロググループ「aws-cloudtrail-logs-qiita-tutorial」をクリック**

**3. 画面右上の「アクション」ボタンから、「メトリクスフィルターを作成」をクリック**

![スクリーンショット 2023-12-20 20.32.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3332694/a4696370-f076-f505-9d23-fe789b8536bc.png)

**4. 「フィルターパターン」に下記パターンを入力**
```bash
{ ($.eventName = "CreateBucket") }
```

フィルターパターンで利用できる構文は下記公式ドキュメントを参照。

https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/FilterAndPatternSyntax.html

:::note info
上記構文は「Match terms in JSON log events using simple expressions」の項目を参照。
:::

**5. ページ下部にある「Next」をクリック。**

![スクリーンショット 2023-12-20 20.49.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3332694/f070f7c4-450a-770b-7712-86fefcb6d925.png)

*ここだけいきなり英語なんですよね笑*
*毎回こうなります*🫢

**6. フィルター名を入力**

![スクリーンショット 2023-12-20 20.57.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3332694/05fdcfff-c299-b5cf-b410-942e43c845a7.png)


**7. メトリクスの詳細情報を設定**

設定項目の情報はこちらの公式ドキュメントを参照

https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/cloudwatch_concepts.html

![スクリーンショット 2023-12-20 20.59.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3332694/c3008f53-d174-be97-e8ab-98ce6d044f4d.png)

- **メトリクス名前空間**
  メトリクスを分類する名称？という認識です。
  *正直、あまり詳しく理解していないです。。*
  
- **メトリクス名**
  本メトリクス単体を識別する名称？という認識です。
  *正直、こちらもあまり理解していないです。。。*
- **メトリクス値**
  フィルターパターンによって監視しているアクション（今回は S3 バケットの新規作成）が発生した際にメトリクスへ配信される数値です。
  今回「1」を設定したため、S3 バケットが新規作成されるために1ずつインクリメントされることになります。
- **デフォルト値（オプション）**
  フィルターパターンによって監視しているアクションが発生していない時にメトリクスへ配信される数値です。
- **Unit(オプション）**
  「メトリクス値」「デフォルト値」の単位です。
  今回は「カウント」を設定しました。

*上記、さも理解しているように記載しましたが、正直あまり自信がありません*😮‍💨
*ぜひコメント等でご指摘いただけますと幸いです。*
*色々とカスタムメトリクスを作成しだすと、この項目の恩恵を理解ですんですかね〜*

**8. ページ下部の「Next」をクリック**

![スクリーンショット 2023-12-20 21.16.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3332694/f3bc559c-4f63-886a-c251-22fe44fbd95f.png)

**9. 設定した内容を確認し、「メトリクスフィルターを作成」をクリック**

![スクリーンショット 2023-12-20 21.17.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3332694/e737a0df-37ac-3597-3917-1571431b95c5.png)

## (補足) S3 バケットの新規作成イベントを確認する

S3 バケットの新規作成イベントの詳細情報を `AWS CloudTrail`　で確認してみようと思います。

**1. `Amazon S3` にて適当なバケットを作成**

**2. `AWS CloudTrail`にて「イベント履歴」をクリック**

![スクリーンショット 2023-12-21 20.42.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3332694/e8331371-68b7-5ffd-c738-dedd7874a9c1.png)

**3. 「CreateBucket」をクリック**

![スクリーンショット 2023-12-21 20.45.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3332694/c7560144-2e80-a598-cfce-2299947ceb42.png)

**4. 表示された詳細画面にて、イベントレコードを確認**

表示されている内容を抜粋したものを以下に示します。
```json
{
    "eventVersion": "1.09",
    "userIdentity": {
        "type": "IAMUser",
        "principalId": "hogehoge",
        "arn": "hogehoge",
        "accountId": "hogehoge",
        "accessKeyId": "hogehoge",
        "userName": "hogehoge",
        "sessionContext": {
            "attributes": {
                "creationDate": "2023-12-21T11:30:05Z",
                "mfaAuthenticated": "true"
            }
        }
    },
    "eventTime": "2023-12-21T11:35:14Z",
    "eventSource": "s3.amazonaws.com",
    "eventName": "CreateBucket",
    "awsRegion": "ap-northeast-1",
    "sourceIPAddress": "hogehoge",

    // 中略
     
    "readOnly": false,
    "eventType": "AwsApiCall",
    "managementEvent": true,
    "recipientAccountId": "hogehoge",
    "vpcEndpointId": "hogehoge",
    "eventCategory": "Management",

    // 省略
}
```

すべて記載するとセキュリティ面で良くないかと思い、省略等行なっています。

確認していただきたいのは下記 3 箇所です。
```json
    "eventName": "CreateBucket"
    "readOnly": false
    "managementEvent": true
```
`CreateBuket`というイベントが、「管理イベント」かつ「書き込み」であることを読み取ることができます。


## 3. カスタムメトリクスをもとに SNS トピックをトリガーする `CloudWatch Alerm` を作成

**1. 作成したロググループにて、「メトリクスフィルター」タグをクリック**

![スクリーンショット 2023-12-21 21.23.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3332694/90e691cc-e367-5cd3-1c11-0a0e7d22ce27.png)

**2. 今回作成したカスタムメトリクスをクリックし選択**

![スクリーンショット 2023-12-21 21.24.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3332694/65e93867-d7ef-f080-4e19-37ebe54c9f43.png)

**3. 「アラームの作成」をクリック**

![スクリーンショット 2023-12-21 21.27.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3332694/c202da57-56c9-2ab4-3573-c9a2c229384e.png)


**4. 「統計」と「期間」を設定**

![スクリーンショット 2023-12-23 9.34.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3332694/5fb67fe6-a41f-af5c-85d6-d72bf01774ca.png)

収集したい統計情報の種別と期間を設定します。
今回は「合計」「1分」に設定しました。

*バケットが新規作成される度に本アラームを「アラーム状態」にしたいのですが、ベストな方法がわかりませんでした*

**5. 「条件」を指定**

![スクリーンショット 2023-12-23 9.39.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3332694/3e3af8e9-71f3-bf9d-4a39-fffe093921f2.png)

現在、デフォルト値は「0」、S3 バケットが作成されると1ずつインクリメントされるようにメトリクスを設定しているため、メトリクス値が「0」以上になった時に本アラームが「アラーム状態」になるよう設定したいと思います。

**6. ページ下部の「次へ」をクリック**

![スクリーンショット 2023-12-25 21.14.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3332694/1152b66f-925b-c22b-87b4-a558df525f6d.png)

**7. 「アラーム状態のトリガー」で「アラーム状態」を選択**

![スクリーンショット 2023-12-25 21.17.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3332694/3ecfb605-dfb6-b91e-d668-b1c2ace3c392.png)

指定したメトリクス条件を満たした際に本アラームが「アラーム状態」となるよう、「アラーム状態」を選択しました。

**8. 本アラームが「アラーム状態」となった際に通知を送る `SNS` トピックを設定**

![スクリーンショット 2023-12-25 21.21.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3332694/5af04e52-c142-97ea-8dc3-352570e56269.png)


今回、すでに僕が利用している既存の `SNS` トピックを指定しました。
まだ用意されていない場合は「新しいトピックの作成」にて新規トピックを作成してください。

::: note info
もし新規トピックを作成した場合、トピックに登録したメールアドレスを認証する必要があります。
トピックを作成し、サブスクリプションにメールアドレスを登録したタイミングで認証用メールが届くなずなので、認証を済ませるようにしましょう。
:::

**9. ページ下部にて「次へ」をクリック**

![スクリーンショット 2023-12-25 21.25.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3332694/c61e402b-fb8f-2a38-df53-c6c44c2c47b3.png)

**10. アラーム名を入力**

![スクリーンショット 2023-12-25 21.27.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3332694/1d8c9437-df27-5410-8c0e-d4a6dc5401a2.png)

**11. ページ下部にて「次へ」をクリック**

![スクリーンショット 2023-12-25 21.25.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3332694/c9555808-a3f3-5f41-531d-e8a639c13992.png)

**12. ページ下部にて「アラームの作成」をクリック**

![スクリーンショット 2023-12-25 21.29.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3332694/e999065d-565d-0917-2ac8-e628cdf591ed.png)


## 4. 動作確認

実際に通知が来るか確認します。
任意のリージョンにて S3 バケットを新規作成してみましょう。

1, 2分後、 `SNS` トピックに登録したメールアドレスに通知が来ることと思います。

なお、`AWS CloudTrail` のコンソール画面で証跡を作成した場合、各種イベントの監視範囲は全リージョンとなるそうです。
つまり、バージニア北部にて　S3 バケットを作成しても、東京リージョンで作成した証跡がそのイベントを監視してくれるということです。


# 今後の展望


上記内容により、「S3 バケットがいつの間にか作成されている」という事態は回避できるようになりました。
ただ、現状新規作成に気づけるようになっただけ、というのが正直なところです。

今後は、「通知メールのボタンをクリックすると、当該バケットにオブジェクトロックをかける」ような処理を実装したいなと考えています！