@fishawack/lab-env 5.6.1-beta.1 → 5.7.0-beta.1
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/CHANGELOG.md +25 -0
- package/cli.js +1 -0
- package/commands/create/cmds/deprovision.js +30 -6
- package/commands/create/cmds/provision.js +116 -1
- package/commands/create/cmds/sync-secrets.js +197 -0
- package/commands/create/libs/vars.js +171 -256
- package/commands/create/services/aws/ec2.js +150 -1
- package/commands/create/services/aws/elasticbeanstalk.js +54 -0
- package/commands/create/services/aws/iam.js +14 -0
- package/commands/create/services/aws/index.js +399 -42
- package/commands/create/services/aws/rds.js +246 -0
- package/commands/create/services/aws/secretsmanager.js +73 -0
- package/commands/create/templates/elasticbeanstalk/.ebextensions/laravel/rds-ssl.config +5 -0
- package/commands/create/templates/elasticbeanstalk/.ebextensions/misc/setvars.config +16 -1
- package/package.json +3 -1
|
@@ -147,6 +147,11 @@ module.exports.syncFWIAMPolicies = async (
|
|
|
147
147
|
UserName,
|
|
148
148
|
"arn:aws:iam::aws:policy/AmazonElastiCacheFullAccess",
|
|
149
149
|
);
|
|
150
|
+
|
|
151
|
+
await module.exports.attachIAMPolicy(
|
|
152
|
+
UserName,
|
|
153
|
+
"arn:aws:iam::aws:policy/SecretsManagerReadWrite",
|
|
154
|
+
);
|
|
150
155
|
}
|
|
151
156
|
|
|
152
157
|
if (permissions.includes("manage-users")) {
|
|
@@ -393,6 +398,10 @@ module.exports.ensureEBInstanceProfileExists = async () => {
|
|
|
393
398
|
role,
|
|
394
399
|
"arn:aws:iam::aws:policy/AWSElasticBeanstalkMulticontainerDocker",
|
|
395
400
|
);
|
|
401
|
+
await module.exports.attachRolePolicy(
|
|
402
|
+
role,
|
|
403
|
+
"arn:aws:iam::aws:policy/AWSSecretsManagerClientReadOnlyAccess",
|
|
404
|
+
);
|
|
396
405
|
await module.exports.attachInlineRolePolicy(
|
|
397
406
|
role,
|
|
398
407
|
"lab-env-elasticbeanstalk-describe-env",
|
|
@@ -465,6 +474,11 @@ module.exports.ensureEBManagedUpdateProfileExists = async () => {
|
|
|
465
474
|
"arn:aws:iam::aws:policy/AWSElasticBeanstalkManagedUpdatesCustomerRolePolicy",
|
|
466
475
|
);
|
|
467
476
|
|
|
477
|
+
await module.exports.attachRolePolicy(
|
|
478
|
+
role,
|
|
479
|
+
"arn:aws:iam::aws:policy/AWSSecretsManagerClientReadOnlyAccess",
|
|
480
|
+
);
|
|
481
|
+
|
|
468
482
|
await module.exports.attachInlineRolePolicy(
|
|
469
483
|
role,
|
|
470
484
|
"lab-env-elasticbeanstalk-custom-managed-updates-permissions",
|
|
@@ -1,7 +1,17 @@
|
|
|
1
1
|
const md5 = require("apache-md5");
|
|
2
2
|
const fs = require("fs-extra");
|
|
3
|
-
|
|
4
|
-
const {
|
|
3
|
+
const generator = require("generate-password");
|
|
4
|
+
const { S3Client, ListBucketsCommand } = require("@aws-sdk/client-s3");
|
|
5
|
+
const {
|
|
6
|
+
RDSClient,
|
|
7
|
+
DescribeDBInstancesCommand,
|
|
8
|
+
} = require("@aws-sdk/client-rds");
|
|
9
|
+
const {
|
|
10
|
+
SecretsManagerClient,
|
|
11
|
+
DescribeSecretCommand,
|
|
12
|
+
} = require("@aws-sdk/client-secrets-manager");
|
|
13
|
+
|
|
14
|
+
const { nameSafe, Spinner } = require("../../libs/utilities.js");
|
|
5
15
|
const { eb } = require("../../libs/vars.js");
|
|
6
16
|
|
|
7
17
|
module.exports.s3 = require("./s3.js");
|
|
@@ -9,10 +19,115 @@ module.exports.cloudfront = require("./cloudfront.js");
|
|
|
9
19
|
module.exports.iam = require("./iam.js");
|
|
10
20
|
module.exports.elasticbeanstalk = require("./elasticbeanstalk.js");
|
|
11
21
|
module.exports.ec2 = require("./ec2.js");
|
|
22
|
+
module.exports.rds = require("./rds.js");
|
|
23
|
+
module.exports.secretsmanager = require("./secretsmanager.js");
|
|
12
24
|
|
|
13
25
|
module.exports.slug = (repo, client, branch, service = "s3") =>
|
|
14
26
|
nameSafe(`${branch}-${repo}-${client}`, service);
|
|
15
27
|
|
|
28
|
+
module.exports.fullstackPreflight = async (
|
|
29
|
+
name,
|
|
30
|
+
repo,
|
|
31
|
+
branch,
|
|
32
|
+
{ storage = false, database = false } = {},
|
|
33
|
+
) => {
|
|
34
|
+
const conflicts = [];
|
|
35
|
+
const existing = {
|
|
36
|
+
storage: false,
|
|
37
|
+
database: false,
|
|
38
|
+
secrets: { app: null, storage: null, database: null },
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const spinner = new Spinner("Running pre-flight checks", true);
|
|
42
|
+
|
|
43
|
+
try {
|
|
44
|
+
// Check EB environment
|
|
45
|
+
spinner.ora.text = "Checking for existing EB environment";
|
|
46
|
+
try {
|
|
47
|
+
const { Environments } =
|
|
48
|
+
await module.exports.elasticbeanstalk.describeEnvironment(name);
|
|
49
|
+
const active = Environments.filter(
|
|
50
|
+
(e) => e.Status !== "Terminated",
|
|
51
|
+
);
|
|
52
|
+
if (active.length) {
|
|
53
|
+
conflicts.push(
|
|
54
|
+
`Elastic Beanstalk environment "${name}" already exists (status: ${active[0].Status})`,
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
} catch {
|
|
58
|
+
/* does not exist */
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Check S3
|
|
62
|
+
if (storage) {
|
|
63
|
+
const s3Slug = module.exports.slug(
|
|
64
|
+
repo,
|
|
65
|
+
process.env.AWS_PROFILE,
|
|
66
|
+
branch,
|
|
67
|
+
"s3",
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
spinner.ora.text = "Checking for existing S3 bucket";
|
|
71
|
+
try {
|
|
72
|
+
const { Buckets } = await new S3Client({}).send(
|
|
73
|
+
new ListBucketsCommand({}),
|
|
74
|
+
);
|
|
75
|
+
if (Buckets.some((b) => b.Name === s3Slug)) {
|
|
76
|
+
existing.storage = true;
|
|
77
|
+
}
|
|
78
|
+
} catch {
|
|
79
|
+
/* empty */
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Check RDS
|
|
84
|
+
if (database) {
|
|
85
|
+
const rdsSlug = module.exports.slug(
|
|
86
|
+
repo,
|
|
87
|
+
process.env.AWS_PROFILE,
|
|
88
|
+
branch,
|
|
89
|
+
"rds",
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
spinner.ora.text = "Checking for existing RDS instance";
|
|
93
|
+
try {
|
|
94
|
+
const res = await new RDSClient({}).send(
|
|
95
|
+
new DescribeDBInstancesCommand({
|
|
96
|
+
DBInstanceIdentifier: rdsSlug,
|
|
97
|
+
}),
|
|
98
|
+
);
|
|
99
|
+
const instance = res.DBInstances[0];
|
|
100
|
+
if (instance && instance.DBInstanceStatus !== "deleting") {
|
|
101
|
+
existing.database = true;
|
|
102
|
+
}
|
|
103
|
+
} catch {
|
|
104
|
+
/* does not exist */
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Check for existing secrets
|
|
109
|
+
const secretGroups = ["app", "storage", "database"];
|
|
110
|
+
for (const group of secretGroups) {
|
|
111
|
+
spinner.ora.text = `Checking for existing ${group} secret`;
|
|
112
|
+
try {
|
|
113
|
+
const secret = await new SecretsManagerClient({}).send(
|
|
114
|
+
new DescribeSecretCommand({ SecretId: `${name}-${group}` }),
|
|
115
|
+
);
|
|
116
|
+
existing.secrets[group] = secret.ARN;
|
|
117
|
+
} catch {
|
|
118
|
+
/* does not exist */
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
spinner.ora.succeed("Pre-flight checks complete");
|
|
123
|
+
} catch (e) {
|
|
124
|
+
spinner.ora.fail("Pre-flight checks failed");
|
|
125
|
+
throw e;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
return { conflicts, existing };
|
|
129
|
+
};
|
|
130
|
+
|
|
16
131
|
module.exports.clients = [
|
|
17
132
|
"fishawack",
|
|
18
133
|
"abbvie",
|
|
@@ -166,36 +281,97 @@ module.exports.fullstack = async (
|
|
|
166
281
|
framework,
|
|
167
282
|
availability,
|
|
168
283
|
database = false,
|
|
284
|
+
storage = false,
|
|
285
|
+
existingSecrets = { app: null, storage: null, database: null },
|
|
286
|
+
snapshot = null,
|
|
169
287
|
) => {
|
|
170
288
|
const { platform, language } = eb.configurations[framework];
|
|
171
289
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
process.env.AWS_PROFILE,
|
|
175
|
-
branch,
|
|
176
|
-
"s3",
|
|
177
|
-
);
|
|
290
|
+
let s3Slug;
|
|
291
|
+
let s3Data = {};
|
|
178
292
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
293
|
+
if (storage) {
|
|
294
|
+
s3Slug = module.exports.slug(
|
|
295
|
+
repo,
|
|
296
|
+
process.env.AWS_PROFILE,
|
|
297
|
+
branch,
|
|
298
|
+
"s3",
|
|
299
|
+
);
|
|
300
|
+
|
|
301
|
+
await module.exports.iam.createIAMUser(s3Slug, tags);
|
|
302
|
+
await module.exports.iam.attachIAMPolicy(
|
|
303
|
+
s3Slug,
|
|
304
|
+
"arn:aws:iam::aws:policy/AmazonS3FullAccess",
|
|
305
|
+
);
|
|
306
|
+
const {
|
|
307
|
+
AccessKey: { AccessKeyId },
|
|
308
|
+
AccessKey: { SecretAccessKey },
|
|
309
|
+
} = await module.exports.iam.createAccessKey(s3Slug);
|
|
310
|
+
|
|
311
|
+
await module.exports.s3.createS3Bucket(
|
|
312
|
+
s3Slug,
|
|
313
|
+
tags,
|
|
314
|
+
false,
|
|
315
|
+
"BucketOwnerPreferred",
|
|
316
|
+
);
|
|
317
|
+
|
|
318
|
+
s3Data = { s3Slug, AccessKeyId, SecretAccessKey };
|
|
319
|
+
}
|
|
195
320
|
|
|
196
321
|
await module.exports.iam.ensureEBInstanceProfileExists();
|
|
197
322
|
await module.exports.iam.ensureEBManagedUpdateProfileExists();
|
|
198
323
|
|
|
324
|
+
// Create decoupled RDS instance if database is required
|
|
325
|
+
let rdsData = {};
|
|
326
|
+
|
|
327
|
+
if (database) {
|
|
328
|
+
const rdsSlug = module.exports.slug(
|
|
329
|
+
repo,
|
|
330
|
+
process.env.AWS_PROFILE,
|
|
331
|
+
branch,
|
|
332
|
+
"rds",
|
|
333
|
+
);
|
|
334
|
+
|
|
335
|
+
const dbPassword = generator.generate({
|
|
336
|
+
length: 10,
|
|
337
|
+
numbers: true,
|
|
338
|
+
});
|
|
339
|
+
|
|
340
|
+
await module.exports.rds.ensureSSLParameterGroup();
|
|
341
|
+
|
|
342
|
+
const rdsSecurityGroupId =
|
|
343
|
+
await module.exports.ec2.createRDSSecurityGroup(rdsSlug, tags);
|
|
344
|
+
|
|
345
|
+
if (snapshot) {
|
|
346
|
+
await module.exports.rds.restoreRDSInstanceFromSnapshot(
|
|
347
|
+
rdsSlug,
|
|
348
|
+
snapshot,
|
|
349
|
+
rdsSecurityGroupId,
|
|
350
|
+
tags,
|
|
351
|
+
);
|
|
352
|
+
|
|
353
|
+
await module.exports.rds.waitForRDSInstance(rdsSlug);
|
|
354
|
+
|
|
355
|
+
await module.exports.rds.modifyRDSPassword(rdsSlug, dbPassword);
|
|
356
|
+
} else {
|
|
357
|
+
await module.exports.rds.createRDSInstance(
|
|
358
|
+
rdsSlug,
|
|
359
|
+
tags,
|
|
360
|
+
dbPassword,
|
|
361
|
+
rdsSecurityGroupId,
|
|
362
|
+
);
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
const rdsInstance =
|
|
366
|
+
await module.exports.rds.waitForRDSInstance(rdsSlug);
|
|
367
|
+
|
|
368
|
+
rdsData = {
|
|
369
|
+
RDS_HOSTNAME: rdsInstance.Endpoint.Address,
|
|
370
|
+
RDS_PORT: String(rdsInstance.Endpoint.Port),
|
|
371
|
+
RDS_PASSWORD: dbPassword,
|
|
372
|
+
};
|
|
373
|
+
}
|
|
374
|
+
|
|
199
375
|
try {
|
|
200
376
|
await module.exports.elasticbeanstalk.createElasticBeanstalkApplication(
|
|
201
377
|
repo,
|
|
@@ -217,12 +393,71 @@ module.exports.fullstack = async (
|
|
|
217
393
|
const CNAMEPrefix = `fw-auto-${name.split("-")[name.split("-").length - 1]}`;
|
|
218
394
|
process.env.DOMAIN_LINK = `${CNAMEPrefix}.${process.env.AWS_REGION}.elasticbeanstalk.com`;
|
|
219
395
|
|
|
396
|
+
// Build secret payloads and create/reuse secrets
|
|
397
|
+
const payloads = eb.buildSecretPayloads(
|
|
398
|
+
{ framework, availability, platform, language, database, storage },
|
|
399
|
+
{ ...s3Data, ...rdsData },
|
|
400
|
+
);
|
|
401
|
+
|
|
402
|
+
const secretArns = {};
|
|
403
|
+
|
|
404
|
+
for (const group of ["app", "storage", "database"]) {
|
|
405
|
+
if (existingSecrets[group]) {
|
|
406
|
+
secretArns[`${group}SecretArn`] = existingSecrets[group];
|
|
407
|
+
} else if (Object.keys(payloads[group]).length) {
|
|
408
|
+
const res = await module.exports.secretsmanager.createSecret(
|
|
409
|
+
`${name}-${group}`,
|
|
410
|
+
payloads[group],
|
|
411
|
+
tags,
|
|
412
|
+
);
|
|
413
|
+
secretArns[`${group}SecretArn`] = res.ARN;
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
// Auto-generate environmentsecrets entries from secret keys + ARNs
|
|
418
|
+
const secretSettings = [];
|
|
419
|
+
|
|
420
|
+
for (const group of ["app", "storage", "database"]) {
|
|
421
|
+
const arn = secretArns[`${group}SecretArn`];
|
|
422
|
+
if (!arn) continue;
|
|
423
|
+
|
|
424
|
+
let keys;
|
|
425
|
+
|
|
426
|
+
if (existingSecrets[group]) {
|
|
427
|
+
const secretValue =
|
|
428
|
+
await module.exports.secretsmanager.getSecretValue(
|
|
429
|
+
`${name}-${group}`,
|
|
430
|
+
);
|
|
431
|
+
keys = Object.keys(secretValue);
|
|
432
|
+
} else {
|
|
433
|
+
keys = Object.keys(payloads[group]);
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
for (const key of keys) {
|
|
437
|
+
secretSettings.push({
|
|
438
|
+
OptionName: key,
|
|
439
|
+
Value: `${arn}:${key}`,
|
|
440
|
+
Namespace:
|
|
441
|
+
"aws:elasticbeanstalk:application:environmentsecrets",
|
|
442
|
+
});
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
|
|
220
446
|
const OptionSettings = eb.merge(
|
|
221
447
|
"environments",
|
|
222
|
-
{
|
|
223
|
-
|
|
448
|
+
{
|
|
449
|
+
framework,
|
|
450
|
+
availability,
|
|
451
|
+
platform,
|
|
452
|
+
language,
|
|
453
|
+
database,
|
|
454
|
+
storage,
|
|
455
|
+
},
|
|
456
|
+
{ ...s3Data, ...rdsData },
|
|
224
457
|
);
|
|
225
458
|
|
|
459
|
+
OptionSettings.push(...secretSettings);
|
|
460
|
+
|
|
226
461
|
if (hasKeyPair) {
|
|
227
462
|
OptionSettings.push({
|
|
228
463
|
OptionName: "EC2KeyName",
|
|
@@ -241,6 +476,38 @@ module.exports.fullstack = async (
|
|
|
241
476
|
tags,
|
|
242
477
|
);
|
|
243
478
|
|
|
479
|
+
// Add RDS security group ingress rule from EB security group
|
|
480
|
+
const rdsSlugForIngress = module.exports.slug(
|
|
481
|
+
repo,
|
|
482
|
+
process.env.AWS_PROFILE,
|
|
483
|
+
branch,
|
|
484
|
+
"rds",
|
|
485
|
+
);
|
|
486
|
+
|
|
487
|
+
try {
|
|
488
|
+
const rdsSg = await module.exports.ec2.findSecurityGroupByName(
|
|
489
|
+
`${rdsSlugForIngress}-rds`,
|
|
490
|
+
);
|
|
491
|
+
const ebSg = await module.exports.ec2.findSecurityGroupByTag([
|
|
492
|
+
{
|
|
493
|
+
Name: "tag:elasticbeanstalk:environment-name",
|
|
494
|
+
Values: [name],
|
|
495
|
+
},
|
|
496
|
+
{
|
|
497
|
+
Name: "tag:aws:cloudformation:logical-id",
|
|
498
|
+
Values: ["AWSEBSecurityGroup"],
|
|
499
|
+
},
|
|
500
|
+
]);
|
|
501
|
+
if (rdsSg && ebSg) {
|
|
502
|
+
await module.exports.ec2.authorizeRDSIngress(
|
|
503
|
+
rdsSg.GroupId,
|
|
504
|
+
ebSg.GroupId,
|
|
505
|
+
);
|
|
506
|
+
}
|
|
507
|
+
} catch {
|
|
508
|
+
/* empty */
|
|
509
|
+
}
|
|
510
|
+
|
|
244
511
|
const configurations = eb.merge("configurations", {
|
|
245
512
|
framework,
|
|
246
513
|
availability,
|
|
@@ -287,28 +554,71 @@ module.exports.fullstack = async (
|
|
|
287
554
|
return config;
|
|
288
555
|
};
|
|
289
556
|
|
|
290
|
-
module.exports.fullstackTerminate = async (
|
|
291
|
-
|
|
557
|
+
module.exports.fullstackTerminate = async (
|
|
558
|
+
name,
|
|
559
|
+
repo,
|
|
560
|
+
branch,
|
|
561
|
+
{
|
|
562
|
+
deleteStorage = false,
|
|
563
|
+
deleteDatabase = false,
|
|
564
|
+
deleteAppSecret = false,
|
|
565
|
+
} = {},
|
|
566
|
+
) => {
|
|
567
|
+
if (deleteStorage) {
|
|
568
|
+
const s3Slug = module.exports.slug(
|
|
569
|
+
repo,
|
|
570
|
+
process.env.AWS_PROFILE,
|
|
571
|
+
branch,
|
|
572
|
+
"s3",
|
|
573
|
+
);
|
|
574
|
+
|
|
575
|
+
try {
|
|
576
|
+
await module.exports.iam.removeIAMUser(s3Slug);
|
|
577
|
+
} catch {
|
|
578
|
+
/* empty */
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
try {
|
|
582
|
+
await module.exports.s3.emptyS3Bucket(s3Slug);
|
|
583
|
+
} catch {
|
|
584
|
+
/* empty */
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
try {
|
|
588
|
+
await module.exports.s3.removeS3Bucket(s3Slug);
|
|
589
|
+
} catch {
|
|
590
|
+
/* empty */
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
// Remove RDS inbound rule referencing EB security group before terminating EB
|
|
595
|
+
const rdsSlug = module.exports.slug(
|
|
292
596
|
repo,
|
|
293
597
|
process.env.AWS_PROFILE,
|
|
294
598
|
branch,
|
|
295
|
-
"
|
|
599
|
+
"rds",
|
|
296
600
|
);
|
|
297
601
|
|
|
298
602
|
try {
|
|
299
|
-
await module.exports.
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
603
|
+
const rdsSg = await module.exports.ec2.findSecurityGroupByName(
|
|
604
|
+
`${rdsSlug}-rds`,
|
|
605
|
+
);
|
|
606
|
+
const ebSg = await module.exports.ec2.findSecurityGroupByTag([
|
|
607
|
+
{
|
|
608
|
+
Name: "tag:elasticbeanstalk:environment-name",
|
|
609
|
+
Values: [name],
|
|
610
|
+
},
|
|
611
|
+
{
|
|
612
|
+
Name: "tag:aws:cloudformation:logical-id",
|
|
613
|
+
Values: ["AWSEBSecurityGroup"],
|
|
614
|
+
},
|
|
615
|
+
]);
|
|
616
|
+
if (rdsSg && ebSg) {
|
|
617
|
+
await module.exports.ec2.revokeRDSIngress(
|
|
618
|
+
rdsSg.GroupId,
|
|
619
|
+
ebSg.GroupId,
|
|
620
|
+
);
|
|
621
|
+
}
|
|
312
622
|
} catch {
|
|
313
623
|
/* empty */
|
|
314
624
|
}
|
|
@@ -328,4 +638,51 @@ module.exports.fullstackTerminate = async (name, repo, branch) => {
|
|
|
328
638
|
} catch {
|
|
329
639
|
/* empty */
|
|
330
640
|
}
|
|
641
|
+
|
|
642
|
+
if (deleteDatabase) {
|
|
643
|
+
try {
|
|
644
|
+
await module.exports.rds.deleteRDSInstance(rdsSlug);
|
|
645
|
+
await module.exports.rds.waitForRDSDeletion(rdsSlug);
|
|
646
|
+
} catch {
|
|
647
|
+
/* empty */
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
try {
|
|
651
|
+
const sg = await module.exports.ec2.findSecurityGroupByName(
|
|
652
|
+
`${rdsSlug}-rds`,
|
|
653
|
+
);
|
|
654
|
+
if (sg) {
|
|
655
|
+
await module.exports.ec2.deleteSecurityGroup(sg.GroupId);
|
|
656
|
+
}
|
|
657
|
+
} catch {
|
|
658
|
+
/* empty */
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
// Delete secrets
|
|
663
|
+
if (deleteStorage) {
|
|
664
|
+
try {
|
|
665
|
+
await module.exports.secretsmanager.deleteSecret(`${name}-storage`);
|
|
666
|
+
} catch {
|
|
667
|
+
/* empty */
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
if (deleteDatabase) {
|
|
672
|
+
try {
|
|
673
|
+
await module.exports.secretsmanager.deleteSecret(
|
|
674
|
+
`${name}-database`,
|
|
675
|
+
);
|
|
676
|
+
} catch {
|
|
677
|
+
/* empty */
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
if (deleteAppSecret) {
|
|
682
|
+
try {
|
|
683
|
+
await module.exports.secretsmanager.deleteSecret(`${name}-app`);
|
|
684
|
+
} catch {
|
|
685
|
+
/* empty */
|
|
686
|
+
}
|
|
687
|
+
}
|
|
331
688
|
};
|