(aws-lambda-event-sources): addEventSource is missing dependency on Policy
- Dominant language
- TypeScript
- Stars
- 12.9k
- Forks
- 4.6k
- Avg merge
- 2d 3h
- Merged PRs (30d)
- 83
Description
### What is the problem?
When setting up a Lambda function with an `DynamoEventSource` attachment to invoke the lambda function.
The resource creation is trying to add the `DynamoEventSource` prior to creating the Policy allowing the Lambda function to be invoked by the stream. This is resulting in an error on initial deployment due to the race condition in the CloudFormation stack.
### Reproduction Steps
Here we have a small example from our stack.
We have a lambda function `auditLambda` which is deployed by a separate stack. The audit lambda is processing streams from the dynamodb table and putting it into cloudwatch. The policy for accessing cloudwatch logs is handled by the other stack. In here we focus on permissions to read the stream of the Dynamodb table.
```typescript
const auditLambda = lambda.Function.fromFunctionAttributes(parent, `auditLambda${table.node.id}`, {
functionArn: cdk.Fn.importValue('auditFunctionArn'),
role: iam.Role.fromRoleArn(parent, `importedAuditRoleARN${table.node.id}`, cdk.Fn.importValue('auditRoleArn')),
});
const source = new DynamoEventSource(table, {
batchSize: 100,
startingPosition: lambda.StartingPosition.TRIM_HORIZON,
bisectBatchOnError: true,
});
auditLambda.addEventSource(
source
);
```
### What did you expect to happen?
We expected the DynamoEventSource to depend on the Policy creation which allowed
the function to read the Dynamodb stream. CloudFormation may not execute the
resource creation in any particular order, so the creation of the event source
mapping may finish before the IAM policy is created. A DependsOn attribute on
the mapping ensures the correct creation order
### What actually happened?
The stack will synthesize successful but on initial deployment following error will rollback the deployment.
```
Resource handler returned message: "Invalid request provided: Cannot access stream arn:aws:dynamodb:***:****:table/*****/stream/2021-11-05T08:59:04.713. Please ensure the role can perform the GetRecords, GetShardIterator, DescribeStream, ListShards, and ListStreams Actions on your stream in IAM
```
### CDK CLI Version
1.130.0
### Framework Version
_No response_
### Node.js Version
14.x
### OS
Linux
### Language
Typescript
### Language Version
4.x
### Other information
Workaround:
```typescript
table.grantStreamRead(auditLambda);
// NOTE: Temporary till the dependency is added officially in aws-cdk
const eventSource = auditLambda.addEventSourceMapping(`auditLambda{table.node.id}Mapping`, {
eventSourceArn: table.tableStreamArn,
startingPosition: lambda.StartingPosition.TRIM_HORIZON,
enabled: true,
batchSize: 100,
bisectBatchOnError: true,
});
eventSource.node.addDependency((auditLambda.role as any)?.attachedPolicies.policies[0]);
```
Contributor guide
Research direction
Start at the addEventSource and DynamoEventSource entry points, then compare their generated event source mapping with the workaround using addEventSourceMapping and node.addDependency. Confirm which Policy resource grants stream-read access and whether the mapping lacks that dependency. Done means the synthesized mapping waits for the policy and the initial deployment no longer races IAM permissions.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- aws, typescript
- Domain
- authorization, cloud, infrastructure
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100