この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
土日となると天気が悪い北海道の渡辺です。
今日は七夕の創立記念日ということで、AnsibleのAWSモジュールを使ってIAM User, Group, Role を管理する方法を紹介します。
iam / iam_policyモジュール
Ansibleのiamモジュールとiam_policyモジュールはコアモジュールのひとつで、AWS上のIAMリソースとポシリードキュメントを管理します。
IAMリソースは、CloudFormationでも管理可能です。 Ansibleのモジュールを利用した場合、ポリシードキュメントの再利用やテンプレートが利用できる点がポイントとなってきます。
iamモジュールでIAM Roleを作成する
iamモジュールは、iam_type
でIAMリソースの種類を指定し、User / Group / Roleを作成します。
profile
とstate
を指定すること以外で特別なことはありません。
次のplaybookは、developという名前のIAM Roleを作成します。
- hosts: localhost
connection: local
gather_facts: False
vars:
profile: default
tasks:
- name: IAM Role, develop
iam:
iam_type: role
name: develop
state: present
profile: "{{ profile }}"
iam_type
では、user
, group
, role
のいずれかを指定します。
次のように、with_ite
msなども併用して複数のユーザをまとめて作成することも容易です。
- hosts: localhost
connection: local
gather_facts: False
vars:
profile: default
tasks:
- name: IAM Users
iam:
iam_type: user
name: {{ item }}
state: present
profile: "{{ profile }}"
with_items:
- greipel
- sagan
- kittel
- cavendish
iam_policyモジュールでポリシードキュメントを管理する
iam_policyモジュールでは、IAMリソースのポリシードキュメントを管理します。
policy_document
でjsonファイルを指定し、対象のIAMリソースにアタッチします。
次のplaybookは、develop Roleにポリシードキュメントを2つ追加しています。
- hosts: localhost
connection: local
gather_facts: False
vars:
profile: default
tasks:
- name: IAM Policy, develop/cloudwatch-logs
iam_policy:
iam_type: role
iam_name: develop
policy_name: cloudwatch-logs
policy_document: policy/cloudwatch-logs.json
state: present
profile: "{{ profile }}"
- name: IAM Policy, develop/codedeploy
iam_policy:
iam_type: role
iam_name: develop
policy_name: codedeploy
policy_document: policy/codedeploy.json
state: present
profile: "{{ profile }}"
ポリシードキュメントは、playbookを保存したディレクトリにpolicyディレクトリを作成し、それぞれjsonファイルとして保存します。
policy/cloudwatch-logs.json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents",
"logs:DescribeLogStreams"
],
"Resource": [
"arn:aws:logs:*:*:*"
]
}
]
}
policy/codedeploy.json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:GetObjectVersion",
"s3:ListObjects",
"codedeploy:RegisterApplicationRevision"
],
"Resource": [
"*"
]
}
]
}
ポリシードキュメントが独立したファイルとして参照され、共有資産として再利用可能です。
AWSの標準機能で管理ポリシーと呼ばれるテンプレート的なポリシーを提供しています。 現実的な運用では、管理ポリシーでは大雑把過ぎることが多いため、ポリシードキュメントのスニペットをコピペしながら利用することが多いでしょう(主にドキュメントからコピーします)。 Ansibleを利用することで、ポリシードキュメントはチームの資産としてストックできるようになります。
ポリシードキュメントをテンプレート化する
Jinja2によるテンプレート機能はAnsibleの魅力のひとつです。
実は、iam_policyモジュールのpolicy_json
を利用すれば、このテンプレート機能が利用できます。
ポリシードキュメントをテンプレート化し、検証環境と本番環境での差異を吸収できれば、シアワセになれうでしょう。
例えばあるバケットにアクセスできるポリシードキュメントの「バケット名」のみを変数化したポリシードキュメントのテンプレートは次のようになります。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:*"
],
"Resource": [
"arn:aws:s3:::{{ s3_bucket_name }}"
]
}
]
}
しかしながら、Ansible 2.1ではこの機能が利用できません。 テンプレートからの変換時、JSONのエスケープ処理に不具合があるようで、ポリシードキュメント適用時にシンタックスエラーとなってしまいます。 Ansible 2.2では解決されるようなので、この機能は2.2リリース後に紹介したいと思います。
管理ポリシーに対応できない
Ansibleのiam_policyモジュールは管理ポリシーに対応できません。 実はこれ、Ansibleで利用しているbotoが対応していないからというのが理由のようです。
まとめ
AWSでの構成管理と言えば基本はCloudFormationです。 ですが、適用するシーンや再利用性などを検討すると使いにくい部分も幾つかあります。 先日紹介したキーペアの管理やポリシードキュメントあたりはそのひとつです。 AnsibleのAWSモジュールやCloudFormationを併用し、適材適所で構成管理をするのがベストプラクティスではないでしょうか?