-
Notifications
You must be signed in to change notification settings - Fork 5
/
sns-lambda.ts
106 lines (102 loc) · 4.38 KB
/
sns-lambda.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
import { CfnOutput } from "aws-cdk-lib";
import { SnsEventSource } from "aws-cdk-lib/aws-lambda-event-sources";
import { Topic } from "aws-cdk-lib/aws-sns";
import type { GuLambdaErrorPercentageMonitoringProps, NoMonitoring } from "../constructs/cloudwatch";
import { AppIdentity } from "../constructs/core";
import type { GuMigratingResource, GuStack } from "../constructs/core";
import { GuLambdaFunction } from "../constructs/lambda";
import type { GuFunctionProps } from "../constructs/lambda";
import { GuSnsTopic } from "../constructs/sns";
/**
* Used to provide information about an existing SNS topic to the [[`GuSnsLambda`]] pattern.
*
* Specify a `existingLogicalId` to inherit an SNS topic which has already
* been created via a CloudFormation stack. This is necessary to avoid interruptions of
* service when migrating stacks from CloudFormation to `cdk`.
*
* Specify an `externalTopicName` to link the lambda to an SNS topic owned by a different stack
* (or created outside of version control).
*
* **Example Usage**
*
* When migrating a CloudFormation stack which includes the following resource:
* ```yaml
* MyCloudFormedSnsTopic:
* Type: AWS::SNS::Topic
* ```
* Inherit the SNS topic (rather than creating a new one) using:
* ```typescript
* existingSnsTopic: { existingLogicalId: "MyCloudFormedSnsTopic" }
* ```
*
* Alternatively, reference an SNS topic which belongs to another stack using:
* ```typescript
* existingSnsTopic: { externalTopicName: "MySnsTopicNameFromAnotherStack" }
* ```
*/
export interface ExistingSnsTopic extends GuMigratingResource {
externalTopicName?: string;
}
/**
* Configuration options for the [[`GuSnsLambda`]] pattern.
*
* For all lambda function configuration options, see [[`GuFunctionProps`]].
*
* The `existingSnsTopic` property can be used to inherit or reference an SNS topic which
* has been created outside of `cdk`. If this property is omitted, the [[`GuSnsLambda`]] pattern
* will create a new topic. For more details and example usage, see [[`ExistingSnsTopic`]].
*
* It is advisable to configure an alarm based on the lambda's error percentage.
* To do this, add the `monitoringConfiguration` property. The required properties for this are:
*
* ```typescript
* monitoringConfiguration: {
* toleratedErrorPercentage: <sensible_error_percentage_threshold>,
* snsTopicName: "my-topic-for-cloudwatch-alerts",
* }
* ```
* Other alarm properties (e.g. alarm name and description) will be pre-populated with sensible defaults.
* For a full list of optional properties, see [[`GuLambdaErrorPercentageMonitoringProps`]].
*
* If your team do not use CloudWatch, it's possible to opt-out with the following configuration:
* ```typescript
* monitoringConfiguration: { noMonitoring: true } as NoMonitoring
* ```
*/
export interface GuSnsLambdaProps extends Omit<GuFunctionProps, "errorPercentageMonitoring"> {
monitoringConfiguration: NoMonitoring | GuLambdaErrorPercentageMonitoringProps;
existingSnsTopic?: ExistingSnsTopic;
}
/**
* Pattern which creates all of the resources needed to invoke a lambda function whenever a message
* is published onto an SNS topic.
*
* This pattern will create a new SNS topic by default. If you are migrating a stack from CloudFormation,
* you will need to opt-out of this behaviour. For information on overriding the default behaviour,
* see [[`GuSnsLambdaProps`]].
*
* @alpha This pattern is in early development. The API is likely to change in future releases.
*/
export class GuSnsLambda extends GuLambdaFunction {
constructor(scope: GuStack, id: string, props: GuSnsLambdaProps) {
super(scope, id, {
...props,
errorPercentageMonitoring: props.monitoringConfiguration.noMonitoring ? undefined : props.monitoringConfiguration,
});
const topicId = props.existingSnsTopic?.existingLogicalId?.logicalId ?? "SnsIncomingEventsTopic";
const snsTopic = props.existingSnsTopic?.externalTopicName
? Topic.fromTopicArn(
scope,
topicId,
`arn:aws:sns:${scope.region}:${scope.account}:${props.existingSnsTopic.externalTopicName}`
)
: AppIdentity.taggedConstruct(
props,
new GuSnsTopic(scope, topicId, {
existingLogicalId: props.existingSnsTopic?.existingLogicalId,
})
);
this.addEventSource(new SnsEventSource(snsTopic));
new CfnOutput(this, "TopicName", { value: snsTopic.topicName });
}
}