以下の内容はhttps://makky12.hatenablog.com/entry/2024/06/03/120500より取得しました。


【AWS CDK】IAMロールにIAMポリシーをアタッチする際の挙動について調べてみた

今回の記事の概要

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つは画像はないですが、目視で確認)

  1. すべて「カスタマーインライン」として扱われる(「カスタマー管理」ではない)
  2. addToPrincipalPolicyaddToPolicy のポリシーは1つにまとめられる
  3. 逆に inlinePolicies propsとattachInlinePolicy のポリシーはそれぞれ個別に扱われる
  4. inlinePolicies props のポリシーは、CFnテンプレートで AWS::IAM::Policy の定義は作成されない(「検証内容」の表に記載した通り)
  5. 他のポリシーはAWS::IAM::Policy の定義はあるが、実際に「ポリシー」として作成はされない(「カスタマーインライン」だから?)

個人的に2と3は逆の感覚だったので、ちょっと意外でした。

まとめ

上記を踏まえ、CDKでロールにポリシーをアタッチする際は、下記のようにするのがいいのではないかと思いました。(あくまで個人の見解です)

  • InlinePolicy 系は、1つの手段にまとめる。
    • CFnのクオータ(最大500個)を考えると、テンプレートが作成されない inlinePolicies props にまとめるのが良い?
  • それ以外は、コードの可視性とか管理のしやすさなどで決めると良い
    • 正直、あまり深く考える必要はなさそう(CFnテンプレートでも1定義に集約されるので)

告知

今週土曜日の2024/06/08(土)に石川県金沢市で「JAWS-UG金沢 #99 CDKワークショップやってみよう」というAWS CDKのイベントが開催されます。

jawsug-kanazawa.doorkeeper.jp

こちらのイベントにゲスト(講師?)として参加させて頂くことになりましたので、よろしくお願いします。(ちなみにワークショップの内容も私が作成しています)

まだ数名ほど参加可能のようなので、興味がある方はぜひ参加してみてください。

それでは、今回はこの辺で。




以上の内容はhttps://makky12.hatenablog.com/entry/2024/06/03/120500より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14