Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions rds-sns-event-notification-cdk-ts/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Amazon RDS to Amazon SNS

RDS Event Subscriptions allow users to configure notifications for RDS Events (provided through an SNS topic). This template configures an event subscription for failure, low storage, and availability event categories for RDS Instances.

Learn more about this pattern at Serverless Land Patterns:https://serverlessland.com/patterns/rds-sns-event-notification-cdk-ts

Important: this application uses various AWS services and there are costs associated with these services after the Free Tier usage - please see the [AWS Pricing page](https://aws.amazon.com/pricing/) for details. You are responsible for any AWS costs incurred. No warranty is implied in this example.

## Requirements

* [Create an AWS account](https://portal.aws.amazon.com/gp/aws/developer/registration/index.html) if you do not already have one and log in. The IAM user that you use must have sufficient permissions to make necessary AWS service calls and manage AWS resources.
* [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html) installed and configured
* [Git Installed](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)
* [AWS CDK](https://docs.aws.amazon.com/cdk/latest/guide/cli.html) installed and configured
* [Create an RDS Instance and copy Name of RDS Instance somewhere in notes. You will need it during template deployment](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_CreateDBInstance.html#USER_CreateDBInstance.Creating)

## Deployment Instructions

1. Create a new directory, navigate to that directory in a terminal and clone the GitHub repository:
```bash
git clone https://github.com/aws-samples/serverless-patterns
```
2. Change directory to the pattern directory:
```bash
cd serverless-patterns/rds-sns-event-notification-cdk-ts
```
3. Install the required dependencies.
```bash
npm install
```
4. To deploy the application:
- In SNSEndpoint, Provide your email address to receive notification from Amazon SNS
- In RDSInstanceName, Provide name of RDS Instance you created during Requirements
```bash
cdk deploy --parameters SNSEndpoint=EmailID --parameters RDSInstanceName=RDSInstanceName
```

## How it works

RDS Event Subscriptions allow users to configure notifications for RDS Events (provided through an SNS topic). This template configures an event subscription for failure, low storage, and availability event categories for RDS Instances.

## Testing

Once the CDK deployment is successful, first thing to do is to confirm the Email subscription. You will receive an email to confirm it. Then go to RDS console. Select the RDS Instance you have created. Stop the Instance and Restart it again. You will receive a notification related to it on your Email Address. Moving forward, you will receive failure, low storage, and availability events that happen on your RDS Instance.

## Cleanup

* Delete the stack
```bash
cdk destroy
```
----
Copyright 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved.

SPDX-License-Identifier: MIT-0
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/usr/bin/env node
import 'source-map-support/register';
import * as cdk from 'aws-cdk-lib';
import { RdsSnsEventNotificationCdkTsStack } from '../lib/rds-sns-event-notification-cdk-ts-stack';

const app = new cdk.App();
new RdsSnsEventNotificationCdkTsStack(app, 'RdsSnsEventNotificationCdkTsStack', {
/* If you don't specify 'env', this stack will be environment-agnostic.
* Account/Region-dependent features and context lookups will not work,
* but a single synthesized template can be deployed anywhere. */

/* Uncomment the next line to specialize this stack for the AWS Account
* and Region that are implied by the current CLI configuration. */
// env: { account: process.env.CDK_DEFAULT_ACCOUNT, region: process.env.CDK_DEFAULT_REGION },

/* Uncomment the next line if you know exactly what Account and Region you
* want to deploy the stack to. */
// env: { account: '123456789012', region: 'us-east-1' },

/* For more information, see https://docs.aws.amazon.com/cdk/latest/guide/environments.html */
});
60 changes: 60 additions & 0 deletions rds-sns-event-notification-cdk-ts/cdk.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
{
"app": "npx ts-node --prefer-ts-exts bin/rds-sns-event-notification-cdk-ts.ts",
"watch": {
"include": [
"**"
],
"exclude": [
"README.md",
"cdk*.json",
"**/*.d.ts",
"**/*.js",
"tsconfig.json",
"package*.json",
"yarn.lock",
"node_modules",
"test"
]
},
"context": {
"@aws-cdk/aws-lambda:recognizeLayerVersion": true,
"@aws-cdk/core:checkSecretUsage": true,
"@aws-cdk/core:target-partitions": [
"aws",
"aws-cn"
],
"@aws-cdk-containers/ecs-service-extensions:enableDefaultLogDriver": true,
"@aws-cdk/aws-ec2:uniqueImdsv2TemplateName": true,
"@aws-cdk/aws-ecs:arnFormatIncludesClusterName": true,
"@aws-cdk/aws-iam:minimizePolicies": true,
"@aws-cdk/core:validateSnapshotRemovalPolicy": true,
"@aws-cdk/aws-codepipeline:crossAccountKeyAliasStackSafeResourceName": true,
"@aws-cdk/aws-s3:createDefaultLoggingPolicy": true,
"@aws-cdk/aws-sns-subscriptions:restrictSqsDescryption": true,
"@aws-cdk/aws-apigateway:disableCloudWatchRole": true,
"@aws-cdk/core:enablePartitionLiterals": true,
"@aws-cdk/aws-events:eventsTargetQueueSameAccount": true,
"@aws-cdk/aws-iam:standardizedServicePrincipals": true,
"@aws-cdk/aws-ecs:disableExplicitDeploymentControllerForCircuitBreaker": true,
"@aws-cdk/aws-iam:importedRoleStackSafeDefaultPolicyName": true,
"@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy": true,
"@aws-cdk/aws-route53-patters:useCertificate": true,
"@aws-cdk/customresources:installLatestAwsSdkDefault": false,
"@aws-cdk/aws-rds:databaseProxyUniqueResourceName": true,
"@aws-cdk/aws-codedeploy:removeAlarmsFromDeploymentGroup": true,
"@aws-cdk/aws-apigateway:authorizerChangeDeploymentLogicalId": true,
"@aws-cdk/aws-ec2:launchTemplateDefaultUserData": true,
"@aws-cdk/aws-secretsmanager:useAttachedSecretResourcePolicyForSecretTargetAttachments": true,
"@aws-cdk/aws-redshift:columnId": true,
"@aws-cdk/aws-stepfunctions-tasks:enableEmrServicePolicyV2": true,
"@aws-cdk/aws-ec2:restrictDefaultSecurityGroup": true,
"@aws-cdk/aws-apigateway:requestValidatorUniqueId": true,
"@aws-cdk/aws-kms:aliasNameRef": true,
"@aws-cdk/aws-autoscaling:generateLaunchTemplateInsteadOfLaunchConfig": true,
"@aws-cdk/core:includePrefixInUniqueNameGeneration": true,
"@aws-cdk/aws-efs:denyAnonymousAccess": true,
"@aws-cdk/aws-opensearchservice:enableOpensearchMultiAzWithStandby": true,
"@aws-cdk/aws-lambda-nodejs:useLatestRuntimeVersion": true,
"@aws-cdk/aws-efs:mountTargetOrderInsensitiveLogicalId": true
}
}
57 changes: 57 additions & 0 deletions rds-sns-event-notification-cdk-ts/example-pattern.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
{
"title": "Amazon RDS instance event notification to Amazon SNS",
"description": "Amazon RDS event subscriptions allow users to configure notifications for RDS events (provided through an SNS topic).",
"language": "TypeScript",
"level": "200",
"framework": "CDK",
"introBox": {
"headline": "How it works",
"text": [
"Amazon RDS event subscriptions allow users to configure notifications for RDS events (provided through an SNS topic).",
"This template configures an event subscription for failure, low storage, and availability event categories for RDS Instances."
]
},
"gitHub": {
"template": {
"repoURL": "https://github.com/aws-samples/serverless-patterns/tree/main/rds-sns-event-notification-cdk-ts",
"templateURL": "serverless-patterns/rds-sns-event-notification-cdk-ts",
"projectFolder": "rds-sns-event-notification-cdk-ts",
"templateFile": "lib/rds-sns-event-notification-cdk-ts-stack.ts"
}
},
"resources": {
"bullets": [
{
"text": "Working with Amazon RDS event notification",
"link": "https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_Events.html"
},
{
"text": "Creating an Amazon RDS DB instance",
"link": "https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_CreateDBInstance.html#USER_CreateDBInstance.Creating"
}
]
},
"deploy": {
"text": [
"cdk deploy --parameters SNSEndpoint=EmailID --parameters RDSInstanceName=RDSInstanceName"
]
},
"testing": {
"text": [
"See the GitHub repo for detailed testing instructions."
]
},
"cleanup": {
"text": [
"cdk destroy"
]
},
"authors": [
{
"name": "Tejendra Khatri",
"image": "https://drive.google.com/file/d/1FR9bL3aJz2YRYkIsmfR_zL3RvE65oR0b/view",
"bio": "Cloud Support Engineer @ AWS",
"linkedin": "https://www.linkedin.com/in/tejendrakhatri"
}
]
}
8 changes: 8 additions & 0 deletions rds-sns-event-notification-cdk-ts/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module.exports = {
testEnvironment: 'node',
roots: ['<rootDir>/test'],
testMatch: ['**/*.test.ts'],
transform: {
'^.+\\.tsx?$': 'ts-jest'
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import * as cdk from 'aws-cdk-lib';
import * as sns from 'aws-cdk-lib/aws-sns';
import * as subscriptions from 'aws-cdk-lib/aws-sns-subscriptions';
import * as events from 'aws-cdk-lib/aws-events';
import * as rds from 'aws-cdk-lib/aws-rds';
import * as iam from 'aws-cdk-lib/aws-iam';

import { Construct } from 'constructs';

export class RdsSnsEventNotificationCdkTsStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
// Parameters
const snsEndpoint = new cdk.CfnParameter(this, 'SNSEndpoint', {
type: 'String',
description: 'Provide your email address to receive notification from SNS'
});
const rdsInstanceName = new cdk.CfnParameter(this, 'RDSInstanceName', {
type: 'String',
description: 'Provide name of your existing RDS Instance for which you want to receive event notifications'
});
// SNS Topic for RDS Event Subscription
const topic = new sns.Topic(this, 'SnsForRdsEventSubscription', {
displayName: 'rds-subscription-topic'
});
const awsAccountId = cdk.Fn.ref('AWS::AccountId');
// SNS Topic Policy
const topicPolicy = new sns.TopicPolicy(this, 'SnsTopicPolicyEventRule', {
topics: [topic]
});
topicPolicy.document.addStatements(
new iam.PolicyStatement({
actions: [
"SNS:GetTopicAttributes",
"SNS:SetTopicAttributes",
"SNS:AddPermission",
"SNS:RemovePermission",
"SNS:DeleteTopic",
"SNS:Subscribe",
"SNS:ListSubscriptionsByTopic",
"SNS:Publish",
"SNS:Receive"
],
principals: [new iam.AccountPrincipal(awsAccountId)],
resources: [topic.topicArn],
conditions: {
StringEquals: {
"aws:SourceOwner": awsAccountId
}
}
}),
new iam.PolicyStatement({
effect: iam.Effect.ALLOW,
actions: ["sns:Publish"],
resources: [topic.topicArn],
principals: [new iam.ServicePrincipal("events.rds.amazonaws.com")]
})
);
topic.addSubscription(new subscriptions.EmailSubscription(snsEndpoint.valueAsString, { json: true }));
// RDS Event Subscription
new rds.CfnEventSubscription(this, 'RdsEventSubscription', {
enabled: true,
snsTopicArn: topic.topicArn,
sourceIds: [rdsInstanceName.valueAsString],
sourceType: 'db-instance',
eventCategories: ['failure', 'low storage', 'availability']
});
// Outputs
new cdk.CfnOutput(this, 'MySnsTopicName', {
value: topic.topicName,
description: 'SNS topic name'
});
new cdk.CfnOutput(this, 'RDSInstanceNames', {
value: rdsInstanceName.valueAsString
});
}
}
27 changes: 27 additions & 0 deletions rds-sns-event-notification-cdk-ts/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"name": "rds-sns-event-notification-cdk-ts",
"version": "0.1.0",
"bin": {
"rds-sns-event-notification-cdk-ts": "bin/rds-sns-event-notification-cdk-ts.js"
},
"scripts": {
"build": "tsc",
"watch": "tsc -w",
"test": "jest",
"cdk": "cdk"
},
"devDependencies": {
"@types/jest": "^29.5.4",
"@types/node": "20.5.3",
"jest": "^29.6.3",
"ts-jest": "^29.1.1",
"aws-cdk": "2.93.0",
"ts-node": "^10.9.1",
"typescript": "~5.1.6"
},
"dependencies": {
"aws-cdk-lib": "2.93.0",
"constructs": "^10.0.0",
"source-map-support": "^0.5.21"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// import * as cdk from 'aws-cdk-lib';
// import { Template } from 'aws-cdk-lib/assertions';
// import * as RdsSnsEventNotificationCdkTs from '../lib/rds-sns-event-notification-cdk-ts-stack';

// example test. To run these tests, uncomment this file along with the
// example resource in lib/rds-sns-event-notification-cdk-ts-stack.ts
test('SQS Queue Created', () => {
// const app = new cdk.App();
// // WHEN
// const stack = new RdsSnsEventNotificationCdkTs.RdsSnsEventNotificationCdkTsStack(app, 'MyTestStack');
// // THEN
// const template = Template.fromStack(stack);

// template.hasResourceProperties('AWS::SQS::Queue', {
// VisibilityTimeout: 300
// });
});
31 changes: 31 additions & 0 deletions rds-sns-event-notification-cdk-ts/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"compilerOptions": {
"target": "ES2020",
"module": "commonjs",
"lib": [
"es2020",
"dom"
],
"declaration": true,
"strict": true,
"noImplicitAny": true,
"strictNullChecks": true,
"noImplicitThis": true,
"alwaysStrict": true,
"noUnusedLocals": false,
"noUnusedParameters": false,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": false,
"inlineSourceMap": true,
"inlineSources": true,
"experimentalDecorators": true,
"strictPropertyInitialization": false,
"typeRoots": [
"./node_modules/@types"
]
},
"exclude": [
"node_modules",
"cdk.out"
]
}