Read AWS IAM permission errors carefully – they tell you everything you need to know (Twitter to Mastodon bot migration)

Migrating my @kevinhookebot Twitter bot to Mastodon, I made some updates to how the Lambda queries a source DynamoDB table for new messages to be posted and ran into this error:

"errorType": "AccessDeniedException",
    "errorMessage": "User: arn:aws:sts::account-id:assumed-role/lambda-kevinhookebot-role/kevinhooketwitterbot-v2-dev-sendTweet is not authorized to perform: dynamodb:Query on resource: arn:aws:dynamodb:us-west-1:account-id:table/tweetbottweets/index/tweetdate-createdate-index because no identity-based policy allows the dynamodb:Query action"

The IAM role I’m reusing does have dynamodb:Query, but only on these resources:

"Resource": [
  "arn:aws:dynamodb:us-west-1:account-id:table/tweetbottweets",
  "arn:aws:dynamodb:us-west-1:account-id:table/tweetbottweets/index/Index",
  "arn:aws:dynamodb:us-west-1:account-id:table/tweetbotreplies"
]

This only includes the table itself, the primary index called Index, and another table tweebotreplies.

Notice this part of the message:

is not authorized to perform: dynamodb:Query on resource: arn:aws:dynamodb:us-west-1:account-id:table/tweetbottweets/index/tweetdate-createdate-index

The issue is this role does not include Query on a new index I added, called tweetdate-createdate-index. To resolve this, add this index to the list of Resources, and problem resolved.

AWS DynamoDB error: ValidationException: One or more parameter values were invalid: Condition parameter type does not match schema type

Executing a query against a Global Secondary Index I got this error:

ValidationException: One or more parameter values were invalid: Condition parameter type does not match schema type

Using the NodeJS Document api, my query looked like this:

let params = {
        "TableName": "exampletable",
        "IndexName": "example-createdate-index",
        "KeyConditionExpression": "exampleattr1 = :exampleattr1",
        "ExpressionAttributeValues": {
            ":exampleattr1": { "S": "0" }
        },
        "ProjectionExpression": "createdate, exampletext",
        "ScanIndexForward": false
    }
return docClient.query(params).promise();

The error is saying that one of my query parameter types does not match the values in the schema. I know this value is a String so this looks correct. Following recommendations on this question, it’s suggested to not pass the param type as “S” and let the Document api work out the type itself.Remove the “S” and just passed the value and now it’s working as expected.