Last updated: Jan 26, 2024
Reading timeยท3 min
We are going to:
Let's start by creating an SNS topic in CDK, by instantiating the Topic class.
import * as lambda from 'aws-cdk-lib/aws-lambda'; import {NodejsFunction} from 'aws-cdk-lib/aws-lambda-nodejs'; import * as sns from 'aws-cdk-lib/aws-sns'; import * as subs from 'aws-cdk-lib/aws-sns-subscriptions'; import * as sqs from 'aws-cdk-lib/aws-sqs'; import * as cdk from 'aws-cdk-lib'; import * as path from 'path'; export class CdkStarterStack extends cdk.Stack { constructor(scope: cdk.App, id: string, props?: cdk.StackProps) { super(scope, id, props); // ๐ create sns topic const topic = new sns.Topic(this, 'sns-topic', { displayName: 'My SNS topic', }); // ๐ create lambda function const myLambda = new NodejsFunction(this, 'my-lambda', { memorySize: 1024, timeout: cdk.Duration.seconds(5), runtime: lambda.Runtime.NODEJS_18_X, handler: 'main', entry: path.join(__dirname, `/../src/my-lambda/index.ts`), }); // ๐ subscribe Lambda to SNS topic topic.addSubscription(new subs.LambdaSubscription(myLambda)); new cdk.CfnOutput(this, 'snsTopicArn', { value: topic.topicArn, description: 'The arn of the SNS topic', }) } }
Let's go over what we did in the code sample:
ARN
of the SNS
topic. We will write the topic ARN to a file, so
we can easily test our application via the AWS CLI.Create the Lambda function at src/my-lambda/index.ts
and add the following
code to the file.
import {APIGatewayProxyResultV2, SNSEvent} from 'aws-lambda'; export async function main(event: SNSEvent): Promise<APIGatewayProxyResultV2> { const records = event.Records.map(record => { const {Message, Subject, Type} = record.Sns; return {subject: Subject, message: Message, type: Type}; }); console.log('records: ๐', JSON.stringify(records, null, 2)); return { body: JSON.stringify({records}), statusCode: 2000, }; }
The lambda function simply gathers the SNS records into an object and prints them to the console.
Let's run the deploy
command:
npx aws-cdk deploy \ --outputs-file ./cdk-outputs.json
We wrote the SNS topic ARN to a file named cdk-outputs.json
in the root
directory.
If we take a look at the Triggers
section in the Lambda management console, we
can see that SNS is configured as a trigger for the function:
The SNS management console also shows the subscription has been set up:
Protocol
is set to Lambda
Endpoint
is the function's ARNLet's publish a message to the SNS topic, you can grab your topic ARN from the
cdk-outputs.json
file in the root directory:
aws sns publish \ --subject "My Subject ๐" \ --message "Hello world ๐" \ --topic-arn "YOUR SNS TOPIC ARN"
If we look at the CloudWatch logs for the Lambda function, we can see that our function has been triggered by SNS:
Let's subscribe an SQS queue to our SNS topic as well. In order to create the queue we will instantiate the Queue class.
import * as sqs from 'aws-cdk-lib/aws-sqs'; export class CdkStarterStack extends cdk.Stack { constructor(scope: cdk.App, id: string, props?: cdk.StackProps) { super(scope, id, props) // ... rest // ๐ create queue const queue = new sqs.Queue(this, 'sqs-queue'); // ๐ subscribe queue to topic topic.addSubscription(new subs.SqsSubscription(queue)); } }
We created an SQS queue and subscribed the queue to our SNS topic.
Let's deploy the changes.
npx aws-cdk deploy \ --outputs-file ./cdk-outputs.json
The SNS management console shows that the SQS subscription has also been set up.
The SQS queue currently has 0 messages available.
Let's publish another message to the SNS topic to test the SQS integration.
aws sns publish \ --subject "My Subject ๐" \ --message "Hello world ๐" \ --topic-arn "YOUR SNS TOPIC ARN"
After I've published a message to the SNS topic, the queue has 1 message available.
To delete the resources we've provisioned, issue the destroy
command.
npx aws-cdk destroy
You can learn more about the related topics by checking out the following tutorials: