AWS CDK で Lambda 関数の特定のバージョンの権限を付与するメソッドが利用可能になっていました

AWS CDK で Lambda 関数の特定のバージョンの権限を付与するメソッドが利用可能になっていました

Clock Icon2024.08.21

こんにちは、製造ビジネステクノロジー部の若槻です。

AWS CDK の最近のリリースで、下記のアップデートが追加されていました。

https://github.com/aws/aws-cdk/releases/tag/v2.148.0

lambda: add grantInvokeLatestVersion to grant invoke only to latest function version (#29856) (61c28dd), closes #20177

今までは grantInvoke() メソッドにより Lambda 関数のすべてのバージョンの実行権限をプリンシパルに付与せざるを得なかったのですが、今回のアップデートにより Lambda 関数の特定のバージョンの権限を付与するメソッドが利用可能になりました。

試してみた

CDK モジュールのアップデート

AWS CDK モジュールを v2.148.0 以上にアップデートします。

npm i aws-cdk-lib@latest aws-cdk@latest

これにより Function Construct クラスで次のメソッドが利用可能となります。

  • grantInvokeVersion():指定のバージョンの実行権限を付与する
  • grantInvokeLatestVersion():最新のバージョンの実行権限を付与する

CDK コード

利用可能になったメソッドを実際に CDK の実装で利用して、IAM ロールに実行権限を付与してみます。比較のために grantInvoke() の実装も末尾に追加しています。

lib/cdk-sample-stack.ts
import { aws_lambda_nodejs, aws_lambda, aws_iam, Stack } from 'aws-cdk-lib';
import { Construct } from 'constructs';

export class CdkSampleStack extends Stack {
  constructor(scope: Construct, id: string) {
    super(scope, id);

    const myFunction = new aws_lambda_nodejs.NodejsFunction(
      this,
      'MyFunction',
      {
        runtime: aws_lambda.Runtime.NODEJS_20_X,
      }
    );

    // Current version の実行権限を付与
    const roleForCurrentVersion = new aws_iam.Role(
      this,
      'RoleForCurrentVersion',
      {
        assumedBy: new aws_iam.ServicePrincipal('lambda.amazonaws.com'),
      }
    );
    const currentVersion = myFunction.currentVersion;
    myFunction.grantInvokeVersion(roleForCurrentVersion, currentVersion);

    // Latest version の実行権限を付与
    const roleForLatestVersion = new aws_iam.Role(
      this,
      'RoleForLatestVersion',
      {
        assumedBy: new aws_iam.ServicePrincipal('lambda.amazonaws.com'),
      }
    );
    myFunction.grantInvokeLatestVersion(roleForLatestVersion);

    // 全ての version の実行権限を付与
    const roleForAllVersion = new aws_iam.Role(this, 'roleForAllVersion', {
      assumedBy: new aws_iam.ServicePrincipal('lambda.amazonaws.com'),
    });
    myFunction.grantInvoke(roleForAllVersion);
  }
}

上記コードを CDK デプロイしてスタックを作成します。

ここで、上記実装により作成された Lambda 関数のバージョンは、2 のみでした。これに対してどのように権限が付与されているでしょうか。

作成されたロールの権限を確認してみる

作成された 3 つのロールの権限を確認してみます。

まず grantInvokeVersion() を付与したロールのポリシーでは関数バージョンとして 2 が許可されており、**現在のバージョン(CurrentVersion)**の実行権限が付与されていることが分かります。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": "lambda:InvokeFunction",
            "Resource": "arn:aws:lambda:ap-northeast-1:XXXXXXXXXXXX:function:CdkSampleStack-MyFunction3BAA72D1-F4COWMbLRhSI:2",
            "Effect": "Allow"
        }
    ]
}

次に grantInvokeLatestVersion() を付与したロールのポリシーでは関数バージョンとして LATEST が許可されており、**最新のバージョン(LatestVersion)**の実行権限のみが付与されていることが分かります。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": "lambda:InvokeFunction",
            "Resource": [
                "arn:aws:lambda:ap-northeast-1:XXXXXXXXXXXX:function:CdkSampleStack-MyFunction3BAA72D1-F4COWMbLRhSI",
                "arn:aws:lambda:ap-northeast-1:XXXXXXXXXXXX:function:CdkSampleStack-MyFunction3BAA72D1-F4COWMbLRhSI:$LATEST"
            ],
            "Effect": "Allow"
        }
    ]
}

最後に比較として、grantInvoke() を付与したロールのポリシーでは関数バージョンとして * が許可されており、すべてのバージョンの実行権限のみが付与されていることが分かります。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": "lambda:InvokeFunction",
            "Resource": [
                "arn:aws:lambda:ap-northeast-1:XXXXXXXXXXXX:function:CdkSampleStack-MyFunction3BAA72D1-F4COWMbLRhSI",
                "arn:aws:lambda:ap-northeast-1:XXXXXXXXXXXX:function:CdkSampleStack-MyFunction3BAA72D1-F4COWMbLRhSI:*"
            ],
            "Effect": "Allow"
        }
    ]
}

おわりに

AWS CDK で Lambda 関数の特定のバージョンの権限を付与するメソッドが利用可能になっていたのでご紹介しました。

IaC である AWS CDK と Lammbda 関数のバージョニングを組み合わせて使うことはもしかしたらあまり無いかも知れませんが、関数の古いバージョンが残っている環境で権限を厳密に絞りたい場合などは役に立つのではないでしょうか。

以上

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.