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

こちらは [Ansible Advent Calendar 2024](https://qiita.com/advent-calendar/2024/ansible) 13日目の記事になります。

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

AWS IAM のポリシー管理はセキュリティにおいて重要なタスクです。しかし、ポリシーや設定の変更を手動で追跡するのは非効率でミスが起こりやすい作業です。この記事では、Ansible を使って AWS IAM のポリシーの変更を自動的に監視し、検出する方法を解説します。

---

## **前提条件**

この手順を実行する前に、以下の要件を満たしていることを確認してください：

1. **Ansible のセットアップ**:
   - Ansible がインストールされていること。
   - 必要な Python ライブラリ（`boto3` と `botocore`）がインストールされていること。
     ```bash
     pip install boto3 botocore
     ```

2. **AWS CLI の設定**:
   - AWS CLI を使用して、適切なアクセスキーとシークレットキーを設定していること。
   - 必要な IAM 権限（`iam:ListAttachedUserPolicies`, `iam:ListGroupsForUser`, `iam:ListAttachedGroupPolicies` など）が付与されていること。

3. **Ansible Playbook 実行環境**:
   - ローカル環境、または適切な管理サーバー。

---

## **全体の流れ**

1. IAM ユーザーおよびグループに紐づくポリシーを取得。
2. 前回のデータを保存し、現在のデータと比較。
3. 差分を検出して、変更があれば通知またはログ表示。

---

## **Ansible Playbook の構成**

以下の手順に基づき、Playbook を作成します。

### **1. IAM ユーザーとグループのポリシーを取得する Playbook**

この Playbook は、IAM ユーザーにアタッチされたポリシーや、所属するグループにアタッチされたポリシーを取得します。

#### Playbook

```yaml
- name: Get IAM user and group policies
  hosts: localhost
  gather_facts: no
  vars:
    iam_data_file: "./iam_previous_data.json"

  tasks:
    - name: Check if previous IAM data file exists
      ansible.builtin.stat:
        path: "{{ iam_data_file }}"
      register: file_stat

    - name: Load previous IAM data if it exists
      when: file_stat.stat.exists
      include_tasks: load_previous_data.yml

    - name: Fetch IAM user policies
      community.aws.aws_iam_info:
        user_name: "{{ iam_user_name }}"
      register: current_iam_data

    - name: Save current IAM data to file
      ansible.builtin.copy:
        content: "{{ current_iam_data }}"
        dest: "{{ iam_data_file }}"
      delegate_to: localhost

    - name: Compare current and previous IAM data
      when: file_stat.stat.exists
      ansible.builtin.debug:
        msg: >
          Detected changes:
          Previous: {{ previous_iam_data }}
          Current: {{ current_iam_data }}
      failed_when: current_iam_data != previous_iam_data
```

### **2. 過去のデータを読み込むタスクファイル**

`load_previous_data.yml` を以下のように作成し、前回保存されたデータをロードします。

```yaml
- name: Load previous IAM data
  ansible.builtin.slurp:
    src: "{{ iam_data_file }}"
  register: previous_data_raw

- name: Decode previous IAM data
  ansible.builtin.set_fact:
    previous_iam_data: "{{ previous_data_raw.content | b64decode | from_json }}"
```

### **3. グループにアタッチされたポリシーの取得**

IAM ユーザーが所属するグループのポリシーを取得するためのタスクを追加します。

```yaml
- name: Get groups for the IAM user
  community.aws.aws_iam_info:
    user_name: "{{ iam_user_name }}"
  register: user_groups

- name: Fetch policies for each group
  community.aws.aws_iam_info:
    group_name: "{{ item.group_name }}"
  loop: "{{ user_groups.user_groups }}"
  register: group_policies

- name: Display group attached policies
  ansible.builtin.debug:
    msg: "Group {{ item.group_name }} has policies: {{ item.attached_group_policies }}"
  loop: "{{ group_policies.results }}"
```

---

## **実行方法**

1. Playbook を保存します（例: `detect_iam_changes.yml`）。
2. 必要な変数（`iam_user_name`）を指定して実行します。
   ```bash
   ansible-playbook detect_iam_changes.yml -e "iam_user_name=your-iam-user-name"
   ```

3. 初回実行時には IAM データが保存されます。
4. 次回以降の実行時、変更があれば以下のように差分が表示されます。

```plaintext
TASK [Compare current and previous IAM data] *********************************
ok: [localhost] => {
    "msg": "Detected changes: Previous: {...} Current: {...}"
}
```

---

## **差分をフォーマットして表示する方法**

差分をわかりやすく表示するために、Ansible の `command` モジュールを使用して外部ツール（例: `jsondiff`）を実行する方法もあります。

```yaml
- name: Install jsondiff if not installed
  ansible.builtin.command: pip install jsondiff

- name: Compare previous and current data using jsondiff
  ansible.builtin.command: |
    python -c "import json, sys, jsondiff; print(jsondiff.diff(json.load(open('{{ iam_data_file }}')), {{ current_iam_data }}))"
  register: json_diff_output

- name: Display formatted diff
  ansible.builtin.debug:
    msg: "Detected differences: {{ json_diff_output.stdout }}"
```

---

## **まとめ**

Ansible を活用することで、AWS IAM のポリシー変更を効率的に監視し、変更点を迅速に検出できます。この仕組みを自動化に組み込むことで、セキュリティ体制をさらに強化できます。

必要に応じて通知やログ機能を追加し、チーム全体で変更を共有できるようにカスタマイズします。