I want to create an S3 bucket in one stack, pass it into another and then use it to create a notification onto an sns or sqs. Here is an example of broken down code would look like.
stack 1
export class BucketStack extends BaseStack {
public readonly mynBucket: Bucket;
constructor(scope: App, id: string, props?: StackProps) {
const properties: StackProps = {
env: {
region: StackConfiguration.region,
},
};
super(scope, id, properties);
this.myBucket = this.createMyBucket();
}
private createMyBucket() {
// create and return bucket
}
stack 2
import * as s3n from '@aws-cdk/aws-s3-notifications';
export class ServiceStack extends BaseStack {
constructor(scope: App, id: string, myBucket: Bucket) {
const properties: StackProps = {
env: {
region: StackConfiguration.region,
},
};
super(scope, id, properties);
const topic = new Topic(this, 'Topic');
myBucket.addEventNotification(EventType.OBJECT_CREATED_PUT, new s3n.SnsDestination(topic));
Error is
Error: 'my-bucket-stack' depends on 'my-service-stack' (Depends on Lambda resources., Depends on resources.). Adding this dependency (my-service-stack -> my-bucket-stack/myBucket/Resource.Arn) would create a cyclic reference.
The error message indicates, that you use a Lambda.
Where is that Lamdba definition?
What are you trying to do with SNS?
I assume that you wanted to apply the pattern (S3 PUT -> Notification -> Lambda) because you didn't post the full code (including the Lambda) itself.
Proceeding with my assumption, let me show you the issue what you're currently facing:
Plain Cloud Formation, which is being used under the hood with CDK, can't tackle that by itself and you would need to create a Custom Resource to overcome this issue. AWS CDK can tackle this though, because it's creating the required Custom Resource and the correct creation sequence automatically!
Instead of using the s3n.SnsDestination
, use the Lambda Destination as shown in the snippet. You can easily extract everything in separate stacks, because the issue shouldn't be with separating stacks.
export class TestStack extends Stack {
constructor(scope: cdk.Construct, id: string, props?: StackProps) {
super(scope, id, props);
const bucket = new Bucket(this, "your-bucket-construct-id",{
// ...
});
// Lambda
const lambda = new Function(this, 'the-triggered-lambda', {
code: Code.asset(path.join(__dirname, '../src/your-lambda-folder')),
handler: 'index.handler',
runtime: Runtime.NODEJS_12_X,
});
// S3 -> Lambda
bucket.addEventNotification(EventType.OBJECT_CREATED_PUT, new LambdaDestination(lambda));
}
}
Let me know, if that's answering your question or if you're facing any issues.