aws / aws-cdk

The AWS Cloud Development Kit is a framework for defining cloud infrastructure in code
https://aws.amazon.com/cdk
Apache License 2.0
11.61k stars 3.91k forks source link

appsync: resolver IAM permissions not provided for secondary indexes on dynamodb #14687

Closed pszabop closed 3 years ago

pszabop commented 3 years ago

:question: General Issue

An example of using secondary indexes is provided in the appsync developer guide, but it is not implementable using the CDK because access is only granted to the primary table by the CDK implementation of appsync. Furthermore, unlike Lambda and other CDK implementations, there is no obvious way to extend the permissions of the IAM policy that is generated.

The Question

How can appsync dynamodb resolvers generated by the CDK be given permission to access secondary indexes in dynamodb?

Environment

Other information

with Lambda, the following code alllows one to extend policies for that Lambda function, but there is no corresponding API to addToPolicy() with appsync, one cannot even get the role property on the data source.

      lambdaFunction.role.addToPolicy(new awsiam.PolicyStatement({
         actions: ['dynamodb:*'], // XXX probably want to scope it down to something more manageable
         resources: [`${userTable.tableArn}/index/*`],
      }));

The following is the log generated in Cloudwatch regarding the permissions:

"error": {
            "message": "User: arn:aws:sts::064156463146:assumed-role/RecipeServiceRol-HKZJ5S7F6SHD/APPSYNC_ASSUME_ROLE is not authorized to perform: dynamodb:Query on resource: arn:aws:dynamodb:us-east-1:064156463146:table/RecipeTablerecipeTable1FB38ADD-1GNTAPAQX30GA/index/byName (Service: DynamoDb, Status Code: 400, Request ID: 1RO5KU5UTU7I832MK0Q35CGTFVVV4KQNSO5AEMVJF66Q9ASUAAJG, Extended Request ID: null)",
            "type": "DynamoDB:DynamoDbException"

using this resolver, which works just fine if the index parameter is removed

        {
          "version": "2018-05-29",
          "index": "byName",
          "operation": "Query",
          "query": {
            "expression": "userId = :UserId",
            "expressionValues": {
              ":UserId": $util.dynamodb.toDynamoDBJson($ctx.identity.sub),
            }
          }
        }
pszabop commented 3 years ago

I should add that I am importing the table because unstable API implementations and databases have completely different lifetimes and thus belong in different stacks.

This issue notes problems with importing tables. Nevertheless, unlike that issue there's no apparent workaround in appsync..

pszabop commented 3 years ago

Import was the problem. Instead of importing dynamodb by tableArn, import dynamodb by properties. i.e. this fixed it:

    const recipeTable = dynamodb.Table.fromTableAttributes(this, 'importedRecipeTable', {
      tableArn: recipeTableArn.toString(),
      localIndexes: [ 'byName' ],
    }) as dynamodb.Table;

instead of

 const recipeTable = dynamodb.Table.fromTableArn(this, 'importedRecipeTable', recipeTableArn.toString()) as dynamodb.Table;

not that localIndexes should not be hard coded as best practice, but also imported. Which brings to mind that export/import should be as first class feature and "just work" without a lot of gotchas. Yes,. that is an official feature request, given that it's a nightmare if you have to delete a database due to some reentrency bug in CDK or CloudFormation but not a big deal for APIs, so the databases and APIsd should not ever be in the same stack, but instead use export/import mechanisms. That has already saved me pain several times.

MrArnoldPalmer commented 3 years ago

@pszabop So looks like this turned out to be the same issue as the dynamo one you linked. There is a PR in progress that changes grantReadWrite to include all secondary indices so I'm gonna close this in favor of that for tracking. Reopen if you think this covers something else though that I'm missing.

github-actions[bot] commented 3 years ago

⚠️COMMENT VISIBILITY WARNING⚠️

Comments on closed issues are hard for our team to see. If you need more assistance, please either tag a team member or open a new issue that references this one. If you wish to keep having a conversation with other community members under this issue feel free to do so.