Terraform で AWS IAM のポリシー変更を監視する

AWS IAM のポリシーはセキュリティの中核を担う重要な要素です。ポリシーの変更を追跡しないと、意図しないアクセスが許可されるリスクがあります。本記事では、Terraform を使って AWS IAM のポリシー変更を監視し、検出する方法を解説します。

---

## **前提条件**

Terraform を使用して IAM ポリシー変更を監視するには、以下の準備が必要です：

1. **Terraform のセットアップ**:
   - Terraform がインストールされていること。
   - インストール方法：[Terraform インストールガイド](https://developer.hashicorp.com/terraform/tutorials/aws-get-started/install-cli)

2. **AWS CLI の設定**:
   - AWS CLI が設定されており、アクセスキーとシークレットキーが構成されていること。

3. **Terraform AWS Provider の設定**:
   - AWS Provider を使用して AWS リソースを管理する。
     ```hcl
     provider "aws" {
       region = "us-east-1"  # 必要に応じて変更
     }
     ```

4. **IAM に必要な権限**:
   - `iam:ListPolicies`, `iam:GetPolicy`, `iam:ListAttachedUserPolicies`, `iam:GetPolicyVersion`, `iam:ListGroupsForUser`, `iam:ListAttachedGroupPolicies` などの権限。

---

## **全体の流れ**

1. Terraform を使用して IAM ユーザーおよびグループのポリシーを取得。
2. 取得した設定をファイルに保存。
3. 次回実行時に前回の設定と比較して差分を検出。

---

## **Terraform 設定ファイルの作成**

### **1. IAM ユーザーのポリシーを取得**

以下の Terraform 設定は、IAM ユーザーとそのポリシー情報を取得します。

#### `main.tf`

```hcl
provider "aws" {
  region = "us-east-1"
}

# IAM ユーザーのリストを取得
data "aws_iam_users" "all_users" {}

# 各ユーザーに関連付けられているポリシーを取得
resource "local_file" "iam_user_policies" {
  for_each = toset(data.aws_iam_users.all_users.users)

  filename = "./iam_policies_${each.key}.json"
  content  = jsonencode({
    attached_policies = data.aws_iam_user.attached_policies(each.key).attached_policies,
    inline_policies   = data.aws_iam_user.inline_policies(each.key).inline_policies
  })
}

# IAM ユーザーの詳細
data "aws_iam_user" "attached_policies" {
  for_each = toset(data.aws_iam_users.all_users.users)
  user_name = each.key
}

data "aws_iam_user" "inline_policies" {
  for_each = toset(data.aws_iam_users.all_users.users)
  user_name = each.key
}
```

### **2. IAM グループのポリシーを取得**

IAM ユーザーが所属するグループのポリシーを取得するために、以下を追加します。

```hcl
# IAM グループのリストを取得
resource "local_file" "iam_group_policies" {
  for_each = toset(data.aws_iam_users.all_users.users)

  filename = "./iam_group_policies_${each.key}.json"
  content  = jsonencode({
    groups            = data.aws_iam_user.groups(each.key).groups,
    attached_policies = data.aws_iam_group.attached_policies(each.key).attached_policies
  })
}

# 各グループに関連付けられているポリシー
data "aws_iam_user" "groups" {
  for_each = toset(data.aws_iam_users.all_users.users)
  user_name = each.key
}

data "aws_iam_group" "attached_policies" {
  for_each = toset(data.aws_iam_user.groups(each.key).groups)
  group_name = each.key
}
```

### **3. 差分の検出**

Terraform では直接差分を検出する機能がないため、ローカルファイルに保存した JSON を外部ツール（例: `diff` や `jq`）で比較します。

#### 差分を比較するスクリプト

以下は、差分を比較するためのスクリプト例です：

```bash
#!/bin/bash

PREVIOUS_DIR="./previous_iam_policies"
CURRENT_DIR="./current_iam_policies"

# 差分検出
for file in $(ls $CURRENT_DIR); do
  if [ -f "$PREVIOUS_DIR/$file" ]; then
    diff "$PREVIOUS_DIR/$file" "$CURRENT_DIR/$file"
  else
    echo "New file detected: $file"
  fi
done
```

スクリプトを実行することで、変更があったポリシーを特定できます。

---

## **実行方法**

1. Terraform 設定を適用します：
   ```bash
   terraform init
   terraform apply -auto-approve
   ```

2. 初回実行時には IAM ポリシーがローカルファイルに保存されます。

3. 次回以降の実行時に差分スクリプトを実行して変更を検出します：
   ```bash
   ./detect_iam_policy_changes.sh
   ```

---

## **まとめ**

Terraform を使うことで、AWS IAM のポリシーを簡単に取得し、ローカルに保存して変更を監視できます。この仕組みを活用することで、IAM の管理をより効率的かつセキュアにすることが可能です。

必要に応じて CI/CD パイプラインに統合し、自動的に差分を通知する仕組みを追加することも検討してください！