[AWS CDK]AWS Lambdaに既存のDynamoDBテーブルのIndexに対してアクセスを許可する方法

2024.05.22

どうも!オペレーション部の西村祐二です。

AWS CDKでAWS Lambdaに既存のDynamoDBのGSIなどを使った検索ができるようにアクセス権限を付与しようとしたときにハマったので備忘録も兼ねてブログにしておきます。

結論

既存のテーブルを読み込むときでGSIなど利用する場合は fromTableNamefromTableArnはではなく、fromTableAttributesを利用し、grantIndexPermissionsを付与しておくことでIndexを使った場合でも権限エラーなく利用できるようになります。

...
Table.fromTableAttributes(
	this,
	"<YOUR-TABLE-ID>",
	{
		tableName: "<YOUR_TABLE_NAME>",
		grantIndexPermissions: true,
	},
).grantReadWriteData(lambda);
...

fromTableName、fromTableArnをつかった場合との違い

はじめ、fromTableNameを使って既存のテーブルを読み込み、Lambdaに権限を付与していました。

以下に例を記載

Table.fromTableName(
	this,
	"<YOUR-TABLE-ID>",
	"<YOUR-TABLE-NAME>",
).grantReadWriteData(lambda);

これでデプロイし、IAMポリシーを確認すると下記のようなResourceの設定になっておりました。しかし、Indexを許可するには arn:aws:dynamodb:ap-northeast-1:123456789012:table/<YOUR-TABLE-NAME>/index/HogeIndexのようにテーブル名の後ろに記載する必要があり、これが原因で権限不足のエラーとなっていました。

...
        {
            "Action": [
                "dynamodb:BatchGetItem",
                "dynamodb:BatchWriteItem",
                "dynamodb:ConditionCheckItem",
                "dynamodb:DeleteItem",
                "dynamodb:DescribeTable",
                "dynamodb:GetItem",
                "dynamodb:GetRecords",
                "dynamodb:GetShardIterator",
                "dynamodb:PutItem",
                "dynamodb:Query",
                "dynamodb:Scan",
                "dynamodb:UpdateItem"
            ],
            "Resource": [
                "arn:aws:dynamodb:ap-northeast-1:123456789012:table/<YOUR-TABLE-NAME>"
            ],
...

結論の箇所で提示したプログラムだと下記のようになりResourceに追加で.../index/*が付与されるようになります。

...
        {
            "Action": [
                "dynamodb:BatchGetItem",
                "dynamodb:BatchWriteItem",
                "dynamodb:ConditionCheckItem",
                "dynamodb:DeleteItem",
                "dynamodb:DescribeTable",
                "dynamodb:GetItem",
                "dynamodb:GetRecords",
                "dynamodb:GetShardIterator",
                "dynamodb:PutItem",
                "dynamodb:Query",
                "dynamodb:Scan",
                "dynamodb:UpdateItem"
            ],
            "Resource": [
                "arn:aws:dynamodb:ap-northeast-1:123456789012:table/<YOUR-TABLE-NAME>",
                "arn:aws:dynamodb:ap-northeast-1:123456789012:table/<YOUR-TABLE-NAME>/index/*"
            ],
...

一応ドキュメントにも記載がありました。

https://docs.aws.amazon.com/cdk/api/v2/python/aws_cdk.aws_dynamodb/README.html#referencing-existing-global-tables

許可するIndexを細かく制御する

また、下記のように記載することで細かく制御することもできます。

Table.fromTableAttributes(this, "MyTable", {
  tableName: "MyTable",
  globalIndexes: ["foo", "bar"],
}).grantReadData(lambda);

さいごに

AWS CDKでAWS Lambdaに既存のDynamoDBのGSIなどを使った検索ができるようにアクセス権限を付与する方法をまとめました。

調べてもドンピシャな記事がなかなか見つけられなかったのでブログにしてみました。

誰かの参考になれば幸いです。