Created
December 11, 2022 20:33
-
-
Save dmost714/dde2a869cf9e3adfcfcb6d4aae6b6940 to your computer and use it in GitHub Desktop.
Custom SNS Topic and subscriptions, triggered by Lambda in AWS Amplify
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { SNSClient, PublishCommand } from "@aws-sdk/client-sns" | |
const sns = new SNSClient({ region: process.env.REGION }) | |
export const alertNotice = async (subject: string, message: string) => { | |
try { | |
const params = { | |
TopicArn: process.env.ALERT_NOTICE_SNS_TOPIC_ARN, | |
Subject: subject, | |
Message: message | |
} | |
console.log('ALERT NOTICE: Sending SNS message - ', subject) | |
const command = new PublishCommand(params) | |
const result = await sns.send(command) | |
console.log('SNS result', result) | |
} catch (error) { | |
console.log('SNS error', error) | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"AWSTemplateFormatVersion": "2010-09-09", | |
"Parameters": { | |
"env": { | |
"Type": "String" | |
} | |
}, | |
"Resources": { | |
"SNSTOPIC": { | |
"Type": "AWS::SNS::Topic", | |
"Properties": { | |
"TopicName": { | |
"Fn::Join": [ | |
"", | |
[ | |
"yetanothersaas-sns-topic-alert", | |
{ | |
"Fn::Select": [ | |
3, | |
{ | |
"Fn::Split": [ | |
"-", | |
{ | |
"Ref": "AWS::StackName" | |
} | |
] | |
} | |
] | |
}, | |
"-", | |
{ | |
"Ref": "env" | |
} | |
] | |
] | |
} | |
} | |
}, | |
"SNSSUBSCRIPTIONEMAILUSERTWO": { | |
"Type": "AWS::SNS::Subscription", | |
"Properties": { | |
"Protocol": "email", | |
"TopicArn": { | |
"Ref": "SNSTOPIC" | |
}, | |
"Endpoint": "[email protected]" | |
} | |
}, | |
"SNSSUBSCRIPTIONEMAILUSERONE": { | |
"Type": "AWS::SNS::Subscription", | |
"Properties": { | |
"Protocol": "email", | |
"TopicArn": { | |
"Ref": "SNSTOPIC" | |
}, | |
"Endpoint": "[email protected]" | |
} | |
} | |
}, | |
"Outputs": { | |
"SNSTopicArn": { | |
"Value": { | |
"Ref": "SNSTOPIC" | |
} | |
} | |
}, | |
"Description": "{\"createdOn\":\"Mac\",\"createdBy\":\"Amplify\",\"createdWith\":\"9.2.1\",\"stackType\":\"custom-customCloudformation\",\"metadata\":{}}" | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"auth": { | |
// ... | |
}, | |
"function": { | |
"yetanothersaasSomeLambda": { | |
// ... | |
}, | |
"yetanothersaasAnotherLambda": { | |
"build": true, | |
"providerPlugin": "awscloudformation", | |
"service": "Lambda", | |
"dependsOn": [ | |
{ | |
// ... | |
}, | |
{ | |
"category": "custom", | |
"resourceName": "AlertNotice", | |
"attributes": [ | |
"SNSTopicArn" | |
] | |
} | |
] | |
} | |
}, | |
"storage": { | |
// ... | |
}, | |
"custom": { | |
"AlertNotice": { | |
"service": "customCloudformation", | |
"providerPlugin": "awscloudformation", | |
"dependsOn": [] | |
} | |
}, | |
"api": { | |
// ... | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[ | |
{ | |
"Action": [ | |
"SNS:Publish" | |
], | |
"Resource": [ | |
{ | |
"Ref": "customAlertNoticeSNSTopicArn" | |
} | |
] | |
} | |
] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# SNS ALERTS from a Lambda in AWS Amplify | |
Name the custom resource based on what it is used for. | |
Here I want to email "alerts" to myself, so I `amplify add custom` and give the custom resource the name "AlertNotice". | |
In the `amplify/backend/custom/AlertNotice`, define the custom resources in the `AlertNotice-cloudformation.json` file, including the ARN as an output. | |
In the `amplify/backend/backend-config.json` file, add the new custom resource as a dependency of any lambda that will use it. | |
Run `amplify env checkout dev` any time you manually change the backend-config.json file or you will see misleading errors when you do `amplify push`. | |
In any lambda that will trigger the SNS topic, add permissions in that lambda's `custom-policies.json` file. | |
In the lambda's `yetanothersaasAnotherLambda-cloudformation-template.json` cloudformation template, add the custom property to properties and the lambda's `ENVIRONMENT` variables so you can reference it. | |
Then in the Lambda code, trigger the SNS topic. | |
See below for all the files that get touched and samples of their contents. | |
Much more detail in this GIST: | |
How to expose an Amplify Custom category as an ENVIRONMENT variable in an Amplify Lambda | |
https://gist.github.com/dmost714/e914c865e54f9e77a1e49cda3dc78b20 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const requireEnvironmentVars = () => { | |
[ | |
"API_PIXELSTOPOSTCARDS_GRAPHQLAPIENDPOINTOUTPUT", | |
"API_PIXELSTOPOSTCARDS_GRAPHQLAPIIDOUTPUT", | |
"ENV", | |
"REGION", | |
"ALERT_NOTICE_SNS_TOPIC_ARN" | |
].map(envvar => { | |
if (!process.env[envvar]) { | |
throw new Error(`UNDEFINED ENVIRONMENT VAR: ${envvar}:`) | |
} | |
console.log(`[ENVIRONMENT] ${envvar}: ${process.env[envvar]}`) | |
}) | |
} | |
export const handler: APIGatewayProxyHandler = async (event) => { | |
console.log('EVENT', JSON.stringify(event, null, 2)) | |
requireEnvironmentVars() | |
try { | |
return await handleEvent(event) | |
} catch (error) { | |
console.log('FATAL', error) | |
const msg = ` | |
ERROR: | |
${error} | |
Check yetanothersaasAnotherLambda logs.` | |
await alertNotice('Subject of alert', msg) | |
throw error | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"AWSTemplateFormatVersion": "2010-09-09", | |
"Description": "{\"createdOn\":\"Mac\",\"createdBy\":\"Amplify\",\"createdWith\":\"9.2.1\",\"stackType\":\"function-Lambda\",\"metadata\":{}}", | |
"Parameters": { | |
"CloudWatchRule": { | |
"Type": "String", | |
"Default": "NONE", | |
"Description": " Schedule Expression" | |
}, | |
"deploymentBucketName": { | |
"Type": "String" | |
}, | |
"env": { | |
"Type": "String" | |
}, | |
"s3Key": { | |
"Type": "String" | |
}, | |
"customAlertNoticeSNSTopicArn": { | |
"Type": "String" | |
} | |
}, | |
"Conditions": { | |
"ShouldNotCreateEnvResources": { | |
"Fn::Equals": [ | |
{ | |
"Ref": "env" | |
}, | |
"NONE" | |
] | |
} | |
}, | |
"Resources": { | |
"LambdaFunction": { | |
"Type": "AWS::Lambda::Function", | |
"Metadata": { | |
"aws:asset:path": "./src", | |
"aws:asset:property": "Code" | |
}, | |
"Properties": { | |
"Code": {...}, | |
"Handler": "index.handler", | |
"FunctionName": {...}, | |
"Environment": { | |
"Variables": { | |
"ENV": { | |
"Ref": "env" | |
}, | |
"REGION": { | |
"Ref": "AWS::Region" | |
}, | |
"ALERT_NOTICE_SNS_TOPIC_ARN": { | |
"Ref": "customAlertNoticeSNSTopicArn" | |
} | |
} | |
}, | |
"Role": { | |
"Fn::GetAtt": [ | |
"LambdaExecutionRole", | |
"Arn" | |
] | |
}, | |
"Runtime": "nodejs18.x", | |
"Architectures": [ | |
"arm64" | |
], | |
"Layers": [], | |
"MemorySize": 256, | |
"Timeout": 180 | |
} | |
}, | |
"LambdaExecutionRole": {...}, | |
"lambdaexecutionpolicy": {...}, | |
"AmplifyResourcesPolicy": {...}, | |
"CustomLambdaExecutionPolicy": {...} | |
}, | |
"Outputs": {...} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment