@fishawack/lab-env 5.7.0-beta.2 → 5.7.0-beta.4

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.
Files changed (37) hide show
  1. package/CHANGELOG.md +51 -0
  2. package/_Test/provision.js +1 -8
  3. package/_Test/prune.js +8 -5
  4. package/bitbucket-pipelines.yml +2 -2
  5. package/cli.js +1 -0
  6. package/commands/create/cmds/dekey.js +13 -9
  7. package/commands/create/cmds/deprovision.js +29 -0
  8. package/commands/create/cmds/key.js +60 -41
  9. package/commands/create/cmds/provision.js +425 -55
  10. package/commands/create/cmds/rekey.js +218 -0
  11. package/commands/create/libs/output-credentials.js +59 -0
  12. package/commands/create/libs/parallel-runner.js +204 -0
  13. package/commands/create/libs/resolve-operator.js +59 -0
  14. package/commands/create/libs/utilities.js +71 -8
  15. package/commands/create/libs/vars.js +70 -86
  16. package/commands/create/services/aws/acm.js +4 -2
  17. package/commands/create/services/aws/cloudfront.js +51 -45
  18. package/commands/create/services/aws/ec2.js +132 -53
  19. package/commands/create/services/aws/elasticache.js +159 -0
  20. package/commands/create/services/aws/elasticbeanstalk.js +141 -60
  21. package/commands/create/services/aws/iam.js +178 -98
  22. package/commands/create/services/aws/index.js +1202 -466
  23. package/commands/create/services/aws/opensearch.js +25 -17
  24. package/commands/create/services/aws/rds.js +22 -34
  25. package/commands/create/services/aws/s3.js +14 -27
  26. package/commands/create/services/aws/secretsmanager.js +8 -15
  27. package/commands/create/services/aws/ses.js +195 -0
  28. package/commands/create/templates/elasticbeanstalk/.ebextensions/laravel/cron.config +45 -0
  29. package/commands/create/templates/elasticbeanstalk/.ebextensions/laravel/queue-worker.config +29 -0
  30. package/commands/create/templates/elasticbeanstalk/.ebextensions/laravel/software.config +12 -0
  31. package/commands/create/templates/elasticbeanstalk/.ebextensions/misc/setvars.config +2 -16
  32. package/commands/create/templates/elasticbeanstalk/.platform/confighooks/postdeploy/rewrite-flush.sh +1 -1
  33. package/commands/create/templates/elasticbeanstalk/.platform/confighooks/postdeploy/setvars.sh +19 -0
  34. package/commands/create/templates/elasticbeanstalk/.platform/hooks/postdeploy/restart_queue.sh +4 -0
  35. package/commands/create/templates/elasticbeanstalk/.platform/hooks/prebuild/setvars.sh +19 -0
  36. package/commands/scan.js +1 -1
  37. package/package.json +5 -2
@@ -126,10 +126,6 @@ module.exports.templates = [
126
126
  name: "boilerplate-laravel",
127
127
  type: "boilerplate",
128
128
  },
129
- {
130
- name: "boilerplate-laravel-vue",
131
- type: "boilerplate",
132
- },
133
129
  {
134
130
  name: "boilerplate-drupal",
135
131
  type: "boilerplate",
@@ -178,7 +174,14 @@ module.exports.templates = [
178
174
  },
179
175
  ];
180
176
 
181
- module.exports.secretGroups = ["app", "storage", "database", "opensearch"];
177
+ module.exports.secretGroups = [
178
+ "app",
179
+ "storage",
180
+ "database",
181
+ "opensearch",
182
+ "cache",
183
+ "mail",
184
+ ];
182
185
 
183
186
  module.exports.frameworks = [
184
187
  {
@@ -208,18 +211,12 @@ module.exports.eb = {
208
211
  environments: {
209
212
  python: {
210
213
  shared: [],
211
- low: [],
212
- high: [],
213
214
  },
214
215
  php: {
215
216
  shared: [],
216
- low: [],
217
- high: [],
218
217
  },
219
218
  nginx: {
220
219
  shared: [],
221
- low: [],
222
- high: [],
223
220
  },
224
221
  httpd: {
225
222
  shared: [
@@ -229,33 +226,21 @@ module.exports.eb = {
229
226
  Namespace: "aws:elasticbeanstalk:environment:proxy",
230
227
  },
231
228
  ],
232
- low: [],
233
- high: [],
234
229
  },
235
230
  default: {
236
231
  shared: [],
237
- low: [],
238
- high: [],
239
232
  },
240
233
  wordpress: {
241
234
  shared: [],
242
- low: [],
243
- high: [],
244
235
  },
245
236
  laravel: {
246
237
  shared: [],
247
- low: [],
248
- high: [],
249
238
  },
250
239
  adonis: {
251
240
  shared: [],
252
- low: [],
253
- high: [],
254
241
  },
255
242
  drupal: {
256
243
  shared: [],
257
- low: [],
258
- high: [],
259
244
  },
260
245
  shared: [
261
246
  {
@@ -268,13 +253,11 @@ module.exports.eb = {
268
253
  Value: instanceProfileName || "aws-elasticbeanstalk-ec2-role",
269
254
  Namespace: "aws:autoscaling:launchconfiguration",
270
255
  }),
271
- ],
272
- low: [
273
- {
274
- OptionName: "EnvironmentType",
275
- Value: "SingleInstance",
276
- Namespace: "aws:elasticbeanstalk:environment",
277
- },
256
+ ({ instanceType }) => ({
257
+ OptionName: "InstanceType",
258
+ Value: instanceType || "t3.small",
259
+ Namespace: "aws:autoscaling:launchconfiguration",
260
+ }),
278
261
  ],
279
262
  high: [
280
263
  {
@@ -354,6 +337,22 @@ module.exports.eb = {
354
337
 
355
338
  return settings;
356
339
  },
340
+ {
341
+ OptionName: "ConfigDocument",
342
+ Value: JSON.stringify({
343
+ Version: 1,
344
+ CloudWatchMetrics: { Instance: {}, Environment: {} },
345
+ Rules: {
346
+ Environment: {
347
+ Application: {
348
+ ApplicationRequests4xx: { Enabled: false },
349
+ },
350
+ ELB: { ELBRequests4xx: { Enabled: false } },
351
+ },
352
+ },
353
+ }),
354
+ Namespace: "aws:elasticbeanstalk:healthreporting:system",
355
+ },
357
356
  ],
358
357
  },
359
358
  secretPayloads: {
@@ -368,13 +367,7 @@ module.exports.eb = {
368
367
  MYSQL_ATTR_SSL_CA: "/opt/rds-certs/global-bundle.pem",
369
368
  },
370
369
  },
371
- low: {
372
- app: {
373
- DOMAIN_LINK: "<%= DOMAIN_LINK %>",
374
- EMAIL_LINK: "mike.mellor@fishawack.com",
375
- },
376
- },
377
- high: {},
370
+
378
371
  wordpress: {
379
372
  shared: {
380
373
  app: {
@@ -436,11 +429,12 @@ module.exports.eb = {
436
429
  APP_KEY: `base64:${Buffer.from(generator.generate({ length: 32, numbers: true, symbols: true })).toString("base64")}`,
437
430
  APP_DEBUG: "false",
438
431
  APP_URL: "https://<%= APP_DOMAIN %>",
432
+ SESSION_DOMAIN: "<%= SESSION_DOMAIN %>",
433
+ AWS_DEFAULT_REGION: "<%= AWS_REGION %>",
439
434
  },
440
435
  storage: ({ storage }) =>
441
436
  storage && {
442
437
  AWS_BUCKET: "<%= s3Slug %>",
443
- AWS_DEFAULT_REGION: "<%= AWS_REGION %>",
444
438
  AWS_ACL_VISIBILITY: "private",
445
439
  FILESYSTEM_DISK: "s3",
446
440
  FILESYSTEM_DISK_PUBLIC: "s3-public",
@@ -449,6 +443,24 @@ module.exports.eb = {
449
443
  opensearch && {
450
444
  SEARCH_HOST: "<%= SEARCH_HOST %>",
451
445
  },
446
+ cache: ({ cache }) =>
447
+ cache && {
448
+ REDIS_SCHEME: "tls",
449
+ REDIS_HOST: "<%= REDIS_HOST %>",
450
+ REDIS_PORT: "<%= REDIS_PORT %>",
451
+ REDIS_PASSWORD: "<%= REDIS_PASSWORD %>",
452
+ CACHE_STORE: "redis",
453
+ },
454
+ mail: ({ mail }) =>
455
+ mail && {
456
+ MAIL_FROM_ADDRESS: "<%= MAIL_FROM_ADDRESS %>",
457
+ MAIL_FROM_NAME: "<%= MAIL_FROM_NAME %>",
458
+ MAIL_HOST: "email-smtp.us-east-1.amazonaws.com",
459
+ MAIL_MAILER: "smtp",
460
+ MAIL_PASSWORD: "<%= MAIL_PASSWORD %>",
461
+ MAIL_PORT: "587",
462
+ MAIL_USERNAME: "<%= MAIL_USERNAME %>",
463
+ },
452
464
  },
453
465
  high: {
454
466
  app: {
@@ -466,11 +478,11 @@ module.exports.eb = {
466
478
  SESSION_DRIVER: "cookie",
467
479
  PORT: "3333",
468
480
  LOG_LEVEL: "info",
481
+ AWS_DEFAULT_REGION: "<%= AWS_REGION %>",
469
482
  },
470
483
  storage: ({ storage }) =>
471
484
  storage && {
472
485
  AWS_BUCKET: "<%= s3Slug %>",
473
- AWS_DEFAULT_REGION: "<%= AWS_REGION %>",
474
486
  AWS_ACCESS_KEY_ID: "<%= AccessKeyId %>",
475
487
  AWS_SECRET_ACCESS_KEY: "<%= SecretAccessKey %>",
476
488
  FILESYSTEM_DISK: "s3",
@@ -487,18 +499,17 @@ module.exports.eb = {
487
499
  },
488
500
  },
489
501
  buildSecretPayloads(config, data = {}) {
490
- const { framework, availability = "low", platform, language } = config;
491
- const result = { app: {}, storage: {}, database: {}, opensearch: {} };
502
+ const { framework, platform, language } = config;
503
+ const result = Object.fromEntries(
504
+ module.exports.secretGroups.map((g) => [g, {}]),
505
+ );
492
506
 
493
507
  const sources = [
494
508
  this.secretPayloads.shared,
495
- this.secretPayloads[availability],
496
509
  this.secretPayloads[platform]?.shared,
497
- this.secretPayloads[platform]?.[availability],
498
510
  this.secretPayloads[language]?.shared,
499
- this.secretPayloads[language]?.[availability],
500
511
  this.secretPayloads[framework]?.shared,
501
- this.secretPayloads[framework]?.[availability],
512
+ this.secretPayloads[framework]?.high,
502
513
  ];
503
514
 
504
515
  for (const source of sources) {
@@ -529,8 +540,6 @@ module.exports.eb = {
529
540
  configurations: {
530
541
  php: {
531
542
  shared: [".ebextensions/php/ini.config"],
532
- low: [],
533
- high: [],
534
543
  },
535
544
  nginx: {
536
545
  shared: [
@@ -538,14 +547,6 @@ module.exports.eb = {
538
547
  ".platform/nginx/conf.d/upload_size.conf",
539
548
  ".platform/nginx/conf.d/security_headers.conf",
540
549
  ".platform/nginx/conf.d/elasticbeanstalk/www-to-nonwww-redirection.conf",
541
- ],
542
- low: [
543
- ".platform/nginx/conf.d/elasticbeanstalk/http-https-redirection.conf",
544
- ".platform/nginx/conf.d/ssl.conf",
545
- ".ebextensions/nginx/auto-ssl.config",
546
- ],
547
- high: [
548
- ".platform/nginx/conf.d/elasticbeanstalk/health.conf",
549
550
  ".ebextensions/nginx/alb-health.config",
550
551
  ],
551
552
  },
@@ -553,14 +554,6 @@ module.exports.eb = {
553
554
  shared: [
554
555
  ".platform/httpd/conf.d/virtualhost-80.conf",
555
556
  ".platform/httpd/conf.d/elasticbeanstalk/80/www-to-nonwww-redirection.conf",
556
- ],
557
- low: [
558
- ".platform/httpd/conf.d/elasticbeanstalk/80/http-https-redirection.conf",
559
- ".platform/httpd/conf.d/virtualhost-443.conf",
560
- ".platform/httpd/conf.d/elasticbeanstalk/443/ssl.conf",
561
- ".ebextensions/httpd/auto-ssl.config",
562
- ],
563
- high: [
564
557
  ".platform/httpd/conf.d/elasticbeanstalk/80/forward-https-proto.conf",
565
558
  ".ebextensions/wordpress/alb-health.config",
566
559
  ],
@@ -569,8 +562,6 @@ module.exports.eb = {
569
562
  platform: "nginx",
570
563
  language: "php",
571
564
  shared: [],
572
- low: [],
573
- high: [],
574
565
  },
575
566
  wordpress: {
576
567
  platform: "httpd",
@@ -583,21 +574,21 @@ module.exports.eb = {
583
574
  ".ebextensions/wordpress/environment.config",
584
575
  ".ebextensions/wordpress/post-deploy.config",
585
576
  ".ebextensions/wordpress/software.config",
577
+ ".platform/hooks/predeploy/deactivate-plugins.sh",
586
578
  ],
587
- low: [".platform/hooks/predeploy/deactivate-plugins-single.sh"],
588
- high: [".platform/hooks/predeploy/deactivate-plugins.sh"],
589
579
  },
590
580
  laravel: {
591
581
  platform: "nginx",
592
582
  language: "php",
593
583
  shared: [
594
584
  ".platform/nginx/conf.d/elasticbeanstalk/laravel.conf",
585
+ ".ebextensions/laravel/cron.config",
595
586
  ".ebextensions/laravel/post-deploy.config",
596
- ".ebextensions/laravel/software.config",
587
+ ".ebextensions/laravel/queue-worker.config",
597
588
  ".ebextensions/laravel/rds-ssl.config",
589
+ ".ebextensions/laravel/software.config",
590
+ ".platform/hooks/postdeploy/restart_queue.sh",
598
591
  ],
599
- low: [],
600
- high: [],
601
592
  },
602
593
  adonis: {
603
594
  platform: "nginx",
@@ -606,34 +597,27 @@ module.exports.eb = {
606
597
  ".ebextensions/adonis/post-deploy.config",
607
598
  ".ebextensions/adonis/software.config",
608
599
  ],
609
- low: [],
610
- high: [],
611
600
  },
612
601
  drupal: {
613
602
  platform: "httpd",
614
603
  language: "php",
615
604
  shared: [],
616
- low: [],
617
- high: [],
618
605
  },
619
606
  python: {
620
607
  platform: "nginx",
621
608
  language: "python",
622
609
  shared: [],
623
- low: [],
624
- high: [],
625
610
  },
626
- shared: [".ebextensions/misc/setvars.config"],
627
- low: [".ebextensions/misc/enable-https.config"],
628
- high: [
611
+ shared: [
612
+ ".platform/hooks/prebuild/setvars.sh",
613
+ ".platform/confighooks/postdeploy/setvars.sh",
614
+ ".ebextensions/misc/asg-self-healing.config",
629
615
  ".ebextensions/misc/alb-http-to-https-redirection.config",
630
616
  ".ebextensions/misc/enable-https-lb.config",
631
- ".ebextensions/misc/asg-self-healing.config",
632
- ".ebextensions/misc/health-ignore-4xx.config",
633
617
  ],
634
618
  },
635
619
  merge(type, config, data = {}) {
636
- const { framework, availability = "low", platform, language } = config;
620
+ const { framework, platform, language } = config;
637
621
 
638
622
  return JSON.parse(
639
623
  template(
@@ -641,13 +625,10 @@ module.exports.eb = {
641
625
  []
642
626
  .concat(
643
627
  this[type].shared,
644
- this[type][availability],
628
+ this[type].high,
645
629
  this[type][platform]?.shared,
646
- this[type][platform]?.[availability],
647
630
  this[type][language]?.shared,
648
- this[type][language]?.[availability],
649
631
  this[type][framework]?.shared,
650
- this[type][framework]?.[availability],
651
632
  )
652
633
  .map((d) =>
653
634
  typeof d === "function" ? d(config, data) : d,
@@ -727,3 +708,6 @@ module.exports.cloudfront = (
727
708
  },
728
709
  },
729
710
  });
711
+
712
+ // AWS SDK client defaults
713
+ module.exports.awsClientConfig = { maxAttempts: 5, retryMode: "adaptive" };
@@ -1,13 +1,15 @@
1
1
  const { ACMClient, ListCertificatesCommand } = require("@aws-sdk/client-acm");
2
2
  const { Spinner } = require("../../libs/utilities");
3
+ const { awsClientConfig } = require("../../libs/vars");
4
+
5
+ const getClient = () => new ACMClient(awsClientConfig);
3
6
 
4
7
  module.exports.listCertificates = async () => {
5
- const client = new ACMClient({});
6
8
  const certs = [];
7
9
  let nextToken;
8
10
 
9
11
  do {
10
- const res = await client.send(
12
+ const res = await getClient().send(
11
13
  new ListCertificatesCommand({
12
14
  CertificateStatuses: ["ISSUED"],
13
15
  NextToken: nextToken,
@@ -1,3 +1,4 @@
1
+ const dns = require("dns").promises;
1
2
  const {
2
3
  CloudFrontClient,
3
4
  CreateDistributionWithTagsCommand,
@@ -20,7 +21,9 @@ const {
20
21
  const fs = require("fs");
21
22
  const { merge } = require("lodash");
22
23
  const { Spinner, poll } = require("../../libs/utilities");
23
- const { cloudfront } = require("../../libs/vars");
24
+ const { cloudfront, awsClientConfig } = require("../../libs/vars");
25
+
26
+ const getClient = () => new CloudFrontClient(awsClientConfig);
24
27
 
25
28
  module.exports.createCloudFrontDistribution = async (
26
29
  name,
@@ -29,10 +32,8 @@ module.exports.createCloudFrontDistribution = async (
29
32
  FunctionARNResponse = null,
30
33
  region = "us-east-1",
31
34
  ) => {
32
- const client = new CloudFrontClient({});
33
-
34
35
  let OAI = await Spinner.prototype.simple(`Creating CloudFront OAI`, () => {
35
- return client.send(
36
+ return getClient().send(
36
37
  new CreateCloudFrontOriginAccessIdentityCommand({
37
38
  CloudFrontOriginAccessIdentityConfig: {
38
39
  CallerReference: name,
@@ -48,7 +49,7 @@ module.exports.createCloudFrontDistribution = async (
48
49
  res = await Spinner.prototype.simple(
49
50
  `Creating CloudFront distribution with CloudFront OAI and tags`,
50
51
  () => {
51
- return client.send(
52
+ return getClient().send(
52
53
  new CreateDistributionWithTagsCommand({
53
54
  DistributionConfigWithTags: {
54
55
  ...cloudfront(
@@ -80,20 +81,29 @@ module.exports.createCloudFrontDistribution = async (
80
81
  );
81
82
  },
82
83
  );
84
+
85
+ await Spinner.prototype.simple(
86
+ `Waiting for CloudFront DNS to propagate`,
87
+ () => {
88
+ return module.exports.waitForCloudFrontDNS(
89
+ res.Distribution.DomainName,
90
+ );
91
+ },
92
+ );
83
93
  } catch (e) {
84
94
  let Id = e.message.split(" ")[e.message.split(" ").length - 1];
85
95
 
86
96
  res = await Spinner.prototype.simple(
87
97
  `Retrieving the already existing CloudFront distribution`,
88
98
  () => {
89
- return client.send(new GetDistributionCommand({ Id }));
99
+ return getClient().send(new GetDistributionCommand({ Id }));
90
100
  },
91
101
  );
92
102
 
93
103
  res = await Spinner.prototype.simple(
94
104
  `Ensuring CloudFront functions are applied to CloudFront distribution`,
95
105
  () => {
96
- return client.send(
106
+ return getClient().send(
97
107
  new UpdateDistributionCommand({
98
108
  ...merge(
99
109
  res.Distribution,
@@ -116,12 +126,10 @@ module.exports.createCloudFrontDistribution = async (
116
126
  };
117
127
 
118
128
  module.exports.removeCloudFrontDistribution = async (Id) => {
119
- const client = new CloudFrontClient({});
120
-
121
129
  let res = await Spinner.prototype.simple(
122
130
  `Retrieving the CloudFront distribution ${Id}`,
123
131
  () => {
124
- return client.send(new GetDistributionCommand({ Id }));
132
+ return getClient().send(new GetDistributionCommand({ Id }));
125
133
  },
126
134
  );
127
135
 
@@ -135,7 +143,7 @@ module.exports.removeCloudFrontDistribution = async (Id) => {
135
143
  res = await Spinner.prototype.simple(
136
144
  `Disabling the CloudFront distribution`,
137
145
  () => {
138
- return client.send(
146
+ return getClient().send(
139
147
  new UpdateDistributionCommand({
140
148
  DistributionConfig: res.Distribution.DistributionConfig,
141
149
  Id,
@@ -157,7 +165,7 @@ module.exports.removeCloudFrontDistribution = async (Id) => {
157
165
  res = await Spinner.prototype.simple(
158
166
  `Deleting the CloudFront distribution`,
159
167
  () => {
160
- return client.send(
168
+ return getClient().send(
161
169
  new DeleteDistributionCommand({ Id, IfMatch: res.ETag }),
162
170
  );
163
171
  },
@@ -166,14 +174,14 @@ module.exports.removeCloudFrontDistribution = async (Id) => {
166
174
  res = await Spinner.prototype.simple(
167
175
  `Retrieving the CloudFront OAI`,
168
176
  () => {
169
- return client.send(
177
+ return getClient().send(
170
178
  new GetCloudFrontOriginAccessIdentityCommand({ Id: OAI }),
171
179
  );
172
180
  },
173
181
  );
174
182
 
175
183
  res = await Spinner.prototype.simple(`Deleting the CloudFront OAI`, () => {
176
- return client.send(
184
+ return getClient().send(
177
185
  new DeleteCloudFrontOriginAccessIdentityCommand({
178
186
  Id: OAI,
179
187
  IfMatch: res.ETag,
@@ -183,17 +191,27 @@ module.exports.removeCloudFrontDistribution = async (Id) => {
183
191
  };
184
192
 
185
193
  module.exports.waitForCloudFrontDistribution = async (Id) => {
186
- const client = new CloudFrontClient({});
187
-
188
194
  await poll(
189
- async () => await client.send(new GetDistributionCommand({ Id })),
195
+ async () => await getClient().send(new GetDistributionCommand({ Id })),
190
196
  (res) => res.Distribution.Status !== "Deployed",
191
197
  );
192
198
  };
193
199
 
194
- module.exports.createCloudFrontFunction = async (name, fn, config) => {
195
- const client = new CloudFrontClient({});
200
+ module.exports.waitForCloudFrontDNS = async (domain) => {
201
+ await poll(
202
+ async () => {
203
+ try {
204
+ await dns.resolve(domain);
205
+ return true;
206
+ } catch {
207
+ return false;
208
+ }
209
+ },
210
+ (resolved) => !resolved,
211
+ );
212
+ };
196
213
 
214
+ module.exports.createCloudFrontFunction = async (name, fn, config) => {
197
215
  let FunctionConfig = {
198
216
  Comment: `${name} - ${fn}.js`,
199
217
  Runtime: `cloudfront-js-1.0`,
@@ -205,7 +223,7 @@ module.exports.createCloudFrontFunction = async (name, fn, config) => {
205
223
  res = await Spinner.prototype.simple(
206
224
  `Creating CloudFront function`,
207
225
  () => {
208
- return client.send(
226
+ return getClient().send(
209
227
  new CreateFunctionCommand({
210
228
  Name: name,
211
229
  FunctionCode: new TextEncoder().encode(" "),
@@ -218,7 +236,7 @@ module.exports.createCloudFrontFunction = async (name, fn, config) => {
218
236
  res = await Spinner.prototype.simple(
219
237
  `Retrieving the already existing CloudFront function`,
220
238
  () => {
221
- return client.send(
239
+ return getClient().send(
222
240
  new GetFunctionCommand({
223
241
  Name: name,
224
242
  }),
@@ -237,7 +255,7 @@ module.exports.createCloudFrontFunction = async (name, fn, config) => {
237
255
  res = await Spinner.prototype.simple(
238
256
  `Updating CloudFront function with ${fn}.js code`,
239
257
  () => {
240
- return client.send(
258
+ return getClient().send(
241
259
  new UpdateFunctionCommand({
242
260
  Name: name,
243
261
  FunctionCode: new TextEncoder().encode(processedFn),
@@ -251,7 +269,7 @@ module.exports.createCloudFrontFunction = async (name, fn, config) => {
251
269
  res = await Spinner.prototype.simple(
252
270
  `Publishing CloudFront function`,
253
271
  () => {
254
- return client.send(
272
+ return getClient().send(
255
273
  new PublishFunctionCommand({
256
274
  Name: name,
257
275
  IfMatch: res.ETag,
@@ -264,12 +282,10 @@ module.exports.createCloudFrontFunction = async (name, fn, config) => {
264
282
  };
265
283
 
266
284
  module.exports.removeCloudFrontFunction = async (name) => {
267
- const client = new CloudFrontClient({});
268
-
269
285
  let res = await Spinner.prototype.simple(
270
286
  `Retrieving CloudFront function`,
271
287
  () => {
272
- return client.send(
288
+ return getClient().send(
273
289
  new GetFunctionCommand({
274
290
  Name: name,
275
291
  }),
@@ -278,7 +294,7 @@ module.exports.removeCloudFrontFunction = async (name) => {
278
294
  );
279
295
 
280
296
  res = await Spinner.prototype.simple(`Deleting CloudFront function`, () => {
281
- return client.send(
297
+ return getClient().send(
282
298
  new DeleteFunctionCommand({
283
299
  Name: name,
284
300
  IfMatch: res.ETag,
@@ -290,12 +306,10 @@ module.exports.removeCloudFrontFunction = async (name) => {
290
306
  };
291
307
 
292
308
  module.exports.setCloudFrontFunctionAssociation = async (Id) => {
293
- const client = new CloudFrontClient({});
294
-
295
309
  let res = await Spinner.prototype.simple(
296
310
  `Retrieving CloudFront distribution`,
297
311
  () => {
298
- return client.send(new GetDistributionCommand({ Id }));
312
+ return getClient().send(new GetDistributionCommand({ Id }));
299
313
  },
300
314
  );
301
315
 
@@ -304,7 +318,7 @@ module.exports.setCloudFrontFunctionAssociation = async (Id) => {
304
318
  FunctionMetadata: { FunctionARN },
305
319
  },
306
320
  } = await Spinner.prototype.simple(`Retrieving CloudFront function`, () => {
307
- return client.send(
321
+ return getClient().send(
308
322
  new DescribeFunctionCommand({
309
323
  Name: res.Distribution.DistributionConfig.CallerReference,
310
324
  Stage: "LIVE",
@@ -326,7 +340,7 @@ module.exports.setCloudFrontFunctionAssociation = async (Id) => {
326
340
  res = await Spinner.prototype.simple(
327
341
  `Adding CloudFront function to CloudFront distribution`,
328
342
  () => {
329
- return client.send(
343
+ return getClient().send(
330
344
  new UpdateDistributionCommand({
331
345
  DistributionConfig: res.Distribution.DistributionConfig,
332
346
  Id,
@@ -347,12 +361,10 @@ module.exports.setCloudFrontFunctionAssociation = async (Id) => {
347
361
  };
348
362
 
349
363
  module.exports.removeCloudFrontFunctionAssociation = async (Id) => {
350
- const client = new CloudFrontClient({});
351
-
352
364
  let res = await Spinner.prototype.simple(
353
365
  `Retrieving CloudFront distribution`,
354
366
  () => {
355
- return client.send(new GetDistributionCommand({ Id }));
367
+ return getClient().send(new GetDistributionCommand({ Id }));
356
368
  },
357
369
  );
358
370
 
@@ -365,7 +377,7 @@ module.exports.removeCloudFrontFunctionAssociation = async (Id) => {
365
377
  res = await Spinner.prototype.simple(
366
378
  `Removing CloudFront function from CloudFront distribution`,
367
379
  () => {
368
- return client.send(
380
+ return getClient().send(
369
381
  new UpdateDistributionCommand({
370
382
  DistributionConfig: res.Distribution.DistributionConfig,
371
383
  Id,
@@ -386,13 +398,11 @@ module.exports.removeCloudFrontFunctionAssociation = async (Id) => {
386
398
  };
387
399
 
388
400
  module.exports.listDistributions = async () => {
389
- const client = new CloudFrontClient({});
390
-
391
401
  let distributions = [];
392
402
  let marker;
393
403
 
394
404
  do {
395
- const res = await client.send(
405
+ const res = await getClient().send(
396
406
  new ListDistributionsCommand({
397
407
  ...(marker ? { Marker: marker } : {}),
398
408
  }),
@@ -409,9 +419,7 @@ module.exports.listDistributions = async () => {
409
419
  };
410
420
 
411
421
  module.exports.getDistributionTags = async (arn) => {
412
- const client = new CloudFrontClient({});
413
-
414
- const res = await client.send(
422
+ const res = await getClient().send(
415
423
  new ListTagsForResourceCommand({ Resource: arn }),
416
424
  );
417
425
 
@@ -419,9 +427,7 @@ module.exports.getDistributionTags = async (arn) => {
419
427
  };
420
428
 
421
429
  module.exports.getLatestInvalidationDate = async (distributionId) => {
422
- const client = new CloudFrontClient({});
423
-
424
- const res = await client.send(
430
+ const res = await getClient().send(
425
431
  new ListInvalidationsCommand({
426
432
  DistributionId: distributionId,
427
433
  MaxItems: 1,