-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathsns-lambda.ts
91 lines (84 loc) · 3.92 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
import { CfnOutput } from "aws-cdk-lib";
import { SnsEventSource } from "aws-cdk-lib/aws-lambda-event-sources";
import type { ITopic } from "aws-cdk-lib/aws-sns";
import { Topic } from "aws-cdk-lib/aws-sns";
import type { GuLambdaErrorPercentageMonitoringProps, NoMonitoring } from "../../constructs/cloudwatch";
import { AppIdentity } from "../../constructs/core";
import type { GuStack } from "../../constructs/core";
import { GuLambdaFunction } from "../../constructs/lambda";
import type { GuFunctionProps } from "../../constructs/lambda";
/**
* Used to provide information about an existing SNS topic to the [[`GuSnsLambda`]] pattern.
*
* Specify an `externalTopicName` to link the lambda to an SNS topic owned by a different stack
* (or created outside of version control).
*/
export interface ExistingSnsTopic {
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`]].
*
* The SNS topic is stateful, and is accessible via `snsTopic`.
* @see https://github.com/guardian/cdk/blob/main/docs/stateful-resources.md
*
* @experimental This pattern is in early development. The API is likely to change in future releases.
*/
export class GuSnsLambdaExperimental extends GuLambdaFunction {
public readonly snsTopic: ITopic;
constructor(scope: GuStack, id: string, props: GuSnsLambdaProps) {
super(scope, id, {
...props,
errorPercentageMonitoring: props.monitoringConfiguration.noMonitoring ? undefined : props.monitoringConfiguration,
});
const { account, region } = scope;
const { existingSnsTopic } = props;
this.snsTopic = existingSnsTopic
? Topic.fromTopicArn(
scope,
`${id}-SnsExistingIncomingEventsTopic`,
`arn:aws:sns:${region}:${account}:${existingSnsTopic.externalTopicName}`,
)
: AppIdentity.taggedConstruct(props, new Topic(scope, "SnsIncomingEventsTopic"));
// If we have an alias, use this to ensure that all events are sent to a published Lambda version.
// Otherwise, send all events to the latest unpublished version ($LATEST)
const eventSourceTarget = this.alias ?? this;
eventSourceTarget.addEventSource(new SnsEventSource(this.snsTopic));
new CfnOutput(this, "TopicName", { value: this.snsTopic.topicName });
}
}