# AWS CloudTrail と CloudWatch・AWS Config の違いと使い分け（2026年版）：誰が・何を・どう動いているかを正しいサービスで記録する

> CloudTrail（誰が何のAPIを呼んだか=監査）・CloudWatch（メトリクス/ログ/アラーム=性能と運用）・AWS Config（リソース構成と準拠状態）の役割の違い、よくある誤解、組み合わせ方、3者の課金モデル、実装例までを公式ドキュメントに忠実に解説する。1つの変更を3者で追う実例で使い分けを腹落ちさせる。

- 公開日: 2026-06-27
- 著者: 友田 陽大
- タグ: AWS, CloudTrail, CloudWatch, AWS Config, 可観測性, アーキテクチャ設計
- URL: https://tomodahinata.com/blog/aws-cloudtrail-vs-cloudwatch-config-difference-when-to-use-guide
- カテゴリ: AWS CloudTrail 監査・ガバナンス
- 総合ガイド: https://tomodahinata.com/blog/aws-cloudtrail-audit-logging-governance-security-guide

## 要点

- CloudTrail=誰がいつどこから何のAPIを呼んだか（アカウント活動の監査ログ）。性能やメトリクスは測らない
- CloudWatch=システムがどう動いているか（メトリクス・ログ・アラーム・ダッシュボードによる監視と可観測性）
- AWS Config=リソースが今どんな構成で、過去どう変わり、それは準拠しているか（構成項目の履歴と評価）
- 3者は競合でなく補完。1つの変更を CloudTrail（誰が）・Config（どんな構成に）・CloudWatch（どう気づく）で立体的に追える
- 迷ったら用途で選ぶ。監査・誰が→CloudTrail／性能・ログ・アラーム→CloudWatch／構成準拠・ドリフト→Config

---

本番のセキュリティグループが、夜のうちに誰かの手で `0.0.0.0/0` に開けられていた。翌朝それに気づいたとき、あなたは最初にどのサービスのコンソールを開くだろうか。

「誰がやったのか」を知りたいなら CloudTrail。「いま設定はどうなっていて、それは社内ルールに違反しているのか」を知りたいなら AWS Config。「そもそも変更された瞬間に気づくにはどうするか」を考えるなら CloudWatch（と EventBridge）。同じ1つの事故が、3つのサービスにそれぞれ別の角度の証拠を残している。

ここを混同したまま「とりあえず全部 ON にしておけ」とやると、コストは膨らむのに、いざというとき必要な記録がどこにもない、という最悪のパターンに陥る。逆に役割を正しく割り当てれば、監査・可観測性・構成準拠が綺麗に分業し、調査も是正も速くなる。

私はサーバーレス決済基盤（Lambda + DynamoDB）の信頼性レイヤーを設計・主導し、本番二重課金0件を維持してきた。その経験から断言できるのは、「どのサービスに何を記録させるか」という分担設計こそが、障害対応とガバナンスの速度を決めるということだ。本稿は、この3者の違いと使い分けを公式ドキュメントに忠実に、現場で迷わないレベルまで落とし込む決定版ガイドである。

> CloudTrail そのものの全体像（Terraform でのセットアップ、イベント種別、JSON レコードの読み方、整合性検証、セキュリティのベストプラクティス）は、ピラー記事 [CloudTrail 監査ログ・ガバナンス・セキュリティ完全ガイド](/blog/aws-cloudtrail-audit-logging-governance-security-guide) に集約している。本稿は「3者の使い分け」に特化するので、基本設定はそちらを参照してほしい。

## 0. まず3者を一行で固定する（メンタルモデル）

混乱の9割は、この3行を曖昧にしたまま設計に入ることから来る。先に暗記してしまおう。

- **CloudTrail = 誰が・いつ・どこから・何のAPIを呼んだか**（アカウント活動の監査ログ）
- **CloudWatch = システムが今どう動いているか**（メトリクス・ログ・アラーム・ダッシュボードによる監視／可観測性）
- **AWS Config = リソースが今どういう構成で、過去どう変わり、それは準拠しているか**（構成項目のスナップショットと履歴、ルール評価）

公式の一次定義はこうだ。

- AWS Config: 「AWS Config provides a detailed view of the configuration of AWS resources in your AWS account. This includes how the resources are related to one another and how they were configured in the past so that you can see how the configurations and relationships change over time.」（[What Is AWS Config?](https://docs.aws.amazon.com/config/latest/developerguide/WhatIsConfig.html)）
- Amazon CloudWatch: 「Amazon CloudWatch monitors your Amazon Web Services (AWS) resources and the applications you run on AWS in real time, and offers many tools to give you system-wide observability of your application performance, operational health, and resource utilization.」（[What is Amazon CloudWatch?](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/WhatIsCloudWatch.html)）
- AWS CloudTrail: アカウント上の API/非API アクティビティを「イベント」として記録し、運用監査・リスク監査・ガバナンス・コンプライアンスに使う。誰が・いつ・どこから・どの API を呼んだかが残る（[What Is AWS CloudTrail?](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-user-guide.html)）。

### 「監視サービス、どれ使えばいい？」への即答表

知りたいこと → 開くべきサービス、の対応をまず1枚で示す。

| あなたが答えたい問い | 使うサービス |
| --- | --- |
| 誰がこのリソースを変更・削除したのか | CloudTrail |
| いつ・どこ（IP/リージョン）から操作されたのか | CloudTrail |
| この API 呼び出しは成功したのか、拒否されたのか | CloudTrail |
| CPU/メモリ/レイテンシ/エラー率はどう推移しているか | CloudWatch（メトリクス） |
| アプリやサービスのログを検索・集計したい | CloudWatch Logs（Logs Insights） |
| 閾値を超えたら通知・自動対応したい | CloudWatch アラーム |
| このリソースは今どんな構成になっているか | AWS Config |
| この設定は1か月前と比べてどう変わったか | AWS Config（構成履歴タイムライン） |
| 社内ルール/コンプライアンスに準拠しているか | AWS Config Rules / conformance packs |
| リソース同士の依存関係（SG↔EC2↔EBS）を知りたい | AWS Config（relationships） |
| 分散システムのリクエストをトレースしたい | AWS X-Ray |
| VPC のネットワークフローを見たい | VPC Flow Logs |
| 脅威・不審な振る舞いを検知したい | Amazon GuardDuty（CloudTrail 等を入力にする） |

この表が腹落ちすれば、本稿の8割は理解できたと言っていい。残りは「なぜ混同するのか」「組み合わせ方」「コスト」を詰めるだけだ。

表の下のほうに出てくる隣接サービスも、3者との関係で位置づけておくと地図が完成する。**X-Ray** はアプリケーション内のリクエストをエンドツーエンドで追う分散トレーシングで、CloudWatch の可観測性をアプリ層に深掘りするピース。**VPC Flow Logs** は L3/L4 のネットワークフロー（どの IP からどのポートに通信があったか）を記録するもので、CloudTrail の「API 操作」とは別レイヤだ。**GuardDuty** は脅威検知サービスで、CloudTrail のログや VPC Flow Logs、DNS ログを**入力**として不審な振る舞いを見つける――つまり GuardDuty は CloudTrail の上位に乗る分析であって、CloudTrail を置き換えるものではない。このレイヤ感を持っておくと、「どれを入れるか」ではなく「どの層を厚くするか」で考えられるようになる。

もう一段抽象化すると、CloudTrail が見ているのは主にコントロールプレーン（リソースを作る・変える・消すという管理操作。データイベントを有効化すればデータプレーンのアクセスも）、CloudWatch が見ているのはアプリ/インフラのランタイムの振る舞い、Config が見ているのはリソースの構成という静的な状態だ。「操作」「振る舞い」「状態」――この3語で3者を覚えてしまうのが、最も忘れにくい。

## 1. 役割の違いを1枚の表で

3者を同じ軸で並べると、競合ではなく補完だとはっきりわかる。

| 観点 | CloudTrail | CloudWatch | AWS Config |
| --- | --- | --- | --- |
| 一言でいう正体 | アカウント活動の監査ログ | 監視・可観測性プラットフォーム | リソース構成の記録・評価 |
| 答える問い | 誰が何のAPIをしたか | システムがどう動いているか | 今どんな構成で準拠しているか |
| 記録の単位 | イベント（API/非APIアクティビティ） | メトリクス・ログイベント | 構成項目（configuration item） |
| 時間軸 | 操作が起きた瞬間の記録 | 連続的な時系列・ログストリーム | 変更ごとのスナップショット履歴 |
| 主な利用者 | セキュリティ・監査・ガバナンス | SRE・開発・運用 | ガバナンス・コンプライアンス・運用 |
| 典型的な問い合わせ先 | 「このSGを開けたのは誰だ」 | 「レイテンシが上がった原因は」 | 「このSGはルール違反か、いつ変わったか」 |
| 性能（CPU/レイテンシ）を測るか | 測らない | 測る（中核機能） | 測らない |
| 変更の「主体（誰）」を持つか | 持つ（userIdentity） | 基本的に持たない | 構成は持つが「誰が」は持たない |
| 既定の保持・配信 | イベント履歴は90日・管理イベントのみ・無料。継続保存は証跡（Trail）でS3へ | メトリクス/ログは設定した保持期間で課金保存 | S3へ構成履歴を配信、タイムラインを保持 |
| コンプライアンス評価機能 | なし（記録に徹する） | なし（監視に徹する） | あり（Config Rules / conformance packs） |

ポイントは、**3者とも「監査」「ガバナンス」という言葉を自分の文脈で使う**ことだ。CloudTrail の監査は「操作の監査」、Config の監査は「構成の監査」、CloudWatch は監査ではなく「監視」。同じ単語でも指すものが違うので、言葉ではなく「記録の単位」で見分けるのが確実だ。CloudTrail はイベント、CloudWatch はメトリクス/ログ、Config は構成項目。これだけ覚えればまず外さない。

> CloudTrail のイベント履歴（無料・90日・管理イベントのみ・恒久ではない）と、証跡（Trail）による S3 への継続配信の違いは、ピラー記事で詳説している。本稿では「イベント履歴は短期・無料の閲覧窓、継続保存と分析は Trail が前提」とだけ押さえておけば十分だ。

### 「何をしないか」で輪郭を掴む

機能の重なりに惑わされたときは、各サービスが**やらないこと**を確認すると輪郭がはっきりする。設計レビューで「それ、そのサービスの仕事じゃない」と言えるようになるための逆引きだ。

| サービス | やらないこと（これを期待してはいけない） |
| --- | --- |
| CloudTrail | 性能・レイテンシ・エラー率の測定。リソースの「現在の構成」の一覧化。準拠/非準拠の評価。アプリの標準出力ログの収集 |
| CloudWatch | 「誰が操作したか」の特定（主体情報は持たない）。リソース構成の履歴管理。コンプライアンス評価 |
| AWS Config | 「誰がその変更をしたか」の特定（操作主体は CloudTrail 側）。性能メトリクスの測定。アプリログの保管 |

たとえば「Config を入れたから誰が変えたか分かるだろう」は誤解だ。Config は構成項目に「何が変わったか」は残すが、操作の主体（誰が）は持たない。「誰が」を知るには CloudTrail の `userIdentity` が要る。逆に「CloudTrail を入れたから今アカウントに穴がいくつ開いているか棚卸しできる」も誤解で、それは構成の横断クエリができる Config の仕事だ。この「持っている情報の境界」を意識すると、3者を足し算で使う発想に自然と切り替わる。

## 2. なぜ3者を混同するのか

理屈で分けてもなお混ざるのには、はっきりした理由が2つある。ここを言語化しておくと、チーム内の議論が一気に噛み合う。

### 理由1：「ログ」という言葉が3つの別物を指している

「ログを見たい」と言われたとき、それは少なくとも3つの異なるものを指しうる。

- **操作ログ**（誰が何の API を呼んだか）→ CloudTrail
- **アプリ/システムのログ**（標準出力、アクセスログ、Lambda の実行ログ）→ CloudWatch Logs
- **構成の変更ログ**（リソースの設定がどう変わったか）→ AWS Config の構成履歴

「ログ」を主語にした瞬間に会話が空中分解するのは、話者ごとにこの3つのどれかを思い浮かべているからだ。具体例で固定するとこうなる。

| 「ログ」が指しているもの | 具体例 | 正しい置き場所 |
| --- | --- | --- |
| 操作ログ | 「DeleteBucket を呼んだのは誰か」 | CloudTrail |
| アプリ/システムログ | 「Lambda が NullPointerException を吐いた」 | CloudWatch Logs |
| 構成変更ログ | 「この RDS の暗号化設定がいつ変わったか」 | AWS Config 構成履歴 |

設計の打ち合わせでは「操作ログ／アプリログ／構成履歴」と必ず言い分ける。これだけで認識のズレが消え、「どこを見ればいいか」の往復が一気に減る。

### 理由2：CloudTrail を CloudWatch Logs に流せてしまう

最大の混乱源がこれだ。CloudTrail の証跡（Trail）は、配信先として S3 だけでなく **CloudWatch Logs のロググループ**も選べる。つまり「CloudTrail のログが CloudWatch の画面に出てくる」状況が普通に起きる。ここで「じゃあ CloudTrail と CloudWatch は同じものでは？」という誤解が生まれる。

正しい理解はこうだ。**CloudTrail が記録の生産者、CloudWatch Logs はその配信先・分析基盤の1つ**にすぎない。CloudTrail を CloudWatch Logs に流すのは、メトリクスフィルタとアラームで「特定の操作が起きたら即通知する」ためであって、CloudWatch が CloudTrail の役割を兼ねるわけではない。両者は「接点を持つ別サービス」だ。この接点の実装は §4 で具体的に示す。

> 補足：CloudWatch の旧 "CloudWatch Events" は現在 Amazon EventBridge として提供されている。本稿でイベント駆動の検知に触れるときは EventBridge を指す。

### 理由3：3者とも「セキュリティに使える」と紹介される

公式ドキュメントを読むと、CloudTrail も Config も CloudWatch も、それぞれ「セキュリティ分析に役立つ」と書かれている。Config の公式ページにも "Security Analysis" の節があり、過去のIAMポリシーやSGのポート開放状態を遡って調べられると明記されている。この「どれもセキュリティに効く」という説明が、初学者には「じゃあ違いは何？」という疑問を生む。

整理すると、同じセキュリティ目的でも切り口が違う。CloudTrail は「不正な**操作**がなかったか」、Config は「危険な**構成**になっていないか・過去にどんな構成だったか」、CloudWatch は「異常に**気づける**ようにする」。三者はセキュリティという山を別々の登山口から登っているだけで、頂上（安全な運用）は共有している。だから「セキュリティのためにどれを入れるか」は二者択一ではなく、目的の層ごとに重ねるのが正解になる。

## 3. 1つの変更を3者で追う実例

抽象論はここまで。冒頭の事故――「誰かが本番のセキュリティグループを `0.0.0.0/0` に開けた」――を、3者がそれぞれどう記録するかを具体的に見る。これが本稿の核心だ。

問題の操作はこういう Terraform 差分だったとしよう（あるいは誰かがコンソールから手で開けた、でもよい。CloudTrail から見れば同じ `AuthorizeSecurityGroupIngress` API だ）。

```hcl
resource "aws_security_group_rule" "ssh_from_anywhere" {
  type              = "ingress"
  from_port         = 22
  to_port           = 22
  protocol          = "tcp"
  cidr_blocks       = ["0.0.0.0/0"] # 本来は社内CIDRのみのはずだった
  security_group_id = aws_security_group.app.id
}
```

### 3-1. CloudTrail：誰が・いつ・どこから（AuthorizeSecurityGroupIngress）

この操作は EC2 の管理イベント `AuthorizeSecurityGroupIngress` として CloudTrail に残る。`userIdentity` を見れば「誰が」が一意に特定できる。

```json
{
  "eventVersion": "1.09",
  "userIdentity": {
    "type": "AssumedRole",
    "principalId": "AROAEXAMPLEID:alice",
    "arn": "arn:aws:sts::123456789012:assumed-role/Developer/alice",
    "accountId": "123456789012",
    "sessionContext": {
      "attributes": { "mfaAuthenticated": "false" }
    }
  },
  "eventTime": "2026-06-26T18:42:11Z",
  "eventSource": "ec2.amazonaws.com",
  "eventName": "AuthorizeSecurityGroupIngress",
  "awsRegion": "ap-northeast-1",
  "sourceIPAddress": "203.0.113.42",
  "requestParameters": {
    "groupId": "sg-0abc123def4567890",
    "ipPermissions": {
      "items": [
        {
          "ipProtocol": "tcp",
          "fromPort": 22,
          "toPort": 22,
          "ipRanges": { "items": [ { "cidrIp": "0.0.0.0/0" } ] }
        }
      ]
    }
  },
  "responseElements": { "_return": true }
}
```

ここから読めるのは、`Developer` ロールを引き受けた `alice` が、2026-06-26 18:42 UTC に IP `203.0.113.42` から、しかも **MFA なし**で SSH ポートを全開放した、という事実だ。`userIdentity.type` は `AssumedRole`（綴りに注意。`Root` / `IAMUser` / `AssumedRole` / `Role` / `FederatedUser` / `AWSService` / `IdentityCenterUser` が正しい値で、`IAMIdentityCenter` という値は存在しない）。

CloudTrail が答えるのはここまで――**誰が・いつ・どこから・どの API を**。「で、いま SG はどんな状態？」「それはルール違反？」には CloudTrail は答えない。そこは Config の領分だ。

### 3-2. AWS Config：どんな構成になり、それは違反か（構成項目＋ルール評価）

同じ変更を AWS Config は「構成項目（configuration item）」として記録する。Config の構成項目は公式に「a point-in-time view of the various attributes of a supported AWS resource」と定義され、メタデータ・属性・リレーションシップ・現在の構成・関連イベントを含む（[AWS Config terminology and concepts](https://docs.aws.amazon.com/config/latest/developerguide/config-concepts.html)）。

つまり Config には「この SG は今 22番ポートを `0.0.0.0/0` に開けている」という**構成そのもの**が残り、さらに過去の構成項目との差分から**いつその構成に変わったか**がタイムラインで追える。CloudTrail が「操作の点」を記録するのに対し、Config は「構成の状態と、その状態の遷移」を記録する、と捉えるとよい。

そしてここが Config 固有の価値だ。Config Rules を効かせておけば、この構成は自動で「準拠/非準拠（compliant / noncompliant）」と評価される。SSH 全開放を弾く代表的なマネージドルールが `restricted-ssh` だ。Terraform でこう設定する。

```hcl
resource "aws_config_config_rule" "restricted_ssh" {
  name = "restricted-ssh"

  source {
    owner             = "AWS"
    source_identifier = "INCOMING_SSH_DISABLED" # restricted-ssh の識別子
  }

  # 評価対象を SG に限定
  scope {
    compliance_resource_types = ["AWS::EC2::SecurityGroup"]
  }

  depends_on = [aws_config_configuration_recorder.main]
}
```

この状態で誰かが SG を `0.0.0.0/0:22` に開けると、Config はその SG を即座に **NON_COMPLIANT** とマークする。公式の言葉どおり「When AWS Config detects that a resource violates the conditions in one of your rules, AWS Config flags the resource as noncompliant and sends a notification.」という挙動だ。

「いま自分のアカウントで非準拠の SG はどれだけあるか」を棚卸ししたいときは、Config の Advanced Query（SQL 風の構文）で横断的に問い合わせられる。

```sql
SELECT
  resourceId,
  resourceName,
  configuration.ipPermissions
WHERE
  resourceType = 'AWS::EC2::SecurityGroup'
  AND configuration.ipPermissions.ipRanges = '0.0.0.0/0'
```

CloudTrail では「誰が」はわかっても「今アカウント全体でいくつ穴が開いているか」は出せない。これは Config の独壇場だ。

さらに Config はリソース間のリレーションシップを記録する。公式の定義どおり「AWS Config discovers AWS resources in your account and then creates a map of relationships between AWS resources」で、たとえば「この SG はどの EC2 インスタンスにアタッチされているか」が辿れる。つまり「穴が開いた SG が、実際にどの本番インスタンスを露出させているか」という影響範囲（blast radius）まで一気に把握できる。CloudTrail のイベント1件からは決して出てこない情報だ。

そして構成履歴のタイムラインを開けば、「この SG は昨日まで社内 CIDR だけだったが、18:42 に `0.0.0.0/0` を含む構成へ変わった」という状態遷移が時系列で見える。CloudTrail の「操作の点」と、Config の「構成の状態とその遷移」は、こうして突き合わせて初めて完全な物語になる――誰が（CloudTrail）、何時に、どんな構成へ（Config のタイムライン）、どのインスタンスを露出させたか（Config のリレーションシップ）。

### 3-3. CloudWatch / EventBridge：その瞬間にどう気づくか

CloudTrail と Config は「後から追える証拠」だが、事故対応で本当に効くのは「変更された瞬間に気づくこと」だ。ここで CloudWatch（と EventBridge）が登場する。

経路は2つある。

1. **CloudTrail → CloudWatch Logs → メトリクスフィルタ → アラーム**：CloudTrail を CloudWatch Logs に流し、`AuthorizeSecurityGroupIngress` というパターンにマッチしたらカウントを増やすメトリクスフィルタを作り、それが0より大きくなったらアラームで通知する。
2. **EventBridge ルール**：CloudTrail の API コールをイベントソースとして、特定の API 名にマッチしたら直接通知や Lambda を起動する。

CloudWatch 経路の実装は §4 で完全な形を示す。ここで押さえるべきは役割分担だ。**CloudWatch は「気づく（検知・通知・可視化）」を担い、CloudTrail/Config は「証拠を残す」を担う**。同じ事故を、Config は「非準拠」として静的に示し、CloudWatch は「今まさに起きた」と動的に叫ぶ。

ここまでをまとめると、1つの SG 開放という事故に対して3者はこう分業する。

| サービス | この事故に対して残すもの／やること |
| --- | --- |
| CloudTrail | 誰が（alice/Developerロール・MFAなし）・いつ・どのIPから・どのAPIで開けたか |
| AWS Config | SGの新しい構成・restricted-sshルールでの非準拠判定・いつその構成になったかのタイムライン |
| CloudWatch / EventBridge | 開けられた瞬間のメトリクスフィルタ発火とアラーム通知・自動対応のトリガ |

3者を「どれか1つ」で代替しようとすると、必ずこの表のどこかの列が空白になる。だから補完なのだ。

この事故を1本の調査線につなぐと、こう読める。CloudWatch（または EventBridge）が「18:42 に SG が開いた」と**叫び**、CloudTrail が「それは Developer ロールの alice が MFA なしで `203.0.113.42` からやった」と**犯人を指し**、Config が「その SG は今 `restricted-ssh` に非準拠で、本番インスタンス3台を露出させており、昨日まではこの構成ではなかった」と**被害と経緯を語る**。3者がそれぞれの強みを出し合って初めて、「いつ・誰が・何を・どんな構成へ・どれだけの影響で」という事故の全文が揃う。1サービスに寄せた設計では、この文章のどこかが必ず歯抜けになる。

## 4. 組み合わせ設計（検知をどこに置くか）

役割がわかったら、次は実装だ。ここでは「変更を検知する」設計を、CloudTrail を起点に CloudWatch とつなぐ最頻出パターンで示す。

### 4-1. CloudTrail → CloudWatch Logs メトリクスフィルタ + アラーム

まず Trail を CloudWatch Logs のロググループに配信する（S3 配信は前提として別に持っている想定。基本セットアップは[ピラー記事](/blog/aws-cloudtrail-audit-logging-governance-security-guide)を参照）。そのうえでメトリクスフィルタとアラームを張る。

```hcl
# 1) CloudTrail のログを受けるロググループ
resource "aws_cloudwatch_log_group" "trail" {
  name              = "/aws/cloudtrail/security-events"
  retention_in_days = 365
}

# 2) SG 変更を数えるメトリクスフィルタ
#    AuthorizeSecurityGroupIngress / Egress / RevokeSecurityGroup* を拾う
resource "aws_cloudwatch_log_metric_filter" "sg_changes" {
  name           = "security-group-changes"
  log_group_name = aws_cloudwatch_log_group.trail.name

  pattern = <<-PATTERN
    { ($.eventName = AuthorizeSecurityGroupIngress) ||
      ($.eventName = AuthorizeSecurityGroupEgress) ||
      ($.eventName = RevokeSecurityGroupIngress) ||
      ($.eventName = RevokeSecurityGroupEgress) ||
      ($.eventName = CreateSecurityGroup) ||
      ($.eventName = DeleteSecurityGroup) }
  PATTERN

  metric_transformation {
    name          = "SecurityGroupEventCount"
    namespace     = "CloudTrailMetrics"
    value         = "1"
    default_value = "0"
  }
}

# 3) 1件でも起きたら通知するアラーム
resource "aws_cloudwatch_metric_alarm" "sg_changes" {
  alarm_name          = "security-group-changes"
  namespace           = "CloudTrailMetrics"
  metric_name         = "SecurityGroupEventCount"
  statistic           = "Sum"
  period              = 300
  evaluation_periods  = 1
  threshold           = 1
  comparison_operator = "GreaterThanOrEqualToThreshold"
  treat_missing_data  = "notBreaching"
  alarm_actions       = [aws_sns_topic.security_alerts.arn]
}
```

セキュリティグループ変更の検知は、AWS 公式が CloudTrail × CloudWatch のメトリクスフィルタ例として明示的に挙げている3つのうちの1つだ。公式が例示するのは（1）セキュリティグループの変更、（2）コンソールサインインの失敗、（3）IAM ポリシーの変更、の3つである。「root アカウントの使用を検知」といった定番ルールは CIS AWS Foundations Benchmark 由来のもので、AWS のこの基本チュートリアルとは出自が異なる点に注意（混同して「公式が4つ例示している」などと書かないこと）。

つまり同じ仕組みで、`ConsoleLogin` の `errorMessage` が "Failed authentication" のイベントを数えれば総当たりログイン試行を、IAM の `PutGroupPolicy` / `PutUserPolicy` / `AttachRolePolicy` 等を数えれば権限変更を、それぞれアラート化できる。3つとも「特定の管理イベントがロググループに流れてきたら数える→閾値で鳴らす」という同型のパターンであり、SG の例を1つ作れば残りは横展開できる。

そして、アラートを鳴らすほどでもないが後から調べたい、というときに効くのが CloudWatch Logs Insights だ。CloudTrail を流したロググループに対して、こんなクエリで「直近の SG 変更を、誰がやったか付きで」一覧できる。

```sql
fields @timestamp, userIdentity.arn, eventName, requestParameters.groupId
| filter eventSource = "ec2.amazonaws.com"
| filter eventName like /SecurityGroup/
| sort @timestamp desc
| limit 50
```

ここが CloudWatch の真価で、CloudTrail 単体のイベント履歴コンソールよりも柔軟に、SQL/PPL を含む複数のクエリ言語でログを集計・分析できる（公式は Logs Insights を「interactive, fast queries on your log data」と説明）。CloudTrail が「証拠を生む」なら、CloudWatch Logs Insights は「証拠を捌く」道具だ。

### 4-2. CloudTrail → EventBridge（よりイベント駆動に寄せる）

メトリクスフィルタは「集計してから閾値判定」なので、最短でも集計周期ぶんの遅延がある。「特定 API を即トリガにしたい」なら EventBridge ルールの方が素直だ。

```json
{
  "source": ["aws.ec2"],
  "detail-type": ["AWS API Call via CloudTrail"],
  "detail": {
    "eventSource": ["ec2.amazonaws.com"],
    "eventName": ["AuthorizeSecurityGroupIngress"]
  }
}
```

このルールのターゲットに SNS や Lambda を置けば、「SG が開いた瞬間に Slack 通知」「即座に当該ルールを自動 revoke する Lambda を起動」といった対応ができる。EventBridge は CloudWatch ファミリの中で「イベント駆動の検知・自動対応」を担うピースだと位置づけるとよい。

### 4-3. Config Rule + 自動修復（remediation）

検知の最後の選択肢が Config の自動修復だ。Config Rules は「非準拠」を判定するだけでなく、SSM Automation と組み合わせて**自動で是正**できる（公式の Remediation 機能）。SG が `0.0.0.0/0:22` に開いたら自動でそのルールを剥がす、といった運用が可能だ。

検知の3経路を整理しておく。

| 経路 | 反応の速さ | 向いている用途 |
| --- | --- | --- |
| CloudTrail → CloudWatch Logs メトリクスフィルタ + アラーム | 集計周期ぶんの遅延あり | 件数ベースのアラート、ダッシュボード化、既存のCloudWatch運用に統合したい場合 |
| CloudTrail → EventBridge ルール | 速い（イベント駆動） | 特定APIを即トリガに通知/自動対応したい場合 |
| AWS Config Rule + remediation | 評価タイミング依存 | 「準拠/非準拠」という状態で捉えたい、自動是正したい、コンプライアンス報告に使いたい場合 |

「検知はどれを使うべきか」に唯一の正解はない。**速報性が欲しいなら EventBridge、状態と準拠で語りたいなら Config、既存の CloudWatch ダッシュボード/アラーム運用に乗せたいならメトリクスフィルタ**。決済基盤のように「不審な操作には秒で気づき、かつ後から構成の準拠状態も証明したい」ケースでは、EventBridge での即時検知と Config での準拠評価を併用するのが定石だった。

### 4-4. 「割り当て」を設計として固定する

実務で効いたのは、3者の役割を口頭の了解ではなく**設計ドキュメントの分担表**として固定することだった。サーバーレス決済基盤の信頼性レイヤーを設計したときも、監視・監査・準拠の関心事を1つずつ「どのサービスが正本か」を決め切った。たとえば次のような割り当てだ。

- 決済 API（Lambda）の実行ログ・エラー率・実行時間 → **CloudWatch**（メトリクス＋ Logs。ここに「誰が」は要らない、要るのは振る舞い）
- IAM ロール変更・本番リソースの作成削除・MFA なし操作 → **CloudTrail**（誰が・いつ。EventBridge で即時アラート）
- 暗号化必須の S3/DynamoDB、公開してはいけない SG の準拠状態 → **AWS Config**（Config Rules で継続評価、非準拠は通知）

こう割り当てると、新しい監視要件が来たときに「これは振る舞いか／操作か／構成か」を問うだけで、置き場所が一意に決まる。逆に割り当てを曖昧にしたまま「とりあえず CloudWatch に全部」とやると、操作ログと構成履歴を CloudWatch のログ検索で無理やり代用することになり、調査は遅く、課金は無駄に膨らむ。役割分担は、設計の最初に紙に書く価値がある。

## 5. 3者の課金モデルと使い分けの判断

「全部 ON」がなぜ危険か。それは3者の課金軸が全く違うからだ。ここを誤ると、効果の薄いところに金を払い続けることになる。各サービスの**課金の軸（ディメンション）**を正確に押さえる（具体的な単価は地域・時期で変わるので、必ず各 Pricing ページで最新を確認すること。本稿は単価ではなく「何に対して課金されるか」を示す）。

### CloudTrail の課金軸

管理イベント（management events）は、各リージョンで**1コピー目の配信が無料**。同じイベントを複数の証跡に重複配信したり、データイベント（S3 オブジェクトレベル、Lambda 実行など高頻度なもの）や CloudTrail Lake を使うと課金が発生する。さらに配信先 S3 のストレージ料金は別途かかる。要するに「管理イベントを1本の証跡で取るだけ」ならほぼ無料、データイベントを広く取ると一気に効いてくる。

> CloudTrail のコスト最適化（データイベントの絞り方、複数証跡の重複課金回避、Lake の使いどころ）は、姉妹記事 [CloudTrail 料金とコスト最適化ガイド](/blog/aws-cloudtrail-pricing-cost-optimization-guide) で深掘りしている。本稿はあくまで3者の課金軸の比較に留める。

### CloudWatch の課金軸

CloudWatch は監視の各機能ごとに課金軸が分かれている（[Amazon CloudWatch Pricing](https://aws.amazon.com/cloudwatch/pricing/)）。

- **メトリクス**：カスタムメトリクスの数（月あたり）、`PutMetricData`/`GetMetricData` などの API リクエスト
- **ログ**：取り込み量（GB）／保存量（GB・月）／Logs Insights のクエリでスキャンしたデータ量（GB）の3軸
- **アラーム**：アラームメトリクス数（月あたり）。高分解能アラームは追加課金
- **ダッシュボード**：カスタムダッシュボード数（自動ダッシュボードは無料）

無料利用枠もある（基本メトリクス、カスタムメトリクス10、ダッシュボード3、アラームメトリクス10、ログ5GB など）。CloudWatch でコストが膨らむ典型は「ログの取り込み量」だ。verbose なアプリログを全部流し込むと取り込み課金が効くので、ログレベルと保持期間の設計が効く。なお §4 で見たように CloudTrail を CloudWatch Logs に流す構成では、その CloudTrail ログも CloudWatch 側の取り込み・保存課金の対象になる点に注意。「監査ログを長期で安く貯める」のが目的なら CloudTrail から S3 へ、「直近を検索・アラートしたい」のなら CloudWatch Logs へ、と配信先を目的で切り分けると無駄が出にくい。

### AWS Config の課金軸

AWS Config は3つの軸で課金される（[AWS Config Pricing](https://aws.amazon.com/config/pricing/)）。

- **記録した構成項目（configuration item）の数**：リソースが変わるたびに構成項目が記録され、その件数で課金
- **Config Rule の評価回数**：ルールがリソースを評価するたびに課金
- **conformance pack の評価回数**：パック内ルールによる評価回数で課金

加えて、構成履歴の保存先 S3、通知の SNS、カスタムルールの Lambda は標準料金が別途かかる。Config でコストが膨らむ典型は「変更が激しいリソースを記録対象に含めること」と「ルール数が多いこと」だ。記録対象リソースタイプは絞れるので、ガバナンス上重要なものに限定するのが鉄則。

### 課金軸を1枚で

| サービス | 主な課金軸 | コストが膨らむ典型 | 無料/低コストで使える範囲 |
| --- | --- | --- | --- |
| CloudTrail | 管理イベント（1コピー目は無料）／データイベント／Lake／配信先S3 | 高頻度なデータイベントを広く取る | 管理イベントを単一証跡で取得（実質ほぼ無料、S3代のみ） |
| CloudWatch | カスタムメトリクス数／ログ取り込み・保存・クエリ／アラーム数／ダッシュボード数 | verboseなログの大量取り込み | 無料枠（基本メトリクス・少数のアラーム/ダッシュボード・5GBログ） |
| AWS Config | 構成項目の記録数／ルール評価数／conformance pack評価数 | 変更が激しいリソースの記録・大量のルール | 記録対象を重要リソースに限定、ルールを絞る |

判断の指針はシンプルだ。**「誰が何をしたか」を残すのは管理イベント CloudTrail でほぼ無料なので、これは原則オン**。CloudWatch は「測りたいメトリクス／本当に検索するログ」に絞る。Config は「準拠を証明する必要があるリソース」に絞る。全部を最大粒度でオンにするのではなく、目的（監査・可観測性・準拠）ごとに必要な範囲だけ刻むのが、コストと有用性を両立させる唯一の道だ。

## 5-2. よくある疑問への即答

検索で多い質問に、ここまでの内容で短く答えておく。

**Q. CloudTrail だけ入れておけば監視は足りる？**
足りない。CloudTrail は「誰が何の API をしたか」の監査ログであって、CPU・レイテンシ・エラー率といった性能やアプリログは測らない。性能と運用の可視化には CloudWatch が要る。CloudTrail は「監視」ではなく「監査」のサービスだと割り切ること。

**Q. CloudWatch のログに CloudTrail を流したら、Config も要らないのでは？**
別物。CloudWatch に流れる CloudTrail は「操作の記録」であって、「リソースが今どんな構成で、それは準拠しているか」は分からない。準拠評価・構成履歴・リソース間の関係は Config 固有の機能で、CloudWatch では代替できない。

**Q. AWS Config は「誰が変えたか」も教えてくれる？**
教えてくれない。Config は構成項目として「何がどう変わったか」は残すが、操作の主体（誰が）は持たない。「誰が」は CloudTrail の `userIdentity` を突き合わせる必要がある。両者はセットで使って初めて「誰が・どんな構成に変えたか」が完成する。

**Q. コスト的に、最低限まず何を入れるべき？**
管理イベントの CloudTrail（1リージョン1証跡なら実質ほぼ無料、S3 代のみ）と、本当に必要なメトリクス／アラームに絞った CloudWatch。Config は「準拠を証明する必要がある」要件が出てから、対象リソースを絞って入れるのが費用対効果が高い。

**Q. CloudTrail のイベント履歴は90日見られるのに、なぜ証跡（Trail）が要る？**
イベント履歴は「管理イベントのみ・90日・無料の閲覧窓」で、恒久保存ではない。90日を超える保管、データイベントの記録、S3 への継続配信や整合性検証、CloudWatch Logs/EventBridge 連携には証跡（Trail）が前提になる。詳細はピラー記事を参照。

## 6. まとめ：用途別チートシート

最後に、現場で迷ったときに開く1枚を置いておく。問いから逆引きするのがコツだ。

| やりたいこと | 第一選択 | 補足 |
| --- | --- | --- |
| 「誰が」変更・削除したかを知りたい（監査） | CloudTrail | userIdentity で主体を特定。管理イベントは原則オン |
| 操作の証跡を長期保存・分析したい | CloudTrail（証跡→S3 / Lake） | イベント履歴90日は閲覧窓。保存は証跡が前提 |
| 性能・レイテンシ・エラー率を測りたい | CloudWatch（メトリクス） | CloudTrail/Config は性能を測らない |
| アプリ/システムのログを検索・集計したい | CloudWatch Logs（Logs Insights） | 操作ログはCloudTrail、構成履歴はConfig |
| 閾値超えで通知・自動対応したい | CloudWatch アラーム | 件数ベースの検知に向く |
| 特定APIを即トリガに対応したい | EventBridge | CloudTrailを入力に、低遅延で自動対応 |
| リソースが今どんな構成か知りたい | AWS Config | 構成項目のスナップショット |
| 設定がいつどう変わったか追いたい | AWS Config（構成履歴タイムライン） | CloudTrailの「点」に対し状態の遷移 |
| 社内ルール/コンプライアンスへの準拠を判定したい | AWS Config Rules / conformance packs | 非準拠の自動是正も可能 |
| リソースの依存関係を把握したい | AWS Config（relationships） | SG↔EC2↔EBS などのマップ |
| 分散システムのリクエストを追跡したい | AWS X-Ray | アプリ可観測性は別ピース |
| ネットワークフローを見たい | VPC Flow Logs | L3/L4のフロー記録 |
| 脅威・不審な振る舞いを検知したい | Amazon GuardDuty | CloudTrail等を入力にした脅威検知 |

最後の最後、3行に圧縮するならこうだ。

- **監査・「誰が」 → CloudTrail**
- **性能・ログ・アラーム → CloudWatch**
- **構成準拠・ドリフト → AWS Config**

この3つを正しく分担させた設計は、障害の夜に「どこを見ればいいか」で迷わない。CloudTrail で犯人を、Config で被害状況と準拠を、CloudWatch/EventBridge で気づきを――それぞれの強みで立体的に事故を立件できる。アプリ層の可観測性（分散トレース、OpenTelemetry、SRE 観点）まで含めて監視全体を設計したい場合は、[ECS で OpenTelemetry を使った可観測性・SRE の実践](/blog/aws-observability-opentelemetry-sre-ecs) も併せて読むと、コントロールプレーンの監査とアプリ層の可観測性が一本の線でつながる。ネットワーク境界の多層防御を設計するなら [AWS WAF と Cloud Armor による多層防御（OWASP）ガイド](/blog/waf-defense-in-depth-aws-waf-cloud-armor-owasp-guide) も参考になる。

---

監査・可観測性・構成準拠を「正しいサービスに正しく割り当てる」設計は、地味だが効く。事故対応の速度も、監査対応の手間も、毎月のクラウド費用も、この分担設計の質で決まる。私はサーバーレス決済基盤の信頼性レイヤーを設計・主導し、本番二重課金0件を維持する中で、まさにこの「どこに何を記録させ、どこで検知するか」を一つひとつ詰めてきた。

自社の AWS 環境で「監査ログ・可観測性・ガバナンス（構成準拠）の設計をいちど棚卸ししたい」「全部オンにしてコストだけ膨らんでいて、いざというとき必要な記録がない気がする」――そんな状態に心当たりがあれば、[お問い合わせ](/contact)から相談してほしい。3者の役割を整理し、目的に対して過不足のない、コストにも見合う監査・可観測性アーキテクチャを一緒に設計する。
