Cyclic reference if CloudWatch Rule and Lambda are in different stacks
- Dominant language
- TypeScript
- Stars
- 12.9k
- Forks
- 4.6k
- Avg merge
- 2d 3h
- Merged PRs (30d)
- 83
Description
When creating a CloudWatch Rule in CDK, if the rule is in a different stack from the Lambda, this results in an error. The error can be reproduced by typing `cdk ls`.
`Adding this dependency (${reason}) would create a cyclic reference.`
This is/was a similar issue with API Gateway. The CloudWatch problem was mentioned in the bottom of that issue.
https://github.com/aws/aws-cdk/issues/3000
### Reproduction Steps
```typescript
import { App, Aws, Stack } from '@aws-cdk/core';
import awsIam = require('@aws-cdk/aws-iam');
import awsLambda = require('@aws-cdk/aws-lambda');
import awsEvents = require('@aws-cdk/aws-events');
import awsEventsTargets = require('@aws-cdk/aws-events-targets');
class LambdaStack extends Stack {
lambdaRole: awsIam.Role;
lambdaFunction: awsLambda.Function;
constructor(app: App) {
super(app, 'LambdaStack', {});
this.lambdaRole = this.createLambdaRole();
this.lambdaFunction = this.createLambdaFunction();
}
private createLambdaRole(): awsIam.Role {
const lambdaRole: awsIam.Role = new awsIam.Role(this, 'LambdaRole', {
roleName: 'LambdaRole',
assumedBy: new awsIam.ServicePrincipal('lambda.amazonaws.com'),
})
const policyName = 'LambdaPolicy';
const lambdaPolicy = new awsIam.Policy(this, policyName, {
policyName: policyName,
statements: [
new awsIam.PolicyStatement({
actions: [
'logs:CreateLogStream',
'logs:CreateLogGroup',
'logs:DeleteLogStream',
'logs:DeleteLogGroup',
'logs:PutLogEvents',
],
effect: awsIam.Effect.ALLOW,
resources: [
`arn:aws:logs:${Aws.REGION}:${Aws.ACCOUNT_ID}:log-group:/aws/lambda/LambdaFunction`,
],
}),
],
});
lambdaRole.attachInlinePolicy(lambdaPolicy);
return lambdaRole;
}
private createLambdaFunction(): awsLambda.Function {
const lambdaFunction: awsLambda.Function = new awsLambda.Function(this, 'LambdaFunction', {
runtime: awsLambda.Runtime.PYTHON_3_7,
handler: 'lambda.lambda_handler',
code: awsLambda.AssetCode.fromAsset('lambda.zip'),
functionName: 'LambdaFunction',
role: this.lambdaRole,
});
return lambdaFunction;
}
}
class CloudWatchStack extends Stack {
constructor(app: App, lambdaFunction: awsLambda.Function) {
super(app, 'CloudWatchStack', {});
this.createRule(lambdaFunction);
}
private createRule(lambdaFunction: awsLambda.Function) {
const name = 'CwRule';
const cloudWatchRule: awsEvents.Rule = new awsEvents.Rule(this, name, {
ruleName: name,
schedule: awsEvents.Schedule.expression('cron(0/5 11-23 ? * mon-fri *)'),
enabled: false,
});
/* The addTarget() call will fail because the Lambda and CloudWatch rule are
in separate stacks. */
cloudWatchRule.addTarget(
new awsEventsTargets.LambdaFunction(lambdaFunction, {
event: awsEvents.RuleTargetInput.fromObject({}),
}),
);
}
}
const app = new App();
const lambdaStack = new LambdaStack(app);
new CloudWatchStack(app, lambdaStack.lambdaFunction);
```
### Error Log
```
Error: 'LambdaStack' depends on 'CloudWatchStack' (LambdaStack -> CloudWatchStack/CwRule/Resource.Arn). Adding this dependency (CloudWatchStack -> LambdaStack/LambdaFunction/Resource.Arn) would create a cyclic reference.
```
### Environment
- **CLI Version: 1.32.2**
- **Framework Version: 1.36.0**
- **OS: Mac OS Catalina 10.15.4**
- **Language: TypeScript**
### Other
This is/was a similar issue with API Gateway. The CloudWatch problem was mentioned in the bottom of that issue.
https://github.com/aws/aws-cdk/issues/3000
---
This is :bug: Bug Report
Contributor guide
Research direction
Start by running the provided TypeScript reproduction with `cdk ls` and trace `CloudWatchStack`, `Rule.addTarget()`, and `awsEventsTargets.LambdaFunction` while examining how the two `Stack` instances record dependencies. Compare the behavior with the related API Gateway issue. Done means the example no longer reports a cyclic reference and the two stacks can be synthesized successfully.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- aws, typescript
- Domain
- cloud, infrastructure
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 35/100