今回の記事の概要
AWS CDK(以下「CDK」)でIAMロールにIAMポリシーをアタッチする際のアタッチ方法による挙動の違いを検証する
はじめに
IAMロール(以下「ロール」)を使用する際、「ロールにIAMポリシー(以下「ポリシー」)をアタッチして権限を設定する」ということを行います。(=ロールを割り当てたAWSリソースに適用する権限を設定する)
もちろんCDKでもそうなのですが、CDKではロールにポリシーをアタッチする方法が複数用意されています。
そこで、今回はこれらの方法による挙動の違いを検証したいと思います。
検証内容
具体的に、CDKでロールにポリシーをアタッチする手段として、下表のものがあります。(「説明」「備考」は AWS CDK Reference Documentationの説明を和訳したものです)
方法 | 説明 | 備考 |
---|---|---|
inlinePolicies(props) | このロールにインライン化する名前付きポリシーのリスト | これでポリシーを設定した場合、CloudFormation(以下「CFn」)テンプレートで AWS::IAM::Policy の定義は作成されず、AWS::IAM::Role の1プロパティとして設定される |
addToPolicy(メソッド) | このプリンシパル(=ロール)のポリシーを追加する | |
addToPrincipalPolicy(メソッド) | ロールのデフォルトのポリシーDocumentに権限を追加 | デフォルトポリシーが未設定の場合、自動作成する |
attachInlinePolicy(メソッド) | このロールにポリシーをアタッチする |
なお managedPolicies
props、及びaddManagedPolicy
メソッドなどの「『AWS管理ポリシー』をアタッチする処理」は下記の挙動が明確なため、今回は除外します。
- ポリシーが新規に作成されない
- 「AWS管理」としてポリシー単位で個別にアタッチされる
また applyRemovalPolicy
メソッドは、(「Policy」とあるけど)「下記のケースにおいて、そのロールを残すかどうか」の設定であり、IAMポリシーとは無関係です。
- このロールを定義しているスタックが削除された
- CDKの定義からこのロールが削除された
- 上書き不可の変更が発生したため、リソースを削除→再作成する必要がある
CDKコード
検証用に、下記CDK定義を作成してデプロイします。(関係部分のみ抜粋)
import{ Role, Effect, ServicePrincipal, PolicyStatement, PolicyDocument, Policy, ManagedPolicy }from"aws-cdk-lib/aws-iam";// inlinePoliciesで適用するポリシーconst inlinePolicy =new PolicyDocument({ statements: [new PolicyStatement({ actions: ['dynamodb:Scan'], effect: Effect.ALLOW, resources: ['*']})]});// addToPolicyで適用するポリシーconst policy =new PolicyStatement({ actions: ['dynamodb:Query'], effect: Effect.ALLOW, resources: ['*']});// addToPrincipalPolicyで適用するポリシーconst principalPolicy =new PolicyStatement({ actions: ['dynamodb:GetItem'], effect: Effect.ALLOW, resources: ['*']});// attachInlinePolicyで適用するポリシー(ドキュメント)const attachInlinePolicyDocument =new PolicyDocument({ statements: [new PolicyStatement({ actions: ['dynamodb:DescribeTable'], effect: Effect.ALLOW, resources: ['*'],})]});const attachInlinePolicy =new Policy(this,'RoleAttachInlinePolicyId',{document: attachInlinePolicyDocument, policyName: 'RoleAttachInlinePolicy',});// ロール&ポリシーの設定// managedPoliciesは個人的検証で使用しただけなので、スルーしてくださいconst role =new Role(this,'LambdaRole',{ assumedBy: new ServicePrincipal('lambda.amazonaws.com'), roleName: 'RoleForPolicyAttachmentTest', managedPolicies: [ManagedPolicy.fromAwsManagedPolicyName('AmazonDynamoDBReadOnlyAccess')], inlinePolicies: {'RolePropsInitialPolicy': inlinePolicy,},}); role.addToPolicy(policy); role.addToPrincipalPolicy(principalPolicy); role.attachInlinePolicy(attachInlinePolicy);
検証結果
上記コードをデプロイした結果は、下図の通りで、概要としては以下の通りです。(下2つは画像はないですが、目視で確認)
- すべて「カスタマーインライン」として扱われる(「カスタマー管理」ではない)
addToPrincipalPolicy
とaddToPolicy
のポリシーは1つにまとめられる- 逆に
inlinePolicies
propsとattachInlinePolicy
のポリシーはそれぞれ個別に扱われる inlinePolicies
props のポリシーは、CFnテンプレートでAWS::IAM::Policy
の定義は作成されない(「検証内容」の表に記載した通り)- 他のポリシーは
AWS::IAM::Policy
の定義はあるが、実際に「ポリシー」として作成はされない(「カスタマーインライン」だから?)
個人的に2と3は逆の感覚だったので、ちょっと意外でした。
まとめ
上記を踏まえ、CDKでロールにポリシーをアタッチする際は、下記のようにするのがいいのではないかと思いました。(あくまで個人の見解です)
InlinePolicy
系は、1つの手段にまとめる。- CFnのクオータ(最大500個)を考えると、テンプレートが作成されない
inlinePolicies
props にまとめるのが良い?
- CFnのクオータ(最大500個)を考えると、テンプレートが作成されない
- それ以外は、コードの可視性とか管理のしやすさなどで決めると良い
- 正直、あまり深く考える必要はなさそう(CFnテンプレートでも1定義に集約されるので)
告知
今週土曜日の2024/06/08(土)に石川県金沢市で「JAWS-UG金沢 #99 CDKワークショップやってみよう」というAWS CDKのイベントが開催されます。
こちらのイベントにゲスト(講師?)として参加させて頂くことになりましたので、よろしくお願いします。(ちなみにワークショップの内容も私が作成しています)
まだ数名ほど参加可能のようなので、興味がある方はぜひ参加してみてください。
それでは、今回はこの辺で。