AWS
CloudFormation

(メモ) CloudFormation StackSetsでIAM Policyを展開するときに、Policy記述内に展開先のアカウントIDを記載する方法


背景

CloudFormation StackSetsでIAM Policyを展開するとき、Policy記述内に展開先のアカウントIDを記載しないといけない場合にどうしようと一瞬考えたのでメモ。例えばResourceエレメントを使う場合はARNにリージョンやアカウントIDが入るため、展開先のアカウントごとに値が異なる。


解決策

単純にCloudFormationの擬似パラメータ(AWS::AccountIdとかAWS::Regionとか)を使えば良いだけだった。

これで展開先アカウント/リージョンの値に変換される。


サンプル

AWSTemplateFormatVersion: "2010-09-09"

Resources:
TestPolicy:
Type: AWS::IAM::ManagedPolicy
Properties:
ManagedPolicyName: TestPolicy
Description: test policy
Path: /
PolicyDocument:
Version: '2012-10-17'
Statement:
-
Sid: DenyAdminRoleChange
Effect: Deny
Action: iam:*
Resource: !Sub arn:aws:iam::${AWS::AccountId}:role/AdminRole


蛇足

IAM Boundaryの設定展開がきっかけでこれを考えていたが、最初に以下のようにWildcardを試してみたがうまくいかず。

特定のPermissions Boundaryを付与していないとRoleのCreateやらPolicyの付与ができないようにするステートメントのCondition句でアカウントIDをワイルドカードにした場合、適切なBoundaryを付与してもRole作成が拒否されてしまった。

これがなぜかは今の所不明。。。この書き方自体は問題ないはずだが。。。


ステートメント例

<...snip...>

{
"Sid": "DenyCreateOrChangeRoleWithoutBoundary",
"Effect": "Deny",
"Action": [
"iam:CreateRole",
"iam:PutRolePolicy",
"iam:DeleteRolePolicy",
"iam:AttachRolePolicy",
"iam:DetachRolePolicy",
"iam:PutRolePermissionsBoundary"
],
"Resource": "*",
"Condition": {
"StringNotEquals": {
"iam:PermissionsBoundary": "arn:aws:iam::*:policy/ExampleBoundaryPolicy"
}
}
},
<...snip...>