@gradientedge/cdk-utils 5.5.0 → 5.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/lib/common/stack.js +14 -6
- package/dist/src/lib/manager/aws/iam-manager.d.ts +4 -0
- package/dist/src/lib/manager/aws/iam-manager.js +18 -0
- package/dist/src/lib/manager/aws/lambda-manager.js +6 -0
- package/dist/src/lib/manager/aws/sqs-manager.d.ts +18 -3
- package/dist/src/lib/manager/aws/sqs-manager.js +45 -6
- package/dist/src/lib/types/aws/index.d.ts +4 -0
- package/package.json +15 -15
- package/src/lib/common/stack.ts +8 -6
- package/src/lib/manager/aws/iam-manager.ts +19 -0
- package/src/lib/manager/aws/lambda-manager.ts +9 -0
- package/src/lib/manager/aws/sqs-manager.ts +57 -11
- package/src/lib/types/aws/index.ts +4 -0
|
@@ -82,8 +82,10 @@ class CommonStack extends cdk.Stack {
|
|
|
82
82
|
*/
|
|
83
83
|
determineExtraContexts() {
|
|
84
84
|
const extraContexts = this.node.tryGetContext('extraContexts');
|
|
85
|
+
const debug = this.node.tryGetContext('debug');
|
|
85
86
|
if (!extraContexts) {
|
|
86
|
-
|
|
87
|
+
if (debug)
|
|
88
|
+
console.debug(`No additional contexts provided. Using default context properties from cdk.json`);
|
|
87
89
|
return;
|
|
88
90
|
}
|
|
89
91
|
extraContexts.forEach((context) => {
|
|
@@ -93,7 +95,8 @@ class CommonStack extends cdk.Stack {
|
|
|
93
95
|
throw `Extra context properties unavailable in path:${extraContextPath}`;
|
|
94
96
|
/* read the extra properties */
|
|
95
97
|
const extraContextPropsBuffer = fs.readFileSync(extraContextPath);
|
|
96
|
-
|
|
98
|
+
if (debug)
|
|
99
|
+
console.debug(`Adding additional contexts provided in ${extraContextPath}`);
|
|
97
100
|
/* parse as JSON properties */
|
|
98
101
|
const extraContextProps = JSON.parse(extraContextPropsBuffer);
|
|
99
102
|
/* set each of the property into the cdk node context */
|
|
@@ -111,18 +114,23 @@ class CommonStack extends cdk.Stack {
|
|
|
111
114
|
const stage = this.node.tryGetContext('stage');
|
|
112
115
|
const stageContextPath = this.node.tryGetContext('stageContextPath') || 'cdkEnv';
|
|
113
116
|
const stageContextFilePath = `${appRoot.path}/${stageContextPath}/${stage}.json`;
|
|
117
|
+
const debug = this.node.tryGetContext('debug');
|
|
114
118
|
if ((0, utils_1.isDevStage)(stage)) {
|
|
115
|
-
|
|
119
|
+
if (debug)
|
|
120
|
+
console.debug(`Development stage. Using default stage context properties`);
|
|
116
121
|
}
|
|
117
122
|
/* alert default context usage when extra stage config is missing */
|
|
118
123
|
if (!fs.existsSync(stageContextFilePath)) {
|
|
119
|
-
|
|
120
|
-
|
|
124
|
+
if (debug)
|
|
125
|
+
console.debug(`Stage specific context properties unavailable in path:${stageContextFilePath}`);
|
|
126
|
+
if (debug)
|
|
127
|
+
console.debug(`Using default stage context properties for ${stage} stage`);
|
|
121
128
|
return;
|
|
122
129
|
}
|
|
123
130
|
/* read the extra properties */
|
|
124
131
|
const stageContextPropsBuffer = fs.readFileSync(stageContextFilePath);
|
|
125
|
-
|
|
132
|
+
if (debug)
|
|
133
|
+
console.debug(`Adding additional stage contexts provided in ${stageContextFilePath}`);
|
|
126
134
|
/* parse as JSON properties */
|
|
127
135
|
const stageContextProps = JSON.parse(stageContextPropsBuffer);
|
|
128
136
|
/* set each of the property into the cdk node context */
|
|
@@ -128,6 +128,10 @@ export declare class IamManager {
|
|
|
128
128
|
* @summary Method to create iam statement to write any log events
|
|
129
129
|
*/
|
|
130
130
|
statementForPutAnyLogEvent(): cdk.aws_iam.PolicyStatement;
|
|
131
|
+
/**
|
|
132
|
+
* @summary Method to create iam statement to read items from dynamodb table
|
|
133
|
+
*/
|
|
134
|
+
statementForReadTableItems(): cdk.aws_iam.PolicyStatement;
|
|
131
135
|
/**
|
|
132
136
|
* @summary Method to create iam statement for cloud trail
|
|
133
137
|
* @param {string} id scoped id of the resource
|
|
@@ -303,6 +303,24 @@ class IamManager {
|
|
|
303
303
|
resources: ['*'],
|
|
304
304
|
});
|
|
305
305
|
}
|
|
306
|
+
/**
|
|
307
|
+
* @summary Method to create iam statement to read items from dynamodb table
|
|
308
|
+
*/
|
|
309
|
+
statementForReadTableItems() {
|
|
310
|
+
return new iam.PolicyStatement({
|
|
311
|
+
effect: iam.Effect.ALLOW,
|
|
312
|
+
actions: [
|
|
313
|
+
'dynamodb:PartiQLSelect',
|
|
314
|
+
'dynamodb:DescribeTable',
|
|
315
|
+
'dynamodb:ListTables',
|
|
316
|
+
'dynamodb:GetItem',
|
|
317
|
+
'dynamodb:Scan',
|
|
318
|
+
'dynamodb:Query',
|
|
319
|
+
'dynamodb:GetRecords',
|
|
320
|
+
],
|
|
321
|
+
resources: ['*'],
|
|
322
|
+
});
|
|
323
|
+
}
|
|
306
324
|
/**
|
|
307
325
|
* @summary Method to create iam statement for cloud trail
|
|
308
326
|
* @param {string} id scoped id of the resource
|
|
@@ -87,6 +87,11 @@ class LambdaManager {
|
|
|
87
87
|
if (!props)
|
|
88
88
|
throw `Lambda props undefined`;
|
|
89
89
|
const functionName = `${props.functionName}-${scope.props.stage}`;
|
|
90
|
+
let deadLetterQueue;
|
|
91
|
+
if (props.deadLetterQueueEnabled && props.dlq) {
|
|
92
|
+
const redriveQueue = scope.sqsManager.createRedriveQueueForLambda(`${id}-rdq`, scope, props);
|
|
93
|
+
deadLetterQueue = scope.sqsManager.createDeadLetterQueueForLambda(`${id}-dlq`, scope, props, redriveQueue);
|
|
94
|
+
}
|
|
90
95
|
const lambdaFunction = new lambda.Function(scope, `${id}`, {
|
|
91
96
|
...props,
|
|
92
97
|
...{
|
|
@@ -95,6 +100,7 @@ class LambdaManager {
|
|
|
95
100
|
handler: handler || 'index.lambda_handler',
|
|
96
101
|
runtime: LambdaManager.NODEJS_RUNTIME,
|
|
97
102
|
code: code,
|
|
103
|
+
deadLetterQueue: deadLetterQueue,
|
|
98
104
|
environment: {
|
|
99
105
|
REGION: scope.props.region,
|
|
100
106
|
...environment,
|
|
@@ -16,7 +16,7 @@ import * as types from '../../types';
|
|
|
16
16
|
* constructor(parent: cdk.Construct, id: string, props: common.CommonStackProps) {
|
|
17
17
|
* super(parent, id, props)
|
|
18
18
|
* this.props = props
|
|
19
|
-
* this.sqsManager.
|
|
19
|
+
* this.sqsManager.createQueue('MySqs', this, {...})
|
|
20
20
|
* }
|
|
21
21
|
* }
|
|
22
22
|
*
|
|
@@ -28,7 +28,22 @@ export declare class SqsManager {
|
|
|
28
28
|
* @param {string} id scoped id of the resource
|
|
29
29
|
* @param {common.CommonConstruct} scope scope in which this resource is defined
|
|
30
30
|
* @param {types.QueueProps} props
|
|
31
|
-
* @param {sqs.
|
|
31
|
+
* @param {sqs.IQueue} deadLetterQueue
|
|
32
32
|
*/
|
|
33
|
-
|
|
33
|
+
createQueue(id: string, scope: common.CommonConstruct, props: types.QueueProps, deadLetterQueue?: sqs.IQueue): cdk.aws_sqs.Queue;
|
|
34
|
+
/**
|
|
35
|
+
* @summary Method to create a redrive queue for a lambda function
|
|
36
|
+
* @param {string} id scoped id of the resource
|
|
37
|
+
* @param {common.CommonConstruct} scope scope in which this resource is defined
|
|
38
|
+
* @param {types.LambdaProps} props the lambda properties
|
|
39
|
+
*/
|
|
40
|
+
createRedriveQueueForLambda(id: string, scope: common.CommonConstruct, props: types.LambdaProps): cdk.aws_sqs.Queue;
|
|
41
|
+
/**
|
|
42
|
+
* @summary Method to create a dead letter queue for a lambda function
|
|
43
|
+
* @param {string} id scoped id of the resource
|
|
44
|
+
* @param {common.CommonConstruct} scope scope in which this resource is defined
|
|
45
|
+
* @param {types.LambdaProps} props the lambda properties
|
|
46
|
+
* @param {sqs.IQueue} deadLetterQueue
|
|
47
|
+
*/
|
|
48
|
+
createDeadLetterQueueForLambda(id: string, scope: common.CommonConstruct, props: types.LambdaProps, deadLetterQueue: sqs.IQueue): cdk.aws_sqs.Queue;
|
|
34
49
|
}
|
|
@@ -41,7 +41,7 @@ const utils = __importStar(require("../../utils"));
|
|
|
41
41
|
* constructor(parent: cdk.Construct, id: string, props: common.CommonStackProps) {
|
|
42
42
|
* super(parent, id, props)
|
|
43
43
|
* this.props = props
|
|
44
|
-
* this.sqsManager.
|
|
44
|
+
* this.sqsManager.createQueue('MySqs', this, {...})
|
|
45
45
|
* }
|
|
46
46
|
* }
|
|
47
47
|
*
|
|
@@ -53,9 +53,9 @@ class SqsManager {
|
|
|
53
53
|
* @param {string} id scoped id of the resource
|
|
54
54
|
* @param {common.CommonConstruct} scope scope in which this resource is defined
|
|
55
55
|
* @param {types.QueueProps} props
|
|
56
|
-
* @param {sqs.
|
|
56
|
+
* @param {sqs.IQueue} deadLetterQueue
|
|
57
57
|
*/
|
|
58
|
-
|
|
58
|
+
createQueue(id, scope, props, deadLetterQueue) {
|
|
59
59
|
if (!props)
|
|
60
60
|
throw `Queue props undefined`;
|
|
61
61
|
const queue = new sqs.Queue(scope, id, {
|
|
@@ -64,7 +64,12 @@ class SqsManager {
|
|
|
64
64
|
receiveMessageWaitTime: cdk.Duration.seconds(props.receiveMessageWaitTimeInSecs),
|
|
65
65
|
contentBasedDeduplication: props.contentBasedDeduplication,
|
|
66
66
|
dataKeyReuse: cdk.Duration.seconds(props.dataKeyReuseInSecs),
|
|
67
|
-
deadLetterQueue: deadLetterQueue
|
|
67
|
+
deadLetterQueue: !deadLetterQueue
|
|
68
|
+
? undefined
|
|
69
|
+
: {
|
|
70
|
+
queue: deadLetterQueue,
|
|
71
|
+
maxReceiveCount: props.maxReceiveCount,
|
|
72
|
+
},
|
|
68
73
|
deduplicationScope: props.deduplicationScope,
|
|
69
74
|
deliveryDelay: cdk.Duration.seconds(props.deliveryDelayInSecs),
|
|
70
75
|
encryption: props.encryption,
|
|
@@ -72,13 +77,47 @@ class SqsManager {
|
|
|
72
77
|
fifo: props.fifo,
|
|
73
78
|
fifoThroughputLimit: props.fifoThroughputLimit,
|
|
74
79
|
maxMessageSizeBytes: props.maxMessageSizeBytes,
|
|
75
|
-
removalPolicy: props.removalPolicy,
|
|
76
|
-
retentionPeriod: props.
|
|
80
|
+
removalPolicy: props.removalPolicy ?? cdk.RemovalPolicy.DESTROY,
|
|
81
|
+
retentionPeriod: cdk.Duration.days(props.retentionInDays),
|
|
77
82
|
});
|
|
78
83
|
utils.createCfnOutput(`${id}-queueArn`, scope, queue.queueArn);
|
|
79
84
|
utils.createCfnOutput(`${id}-queueName`, scope, queue.queueName);
|
|
80
85
|
utils.createCfnOutput(`${id}-queueUrl`, scope, queue.queueUrl);
|
|
81
86
|
return queue;
|
|
82
87
|
}
|
|
88
|
+
/**
|
|
89
|
+
* @summary Method to create a redrive queue for a lambda function
|
|
90
|
+
* @param {string} id scoped id of the resource
|
|
91
|
+
* @param {common.CommonConstruct} scope scope in which this resource is defined
|
|
92
|
+
* @param {types.LambdaProps} props the lambda properties
|
|
93
|
+
*/
|
|
94
|
+
createRedriveQueueForLambda(id, scope, props) {
|
|
95
|
+
if (!props.dlq || !props.redriveq)
|
|
96
|
+
throw `Redrive queue props for Lambda undefined`;
|
|
97
|
+
return this.createQueue(`${id}`, scope, {
|
|
98
|
+
...props.dlq,
|
|
99
|
+
...props.redriveq,
|
|
100
|
+
...{
|
|
101
|
+
queueName: `${props.functionName}-redriveq-${scope.props.stage}`,
|
|
102
|
+
},
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* @summary Method to create a dead letter queue for a lambda function
|
|
107
|
+
* @param {string} id scoped id of the resource
|
|
108
|
+
* @param {common.CommonConstruct} scope scope in which this resource is defined
|
|
109
|
+
* @param {types.LambdaProps} props the lambda properties
|
|
110
|
+
* @param {sqs.IQueue} deadLetterQueue
|
|
111
|
+
*/
|
|
112
|
+
createDeadLetterQueueForLambda(id, scope, props, deadLetterQueue) {
|
|
113
|
+
if (!props.dlq)
|
|
114
|
+
throw `Dead letter queue props for Lambda undefined`;
|
|
115
|
+
return this.createQueue(`${id}`, scope, {
|
|
116
|
+
...props.dlq,
|
|
117
|
+
...{
|
|
118
|
+
queueName: `${props.functionName}-dlq-${scope.props.stage}`,
|
|
119
|
+
},
|
|
120
|
+
}, deadLetterQueue);
|
|
121
|
+
}
|
|
83
122
|
}
|
|
84
123
|
exports.SqsManager = SqsManager;
|
|
@@ -491,6 +491,8 @@ export interface EventBusProps extends events.EventBusProps {
|
|
|
491
491
|
* @subcategory Properties
|
|
492
492
|
*/
|
|
493
493
|
export interface LambdaProps extends lambda.FunctionProps {
|
|
494
|
+
dlq?: QueueProps;
|
|
495
|
+
redriveq?: QueueProps;
|
|
494
496
|
timeoutInSecs?: number;
|
|
495
497
|
}
|
|
496
498
|
/**
|
|
@@ -575,9 +577,11 @@ export interface ElastiCacheProps extends elasticache.CfnCacheClusterProps {
|
|
|
575
577
|
* @subcategory Properties
|
|
576
578
|
*/
|
|
577
579
|
export interface QueueProps extends sqs.QueueProps {
|
|
580
|
+
maxReceiveCount: number;
|
|
578
581
|
visibilityTimeoutInSecs: number;
|
|
579
582
|
receiveMessageWaitTimeInSecs: number;
|
|
580
583
|
dataKeyReuseInSecs: number;
|
|
581
584
|
deliveryDelayInSecs: number;
|
|
585
|
+
retentionInDays: number;
|
|
582
586
|
}
|
|
583
587
|
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gradientedge/cdk-utils",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.8.0",
|
|
4
4
|
"description": "Utilities for AWS CDK provisioning",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"engines": {
|
|
@@ -46,11 +46,11 @@
|
|
|
46
46
|
},
|
|
47
47
|
"dependencies": {
|
|
48
48
|
"@types/lodash": "^4.14.182",
|
|
49
|
-
"@types/node": "^
|
|
49
|
+
"@types/node": "^18.0.0",
|
|
50
50
|
"app-root-path": "^3.0.0",
|
|
51
|
-
"aws-cdk-lib": "^2.
|
|
52
|
-
"aws-sdk": "^2.
|
|
53
|
-
"constructs": "^10.1.
|
|
51
|
+
"aws-cdk-lib": "^2.28.1",
|
|
52
|
+
"aws-sdk": "^2.1158.0",
|
|
53
|
+
"constructs": "^10.1.42",
|
|
54
54
|
"lodash": "^4.17.21",
|
|
55
55
|
"moment": "^2.29.3",
|
|
56
56
|
"nconf": "^0.12.0",
|
|
@@ -59,16 +59,16 @@
|
|
|
59
59
|
},
|
|
60
60
|
"devDependencies": {
|
|
61
61
|
"@babel/plugin-proposal-class-properties": "^7.17.12",
|
|
62
|
-
"@types/jest": "^28.1.
|
|
63
|
-
"@typescript-eslint/eslint-plugin": "^5.
|
|
64
|
-
"@typescript-eslint/parser": "^5.
|
|
62
|
+
"@types/jest": "^28.1.2",
|
|
63
|
+
"@typescript-eslint/eslint-plugin": "^5.29.0",
|
|
64
|
+
"@typescript-eslint/parser": "^5.29.0",
|
|
65
65
|
"aws-cdk": "*",
|
|
66
66
|
"babel-eslint": "^10.1.0",
|
|
67
67
|
"better-docs": "^2.7.2",
|
|
68
68
|
"codecov": "^3.8.3",
|
|
69
69
|
"commitizen": "^4.2.4",
|
|
70
70
|
"dotenv": "^16.0.1",
|
|
71
|
-
"eslint": "^8.
|
|
71
|
+
"eslint": "^8.18.0",
|
|
72
72
|
"eslint-config-prettier": "^8.5.0",
|
|
73
73
|
"eslint-plugin-import": "^2.26.0",
|
|
74
74
|
"husky": "^8.0.1",
|
|
@@ -78,20 +78,20 @@
|
|
|
78
78
|
"jsdoc": "^3.6.10",
|
|
79
79
|
"jsdoc-babel": "^0.5.0",
|
|
80
80
|
"jsdoc-mermaid": "^1.0.0",
|
|
81
|
-
"lerna": "^5.1.
|
|
82
|
-
"prettier": "^2.7.
|
|
83
|
-
"prettier-plugin-organize-imports": "^
|
|
81
|
+
"lerna": "^5.1.4",
|
|
82
|
+
"prettier": "^2.7.1",
|
|
83
|
+
"prettier-plugin-organize-imports": "^3.0.0",
|
|
84
84
|
"rimraf": "^3.0.2",
|
|
85
85
|
"semantic-release": "^19.0.3",
|
|
86
86
|
"ts-jest": "^28.0.5",
|
|
87
87
|
"ts-node": "^10.8.1",
|
|
88
|
-
"typescript": "4.7.
|
|
88
|
+
"typescript": "4.7.4"
|
|
89
89
|
},
|
|
90
90
|
"optionalDependencies": {
|
|
91
91
|
"@babel/core": "^7.18.5",
|
|
92
92
|
"prop-types": "^15.8.1",
|
|
93
|
-
"react": "^
|
|
94
|
-
"react-dom": "^
|
|
93
|
+
"react": "^17.0.2",
|
|
94
|
+
"react-dom": "^17.0.2"
|
|
95
95
|
},
|
|
96
96
|
"config": {
|
|
97
97
|
"commitizen": {
|
package/src/lib/common/stack.ts
CHANGED
|
@@ -66,9 +66,10 @@ export class CommonStack extends cdk.Stack {
|
|
|
66
66
|
*/
|
|
67
67
|
protected determineExtraContexts() {
|
|
68
68
|
const extraContexts = this.node.tryGetContext('extraContexts')
|
|
69
|
+
const debug = this.node.tryGetContext('debug')
|
|
69
70
|
|
|
70
71
|
if (!extraContexts) {
|
|
71
|
-
console.
|
|
72
|
+
if (debug) console.debug(`No additional contexts provided. Using default context properties from cdk.json`)
|
|
72
73
|
return
|
|
73
74
|
}
|
|
74
75
|
|
|
@@ -80,7 +81,7 @@ export class CommonStack extends cdk.Stack {
|
|
|
80
81
|
|
|
81
82
|
/* read the extra properties */
|
|
82
83
|
const extraContextPropsBuffer = fs.readFileSync(extraContextPath)
|
|
83
|
-
console.
|
|
84
|
+
if (debug) console.debug(`Adding additional contexts provided in ${extraContextPath}`)
|
|
84
85
|
|
|
85
86
|
/* parse as JSON properties */
|
|
86
87
|
const extraContextProps = JSON.parse(extraContextPropsBuffer)
|
|
@@ -101,21 +102,22 @@ export class CommonStack extends cdk.Stack {
|
|
|
101
102
|
const stage = this.node.tryGetContext('stage')
|
|
102
103
|
const stageContextPath = this.node.tryGetContext('stageContextPath') || 'cdkEnv'
|
|
103
104
|
const stageContextFilePath = `${appRoot.path}/${stageContextPath}/${stage}.json`
|
|
105
|
+
const debug = this.node.tryGetContext('debug')
|
|
104
106
|
|
|
105
107
|
if (isDevStage(stage)) {
|
|
106
|
-
console.
|
|
108
|
+
if (debug) console.debug(`Development stage. Using default stage context properties`)
|
|
107
109
|
}
|
|
108
110
|
|
|
109
111
|
/* alert default context usage when extra stage config is missing */
|
|
110
112
|
if (!fs.existsSync(stageContextFilePath)) {
|
|
111
|
-
console.
|
|
112
|
-
console.
|
|
113
|
+
if (debug) console.debug(`Stage specific context properties unavailable in path:${stageContextFilePath}`)
|
|
114
|
+
if (debug) console.debug(`Using default stage context properties for ${stage} stage`)
|
|
113
115
|
return
|
|
114
116
|
}
|
|
115
117
|
|
|
116
118
|
/* read the extra properties */
|
|
117
119
|
const stageContextPropsBuffer = fs.readFileSync(stageContextFilePath)
|
|
118
|
-
console.
|
|
120
|
+
if (debug) console.debug(`Adding additional stage contexts provided in ${stageContextFilePath}`)
|
|
119
121
|
|
|
120
122
|
/* parse as JSON properties */
|
|
121
123
|
const stageContextProps = JSON.parse(stageContextPropsBuffer)
|
|
@@ -308,6 +308,25 @@ export class IamManager {
|
|
|
308
308
|
})
|
|
309
309
|
}
|
|
310
310
|
|
|
311
|
+
/**
|
|
312
|
+
* @summary Method to create iam statement to read items from dynamodb table
|
|
313
|
+
*/
|
|
314
|
+
public statementForReadTableItems() {
|
|
315
|
+
return new iam.PolicyStatement({
|
|
316
|
+
effect: iam.Effect.ALLOW,
|
|
317
|
+
actions: [
|
|
318
|
+
'dynamodb:PartiQLSelect',
|
|
319
|
+
'dynamodb:DescribeTable',
|
|
320
|
+
'dynamodb:ListTables',
|
|
321
|
+
'dynamodb:GetItem',
|
|
322
|
+
'dynamodb:Scan',
|
|
323
|
+
'dynamodb:Query',
|
|
324
|
+
'dynamodb:GetRecords',
|
|
325
|
+
],
|
|
326
|
+
resources: ['*'],
|
|
327
|
+
})
|
|
328
|
+
}
|
|
329
|
+
|
|
311
330
|
/**
|
|
312
331
|
* @summary Method to create iam statement for cloud trail
|
|
313
332
|
* @param {string} id scoped id of the resource
|
|
@@ -30,6 +30,7 @@ import { CloudFrontManager } from './cloudfront-manager'
|
|
|
30
30
|
*/
|
|
31
31
|
export class LambdaManager {
|
|
32
32
|
public static NODEJS_RUNTIME = lambda.Runtime.NODEJS_16_X
|
|
33
|
+
|
|
33
34
|
/**
|
|
34
35
|
* @summary Method to create a lambda layer (nodejs)
|
|
35
36
|
* @param {string} id scoped id of the resource
|
|
@@ -83,6 +84,13 @@ export class LambdaManager {
|
|
|
83
84
|
if (!props) throw `Lambda props undefined`
|
|
84
85
|
|
|
85
86
|
const functionName = `${props.functionName}-${scope.props.stage}`
|
|
87
|
+
|
|
88
|
+
let deadLetterQueue
|
|
89
|
+
if (props.deadLetterQueueEnabled && props.dlq) {
|
|
90
|
+
const redriveQueue = scope.sqsManager.createRedriveQueueForLambda(`${id}-rdq`, scope, props)
|
|
91
|
+
deadLetterQueue = scope.sqsManager.createDeadLetterQueueForLambda(`${id}-dlq`, scope, props, redriveQueue)
|
|
92
|
+
}
|
|
93
|
+
|
|
86
94
|
const lambdaFunction = new lambda.Function(scope, `${id}`, {
|
|
87
95
|
...props,
|
|
88
96
|
...{
|
|
@@ -91,6 +99,7 @@ export class LambdaManager {
|
|
|
91
99
|
handler: handler || 'index.lambda_handler',
|
|
92
100
|
runtime: LambdaManager.NODEJS_RUNTIME,
|
|
93
101
|
code: code,
|
|
102
|
+
deadLetterQueue: deadLetterQueue,
|
|
94
103
|
environment: {
|
|
95
104
|
REGION: scope.props.region,
|
|
96
105
|
...environment,
|
|
@@ -18,7 +18,7 @@ import * as utils from '../../utils'
|
|
|
18
18
|
* constructor(parent: cdk.Construct, id: string, props: common.CommonStackProps) {
|
|
19
19
|
* super(parent, id, props)
|
|
20
20
|
* this.props = props
|
|
21
|
-
* this.sqsManager.
|
|
21
|
+
* this.sqsManager.createQueue('MySqs', this, {...})
|
|
22
22
|
* }
|
|
23
23
|
* }
|
|
24
24
|
*
|
|
@@ -30,14 +30,9 @@ export class SqsManager {
|
|
|
30
30
|
* @param {string} id scoped id of the resource
|
|
31
31
|
* @param {common.CommonConstruct} scope scope in which this resource is defined
|
|
32
32
|
* @param {types.QueueProps} props
|
|
33
|
-
* @param {sqs.
|
|
33
|
+
* @param {sqs.IQueue} deadLetterQueue
|
|
34
34
|
*/
|
|
35
|
-
public
|
|
36
|
-
id: string,
|
|
37
|
-
scope: common.CommonConstruct,
|
|
38
|
-
props: types.QueueProps,
|
|
39
|
-
deadLetterQueue?: sqs.DeadLetterQueue
|
|
40
|
-
) {
|
|
35
|
+
public createQueue(id: string, scope: common.CommonConstruct, props: types.QueueProps, deadLetterQueue?: sqs.IQueue) {
|
|
41
36
|
if (!props) throw `Queue props undefined`
|
|
42
37
|
|
|
43
38
|
const queue = new sqs.Queue(scope, id, {
|
|
@@ -46,7 +41,12 @@ export class SqsManager {
|
|
|
46
41
|
receiveMessageWaitTime: cdk.Duration.seconds(props.receiveMessageWaitTimeInSecs),
|
|
47
42
|
contentBasedDeduplication: props.contentBasedDeduplication,
|
|
48
43
|
dataKeyReuse: cdk.Duration.seconds(props.dataKeyReuseInSecs),
|
|
49
|
-
deadLetterQueue: deadLetterQueue
|
|
44
|
+
deadLetterQueue: !deadLetterQueue
|
|
45
|
+
? undefined
|
|
46
|
+
: {
|
|
47
|
+
queue: deadLetterQueue,
|
|
48
|
+
maxReceiveCount: props.maxReceiveCount,
|
|
49
|
+
},
|
|
50
50
|
deduplicationScope: props.deduplicationScope,
|
|
51
51
|
deliveryDelay: cdk.Duration.seconds(props.deliveryDelayInSecs),
|
|
52
52
|
encryption: props.encryption,
|
|
@@ -54,8 +54,8 @@ export class SqsManager {
|
|
|
54
54
|
fifo: props.fifo,
|
|
55
55
|
fifoThroughputLimit: props.fifoThroughputLimit,
|
|
56
56
|
maxMessageSizeBytes: props.maxMessageSizeBytes,
|
|
57
|
-
removalPolicy: props.removalPolicy,
|
|
58
|
-
retentionPeriod: props.
|
|
57
|
+
removalPolicy: props.removalPolicy ?? cdk.RemovalPolicy.DESTROY,
|
|
58
|
+
retentionPeriod: cdk.Duration.days(props.retentionInDays),
|
|
59
59
|
})
|
|
60
60
|
|
|
61
61
|
utils.createCfnOutput(`${id}-queueArn`, scope, queue.queueArn)
|
|
@@ -64,4 +64,50 @@ export class SqsManager {
|
|
|
64
64
|
|
|
65
65
|
return queue
|
|
66
66
|
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* @summary Method to create a redrive queue for a lambda function
|
|
70
|
+
* @param {string} id scoped id of the resource
|
|
71
|
+
* @param {common.CommonConstruct} scope scope in which this resource is defined
|
|
72
|
+
* @param {types.LambdaProps} props the lambda properties
|
|
73
|
+
*/
|
|
74
|
+
public createRedriveQueueForLambda(id: string, scope: common.CommonConstruct, props: types.LambdaProps) {
|
|
75
|
+
if (!props.dlq || !props.redriveq) throw `Redrive queue props for Lambda undefined`
|
|
76
|
+
|
|
77
|
+
return this.createQueue(`${id}`, scope, {
|
|
78
|
+
...props.dlq,
|
|
79
|
+
...props.redriveq,
|
|
80
|
+
...{
|
|
81
|
+
queueName: `${props.functionName}-redriveq-${scope.props.stage}`,
|
|
82
|
+
},
|
|
83
|
+
})
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* @summary Method to create a dead letter queue for a lambda function
|
|
88
|
+
* @param {string} id scoped id of the resource
|
|
89
|
+
* @param {common.CommonConstruct} scope scope in which this resource is defined
|
|
90
|
+
* @param {types.LambdaProps} props the lambda properties
|
|
91
|
+
* @param {sqs.IQueue} deadLetterQueue
|
|
92
|
+
*/
|
|
93
|
+
public createDeadLetterQueueForLambda(
|
|
94
|
+
id: string,
|
|
95
|
+
scope: common.CommonConstruct,
|
|
96
|
+
props: types.LambdaProps,
|
|
97
|
+
deadLetterQueue: sqs.IQueue
|
|
98
|
+
) {
|
|
99
|
+
if (!props.dlq) throw `Dead letter queue props for Lambda undefined`
|
|
100
|
+
|
|
101
|
+
return this.createQueue(
|
|
102
|
+
`${id}`,
|
|
103
|
+
scope,
|
|
104
|
+
{
|
|
105
|
+
...props.dlq,
|
|
106
|
+
...{
|
|
107
|
+
queueName: `${props.functionName}-dlq-${scope.props.stage}`,
|
|
108
|
+
},
|
|
109
|
+
},
|
|
110
|
+
deadLetterQueue
|
|
111
|
+
)
|
|
112
|
+
}
|
|
67
113
|
}
|
|
@@ -524,6 +524,8 @@ export interface EventBusProps extends events.EventBusProps {}
|
|
|
524
524
|
* @subcategory Properties
|
|
525
525
|
*/
|
|
526
526
|
export interface LambdaProps extends lambda.FunctionProps {
|
|
527
|
+
dlq?: QueueProps
|
|
528
|
+
redriveq?: QueueProps
|
|
527
529
|
timeoutInSecs?: number
|
|
528
530
|
}
|
|
529
531
|
|
|
@@ -614,8 +616,10 @@ export interface ElastiCacheProps extends elasticache.CfnCacheClusterProps {}
|
|
|
614
616
|
* @subcategory Properties
|
|
615
617
|
*/
|
|
616
618
|
export interface QueueProps extends sqs.QueueProps {
|
|
619
|
+
maxReceiveCount: number
|
|
617
620
|
visibilityTimeoutInSecs: number
|
|
618
621
|
receiveMessageWaitTimeInSecs: number
|
|
619
622
|
dataKeyReuseInSecs: number
|
|
620
623
|
deliveryDelayInSecs: number
|
|
624
|
+
retentionInDays: number
|
|
621
625
|
}
|