LoginSignup
3
5

More than 5 years have passed since last update.

IAMポリシーをAnsibleで管理する

Posted at

はじめに

以前、AnsibleでIAMユーザおよびグループを管理するPlaybookをご紹介しましたが、今回はAnsibleでIAMポリシーを管理してみたいと思います。

やること

  • グループにインラインポリシーアタッチ
  • グループに管理ポリシーアタッチ

ポイント

  • Ansibleのモジュールは管理ポリシーの操作に対応していないので、AWS CLIにて実装

注意

ポリシーのデタッチには対応していません。
ユーザへのアタッチ、ロールについては今回はフォローしていません。

前提

  • AWS関連のモジュール実行にはbotoが必要です。
  • AWS CLIが必要です。
  • credential情報は環境変数かaws configureでセットしてある必要があります。

sample

以下のグループにインラインポリシーとAWS管理ポリシーをアタッチします。
ポリシー内容はサンプルなので適当です。

  • ansible
    • インラインポリシー
      • SourceIpを制限したAdminポリシー
    • AWS管理ポリシー
      • CloudWatchReadOnlyAccess
      • AmazonEC2ReadOnlyAccess

ディレクトリ構成

ディレクトリ構成
site.yml
roles/
|--iam/
|  |--tasks/
|  |  |--main.yml
|  |--templates/
|  |  |--admin_policy.json.j2
group_vars/
|--group.yml

vars

こんな感じに変数を定義します。

group_vars/group.yml
---
my_vars:
  aws:
    iam:
      inline_policies:
        - group_name: ansible
          policy:
            - name: admin_ip_restricted
              template: admin_policy.json.j2
              params:
                condition: '{"IpAddress": {"aws:SourceIp": ["XX.XX.XX.XX/32"]}}'
      managed_policies:
        - group_name: ansible
          policy:
            - arn:aws:iam::aws:policy/CloudWatchReadOnlyAccess
            - arn:aws:iam::aws:policy/AmazonEC2ReadOnlyAccess

Role

インラインポリシーは、jsonのテンプレートを読み込んで定義します。

管理ポリシーのアタッチについては、shellモジュールでAWS CLIを実行しています。
重複実行してもエラーとはなりませんが、毎回ステータスがchangedになってしまうので、アタッチ済みポリシーと突き合わせます。

aws iam list-attached-group-policiesによりターゲットグループにアタッチされている管理ポリシーのARNを取得し、結果のjsonをfrom_jsonフィルタを通してset_factモジュールに渡すと、そのままグループごとに<<グループ名>>_policiesというARNのリストが生成されます。

whenにより、上記リストに追加したい管理ポリシーARNがあるかどうかを判定しています。

roles/iam/tasks/main.yml
---
- name: IAM Inline-Policy作成
  iam_policy:
    profile: "{{ lookup('env', 'AWS_DEFAULT_PROFILE') }}"
    iam_type: group
    iam_name: "{{ item.0.group_name }}"
    policy_name: "{{ item.1.name }}"
    state: present
    policy_json: "{{ lookup( 'template', item.1.template ) }}"
  with_subelements:
    - "{{ my_vars.aws.iam.inline_policies }}"
    - policy

- name: Get managed-policy list
  shell: >-
    aws iam list-attached-group-policies \
     --group-name {{ item.group_name }} \
     --query 'AttachedPolicies[].PolicyArn'
  changed_when: no
  with_items: "{{ my_vars.aws.iam.managed_policies }}"
  register: iam_managed_policies

- name: Create managed-policy list
  set_fact:
    "{{ item.item.group_name }}_policies": "{{ item.stdout | from_json }}"
  with_items: "{{ iam_managed_policies.results }}"
  when: not ansible_check_mode

- name: Attach managed-policy
  shell: >-
    aws iam attach-group-policy \
     --group-name {{ item.0.group_name }} \
     --policy-arn {{ item.1 }}
  with_subelements:
    - "{{ my_vars.aws.iam.managed_policies }}"
    - policy
  when: "'{{ item.1 }}' not in {{ item.0.group_name }}_policies"

templates

roles/iam/templates/admin_policy.json.j2
{% set params = item.1.params %}
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "*",
{% if params.condition is defined %}
      "Resource": "*",
      "Condition": {{ params.condition }}
{% else %}
      "Resource": "*"
{% endif %}
    }
  ]
}

まとめ

これでマネコンからだと分かりづらいポリシーを管理しやすくなるかと思います。
こちらのRoleの後ろに連結して一つのRoleとしても使えますのでお試しください。

参考

AnsibleでAWSリソースを管理するシリーズ

3
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
5