Skip to content

Commit 508e593

Browse files
author
Sean Dawson
committed
feat: allow CloudFormation overrides
- We keep having to add new options to the config when someone needs to use an option in the CloudFormation template we haven't mapped yet - This should future proof the plugin to allow users to just pass whatever they need through to override the generated template - Eventually we could also deprecate and remove some of the other options that could just be overrides - Fixes #213
1 parent d0a6162 commit 508e593

6 files changed

+117
-10
lines changed

README.md

+42
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,25 @@ functions:
6060
- dog
6161
- cat
6262

63+
# Overrides for generated CloudFormation templates
64+
# Mirrors the CloudFormation docs but uses camel case instead of title case
65+
#
66+
# https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-sqs-queues.html
67+
mainQueueOverride:
68+
maximumMessageSize: 1024
69+
...
70+
deadLetterQueueOverride:
71+
maximumMessageSize: 1024
72+
...
73+
# https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-eventsourcemapping.html
74+
eventSourceMappingOverride:
75+
sourceAccessConfigurations:
76+
- Type: SASL_SCRAM_256_AUTH
77+
URI: arn:aws:secretsmanager:us-east-1:01234567890:secret:MyBrokerSecretName
78+
# https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-sns-subscription.html
79+
subscriptionOverride:
80+
region: ap-southeast-2
81+
6382
resources:
6483
Resources:
6584
Topic:
@@ -70,3 +89,26 @@ resources:
7089
plugins:
7190
- "@agiledigital/serverless-sns-sqs-lambda"
7291
```
92+
93+
### CloudFormation Overrides
94+
95+
If you would like to override a part of the CloudFormation template
96+
that is generated by this plugin, you can pass raw CloudFormation
97+
to the override config options outlined above.
98+
99+
The configuration must be provided with camel case keys,
100+
but apart from that, you can use the CloudFormation config
101+
as specified by AWS.
102+
103+
For example, if you wanted to override the maximumMessageSize for the main queue
104+
you could find the "MaximumMessageSize" config option in the [AWS documentation](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-sqs-queues.html)
105+
make the key camel case ("maximumMessageSize") and pass it into the override section:
106+
107+
```yaml
108+
events:
109+
- snsSqs:
110+
name: Example
111+
...
112+
mainQueueOverride:
113+
maximumMessageSize: 1024
114+
````
Binary file not shown.

example-service/serverless.yml

+16
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,22 @@ functions:
2828
- dog
2929
- cat
3030

31+
# Overrides for generated CloudFormation templates
32+
# Mirrors the CloudFormation docs but uses camel case instead of title case
33+
#
34+
#
35+
# https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-sqs-queues.html
36+
mainQueueOverride:
37+
maximumMessageSize: 1024
38+
deadLetterQueueOverride:
39+
maximumMessageSize: 2048
40+
# https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-eventsourcemapping.html
41+
eventSourceMappingOverride:
42+
enabled: false
43+
# https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-sns-subscription.html
44+
subscriptionOverride:
45+
rawMessageDelivery: true
46+
3147
resources:
3248
Resources:
3349
Topic:

lib/serverless-sns-sqs-lambda.ts

+53-10
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
33
/* eslint-disable @typescript-eslint/no-explicit-any */
44

5+
import { JsonObject } from "type-fest";
6+
57
/**
68
* Defines the structure of the config object
79
* that is passed to the main functions to
@@ -22,6 +24,11 @@ type Config = {
2224
visibilityTimeout: number;
2325
rawMessageDelivery: boolean;
2426
filterPolicy: any;
27+
28+
mainQueueOverride: JsonObject,
29+
deadLetterQueueOverride: JsonObject,
30+
eventSourceMappingOverride: JsonObject,
31+
subscriptionOverride: JsonObject,
2532
};
2633

2734
/**
@@ -47,9 +54,16 @@ const parseIntOr = (intString, defaultInt) => {
4754
*
4855
* @param {string} camelCase camelCase string
4956
*/
50-
const pascalCase = camelCase =>
57+
const pascalCase = (camelCase: string): string =>
5158
camelCase.slice(0, 1).toUpperCase() + camelCase.slice(1);
5259

60+
61+
const pascalCaseAllKeys = (jsonObject: JsonObject): JsonObject =>
62+
Object.keys(jsonObject).reduce((acc, key) => ({
63+
...acc,
64+
[pascalCase(key)]: jsonObject[key]
65+
}), {})
66+
5367
/**
5468
* The ServerlessSnsSqsLambda plugin looks for functions that contain an
5569
* `snsSqs` event and adds the necessary resources for the Lambda to subscribe
@@ -200,6 +214,25 @@ Usage
200214
pet:
201215
- dog
202216
- cat
217+
218+
# Overrides for generated CloudFormation templates
219+
# Mirrors the CloudFormation docs but uses camel case instead of title case
220+
#
221+
#
222+
# https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-sqs-queues.html
223+
mainQueueOverride:
224+
maximumMessageSize: 1024
225+
...
226+
deadLetterQueueOverride:
227+
maximumMessageSize: 1024
228+
...
229+
# https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-eventsourcemapping.html
230+
eventSourceMappingOverride:
231+
bisectBatchOnFunctionError: true
232+
# https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-sns-subscription.html
233+
subscriptionOverride:
234+
rawMessageDelivery: true
235+
203236
`);
204237
}
205238

@@ -221,7 +254,11 @@ Usage
221254
rawMessageDelivery:
222255
config.rawMessageDelivery !== undefined
223256
? config.rawMessageDelivery
224-
: false
257+
: false,
258+
mainQueueOverride: config.mainQueueOverride ?? {},
259+
deadLetterQueueOverride: config.deadLetterQueueOverride ?? {},
260+
eventSourceMappingOverride: config.eventSourceMappingOverride ?? {},
261+
subscriptionOverride: config.subscriptionOverride ?? {},
225262
};
226263
}
227264

@@ -235,7 +272,7 @@ Usage
235272
*/
236273
addEventSourceMapping(
237274
template,
238-
{ funcName, name, batchSize, maximumBatchingWindowInSeconds, enabled }: Config
275+
{ funcName, name, batchSize, maximumBatchingWindowInSeconds, enabled, eventSourceMappingOverride }: Config
239276
) {
240277
const enabledWithDefault = enabled !== undefined ? enabled : true;
241278
template.Resources[`${funcName}EventSourceMappingSQS${name}Queue`] = {
@@ -246,7 +283,8 @@ Usage
246283
MaximumBatchingWindowInSeconds: maximumBatchingWindowInSeconds !== undefined ? maximumBatchingWindowInSeconds : 0,
247284
EventSourceArn: { "Fn::GetAtt": [`${name}Queue`, "Arn"] },
248285
FunctionName: { "Fn::GetAtt": [`${funcName}LambdaFunction`, "Arn"] },
249-
Enabled: enabledWithDefault ? "True" : "False"
286+
Enabled: enabledWithDefault ? "True" : "False",
287+
...pascalCaseAllKeys(eventSourceMappingOverride)
250288
}
251289
};
252290
}
@@ -266,7 +304,8 @@ Usage
266304
prefix,
267305
kmsMasterKeyId,
268306
kmsDataKeyReusePeriodSeconds,
269-
deadLetterMessageRetentionPeriodSeconds
307+
deadLetterMessageRetentionPeriodSeconds,
308+
deadLetterQueueOverride
270309
}
271310
) {
272311
template.Resources[`${name}DeadLetterQueue`] = {
@@ -287,7 +326,8 @@ Usage
287326
? {
288327
MessageRetentionPeriod: deadLetterMessageRetentionPeriodSeconds
289328
}
290-
: {})
329+
: {}),
330+
...pascalCaseAllKeys(deadLetterQueueOverride)
291331
}
292332
};
293333
}
@@ -308,7 +348,8 @@ Usage
308348
maxRetryCount,
309349
kmsMasterKeyId,
310350
kmsDataKeyReusePeriodSeconds,
311-
visibilityTimeout
351+
visibilityTimeout,
352+
mainQueueOverride
312353
}: Config
313354
) {
314355
template.Resources[`${name}Queue`] = {
@@ -335,7 +376,8 @@ Usage
335376
? {
336377
VisibilityTimeout: visibilityTimeout
337378
}
338-
: {})
379+
: {}),
380+
...pascalCaseAllKeys(mainQueueOverride)
339381
}
340382
};
341383
}
@@ -379,7 +421,7 @@ Usage
379421
*/
380422
addTopicSubscription(
381423
template,
382-
{ name, topicArn, filterPolicy, rawMessageDelivery }: Config
424+
{ name, topicArn, filterPolicy, rawMessageDelivery, subscriptionOverride}: Config
383425
) {
384426
template.Resources[`Subscribe${name}Topic`] = {
385427
Type: "AWS::SNS::Subscription",
@@ -392,7 +434,8 @@ Usage
392434
? {
393435
RawMessageDelivery: rawMessageDelivery
394436
}
395-
: {})
437+
: {}),
438+
...pascalCaseAllKeys(subscriptionOverride)
396439
}
397440
};
398441
}

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
"serverless": "^2.19.0",
4141
"ts-jest": "^26.4.3",
4242
"type-coverage": "^2.14.0",
43+
"type-fest": "^1.0.2",
4344
"typescript": "^4.0.5"
4445
},
4546
"peerDependencies": {

yarn.lock

+5
Original file line numberDiff line numberDiff line change
@@ -10255,6 +10255,11 @@ type-fest@^0.8.1:
1025510255
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d"
1025610256
integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==
1025710257

10258+
type-fest@^1.0.2:
10259+
version "1.0.2"
10260+
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-1.0.2.tgz#3f9c39982859f385c77c38b7e5f1432b8a3661c6"
10261+
integrity sha512-a720oz3Kjbp3ll0zkeN9qjRhO7I34MKMhPGQiQJAmaZQZQ1lo+NWThK322f7sXV+kTg9B1Ybt16KgBXWgteT8w==
10262+
1025810263
type@^1.0.1:
1025910264
version "1.2.0"
1026010265
resolved "https://registry.yarnpkg.com/type/-/type-1.2.0.tgz#848dd7698dafa3e54a6c479e759c4bc3f18847a0"

0 commit comments

Comments
 (0)