背景
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...>