Fazi
08/11/2021, 12:51 PMconst clearDynamodbTableFunction = new Function(this, 'ClearDynamodbTableFunction', {
srcPath: "src/helpers/clear_table",
handler: 'index.handler',
timeout: 30,
environment: env,
permissions: ["ssm", skillsTable, usersTable]
});
skillsTable
and usersTable
are tables I create earlier.
I put this function behind an API:
api.addRoutes(this, {
"DELETE /clear-table/{table-name}": clearDynamodbTableFunction,
});
However, upon hitting this API endpoint, I get the following message:
botocore.exceptions.ClientError: An error occurred (AccessDeniedException) when calling the DescribeTable operation: User: arn:aws:sts::123:assumed-role/dev-sst-integration-my-st-ClearDynamodbTableFuncti-1T3MU86FI83FK/dev-sst-integration-my-st-ClearDynamodbTableFuncti-eQz66VCa26mn is not authorized to perform: dynamodb:DescribeTable on resource: arn:aws:dynamodb:us-east-1:table/UsersTable
Anyone got any ideas why this happens? I thought I was giving my function full access to the table.thdxr
08/11/2021, 12:52 PMconst func = new sst.Function(...)
skillsTable.grantReadWrite(func)
usersTable.grantReadWrite(func)
Fixes itthdxr
08/11/2021, 12:56 PMdev-sst-integration-my-st-ClearDynamodbTableFuncti-1T3MU86FI83FK/dev-sst-integration-my-st-ClearDynamodbTableFuncti-eQz66VCa26mn
what the policy isFazi
08/11/2021, 1:11 PMskillsTable.grantReadWrite(func)
I get the error Property 'grantReadWrite' does not exist on type 'Table'.ts(2339)
My table definition:
const skillsTable = new Table(this, "SkillsTable", {
fields: {
skill_id: TableFieldType.STRING,
},
primaryIndex: { partitionKey: "skill_id" },
});
thdxr
08/11/2021, 1:26 PMskillsTable.dynamodbTable.grantReadWriteData(func)
Fazi
08/11/2021, 1:40 PMusersTable.dynamodbTable.grantFullAccess(clearDynamodbTableFunction)
but that still does not seem to work.
The actual lambda function is as follows (perhaps there is something in there that is not captured by the permissions):
import boto3
dynamo = boto3.resource('dynamodb')
def truncateTable(tableName):
table = dynamo.Table(tableName)
#get the table keys
tableKeyNames = [key.get("AttributeName") for key in table.key_schema]
#Only retrieve the keys for each item in the table (minimize data transfer)
projectionExpression = ", ".join('#' + key for key in tableKeyNames)
expressionAttrNames = {'#'+key: key for key in tableKeyNames}
counter = 0
page = table.scan(ProjectionExpression=projectionExpression, ExpressionAttributeNames=expressionAttrNames)
with table.batch_writer() as batch:
while page["Count"] > 0:
counter += page["Count"]
# Delete items in batches
for itemKeys in page["Items"]:
batch.delete_item(Key=itemKeys)
# Fetch the next page
if 'LastEvaluatedKey' in page:
page = table.scan(
ProjectionExpression=projectionExpression, ExpressionAttributeNames=expressionAttrNames,
ExclusiveStartKey=page['LastEvaluatedKey'])
else:
break
print(f"Deleted {counter}")
truncateTable("YOUR_TABLE_NAME")
https://stackoverflow.com/a/61641766/16433984thdxr
08/11/2021, 1:49 PMFazi
08/11/2021, 1:51 PMFazi
08/11/2021, 2:22 PMthdxr
08/11/2021, 2:23 PMFazi
08/11/2021, 2:23 PM*Full*: Tagging *Limited*: Read, Write
Fazi
08/11/2021, 2:24 PM{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"xray:PutTraceSegments",
"xray:PutTelemetryRecords"
],
"Resource": "*",
"Effect": "Allow"
},
{
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::dev-sst-integration-debug-stack-bucket0000-0000",
"arn:aws:s3:::dev-sst-integration-debug-stack-bucket0000-0000/*"
],
"Effect": "Allow"
},
{
"Action": "ssm:*",
"Resource": "*",
"Effect": "Allow"
},
{
"Action": "dynamodb:*",
"Resource": [
"arn:aws:dynamodb:us-east-1:0000-0000:table/dev-sst-integration-UsersTable"
],
"Effect": "Allow"
},
{
"Action": "dynamodb:*",
"Resource": [
"arn:aws:dynamodb:us-east-1:0000-0000:table/dev-sst-integration-SkillsTable"
],
"Effect": "Allow"
}
]
}
Fazi
08/11/2021, 2:25 PMthdxr
08/11/2021, 2:27 PM0000-0000
in there arethdxr
08/11/2021, 2:27 PMthdxr
08/11/2021, 2:27 PMFazi
08/11/2021, 2:27 PM0000
in case they were sensitiveFazi
08/11/2021, 2:28 PMFazi
08/11/2021, 2:28 PMFazi
08/11/2021, 2:28 PMthdxr
08/11/2021, 2:29 PMthdxr
08/11/2021, 2:29 PMdef truncateTable(tableName):
thdxr
08/11/2021, 2:29 PMthdxr
08/11/2021, 2:30 PMdynamodb:DescribeTable on resource: arn:aws:dynamodb:us-east-1:table/UsersTable
Fazi
08/11/2021, 2:30 PMUsersTable
or SkillsTable
thdxr
08/11/2021, 2:31 PMFazi
08/11/2021, 2:31 PMenv["USERS_TABLE_NAME"] = usersTable.tableName
env["SKILLS_TABLE_NAME"] = skillsTable.tableName
thdxr
08/11/2021, 2:31 PMthdxr
08/11/2021, 2:31 PMFazi
08/11/2021, 2:31 PMthdxr
08/11/2021, 2:31 PMthdxr
08/11/2021, 2:32 PMthdxr
08/11/2021, 2:33 PMFazi
08/11/2021, 2:34 PMput
into the table as follows:
table = dynamodb.Table(os.getenv("SKILLS_TABLE_NAME"))
table.put_item(Item=payload)
I pass in SKILLS_TABLE_NAME
into the function environment. This works completely ok.Fazi
08/11/2021, 2:35 PMtruncateTable
function:
key.get("AttributeName") _for_ key _in_
_table_.key_schema
thdxr
08/11/2021, 2:44 PMthdxr
08/11/2021, 2:45 PMFazi
08/11/2021, 2:48 PMFazi
08/11/2021, 3:09 PMUsersTable
and dev-sst-integration-UsersTable
The incorrect naming was indeed causing the error to say access denied.Fazi
08/11/2021, 3:10 PMthdxr
08/11/2021, 3:13 PM