はじめに
以前、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としても使えますのでお試しください。