skuba 9.0.0 → 9.0.1-upgrade-cdk-template-20241002233314
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/package.json +1 -1
- package/template/greeter/package.json +1 -1
- package/template/lambda-sqs-worker/serverless.yml +1 -1
- package/template/lambda-sqs-worker-cdk/.env +1 -0
- package/template/lambda-sqs-worker-cdk/README.md +145 -0
- package/template/lambda-sqs-worker-cdk/infra/__snapshots__/appStack.test.ts.snap +102 -134
- package/template/lambda-sqs-worker-cdk/infra/appStack.test.ts +13 -2
- package/template/lambda-sqs-worker-cdk/infra/appStack.ts +52 -6
- package/template/lambda-sqs-worker-cdk/infra/config.ts +3 -0
- package/template/lambda-sqs-worker-cdk/package.json +8 -1
- package/template/lambda-sqs-worker-cdk/src/app.test.ts +116 -0
- package/template/lambda-sqs-worker-cdk/src/app.ts +43 -21
- package/template/lambda-sqs-worker-cdk/src/config.ts +15 -0
- package/template/lambda-sqs-worker-cdk/src/framework/handler.test.ts +61 -0
- package/template/lambda-sqs-worker-cdk/src/framework/handler.ts +43 -0
- package/template/lambda-sqs-worker-cdk/src/framework/logging.ts +27 -0
- package/template/lambda-sqs-worker-cdk/src/framework/metrics.ts +14 -0
- package/template/lambda-sqs-worker-cdk/src/framework/validation.test.ts +84 -0
- package/template/lambda-sqs-worker-cdk/src/framework/validation.ts +10 -0
- package/template/lambda-sqs-worker-cdk/src/mapping/jobScorer.ts +22 -0
- package/template/lambda-sqs-worker-cdk/src/services/aws.ts +5 -0
- package/template/lambda-sqs-worker-cdk/src/services/jobScorer.test.ts +44 -0
- package/template/lambda-sqs-worker-cdk/src/services/jobScorer.ts +59 -0
- package/template/lambda-sqs-worker-cdk/src/services/pipelineEventSender.test.ts +40 -0
- package/template/lambda-sqs-worker-cdk/src/services/pipelineEventSender.ts +33 -0
- package/template/lambda-sqs-worker-cdk/src/testing/handler.ts +13 -0
- package/template/lambda-sqs-worker-cdk/src/testing/logging.ts +19 -0
- package/template/lambda-sqs-worker-cdk/src/testing/services.ts +28 -0
- package/template/lambda-sqs-worker-cdk/src/testing/types.ts +33 -0
- package/template/lambda-sqs-worker-cdk/src/types/jobScorer.ts +15 -0
- package/template/lambda-sqs-worker-cdk/src/types/pipelineEvents.ts +21 -0
package/package.json
CHANGED
|
@@ -173,7 +173,7 @@ resources:
|
|
|
173
173
|
# Properties:
|
|
174
174
|
# Endpoint: !GetAtt MessageQueue.Arn
|
|
175
175
|
# Protocol: sqs
|
|
176
|
-
# RawMessageDelivery: true
|
|
176
|
+
# RawMessageDelivery: true # Remove this property if you require end to end datadog tracing
|
|
177
177
|
# TopicArn: 'TODO: sourceSnsTopicArn'
|
|
178
178
|
|
|
179
179
|
DestinationTopic:
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ENVIRONMENT=local
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
# <%- repoName %>
|
|
2
|
+
|
|
3
|
+
[](https://github.com/seek-oss/skuba)
|
|
4
|
+
|
|
5
|
+
Next steps:
|
|
6
|
+
|
|
7
|
+
1. [ ] Finish templating if this was skipped earlier:
|
|
8
|
+
|
|
9
|
+
```shell
|
|
10
|
+
pnpm exec skuba configure
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
2. [ ] Create a new repository in the appropriate GitHub organisation.
|
|
14
|
+
3. [ ] Add the repository to BuildAgency;
|
|
15
|
+
see our internal [Buildkite Docs] for more information.
|
|
16
|
+
4. [ ] Add Datadog extension, deployment bucket configuration and data classification tags to [infra/config.ts](infra/config.ts).
|
|
17
|
+
5. [ ] Push local commits to the upstream GitHub branch.
|
|
18
|
+
6. [ ] Configure [GitHub repository settings].
|
|
19
|
+
7. [ ] Delete this checklist 😌.
|
|
20
|
+
|
|
21
|
+
[Buildkite Docs]: https://backstage.myseek.xyz/docs/default/component/buildkite-docs
|
|
22
|
+
[GitHub repository settings]: https://github.com/<%-orgName%>/<%-repoName%>/settings
|
|
23
|
+
|
|
24
|
+
## Design
|
|
25
|
+
|
|
26
|
+
<%-repoName %> is a Node.js [Lambda] application built in line with our [Technical Guidelines].
|
|
27
|
+
It is backed by a typical SQS message + dead letter queue configuration and uses common SEEK packages.
|
|
28
|
+
Workers enable fault-tolerant asynchronous processing of events.
|
|
29
|
+
|
|
30
|
+
The `lambda-sqs-worker-cdk` template is modelled after a hypothetical enricher that scores job advertisements.
|
|
31
|
+
It's stubbed out with in-memory [scoring service](src/services/jobScorer.ts).
|
|
32
|
+
This would be replaced with internal logic or an external service in production.
|
|
33
|
+
|
|
34
|
+
This project is deployed with [AWS CDK].
|
|
35
|
+
The Lambda runtime provisions a single Node.js process per container.
|
|
36
|
+
The supplied [infra/appStack.ts](infra/appStack.ts) starts out with a minimal `memorySize` which may require tuning based on workload.
|
|
37
|
+
Under load, we autoscale horizontally in terms of container count up to `reservedConcurrency`.
|
|
38
|
+
|
|
39
|
+
[@seek/aws-codedeploy-hooks] configures [CodeDeploy] for a blue-green deployment approach.
|
|
40
|
+
A smoke test is run against the new version before traffic is switched over,
|
|
41
|
+
providing an opportunity to test access and connectivity to online dependencies.
|
|
42
|
+
This defaults to an invocation with an empty object `{}`.
|
|
43
|
+
|
|
44
|
+
## Development
|
|
45
|
+
|
|
46
|
+
### Test
|
|
47
|
+
|
|
48
|
+
```shell
|
|
49
|
+
# Run Jest tests locally
|
|
50
|
+
pnpm test
|
|
51
|
+
|
|
52
|
+
# Authenticate to dev account
|
|
53
|
+
awsauth
|
|
54
|
+
|
|
55
|
+
# Run smoke test against deployed application
|
|
56
|
+
ENVIRONMENT=dev pnpm smoke
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Lint
|
|
60
|
+
|
|
61
|
+
```shell
|
|
62
|
+
# Fix issues
|
|
63
|
+
pnpm format
|
|
64
|
+
|
|
65
|
+
# Check for issues
|
|
66
|
+
pnpm lint
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Start
|
|
70
|
+
|
|
71
|
+
```shell
|
|
72
|
+
# Start a local HTTP server
|
|
73
|
+
pnpm start
|
|
74
|
+
|
|
75
|
+
# Start with Node.js Inspector enabled
|
|
76
|
+
pnpm start:debug
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
This serves the Lambda application over HTTP.
|
|
80
|
+
For example, to invoke the handler with an empty object `{}` for smoke testing:
|
|
81
|
+
|
|
82
|
+
```shell
|
|
83
|
+
curl --data '[{}, {"awsRequestId": "local"}]' --include localhost:<%- port %>
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Deploy
|
|
87
|
+
|
|
88
|
+
This project is deployed through a [Buildkite pipeline](.buildkite/pipeline.yml).
|
|
89
|
+
|
|
90
|
+
- Commits to a feature branch can be deployed to the dev environment by unblocking a step in the Buildkite UI
|
|
91
|
+
- Commits to the default branch are automatically deployed to the dev and prod environments in sequence
|
|
92
|
+
|
|
93
|
+
To deploy locally:
|
|
94
|
+
|
|
95
|
+
```shell
|
|
96
|
+
# Authenticate to dev account
|
|
97
|
+
awsauth
|
|
98
|
+
|
|
99
|
+
ENVIRONMENT=dev pnpm run deploy
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
A hotswap deploy enables faster deployment but come with caveats such as requiring a Lambda to be rebuilt with every build.
|
|
103
|
+
|
|
104
|
+
To deploy a [hotswap]:
|
|
105
|
+
|
|
106
|
+
```shell
|
|
107
|
+
# Authenticate to dev account
|
|
108
|
+
awsauth
|
|
109
|
+
|
|
110
|
+
ENVIRONMENT=dev pnpm run deploy:hotswap
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
To rapidly roll back a change,
|
|
114
|
+
retry an individual deployment step from the previous build in Buildkite.
|
|
115
|
+
Note that this will introduce drift between the head of the default Git branch and the live environment;
|
|
116
|
+
use with caution and always follow up with a proper revert or fix in Git history.
|
|
117
|
+
|
|
118
|
+
## Support
|
|
119
|
+
|
|
120
|
+
### Dev
|
|
121
|
+
|
|
122
|
+
TODO: add support links for the dev environment.
|
|
123
|
+
|
|
124
|
+
<!--
|
|
125
|
+
- CloudWatch dashboard
|
|
126
|
+
- Datadog dashboard
|
|
127
|
+
- Splunk logs
|
|
128
|
+
-->
|
|
129
|
+
|
|
130
|
+
### Prod
|
|
131
|
+
|
|
132
|
+
TODO: add support links for the prod environment.
|
|
133
|
+
|
|
134
|
+
<!--
|
|
135
|
+
- CloudWatch dashboard
|
|
136
|
+
- Datadog dashboard
|
|
137
|
+
- Splunk logs
|
|
138
|
+
-->
|
|
139
|
+
|
|
140
|
+
[@seek/aws-codedeploy-hooks]: https://github.com/seek-oss/aws-codedeploy-hooks
|
|
141
|
+
[AWS CDK]: https://docs.aws.amazon.com/cdk/v2/guide/home.html
|
|
142
|
+
[CodeDeploy]: https://docs.aws.amazon.com/codedeploy
|
|
143
|
+
[Hotswap]: https://docs.aws.amazon.com/cdk/v2/guide/ref-cli-cmd-deploy.html#ref-cli-cmd-deploy-options
|
|
144
|
+
[Lambda]: https://docs.aws.amazon.com/lambda
|
|
145
|
+
[Technical Guidelines]: https://myseek.atlassian.net/wiki/spaces/AA/pages/2358346017/
|
|
@@ -10,6 +10,40 @@ exports[`returns expected CloudFormation stack for dev 1`] = `
|
|
|
10
10
|
},
|
|
11
11
|
},
|
|
12
12
|
"Resources": {
|
|
13
|
+
"datadogapikeysecret046FEF06": {
|
|
14
|
+
"DeletionPolicy": "Delete",
|
|
15
|
+
"Properties": {
|
|
16
|
+
"GenerateSecretString": {},
|
|
17
|
+
},
|
|
18
|
+
"Type": "AWS::SecretsManager::Secret",
|
|
19
|
+
"UpdateReplacePolicy": "Delete",
|
|
20
|
+
},
|
|
21
|
+
"destinationtopicDCE2E0B8": {
|
|
22
|
+
"Properties": {
|
|
23
|
+
"KmsMasterKeyId": {
|
|
24
|
+
"Fn::Join": [
|
|
25
|
+
"",
|
|
26
|
+
[
|
|
27
|
+
"arn:",
|
|
28
|
+
{
|
|
29
|
+
"Ref": "AWS::Partition",
|
|
30
|
+
},
|
|
31
|
+
":kms:",
|
|
32
|
+
{
|
|
33
|
+
"Ref": "AWS::Region",
|
|
34
|
+
},
|
|
35
|
+
":",
|
|
36
|
+
{
|
|
37
|
+
"Ref": "AWS::AccountId",
|
|
38
|
+
},
|
|
39
|
+
":alias/aws/sns",
|
|
40
|
+
],
|
|
41
|
+
],
|
|
42
|
+
},
|
|
43
|
+
"TopicName": "serviceName",
|
|
44
|
+
},
|
|
45
|
+
"Type": "AWS::SNS::Topic",
|
|
46
|
+
},
|
|
13
47
|
"kmskey49FBC3B3": {
|
|
14
48
|
"DeletionPolicy": "Retain",
|
|
15
49
|
"Properties": {
|
|
@@ -105,17 +139,6 @@ exports[`returns expected CloudFormation stack for dev 1`] = `
|
|
|
105
139
|
},
|
|
106
140
|
"Resource": "*",
|
|
107
141
|
},
|
|
108
|
-
{
|
|
109
|
-
"Action": [
|
|
110
|
-
"kms:Decrypt",
|
|
111
|
-
"kms:GenerateDataKey",
|
|
112
|
-
],
|
|
113
|
-
"Effect": "Allow",
|
|
114
|
-
"Principal": {
|
|
115
|
-
"Service": "sns.amazonaws.com",
|
|
116
|
-
},
|
|
117
|
-
"Resource": "*",
|
|
118
|
-
},
|
|
119
142
|
],
|
|
120
143
|
"Version": "2012-10-17",
|
|
121
144
|
},
|
|
@@ -135,9 +158,6 @@ exports[`returns expected CloudFormation stack for dev 1`] = `
|
|
|
135
158
|
},
|
|
136
159
|
"Type": "AWS::KMS::Alias",
|
|
137
160
|
},
|
|
138
|
-
"sourcetopic7C3DC892": {
|
|
139
|
-
"Type": "AWS::SNS::Topic",
|
|
140
|
-
},
|
|
141
161
|
"worker28EA3E30": {
|
|
142
162
|
"DependsOn": [
|
|
143
163
|
"workerServiceRoleDefaultPolicyBA498553",
|
|
@@ -156,6 +176,9 @@ exports[`returns expected CloudFormation stack for dev 1`] = `
|
|
|
156
176
|
"Description": "Updated at 1212-12-12T12:12:12.121Z",
|
|
157
177
|
"Environment": {
|
|
158
178
|
"Variables": {
|
|
179
|
+
"DESTINATION_SNS_TOPIC_ARN": {
|
|
180
|
+
"Ref": "destinationtopicDCE2E0B8",
|
|
181
|
+
},
|
|
159
182
|
"ENVIRONMENT": "dev",
|
|
160
183
|
"NODE_ENV": "production",
|
|
161
184
|
"NODE_OPTIONS": "--enable-source-maps",
|
|
@@ -171,6 +194,20 @@ exports[`returns expected CloudFormation stack for dev 1`] = `
|
|
|
171
194
|
"Arn",
|
|
172
195
|
],
|
|
173
196
|
},
|
|
197
|
+
"Layers": [
|
|
198
|
+
{
|
|
199
|
+
"Fn::Join": [
|
|
200
|
+
"",
|
|
201
|
+
[
|
|
202
|
+
"arn:aws:lambda:",
|
|
203
|
+
{
|
|
204
|
+
"Ref": "AWS::Region",
|
|
205
|
+
},
|
|
206
|
+
":464622532012:layer:Datadog-Extension-ARM:58",
|
|
207
|
+
],
|
|
208
|
+
],
|
|
209
|
+
},
|
|
210
|
+
],
|
|
174
211
|
"ReservedConcurrentExecutions": 2,
|
|
175
212
|
"Role": {
|
|
176
213
|
"Fn::GetAtt": [
|
|
@@ -611,59 +648,6 @@ exports[`returns expected CloudFormation stack for dev 1`] = `
|
|
|
611
648
|
"Type": "AWS::SQS::Queue",
|
|
612
649
|
"UpdateReplacePolicy": "Delete",
|
|
613
650
|
},
|
|
614
|
-
"workerqueuePolicy97054CB4": {
|
|
615
|
-
"Properties": {
|
|
616
|
-
"PolicyDocument": {
|
|
617
|
-
"Statement": [
|
|
618
|
-
{
|
|
619
|
-
"Action": "sqs:SendMessage",
|
|
620
|
-
"Condition": {
|
|
621
|
-
"ArnEquals": {
|
|
622
|
-
"aws:SourceArn": {
|
|
623
|
-
"Ref": "sourcetopic7C3DC892",
|
|
624
|
-
},
|
|
625
|
-
},
|
|
626
|
-
},
|
|
627
|
-
"Effect": "Allow",
|
|
628
|
-
"Principal": {
|
|
629
|
-
"Service": "sns.amazonaws.com",
|
|
630
|
-
},
|
|
631
|
-
"Resource": {
|
|
632
|
-
"Fn::GetAtt": [
|
|
633
|
-
"workerqueueA05CE5C6",
|
|
634
|
-
"Arn",
|
|
635
|
-
],
|
|
636
|
-
},
|
|
637
|
-
},
|
|
638
|
-
],
|
|
639
|
-
"Version": "2012-10-17",
|
|
640
|
-
},
|
|
641
|
-
"Queues": [
|
|
642
|
-
{
|
|
643
|
-
"Ref": "workerqueueA05CE5C6",
|
|
644
|
-
},
|
|
645
|
-
],
|
|
646
|
-
},
|
|
647
|
-
"Type": "AWS::SQS::QueuePolicy",
|
|
648
|
-
},
|
|
649
|
-
"workerqueueappStacksourcetopic613C6BDBD2F224F5": {
|
|
650
|
-
"DependsOn": [
|
|
651
|
-
"workerqueuePolicy97054CB4",
|
|
652
|
-
],
|
|
653
|
-
"Properties": {
|
|
654
|
-
"Endpoint": {
|
|
655
|
-
"Fn::GetAtt": [
|
|
656
|
-
"workerqueueA05CE5C6",
|
|
657
|
-
"Arn",
|
|
658
|
-
],
|
|
659
|
-
},
|
|
660
|
-
"Protocol": "sqs",
|
|
661
|
-
"TopicArn": {
|
|
662
|
-
"Ref": "sourcetopic7C3DC892",
|
|
663
|
-
},
|
|
664
|
-
},
|
|
665
|
-
"Type": "AWS::SNS::Subscription",
|
|
666
|
-
},
|
|
667
651
|
"workerqueuedeadletters83F3505C": {
|
|
668
652
|
"DeletionPolicy": "Delete",
|
|
669
653
|
"Properties": {
|
|
@@ -719,6 +703,40 @@ exports[`returns expected CloudFormation stack for prod 1`] = `
|
|
|
719
703
|
},
|
|
720
704
|
},
|
|
721
705
|
"Resources": {
|
|
706
|
+
"datadogapikeysecret046FEF06": {
|
|
707
|
+
"DeletionPolicy": "Delete",
|
|
708
|
+
"Properties": {
|
|
709
|
+
"GenerateSecretString": {},
|
|
710
|
+
},
|
|
711
|
+
"Type": "AWS::SecretsManager::Secret",
|
|
712
|
+
"UpdateReplacePolicy": "Delete",
|
|
713
|
+
},
|
|
714
|
+
"destinationtopicDCE2E0B8": {
|
|
715
|
+
"Properties": {
|
|
716
|
+
"KmsMasterKeyId": {
|
|
717
|
+
"Fn::Join": [
|
|
718
|
+
"",
|
|
719
|
+
[
|
|
720
|
+
"arn:",
|
|
721
|
+
{
|
|
722
|
+
"Ref": "AWS::Partition",
|
|
723
|
+
},
|
|
724
|
+
":kms:",
|
|
725
|
+
{
|
|
726
|
+
"Ref": "AWS::Region",
|
|
727
|
+
},
|
|
728
|
+
":",
|
|
729
|
+
{
|
|
730
|
+
"Ref": "AWS::AccountId",
|
|
731
|
+
},
|
|
732
|
+
":alias/aws/sns",
|
|
733
|
+
],
|
|
734
|
+
],
|
|
735
|
+
},
|
|
736
|
+
"TopicName": "serviceName",
|
|
737
|
+
},
|
|
738
|
+
"Type": "AWS::SNS::Topic",
|
|
739
|
+
},
|
|
722
740
|
"kmskey49FBC3B3": {
|
|
723
741
|
"DeletionPolicy": "Retain",
|
|
724
742
|
"Properties": {
|
|
@@ -814,17 +832,6 @@ exports[`returns expected CloudFormation stack for prod 1`] = `
|
|
|
814
832
|
},
|
|
815
833
|
"Resource": "*",
|
|
816
834
|
},
|
|
817
|
-
{
|
|
818
|
-
"Action": [
|
|
819
|
-
"kms:Decrypt",
|
|
820
|
-
"kms:GenerateDataKey",
|
|
821
|
-
],
|
|
822
|
-
"Effect": "Allow",
|
|
823
|
-
"Principal": {
|
|
824
|
-
"Service": "sns.amazonaws.com",
|
|
825
|
-
},
|
|
826
|
-
"Resource": "*",
|
|
827
|
-
},
|
|
828
835
|
],
|
|
829
836
|
"Version": "2012-10-17",
|
|
830
837
|
},
|
|
@@ -844,9 +851,6 @@ exports[`returns expected CloudFormation stack for prod 1`] = `
|
|
|
844
851
|
},
|
|
845
852
|
"Type": "AWS::KMS::Alias",
|
|
846
853
|
},
|
|
847
|
-
"sourcetopic7C3DC892": {
|
|
848
|
-
"Type": "AWS::SNS::Topic",
|
|
849
|
-
},
|
|
850
854
|
"worker28EA3E30": {
|
|
851
855
|
"DependsOn": [
|
|
852
856
|
"workerServiceRoleDefaultPolicyBA498553",
|
|
@@ -865,6 +869,9 @@ exports[`returns expected CloudFormation stack for prod 1`] = `
|
|
|
865
869
|
"Description": "Updated at 1212-12-12T12:12:12.121Z",
|
|
866
870
|
"Environment": {
|
|
867
871
|
"Variables": {
|
|
872
|
+
"DESTINATION_SNS_TOPIC_ARN": {
|
|
873
|
+
"Ref": "destinationtopicDCE2E0B8",
|
|
874
|
+
},
|
|
868
875
|
"ENVIRONMENT": "prod",
|
|
869
876
|
"NODE_ENV": "production",
|
|
870
877
|
"NODE_OPTIONS": "--enable-source-maps",
|
|
@@ -880,6 +887,20 @@ exports[`returns expected CloudFormation stack for prod 1`] = `
|
|
|
880
887
|
"Arn",
|
|
881
888
|
],
|
|
882
889
|
},
|
|
890
|
+
"Layers": [
|
|
891
|
+
{
|
|
892
|
+
"Fn::Join": [
|
|
893
|
+
"",
|
|
894
|
+
[
|
|
895
|
+
"arn:aws:lambda:",
|
|
896
|
+
{
|
|
897
|
+
"Ref": "AWS::Region",
|
|
898
|
+
},
|
|
899
|
+
":464622532012:layer:Datadog-Extension-ARM:58",
|
|
900
|
+
],
|
|
901
|
+
],
|
|
902
|
+
},
|
|
903
|
+
],
|
|
883
904
|
"ReservedConcurrentExecutions": 20,
|
|
884
905
|
"Role": {
|
|
885
906
|
"Fn::GetAtt": [
|
|
@@ -1320,59 +1341,6 @@ exports[`returns expected CloudFormation stack for prod 1`] = `
|
|
|
1320
1341
|
"Type": "AWS::SQS::Queue",
|
|
1321
1342
|
"UpdateReplacePolicy": "Delete",
|
|
1322
1343
|
},
|
|
1323
|
-
"workerqueuePolicy97054CB4": {
|
|
1324
|
-
"Properties": {
|
|
1325
|
-
"PolicyDocument": {
|
|
1326
|
-
"Statement": [
|
|
1327
|
-
{
|
|
1328
|
-
"Action": "sqs:SendMessage",
|
|
1329
|
-
"Condition": {
|
|
1330
|
-
"ArnEquals": {
|
|
1331
|
-
"aws:SourceArn": {
|
|
1332
|
-
"Ref": "sourcetopic7C3DC892",
|
|
1333
|
-
},
|
|
1334
|
-
},
|
|
1335
|
-
},
|
|
1336
|
-
"Effect": "Allow",
|
|
1337
|
-
"Principal": {
|
|
1338
|
-
"Service": "sns.amazonaws.com",
|
|
1339
|
-
},
|
|
1340
|
-
"Resource": {
|
|
1341
|
-
"Fn::GetAtt": [
|
|
1342
|
-
"workerqueueA05CE5C6",
|
|
1343
|
-
"Arn",
|
|
1344
|
-
],
|
|
1345
|
-
},
|
|
1346
|
-
},
|
|
1347
|
-
],
|
|
1348
|
-
"Version": "2012-10-17",
|
|
1349
|
-
},
|
|
1350
|
-
"Queues": [
|
|
1351
|
-
{
|
|
1352
|
-
"Ref": "workerqueueA05CE5C6",
|
|
1353
|
-
},
|
|
1354
|
-
],
|
|
1355
|
-
},
|
|
1356
|
-
"Type": "AWS::SQS::QueuePolicy",
|
|
1357
|
-
},
|
|
1358
|
-
"workerqueueappStacksourcetopic613C6BDBD2F224F5": {
|
|
1359
|
-
"DependsOn": [
|
|
1360
|
-
"workerqueuePolicy97054CB4",
|
|
1361
|
-
],
|
|
1362
|
-
"Properties": {
|
|
1363
|
-
"Endpoint": {
|
|
1364
|
-
"Fn::GetAtt": [
|
|
1365
|
-
"workerqueueA05CE5C6",
|
|
1366
|
-
"Arn",
|
|
1367
|
-
],
|
|
1368
|
-
},
|
|
1369
|
-
"Protocol": "sqs",
|
|
1370
|
-
"TopicArn": {
|
|
1371
|
-
"Ref": "sourcetopic7C3DC892",
|
|
1372
|
-
},
|
|
1373
|
-
},
|
|
1374
|
-
"Type": "AWS::SNS::Subscription",
|
|
1375
|
-
},
|
|
1376
1344
|
"workerqueuedeadletters83F3505C": {
|
|
1377
1345
|
"DeletionPolicy": "Delete",
|
|
1378
1346
|
"Properties": {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { App, aws_sns } from 'aws-cdk-lib';
|
|
1
|
+
import { App, aws_secretsmanager, aws_sns } from 'aws-cdk-lib';
|
|
2
2
|
import { Template } from 'aws-cdk-lib/assertions';
|
|
3
3
|
|
|
4
4
|
const currentDate = '1212-12-12T12:12:12.121Z';
|
|
@@ -36,6 +36,12 @@ it.each(['dev', 'prod'])(
|
|
|
36
36
|
.spyOn(aws_sns.Topic, 'fromTopicArn')
|
|
37
37
|
.mockImplementation((scope, id) => new aws_sns.Topic(scope, id));
|
|
38
38
|
|
|
39
|
+
jest
|
|
40
|
+
.spyOn(aws_secretsmanager.Secret, 'fromSecretPartialArn')
|
|
41
|
+
.mockImplementation(
|
|
42
|
+
(scope, id) => new aws_secretsmanager.Secret(scope, id),
|
|
43
|
+
);
|
|
44
|
+
|
|
39
45
|
const app = new App();
|
|
40
46
|
|
|
41
47
|
const stack = new AppStack(app, 'appStack');
|
|
@@ -47,13 +53,18 @@ it.each(['dev', 'prod'])(
|
|
|
47
53
|
/"S3Key":"([0-9a-f]+)\.zip"/g,
|
|
48
54
|
(_, hash) => `"S3Key":"${'x'.repeat(hash.length)}.zip"`,
|
|
49
55
|
)
|
|
50
|
-
.
|
|
56
|
+
.replace(
|
|
51
57
|
/workerCurrentVersion([0-9a-zA-Z]+)"/g,
|
|
52
58
|
(_, hash) => `workerCurrentVersion${'x'.repeat(hash.length)}"`,
|
|
53
59
|
)
|
|
54
60
|
.replaceAll(
|
|
55
61
|
/"Value":"\d+\.\d+\.\d+-([^"]+)"/g,
|
|
56
62
|
(_, hash) => `"Value": "x.x.x-${'x'.repeat(hash.length)}"`,
|
|
63
|
+
)
|
|
64
|
+
.replace(
|
|
65
|
+
/"DD_TAGS":"git.commit.sha:([0-9a-f]+),git.repository_url:([^\"]+)"/g,
|
|
66
|
+
(_, sha, url) =>
|
|
67
|
+
`"DD_TAGS":"git.commit.sha:${'x'.repeat(sha.length)},git.repository_url:${'x'.repeat(url.length)}"`,
|
|
57
68
|
);
|
|
58
69
|
expect(JSON.parse(json)).toMatchSnapshot();
|
|
59
70
|
},
|
|
@@ -8,11 +8,12 @@ import {
|
|
|
8
8
|
aws_lambda,
|
|
9
9
|
aws_lambda_event_sources,
|
|
10
10
|
aws_lambda_nodejs,
|
|
11
|
+
aws_secretsmanager,
|
|
11
12
|
aws_sns,
|
|
12
|
-
aws_sns_subscriptions,
|
|
13
13
|
aws_sqs,
|
|
14
14
|
} from 'aws-cdk-lib';
|
|
15
15
|
import type { Construct } from 'constructs';
|
|
16
|
+
import { Datadog, getExtensionLayerArn } from 'datadog-cdk-constructs-v2';
|
|
16
17
|
|
|
17
18
|
import { config } from './config';
|
|
18
19
|
|
|
@@ -49,13 +50,42 @@ export class AppStack extends Stack {
|
|
|
49
50
|
encryptionMasterKey: kmsKey,
|
|
50
51
|
});
|
|
51
52
|
|
|
52
|
-
const topic = aws_sns.Topic.fromTopicArn(
|
|
53
|
+
// const topic = aws_sns.Topic.fromTopicArn(
|
|
54
|
+
// this,
|
|
55
|
+
// 'source-topic',
|
|
56
|
+
// config.sourceSnsTopicArn,
|
|
57
|
+
// );
|
|
58
|
+
|
|
59
|
+
// topic.addSubscription(
|
|
60
|
+
// new aws_sns_subscriptions.SqsSubscription(queue, {
|
|
61
|
+
// rawMessageDelivery: true, // Remove this property if you require end to end datadog tracing
|
|
62
|
+
// }),
|
|
63
|
+
// );
|
|
64
|
+
|
|
65
|
+
const snsKey = aws_kms.Alias.fromAliasName(
|
|
53
66
|
this,
|
|
54
|
-
'
|
|
55
|
-
|
|
67
|
+
'alias-aws-sns',
|
|
68
|
+
'alias/aws/sns',
|
|
56
69
|
);
|
|
57
70
|
|
|
58
|
-
|
|
71
|
+
const destinationTopic = new aws_sns.Topic(this, 'destination-topic', {
|
|
72
|
+
masterKey: snsKey,
|
|
73
|
+
topicName: '<%- serviceName %>',
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
const datadogSecret = aws_secretsmanager.Secret.fromSecretPartialArn(
|
|
77
|
+
this,
|
|
78
|
+
'datadog-api-key-secret',
|
|
79
|
+
config.datadogApiKeySecretArn,
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
const datadog = new Datadog(this, 'datadog', {
|
|
83
|
+
apiKeySecret: datadogSecret,
|
|
84
|
+
addLayers: false,
|
|
85
|
+
enableDatadogLogs: false,
|
|
86
|
+
flushMetricsToLogs: false,
|
|
87
|
+
extensionLayerVersion: 58,
|
|
88
|
+
});
|
|
59
89
|
|
|
60
90
|
const architecture = '<%- lambdaCdkArchitecture %>';
|
|
61
91
|
|
|
@@ -85,17 +115,33 @@ export class AppStack extends Stack {
|
|
|
85
115
|
...defaultWorkerConfig,
|
|
86
116
|
entry: './src/app.ts',
|
|
87
117
|
timeout: Duration.seconds(30),
|
|
88
|
-
bundling:
|
|
118
|
+
bundling: {
|
|
119
|
+
...defaultWorkerBundlingConfig,
|
|
120
|
+
nodeModules: ['datadog-lambda-js', 'dd-trace'],
|
|
121
|
+
},
|
|
89
122
|
functionName: '<%- serviceName %>',
|
|
90
123
|
environment: {
|
|
91
124
|
...defaultWorkerEnvironment,
|
|
92
125
|
...config.workerLambda.environment,
|
|
126
|
+
DESTINATION_SNS_TOPIC_ARN: destinationTopic.topicArn,
|
|
93
127
|
},
|
|
94
128
|
// https://github.com/aws/aws-cdk/issues/28237
|
|
95
129
|
// This forces the lambda to be updated on every deployment
|
|
96
130
|
// If you do not wish to use hotswap, you can remove the new Date().toISOString() from the description
|
|
97
131
|
description: `Updated at ${new Date().toISOString()}`,
|
|
98
132
|
reservedConcurrentExecutions: config.workerLambda.reservedConcurrency,
|
|
133
|
+
layers: [
|
|
134
|
+
// Workaround for https://github.com/DataDog/datadog-cdk-constructs/issues/201
|
|
135
|
+
aws_lambda.LayerVersion.fromLayerVersionArn(
|
|
136
|
+
this,
|
|
137
|
+
'datadog-layer',
|
|
138
|
+
getExtensionLayerArn(
|
|
139
|
+
this.region,
|
|
140
|
+
datadog.props.extensionLayerVersion as number,
|
|
141
|
+
defaultWorkerConfig.architecture === aws_lambda.Architecture.ARM_64,
|
|
142
|
+
),
|
|
143
|
+
),
|
|
144
|
+
],
|
|
99
145
|
});
|
|
100
146
|
|
|
101
147
|
const workerDeployment = new LambdaDeployment(this, 'workerDeployment', {
|
|
@@ -16,6 +16,7 @@ interface Config {
|
|
|
16
16
|
VERSION: string;
|
|
17
17
|
};
|
|
18
18
|
};
|
|
19
|
+
datadogApiKeySecretArn: string;
|
|
19
20
|
sourceSnsTopicArn: string;
|
|
20
21
|
}
|
|
21
22
|
|
|
@@ -30,6 +31,7 @@ const configs: Record<Environment, Config> = {
|
|
|
30
31
|
VERSION: Env.string('VERSION', { default: 'local' }),
|
|
31
32
|
},
|
|
32
33
|
},
|
|
34
|
+
datadogApiKeySecretArn: 'TODO: datadogApiKeySecretArn',
|
|
33
35
|
sourceSnsTopicArn: 'TODO: sourceSnsTopicArn',
|
|
34
36
|
},
|
|
35
37
|
prod: {
|
|
@@ -42,6 +44,7 @@ const configs: Record<Environment, Config> = {
|
|
|
42
44
|
VERSION: Env.string('VERSION', { default: 'local' }),
|
|
43
45
|
},
|
|
44
46
|
},
|
|
47
|
+
datadogApiKeySecretArn: 'TODO: datadogApiKeySecretArn',
|
|
45
48
|
sourceSnsTopicArn: 'TODO: sourceSnsTopicArn',
|
|
46
49
|
},
|
|
47
50
|
};
|
|
@@ -17,18 +17,25 @@
|
|
|
17
17
|
"@aws-sdk/client-lambda": "^3.363.0",
|
|
18
18
|
"@aws-sdk/client-sns": "^3.363.0",
|
|
19
19
|
"@seek/logger": "^9.0.0",
|
|
20
|
+
"datadog-lambda-js": "^8.0.0",
|
|
21
|
+
"dd-trace": "^5.0.0",
|
|
20
22
|
"skuba-dive": "^2.0.0",
|
|
21
23
|
"zod": "^3.19.1"
|
|
22
24
|
},
|
|
23
25
|
"devDependencies": {
|
|
24
26
|
"@seek/aws-codedeploy-infra": "^2.1.0",
|
|
25
27
|
"@types/aws-lambda": "^8.10.82",
|
|
28
|
+
"@types/chance": "^1.1.3",
|
|
26
29
|
"@types/node": "^20.16.5",
|
|
27
30
|
"aws-cdk": "^2.109.0",
|
|
28
31
|
"aws-cdk-lib": "^2.109.0",
|
|
32
|
+
"aws-sdk-client-mock": "^4.0.0",
|
|
33
|
+
"aws-sdk-client-mock-jest": "^4.0.0",
|
|
34
|
+
"chance": "^1.1.8",
|
|
29
35
|
"constructs": "^10.0.17",
|
|
36
|
+
"datadog-cdk-constructs-v2": "^1.13.0",
|
|
30
37
|
"pino-pretty": "^11.0.0",
|
|
31
|
-
"skuba": "
|
|
38
|
+
"skuba": "9.0.1-upgrade-cdk-template-20241002233314"
|
|
32
39
|
},
|
|
33
40
|
"packageManager": "pnpm@9.11.0",
|
|
34
41
|
"engines": {
|