diff --git a/src/constructs/iam/policies/dynamodb.test.ts b/src/constructs/iam/policies/dynamodb.test.ts index aa7b07a937..6be03aa321 100644 --- a/src/constructs/iam/policies/dynamodb.test.ts +++ b/src/constructs/iam/policies/dynamodb.test.ts @@ -21,22 +21,40 @@ describe("The GuDynamoDBReadPolicy construct", () => { "dynamodb:GetRecords", ], Effect: "Allow", - Resource: { - "Fn::Join": [ - "", - [ - "arn:aws:dynamodb:", - { - Ref: "AWS::Region", - }, - ":", - { - Ref: "AWS::AccountId", - }, - ":table/MyTable", + Resource: [ + { + "Fn::Join": [ + "", + [ + "arn:aws:dynamodb:", + { + Ref: "AWS::Region", + }, + ":", + { + Ref: "AWS::AccountId", + }, + ":table/MyTable", + ], ], - ], - }, + }, + { + "Fn::Join": [ + "", + [ + "arn:aws:dynamodb:", + { + Ref: "AWS::Region", + }, + ":", + { + Ref: "AWS::AccountId", + }, + ":table/MyTable/index/*", + ], + ], + }, + ], }, ], }, @@ -57,22 +75,40 @@ describe("The GuDynamoDBWritePolicy construct", () => { { Action: ["dynamodb:BatchWriteItem", "dynamodb:PutItem", "dynamodb:DeleteItem", "dynamodb:UpdateItem"], Effect: "Allow", - Resource: { - "Fn::Join": [ - "", - [ - "arn:aws:dynamodb:", - { - Ref: "AWS::Region", - }, - ":", - { - Ref: "AWS::AccountId", - }, - ":table/MyTable", + Resource: [ + { + "Fn::Join": [ + "", + [ + "arn:aws:dynamodb:", + { + Ref: "AWS::Region", + }, + ":", + { + Ref: "AWS::AccountId", + }, + ":table/MyTable", + ], ], - ], - }, + }, + { + "Fn::Join": [ + "", + [ + "arn:aws:dynamodb:", + { + Ref: "AWS::Region", + }, + ":", + { + Ref: "AWS::AccountId", + }, + ":table/MyTable/index/*", + ], + ], + }, + ], }, ], }, diff --git a/src/constructs/iam/policies/dynamodb.ts b/src/constructs/iam/policies/dynamodb.ts index b84b7e6b30..87c70e960c 100644 --- a/src/constructs/iam/policies/dynamodb.ts +++ b/src/constructs/iam/policies/dynamodb.ts @@ -15,7 +15,13 @@ abstract class GuDynamoDBPolicy extends GuAllowPolicy { super(scope, id, { ...props, actions: props.actions.map((action) => `dynamodb:${action}`), - resources: [`arn:aws:dynamodb:${scope.region}:${scope.account}:table/${props.tableName}`], + // Note: although the index resource is not supported for all attached actions + // (e.g. BatchWriteItem), it will not cause issues to include it here as it is ignored. + // See: https://docs.aws.amazon.com/service-authorization/latest/reference/reference_policies_actions-resources-contextkeys.html + resources: [ + `arn:aws:dynamodb:${scope.region}:${scope.account}:table/${props.tableName}`, + `arn:aws:dynamodb:${scope.region}:${scope.account}:table/${props.tableName}/index/*`, + ], }); } } diff --git a/src/patterns/ec2-app/base.test.ts b/src/patterns/ec2-app/base.test.ts index ff8a61f094..b38cabe959 100644 --- a/src/patterns/ec2-app/base.test.ts +++ b/src/patterns/ec2-app/base.test.ts @@ -406,22 +406,40 @@ describe("the GuEC2App pattern", function () { { Action: ["dynamodb:BatchWriteItem", "dynamodb:PutItem", "dynamodb:DeleteItem", "dynamodb:UpdateItem"], Effect: "Allow", - Resource: { - "Fn::Join": [ - "", - [ - "arn:aws:dynamodb:", - { - Ref: "AWS::Region", - }, - ":", - { - Ref: "AWS::AccountId", - }, - ":table/my-dynamo-table", + Resource: [ + { + "Fn::Join": [ + "", + [ + "arn:aws:dynamodb:", + { + Ref: "AWS::Region", + }, + ":", + { + Ref: "AWS::AccountId", + }, + ":table/my-dynamo-table", + ], ], - ], - }, + }, + { + "Fn::Join": [ + "", + [ + "arn:aws:dynamodb:", + { + Ref: "AWS::Region", + }, + ":", + { + Ref: "AWS::AccountId", + }, + ":table/my-dynamo-table/index/*", + ], + ], + }, + ], }, ], },