LambdaからDynamoDBを操作するときIAMの設定で失敗した話
#AWS
#Lambda
#DynamoDB
#IAM
詰まったこと
lambda内でDynamoDB操作でGetCommand, UpdateCommand, BatchWriteCommand, PutCommand, QueryCommandを実行したときQueryCommandだけが失敗してしまった。
lambdaの権限設定では以下のようにCDKでDynamoDBテーブルのarnを指定し、dynamodb:*のように全てのDynamoDBのアクションを許可している。
lambdaRole.addToPolicy( new PolicyStatement({ resources: [props.table.tableArn], actions: ["dynamodb:*"], }) );
lambdaのエラーログを見ると、
AccessDeniedException: User: arn:aws:sts::xxxxxxxxxx:assumed-role/xxxxxxxx-lambda-role/xxxxxxxx-ddb-stream-lambda is not authorized to perform: dynamodb:Query on resource: arn:aws:dynamodb:ap-northeast-1:xxxxxxxxxx:table/xxxxxxxStack-xxxxxxxtablexxxxxxxx-xxxxxxxx/index/meta-id-idx
試行1
resourcesにてテーブルのarnだけを指定していたがログの「arn:aws:dynamodb:ap-northeast-1:xxxxxxxxxx:table/xxxxxxxStack-xxxxxxxtablexxxxxxxx-xxxxxxxx/index/meta-id-idx」を見るとGSIで指定した場合「table_arn/index/meta-id-idx」をリソースとして設定しないといけなそう。
そこで以下のように変更
lambdaRole.addToPolicy( new PolicyStatement({ resources: [props.table.tableArn + "/*"], actions: ["dynamodb:*"], }) );
早速実行、しかし失敗。。
再度ログを見ると
AccessDeniedException: User: arn:aws:sts::xxxxxxxxx:assumed-role/xxxxxxxxx-lambda-role/xxxxxxxxx-lambda is not authorized to perform: dynamodb:GetItem on resource: arn:aws:dynamodb:ap-northeast-1:xxxxxxx:table/xxxxxxxxxtablexxxxxxx-xxxxxxxx
今度はGetItemが失敗していた。 今度はプライマリーインデックスの処理が失敗している模様
試行2
今度は以下のようにテーブルのarnとテーブルのarn + "/*"の二つを追加した
lambdaRole.addToPolicy( new PolicyStatement({ resources: [props.table.tableArn, props.table.tableArn + "/*"], actions: ["dynamodb:*"], }) );
再度実行、、
今度は正常終了できました
結論
lambdaでDynamoDBを操作する時、GSIなどでプライマリーインデックス以外の処理を行う場合、
table_arn/index/<インデックス名>
のリソースを許可する必要があるので、 テーブルArn単体ではなく、追加インデックス分のリソースを指定する必要があるようでした。