【AWS】Fn::Sub とポリシー変数を使用して IAM ポリシーを定義する。【CloudFormation】
こんばんは。横浜事業所の えんどぅ です。
業務で IAM リソースを作成する機会があり、せっかくなので CloudFormation を利用して作成しようとしたのですが、まんまと躓きました…。
今回は、CloudFormation テンプレートで Fn::Sub とポリシー変数を使用して IAM ポリシーを定義する方法について確認しましたので、共有します。
AWS CloudFormation とは?
AWS CloudFormation とは「テンプレート」と呼ばれる JSON または YAML 形式のテキストファイルに記述した AWS リソースの構築や設定を自動で行ってくれる AWS サービスです。
構築したいリソースをテンプレートとして 1 度記述しておけば、リソースの複製・再構築・管理等が容易になります。
いちいちマネジメントコンソール上で一つ一つ設定を入力する必要なく、CloudFormation の API を叩くだけで複数のリソースをまとめて制御できます。
例えば、50 の IAM ポリシーを作成するシーンを考えてみます。
マネジメントコンソール上で IAM ポリシーの設定値を一つ一つ入力して、作成して、IAM ポリシー名を間違えたらほぼ全く同じ設定値を再度一つ一つ入力して、再作成して、それを 50 回繰り返して…。
やってられっかぁぁぁぁ!!と叫んでしまいそうです。
CloudFormation テンプレートを利用すれば、共通部分はコピー & ペーストして繰り返し作業を削減できたり、設定変更時は対象項目だけ変更すれば良くなったりと、作業効率をかなり向上できます。
YAML
...
Resources:
Policy1:
Type: 'AWS::IAM::ManagedPolicy'
Properties:
ManagedPolicyName: 'Policy1'
PolicyDocument:
Version: '2012-10-17'
...
Policy2:
Type: 'AWS::IAM::ManagedPolicy'
Properties:
ManagedPolicyName: 'Policy2'
PolicyDocument:
Version: '2012-10-17'
...
Fn::Sub とは?
Fn::Sub とは、CloudFormation テンプレートに組み込まれている関数の 1 つです。
文字列中に設定した変数を、テンプレート評価時に指定した値に置換します。
例えば複数の AWS アカウントで利用される可能性のある、テンプレートを作成するシーンを考えてみます。
テンプレート内で特定の AWS アカウント ID を記述すると、場合によっては他の AWS アカウントで同じテンプレートを使用する際にエラーが発生してしまいます。
そのため同様の AWS リソースを構築したい場合でも、AWS アカウント毎にテンプレートを作成する必要があります。
YAML
...
Resources:
Policy:
Type: 'AWS::IAM::ManagedPolicy'
Properties:
ManagedPolicyName: 'DemoPolicyVariables'
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: 'Allow'
Action: 'iam:ChangePassword'
Resource: 'arn:aws:iam::123456789012:user/user1' # AWS アカウント ID だけ違う。
...
YAML
...
Resources:
Policy:
Type: 'AWS::IAM::ManagedPolicy'
Properties:
ManagedPolicyName: 'DemoPolicyVariables'
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: 'Allow'
Action: 'iam:ChangePassword'
Resource: 'arn:aws:iam::234567890123:user/user1' # AWS アカウント ID だけ違う。
...
やってられっかぁぁぁぁ!!!と絶叫してしまいそうです。
Fn::Sub を使用して AWS アカウント ID を指定する部分を変数化する事で、テンプレートを使用する AWS アカウント ID に置換されて評価されるため、1 つのテンプレートを複数の AWS アカウントで使い回す事ができます。
YAML
...
Resources:
Policy:
Type: 'AWS::IAM::ManagedPolicy'
Properties:
ManagedPolicyName: 'DemoPolicyVariables'
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: 'Allow'
Action: 'iam:ChangePassword'
Resource: !Sub 'arn:aws:iam::${AWS::AccountId}:user/user1' # ${AWS::AccountId} 部分が AWS アカウント ID に置換される。
...
組み込み関数には、Fn::Sub 以外にも種類があり、それぞれ使用方法が異なります。
詳細は公式ドキュメントを参照してください。
ポリシー変数とは?
ポリシー変数とは、IAM ポリシーに設定できる「プレースホルダー」です。
特定の値を事前に設定しておくのではなく、ポリシーの評価時に動的に値を設定する事ができます。
例えば、100 の IAM ユーザーに「自分のパスワードのみを変更できる」という IAM ポリシーをアタッチするシーンを考えてみます。
ポリシー変数を使用しない場合、各 IAM ユーザー用の IAM ポリシーを作成する必要があります。
JSON
...
"Effect": "Allow",
"Action": "iam:ChangePassword",
"Resource": "arn:aws:iam::123456789012:user/user1" ← IAM ユーザー名だけ違う。
...
JSON
...
"Effect": "Allow",
"Action": "iam:ChangePassword",
"Resource": "arn:aws:iam::123456789012:user/user2" ← IAM ユーザー名だけ違う。
...
やってられっかぁぁぁぁ!!!!と発狂してしまいそうです。
IAM ユーザー名を表すポリシー変数を使用すれば、ポリシー変数部分が IAM ポリシーをアタッチした IAM ユーザー名に置換されて評価されるため、1 つの IAM ポリシーを複数の IAM ユーザーで使い回す事ができます。
JSON
...
"Effect": "Allow",
"Action": "iam:ChangePassword",
"Resource": "arn:aws:iam::123456789012:user/${aws:username}" ← ${aws:username} 部分が IAM ユーザー名に置換される。
...
ポリシー変数には、 IAM ユーザー名を表すもの以外にも種類があります。
詳細は公式ドキュメントを参照してください。
テンプレートで IAM ポリシーを定義して作成する
まずは、 CloudFormation テンプレートで Fn::Sub とポリシー変数を使用して IAM ポリシーを定義します。
IAM ポリシー定義の構文は公式リファレンスを参照してください。
YAML
AWSTemplateFormatVersion: '2010-09-09'
Description: 'IAM resources.'
Resources:
Policy:
Type: 'AWS::IAM::ManagedPolicy'
Properties:
ManagedPolicyName: 'DemoPolicyVariables'
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: 'Allow'
Action: 'iam:ChangePassword'
Resource: !Sub 'arn:aws:iam::${AWS::AccountId}:user/${!aws:username}' # ココ
CloudFormation の CreateStack API を叩きます。
無事、ポリシー変数を使用した IAM ポリシーを作成できました!
ミソは「${!aws:username}」の「${」の直後にある「!」です!
この記述により、CloudFormation 実行時に「${!...}」の部分を「${...}」として設定してくれます。
公式ドキュメントにもちゃんと記載がありました。
ちなみに、この「!」が無いとエラーになりますので、気をつけましょう。
Shell
An error occurred (ValidationError) when calling the CreateStack operation: Template format error: Unresolved resource dependencies [aws:username] in the Resources block of the template
まとめ
今回は、CloudFormation テンプレートで Fn::Sub とポリシー変数を使用して IAM ポリシーを定義する方法について、確認しました。
CloudFormation を利用すれば AWS リソースの管理がとても楽になるので、こうした細かな仕様も少しずつ把握して、効果的に活用していきましょう〜。
ALHについて知る
↓ ↓ ↓ 採用サイトはこちら ↓ ↓ ↓
↓ ↓ ↓ コーポレートサイトはこちら ↓ ↓ ↓
↓ ↓ ↓ もっとALHについて知りたい? ↓ ↓ ↓