Skip to content

Commit 8d49555

Browse files
authored
Merge pull request aws-samples#1620 from tjkhatri/tjkhatri-feature-rds-sns-event-notification-cdk-python
New serverless pattern - rds-sns-event-notification-cdk-python
2 parents f8e6bc5 + 93fcf65 commit 8d49555

13 files changed

Lines changed: 313 additions & 0 deletions
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# Amazon RDS to Amazon SNS
2+
3+
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.
4+
5+
Learn more about this pattern at Serverless Land Patterns:https://serverlessland.com/patterns/rds-sns-event-notification-cdk-python
6+
7+
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.
8+
9+
## Requirements
10+
11+
* [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.
12+
* [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html) installed and configured
13+
* [Git Installed](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)
14+
* [AWS CDK](https://docs.aws.amazon.com/cdk/latest/guide/cli.html) installed and configured
15+
* [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)
16+
17+
## Deployment Instructions
18+
19+
1. Create a new directory, navigate to that directory in a terminal and clone the GitHub repository:
20+
```bash
21+
git clone https://github.com/aws-samples/serverless-patterns
22+
```
23+
2. Change directory to the pattern directory:
24+
```bash
25+
cd serverless-patterns/rds-sns-event-notification-cdk-python
26+
```
27+
3. To manually create a virtualenv on MacOS and Linux:
28+
```bash
29+
python3 -m venv .venv
30+
```
31+
4. After the init process completes and the virtualenv is created, you can use the following
32+
step to activate your virtualenv.
33+
```bash
34+
source .venv/bin/activate
35+
```
36+
5. If you are a Windows platform, you would activate the virtualenv like this:
37+
```bash
38+
.venv\Scripts\activate.bat
39+
```
40+
6. Once the virtualenv is activated, you can install the required dependencies.
41+
```bash
42+
pip install -r requirements.txt
43+
```
44+
7. To deploy the application:
45+
- In SNSEndpoint, Provide your email address to receive notification from Amazon SNS
46+
- In RDSInstanceName, Provide name of RDS Instance you created during Requirements
47+
```bash
48+
cdk deploy --parameters SNSEndpoint=EmailID --parameters RDSInstanceName=RDSInstanceName
49+
```
50+
51+
## How it works
52+
53+
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.
54+
55+
## Testing
56+
57+
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.
58+
59+
## Cleanup
60+
61+
* Delete the stack
62+
```bash
63+
cdk destroy
64+
```
65+
----
66+
Copyright 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved.
67+
68+
SPDX-License-Identifier: MIT-0
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#!/usr/bin/env python3
2+
import os
3+
4+
import aws_cdk as cdk
5+
6+
from rds_sns_event_notification_cdk_python.rds_sns_event_notification_cdk_python_stack import RdsSnsEventNotificationCdkPythonStack
7+
8+
9+
app = cdk.App()
10+
RdsSnsEventNotificationCdkPythonStack(app, "RdsSnsEventNotificationCdkPythonStack",
11+
# If you don't specify 'env', this stack will be environment-agnostic.
12+
# Account/Region-dependent features and context lookups will not work,
13+
# but a single synthesized template can be deployed anywhere.
14+
15+
# Uncomment the next line to specialize this stack for the AWS Account
16+
# and Region that are implied by the current CLI configuration.
17+
18+
#env=cdk.Environment(account=os.getenv('CDK_DEFAULT_ACCOUNT'), region=os.getenv('CDK_DEFAULT_REGION')),
19+
20+
# Uncomment the next line if you know exactly what Account and Region you
21+
# want to deploy the stack to. */
22+
23+
#env=cdk.Environment(account='123456789012', region='us-east-1'),
24+
25+
# For more information, see https://docs.aws.amazon.com/cdk/latest/guide/environments.html
26+
)
27+
28+
app.synth()
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
{
2+
"app": "python3 app.py",
3+
"watch": {
4+
"include": [
5+
"**"
6+
],
7+
"exclude": [
8+
"README.md",
9+
"cdk*.json",
10+
"requirements*.txt",
11+
"source.bat",
12+
"**/__init__.py",
13+
"python/__pycache__",
14+
"tests"
15+
]
16+
},
17+
"context": {
18+
"@aws-cdk/aws-lambda:recognizeLayerVersion": true,
19+
"@aws-cdk/core:checkSecretUsage": true,
20+
"@aws-cdk/core:target-partitions": [
21+
"aws",
22+
"aws-cn"
23+
],
24+
"@aws-cdk-containers/ecs-service-extensions:enableDefaultLogDriver": true,
25+
"@aws-cdk/aws-ec2:uniqueImdsv2TemplateName": true,
26+
"@aws-cdk/aws-ecs:arnFormatIncludesClusterName": true,
27+
"@aws-cdk/aws-iam:minimizePolicies": true,
28+
"@aws-cdk/core:validateSnapshotRemovalPolicy": true,
29+
"@aws-cdk/aws-codepipeline:crossAccountKeyAliasStackSafeResourceName": true,
30+
"@aws-cdk/aws-s3:createDefaultLoggingPolicy": true,
31+
"@aws-cdk/aws-sns-subscriptions:restrictSqsDescryption": true,
32+
"@aws-cdk/aws-apigateway:disableCloudWatchRole": true,
33+
"@aws-cdk/core:enablePartitionLiterals": true,
34+
"@aws-cdk/aws-events:eventsTargetQueueSameAccount": true,
35+
"@aws-cdk/aws-iam:standardizedServicePrincipals": true,
36+
"@aws-cdk/aws-ecs:disableExplicitDeploymentControllerForCircuitBreaker": true,
37+
"@aws-cdk/aws-iam:importedRoleStackSafeDefaultPolicyName": true,
38+
"@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy": true,
39+
"@aws-cdk/aws-route53-patters:useCertificate": true,
40+
"@aws-cdk/customresources:installLatestAwsSdkDefault": false,
41+
"@aws-cdk/aws-rds:databaseProxyUniqueResourceName": true,
42+
"@aws-cdk/aws-codedeploy:removeAlarmsFromDeploymentGroup": true,
43+
"@aws-cdk/aws-apigateway:authorizerChangeDeploymentLogicalId": true,
44+
"@aws-cdk/aws-ec2:launchTemplateDefaultUserData": true,
45+
"@aws-cdk/aws-secretsmanager:useAttachedSecretResourcePolicyForSecretTargetAttachments": true,
46+
"@aws-cdk/aws-redshift:columnId": true,
47+
"@aws-cdk/aws-stepfunctions-tasks:enableEmrServicePolicyV2": true,
48+
"@aws-cdk/aws-ec2:restrictDefaultSecurityGroup": true,
49+
"@aws-cdk/aws-apigateway:requestValidatorUniqueId": true,
50+
"@aws-cdk/aws-kms:aliasNameRef": true,
51+
"@aws-cdk/aws-autoscaling:generateLaunchTemplateInsteadOfLaunchConfig": true,
52+
"@aws-cdk/core:includePrefixInUniqueNameGeneration": true,
53+
"@aws-cdk/aws-efs:denyAnonymousAccess": true,
54+
"@aws-cdk/aws-opensearchservice:enableOpensearchMultiAzWithStandby": true,
55+
"@aws-cdk/aws-lambda-nodejs:useLatestRuntimeVersion": true,
56+
"@aws-cdk/aws-efs:mountTargetOrderInsensitiveLogicalId": true
57+
}
58+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
{
2+
"title": "Amazon RDS instance event notification to Amazon SNS",
3+
"description": "Amazon RDS event subscriptions allow users to configure notifications for RDS events (provided through an SNS topic).",
4+
"language": "Python",
5+
"level": "200",
6+
"framework": "CDK",
7+
"introBox": {
8+
"headline": "How it works",
9+
"text": [
10+
"Amazon RDS event subscriptions allow users to configure notifications for RDS events (provided through an SNS topic).",
11+
"This template configures an event subscription for failure, low storage, and availability event categories for RDS Instances."
12+
]
13+
},
14+
"gitHub": {
15+
"template": {
16+
"repoURL": "https://github.com/aws-samples/serverless-patterns/tree/main/rds-sns-event-notification-cdk-python",
17+
"templateURL": "serverless-patterns/rds-sns-event-notification-cdk-python",
18+
"projectFolder": "rds-sns-event-notification-cdk-python",
19+
"templateFile": "rds_sns_event_notification_cdk_python/rds_sns_event_notification_cdk_python_stack.py"
20+
}
21+
},
22+
"resources": {
23+
"bullets": [
24+
{
25+
"text": "Working with Amazon RDS event notification",
26+
"link": "https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_Events.html"
27+
},
28+
{
29+
"text": "Creating an Amazon RDS DB instance",
30+
"link": "https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_CreateDBInstance.html#USER_CreateDBInstance.Creating"
31+
}
32+
]
33+
},
34+
"deploy": {
35+
"text": [
36+
"cdk deploy --parameters SNSEndpoint=EmailID --parameters RDSInstanceName=RDSInstanceName"
37+
]
38+
},
39+
"testing": {
40+
"text": [
41+
"See the GitHub repo for detailed testing instructions."
42+
]
43+
},
44+
"cleanup": {
45+
"text": [
46+
"cdk destroy"
47+
]
48+
},
49+
"authors": [
50+
{
51+
"name": "Tejendra Khatri",
52+
"image": "https://drive.google.com/file/d/1FR9bL3aJz2YRYkIsmfR_zL3RvE65oR0b/view",
53+
"bio": "Cloud Support Engineer @ AWS",
54+
"linkedin": "https://www.linkedin.com/in/tejendrakhatri"
55+
}
56+
]
57+
}

rds-sns-event-notification-cdk-python/rds_sns_event_notification_cdk_python/__init__.py

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
from aws_cdk import (
2+
Stack,
3+
aws_sns as sns,
4+
aws_sns_subscriptions as subscriptions,
5+
aws_events as events,
6+
aws_rds as rds,
7+
aws_iam as iam,
8+
CfnParameter,
9+
CfnOutput,
10+
Fn
11+
)
12+
from constructs import Construct
13+
14+
15+
class RdsSnsEventNotificationCdkPythonStack(Stack):
16+
17+
def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
18+
super().__init__(scope, construct_id, **kwargs)
19+
20+
# Parameters
21+
sns_endpoint = CfnParameter(self, "SNSEndpoint", type="String", description="Provide your email address to receive notification from SNS")
22+
rds_instance_name = CfnParameter(self, "RDSInstanceName", type="String", description="Provide name of your existing RDS Instance for which you want to receive event notifications")
23+
# SNS Topic for RDS Event Subscription
24+
topic = sns.Topic(self, "SnsForRdsEventSubscription", display_name="rds-subscription-topic")
25+
aws_account_id = Fn.ref("AWS::AccountId")
26+
# SNS Topic Policy
27+
topic_policy = sns.TopicPolicy(
28+
self,
29+
"SnsTopicPolicyEventRule",
30+
topics=[topic]
31+
)
32+
topic_policy.document.add_statements(iam.PolicyStatement(
33+
actions=[
34+
"SNS:GetTopicAttributes",
35+
"SNS:SetTopicAttributes",
36+
"SNS:AddPermission",
37+
"SNS:RemovePermission",
38+
"SNS:DeleteTopic",
39+
"SNS:Subscribe",
40+
"SNS:ListSubscriptionsByTopic",
41+
"SNS:Publish",
42+
"SNS:Receive"
43+
],
44+
principals=[iam.AccountPrincipal(aws_account_id)],
45+
resources=[topic.topic_arn],
46+
conditions={
47+
"StringEquals": {
48+
"aws:SourceOwner": aws_account_id
49+
}
50+
}
51+
),
52+
iam.PolicyStatement(
53+
effect=iam.Effect.ALLOW,
54+
actions=["sns:Publish"],
55+
resources=[topic.topic_arn],
56+
principals=[iam.ServicePrincipal("events.rds.amazonaws.com")]
57+
)
58+
)
59+
topic.add_subscription(subscriptions.EmailSubscription(sns_endpoint.value_as_string, json=True))
60+
# RDS Event Subscription
61+
rds_event_subscription = rds.CfnEventSubscription(
62+
self,
63+
"RdsEventSubscription",
64+
enabled=True,
65+
sns_topic_arn=topic.topic_arn,
66+
source_ids=[rds_instance_name.value_as_string],
67+
source_type="db-instance",
68+
event_categories=["failure", "low storage", "availability"]
69+
)
70+
# Outputs
71+
CfnOutput(self, "MySnsTopicName", value=topic.topic_name, description="SNS topic name")
72+
CfnOutput(self, "RDSInstanceNames", value=rds_instance_name.value_as_string)
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
aws-cdk-lib==2.93.0
2+
constructs>=10.0.0,<11.0.0
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
@echo off
2+
3+
rem The sole purpose of this script is to make the command
4+
rem
5+
rem source .venv/bin/activate
6+
rem
7+
rem (which activates a Python virtualenv on Linux or Mac OS X) work on Windows.
8+
rem On Windows, this command just runs this batch file (the argument is ignored).
9+
rem
10+
rem Now we don't need to document a Windows command for activating a virtualenv.
11+
12+
echo Executing .venv\Scripts\activate.bat for you
13+
.venv\Scripts\activate.bat

0 commit comments

Comments
 (0)