aws / aws/aws-cdk

(aws-lambda-event-sources): addEventSource is missing dependency on Policy

Open
#17,412 5 comments 1 reaction 0 assignees View on GitHub
@aws-cdk/aws-lambda-event-sources bug effort/small p2
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.