cloudmason 0.0.1 → 1.0.2

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 (46) hide show
  1. package/.github/workflows/CODEOWNERS +1 -0
  2. package/.github/workflows/main.yml +27 -27
  3. package/README.md +373 -25
  4. package/build.js +20 -20
  5. package/commands/delete.js +67 -28
  6. package/commands/helpers/cf.js +181 -117
  7. package/commands/helpers/common.js +82 -0
  8. package/commands/helpers/ec2.js +154 -40
  9. package/commands/helpers/params.js +231 -178
  10. package/commands/helpers/s3.js +186 -67
  11. package/commands/helpers/stacks/asg.yaml +420 -224
  12. package/commands/helpers/stacks/infra.yaml +102 -106
  13. package/commands/helpers/stacks.js +25 -25
  14. package/commands/index.html +22 -0
  15. package/commands/init_org.js +54 -61
  16. package/commands/inspect.js +40 -0
  17. package/commands/launch_app.js +80 -57
  18. package/commands/list_apps.js +21 -21
  19. package/commands/new_app.js +44 -50
  20. package/commands/new_instance.js +133 -186
  21. package/commands/reset_stack.js +27 -27
  22. package/commands/starter.js +21 -0
  23. package/commands/starters/asg_node/index.js +62 -0
  24. package/commands/starters/asg_node/mason.txt +1 -0
  25. package/commands/starters/asg_node/modules/appConfig.js +131 -0
  26. package/commands/starters/asg_node/package-lock.json +5877 -0
  27. package/commands/starters/asg_node/package.json +23 -0
  28. package/commands/starters/asg_node/public/css/favicon-16x16.png +0 -0
  29. package/commands/starters/asg_node/public/css/fonts/Lato-Bold.ttf +0 -0
  30. package/commands/starters/asg_node/public/css/fonts/Lato-Regular.ttf +0 -0
  31. package/commands/starters/asg_node/public/css/fonts/Montserrat-Var.ttf +0 -0
  32. package/commands/starters/asg_node/public/css/fonts/OpenSans.ttf +0 -0
  33. package/commands/starters/asg_node/public/css/fonts/bpmn.woff2 +0 -0
  34. package/commands/starters/asg_node/public/css/fonts/fonts.css +17 -0
  35. package/commands/starters/asg_node/public/css/index.css +9 -0
  36. package/commands/starters/asg_node/public/index.html +15 -0
  37. package/commands/starters/asg_node/public/js/index.js +5 -0
  38. package/commands/starters/asg_node/start.sh +4 -0
  39. package/commands/update_app.js +235 -272
  40. package/commands/update_stack.js +27 -0
  41. package/commands/utils.js +32 -32
  42. package/main.js +262 -220
  43. package/package.json +1 -28
  44. package/test.bat +16 -9
  45. package/commands/delete_app.js +0 -28
  46. package/commands/helpers/stacks/asg_draft.json +0 -321
@@ -0,0 +1 @@
1
+ * @kai-harvey
@@ -1,27 +1,27 @@
1
- name: Node.js Package
2
-
3
- on:
4
- pull_request:
5
- types:
6
- - closed
7
- branches:
8
- - 'release/**'
9
-
10
- jobs:
11
- if_merged:
12
- if: github.event.pull_request.merged == true
13
- runs-on: ubuntu-latest
14
- steps:
15
- - uses: actions/checkout@v3
16
- - uses: actions/setup-node@v3
17
- with:
18
- node-version: 16
19
- registry-url: https://registry.npmjs.org/
20
- - run: npm run build
21
- env:
22
- branch: ${{ github.base_ref }}
23
- build: ${{ github.run_number }}
24
- - run: npm ci
25
- - run: npm publish
26
- env:
27
- NODE_AUTH_TOKEN: ${{secrets.npm_token}}
1
+ name: Publish Node.js Package
2
+
3
+ on:
4
+ pull_request:
5
+ types:
6
+ - closed
7
+ branches:
8
+ - 'release/**'
9
+
10
+ jobs:
11
+ if_merged:
12
+ if: github.event.pull_request.merged == true
13
+ runs-on: ubuntu-latest
14
+ steps:
15
+ - uses: actions/checkout@v3
16
+ - uses: actions/setup-node@v3
17
+ with:
18
+ node-version: 16
19
+ registry-url: https://registry.npmjs.org/
20
+ - run: npm run build
21
+ env:
22
+ branch: ${{ github.base_ref }}
23
+ build: ${{ github.run_number }}
24
+ - run: npm ci
25
+ - run: npm publish
26
+ env:
27
+ NODE_AUTH_TOKEN: ${{secrets.npm_token}}
package/README.md CHANGED
@@ -1,25 +1,373 @@
1
- # Introduction
2
- TODO: Give a short introduction of your project. Let this section explain the objectives or the motivation behind this project.
3
-
4
- ## Sub Introduction
5
-
6
- ### Sub2 Introduction
7
-
8
-
9
- # Getting Started
10
- TODO: Guide users through getting your code up and running on their own system. In this section you can talk about:
11
- 1. Installation process
12
- 2. Software dependencies
13
- 3. Latest releases
14
- 4. API references
15
-
16
- # Build and Test
17
- TODO: Describe and show how to build your code and run the tests.
18
-
19
- # Contribute
20
- TODO: Explain how other users and developers can contribute to make your code better.
21
-
22
- If you want to learn more about creating good readme files then refer the following [guidelines](https://docs.microsoft.com/en-us/azure/devops/repos/git/create-a-readme?view=azure-devops). You can also seek inspiration from the below readme files:
23
- - [ASP.NET Core](https://github.com/aspnet/Home)
24
- - [Visual Studio Code](https://github.com/Microsoft/vscode)
25
- - [Chakra Core](https://github.com/Microsoft/ChakraCore)
1
+ Set up an AWS organization from scratch and deploy a static site or AMI-based EC2 application in just 4 commands.
2
+
3
+ The tool will handle everything from obtaining ACM certificates to building AMIs and deploying cloudformation stacks.
4
+
5
+ Can be used as a command line tool, or in a CI/CD pipeline.
6
+
7
+ ## Contents
8
+ - [Quick Start](##quick-start)
9
+ - [Important Notes](##important)
10
+ - [Commands](##commands)
11
+
12
+
13
+
14
+ ## Quick Start
15
+
16
+ Get an Ec2 nodejs app up and running in 4 commands.
17
+
18
+ 1. **Prereqs**
19
+ 1. Open an AWS account
20
+ 2. Download and set up the AWS CLI (or just set your AWS credentials with enviroment variables)
21
+ 3. Buy a domain to deploy apps to
22
+ 4. Run the following command to set up your org:
23
+ - `init-org -name MyOrg -region us-east-1`
24
+ 2. **Set up a Local App Template**
25
+ 1. Get a sample nodejs app template:
26
+ - `mason starter -p ./myDesktop/MyFirstApp -type asg`
27
+ 3. **Add an App**
28
+ ```
29
+ mason new-app -name MyFirstApp -type asg
30
+ mason new-instance -app MyFirstApp -domain myfirstapp.com -region us-east-2 -admin me@gmail.com
31
+ mason update-app -app MyFirstApp -v 1.0 -path ./myDesktop/HelloWorld
32
+ mason list-apps
33
+ ```
34
+ 4. **Launch it**
35
+ ```
36
+ mason launch -app MyFirstApp -v 1.0 -domain myfirstapp.com
37
+ mason inspect -app MyFirstApp -domain myfirstapp.com -boot
38
+ ```
39
+ 5. **Review It**
40
+ 1. Visit the domain you specified. You'll see a login page.
41
+ 2. Check the email address you specified for a temp password. Use it to log in.
42
+ 3. After logging in, you'll see a "Hello World" page.
43
+
44
+ #### All Together
45
+
46
+ ```
47
+ init-org -name MyOrg -region us-east-1
48
+ mason starter -p ./myDesktop/MyFirstApp -type asg
49
+ mason new-app -name MyFirstApp -type asg
50
+ mason new-instance -app MyFirstApp -domain myfirstapp.com -region us-east-2 -admin me@gmail.com
51
+ mason update-app -app MyFirstApp -v 1.0 -path ./myDesktop/MyFirstApp
52
+ mason launch -app MyFirstApp -v 1.0 -domain myfirstapp.com
53
+ mason inspect -app MyFirstApp -domain myfirstapp.com -boot
54
+ ```
55
+
56
+
57
+ ## IMPORTANT!!!
58
+
59
+ - THIS APP DEPLOYS EC2 INSTANCES THAT ARE NOT FREE! IT WILL RESULT IN AWS CHARGES!
60
+ - Make sure to run `delete-instance` when you're done to avoid major surprises
61
+ - update-app will build an AMI, which may not be immediately available. Leave a few minutes between running update-app and launch
62
+ - Your web application must serve on localhost:8080
63
+ - Use `inspect` ! It will return all console output of your application - very useful for debugging
64
+
65
+
66
+
67
+
68
+
69
+ # Commands
70
+
71
+ Run `mason [command] -<options>`
72
+
73
+ | Command | Description |
74
+ | ---------------------------- | ------------------------------ |
75
+ | [init-org](###init-org) | Set up a new organization |
76
+ | [set-org](###set-org) | Set default org to an existing org |
77
+ | [new-app](###new-app) | Create a new application |
78
+ | [new-instance](###new-instance) | Create a new instance of an application |
79
+ | [update-app](###update-app) | Update the code and/or stack of an app version |
80
+ | [launch](###launch) | Deploy an app version to an instance |
81
+ | [inspect](###inspect) | Get cloudformation stack status and boot logs for an instance |
82
+ | [starter](###starter) | Get a starter template for a specified architecture type |
83
+ | [delete-instance](###delete-instance) | Delete an instance |
84
+ | [delete-app](###delete-app) | Delete an app |
85
+ | [update-stack](###update-stack) | Update cloudformation stack |
86
+ | [list-apps](###list-apps) | List all apps |
87
+
88
+
89
+
90
+ ### init-org
91
+
92
+
93
+ `mason init-org -name -domain -region `
94
+
95
+ Sets up base infrastructure in a new AWS organization. This command should only be run once. To set up the tool with an existing org, use set-org.
96
+
97
+ | Parameter | Required | Type | Description |
98
+ | -------------- | ------------ | ---------------- | ---------------------------- |
99
+ | **name** | Y | String | Unique org Name. Letters only, no spaces |
100
+ | **domain** | Y | Valid domain | A base domain to use for core resources (e.g., cmason.io) |
101
+ | **region** | Y | AWS Region | Default AWS region for core resources (e.g., us-east-1) |
102
+
103
+
104
+ #### What it does
105
+
106
+ 1. Retrieves the default VPC ID
107
+ 2. Deploys a basic org infra stack
108
+ 1. S3 Bucket + policies for infra resources at `infra.[domain]`
109
+ 2. IAM Role, Instance Profile, and Security Group for Ec2 build agent
110
+ 3. SSM Parameters for oprg name, domain, instance profile, and security group
111
+
112
+
113
+
114
+
115
+ ### new-app
116
+
117
+ `mason new-app -name -type -node -py`
118
+
119
+ #### Params
120
+
121
+ | Parameter | Required | Type | Description |
122
+ | -------------- | ------------ | ---------------- | ---------------------------- |
123
+ | **name** | Y | String | Application name. Letters only |
124
+ | **type** | Y | Application Type | (Application architecture)[##Architectures]. See below for options. |
125
+ | node | n | Number | Version of nodejs to install on the base AMI. If set, app will run using nodejs |
126
+ | py | n | Number | Version of python to install on the base AMI. If set, app will run using python |
127
+
128
+
129
+ **Architecture Options**
130
+
131
+ - asg: autoscaling group
132
+ - static: static site
133
+
134
+ #### Examples
135
+
136
+ ```
137
+ mason new-app -name MyFirstApp -type asg -node
138
+ ```
139
+
140
+ #### What it does
141
+
142
+ 1. Builds a cloudformation stack with the appropriate boot script for nodejs or python
143
+ 2. Uploads the cloudformation template to the S3 infrastructure bucket
144
+ 3. Records the app name, type, and other key detail in SSM params
145
+
146
+
147
+
148
+
149
+ ### new-instance
150
+
151
+ `mason new-instance -app -name -domain -region -admin -max -ins -env`
152
+
153
+ Creates a new instance in a specified region. An instance is a deployment of an application. For example, MyFirstApp could have a test, UAT, and prod instance in us-east-1,us-east-2,and us-west-1.
154
+
155
+ Use -admin to specify the first admin user who will have access to set up other users.
156
+
157
+ #### Params
158
+
159
+ | Parameter | Required | Type | Description |
160
+ | -------------- | ------------ | ---------------- | ---------------------------- |
161
+ | **app** | Y | string | Name of existing application |
162
+ | **name** | Y | string | Instance name (ex., test, uat, etc). Letters only |
163
+ | **domain** | Y | string | Name of a subdomain or domain to deploy behind |
164
+ | **region** | Y | AWS region | region to deploy the instance in |
165
+ | **admin** | Y | email | email adress of first admin user |
166
+ | max | N | int | Maximum number of Ec2 instance to allow in the ASG. Higher number will result in better performance but possibly higher charges. Minimum is 2 to allow for proper refresh. |
167
+ | ins | N | string | Ec2 instance type. Default is t3.small |
168
+ | env | N | string | Enviroment (dev,test,prod). This value will be passed to the application. |
169
+
170
+
171
+ #### Examples
172
+
173
+ ```
174
+ mason new-app -name MyFirstApp -type asg -node
175
+ mason new-instance -app MyFirstApp -name uat -domain test.cmason.io -region us-east-2
176
+ mason new-instance -app MyFirstApp -name beta -domain beta.cmason.io -region us-west-1
177
+ ```
178
+
179
+
180
+ #### What it does
181
+
182
+ 1. Requests an ACM certificate for the domain if none exists (for HTTPS)
183
+ 2. Gets the default VPC ID and Subnets for the target region
184
+ 3. Saves deployment params to SSM for use when deploying the cloud formation template:
185
+ 1. ACM Certificate ID
186
+ 2. VPC Id
187
+ 3. Subnets and hosted zone ID
188
+
189
+
190
+
191
+ ### update-app
192
+
193
+ `mason update -app -v -path`
194
+
195
+ Updates the code for the specified application. This command will build a new AMI and update cloudformation stacks to point to the new AMI.
196
+ Path must lead to the root folder of your application. The bootscript will run with that directory as the root.
197
+
198
+ #### Params
199
+
200
+ | Parameter | Required | Type | Description |
201
+ | -------------- | ------------ | ---------------- | ---------------------------- |
202
+ | **app** | Y | string | Name of the existing app to update |
203
+ | **v** | Y | number | Version number to update |
204
+ | **path** | Y | Path to a folder or zip file containing the updated app code |
205
+
206
+
207
+ #### Examples
208
+
209
+ ```
210
+ mason update -app MyFirstApp -v 1.1 -path ./myfirstapp/src -stack ./myfirstapp/stack.json
211
+ ```
212
+
213
+ #### What it does
214
+
215
+ 1. Zips the folder (if not already zipped)
216
+ 2. Updates the cloudformation stack.yml file and uploads to S3
217
+ 3. Identifies the appropriate AWS Linux AMI ID for the base region
218
+ 4. Launches an EC2 instance, waits until it's ready, and then builds an AMI with the updated code package
219
+ 5. Terminates the EC2 instance
220
+ 6. Updates SSM with the updated AMI ID and build number
221
+
222
+
223
+
224
+
225
+ ### launch
226
+
227
+ `mason launch -app -v -i`
228
+
229
+ Launches a specific version of an application to an instance. For example, launch (deploy) MyFirstApp version 1.2 to test.cmason.io.
230
+
231
+
232
+ #### Params
233
+
234
+ | Parameter | Required | Type | Description |
235
+ | -------------- | ------------ | ---------------- | ---------------------------- |
236
+ | **app** | Y | string | Name of existing application to launch |
237
+ | **v** | Y | number | Version of the app to launch |
238
+ | **i** | Y | string | Name of the instance to deploy to |
239
+
240
+
241
+ #### Examples
242
+
243
+ ```
244
+ mason new-instance -app MyFirstApp -name uat -domain test.cmason.io -region us-east-2
245
+ mason update -app MyFirstApp -v 1.1 -path ./myfirstapp/src -stack ./myfirstapp/stack.jso
246
+ mason launch -app MyFirstApp -v 1.1 -i uat
247
+ ```
248
+
249
+
250
+ #### What it does
251
+
252
+ 1. Copies the AMI version created in the `update` command to the instance region
253
+ 2. Deploys the updated cloudformation stack
254
+
255
+
256
+
257
+ ### update-stack
258
+
259
+ `mason update-stack -app -v -default -stack`
260
+
261
+ Updates the default cloudformation template, or updates the template for a specific version.
262
+
263
+ #### Params
264
+
265
+ | Parameter | Required | Type | Description |
266
+ | -------------- | ------------ | ---------------- | ---------------------------- |
267
+ | **app** | Y | string | Name of the app to update |
268
+ | **stack** | Y | path | File path to updated cloudformation template |
269
+ | -v | N | number | Version number to update. Leave blank to update the default template |
270
+ | -default | flag | Include this flag to update the default cloudformation template for the app |
271
+
272
+
273
+ #### Examples
274
+
275
+ Update version 5 with a new stack
276
+
277
+ ```
278
+ mason update-stack -app MyFirstApp -v 1.0 -stack ../myfirstapp/stack.json
279
+ ```
280
+
281
+ Update the default cloduformation template for all future versions
282
+
283
+ ```
284
+ mason update-stack -app MyFirstApp -default -stack ../myfirstapp/stack.json
285
+ ```
286
+
287
+ #### What it does
288
+
289
+ 1. Uploads the specified stack file to S3
290
+
291
+
292
+
293
+ ### inspect
294
+
295
+ `mason inspect -app -domain [-run or -boot]`
296
+
297
+ Get stack status and EC2 console logs for an instance.
298
+ Useful for debugging issues with application boot up. Console output will
299
+
300
+ To get run logs, the application must write logs to S3 in the logs/run folder. See the starter nodejs app for an example.
301
+
302
+ #### Params
303
+
304
+ | Parameter | Required | Type | Description |
305
+ | -------------- | ------------ | ---------------- | ---------------------------- |
306
+ | **-app** | Y | string | App name |
307
+ | **-domain** | Y | string | Domain to inspect |
308
+ | -boot | N | null | If included, returns logs from the instance start up |
309
+ | -run | N | null | If included, returns run logs stored by the application in the s3 bucket at logs/run/* |
310
+
311
+ #### Examples
312
+
313
+ ```
314
+ mason inspect -app MyFirstApp -domain myfirstapp.com
315
+ ```
316
+
317
+
318
+ ### starter
319
+
320
+ `mason starter -type -l -path`
321
+
322
+ Sets up a starter application template for the specified architecture and language
323
+
324
+ #### Params
325
+
326
+ | Parameter | Required | Type | Description |
327
+ | -------------- | ------------ | ---------------- | ---------------------------- |
328
+ | **-type** | Y | string | Architecture of the application (asg, static, etc) |
329
+ | **-p** | Y | string | Path to output the project to |
330
+ | -l | Y | string | Language. py or node |
331
+
332
+ #### Examples
333
+
334
+ ```
335
+ mason starter -type asg -l node -path ../myfirstapp
336
+ ```
337
+
338
+
339
+
340
+
341
+
342
+ ## TODO
343
+
344
+ - [x] Run logs
345
+ - [x] Read token
346
+ - [x] Verify token
347
+ - [x] Get user groups
348
+ - [x] DDB connect
349
+ - [x] Fix starter routes
350
+ - [x] Add arguments for max ec2 instance and instance type
351
+ - [X] Customize boot script
352
+ - [x] Secure param permissions
353
+ - [X] Pass node/py versions
354
+ - [X] Pass version info to instance
355
+ - [X] Fix Delete App
356
+ - [X] Update default instance
357
+ - [X] Pass Env to instance
358
+ - [] Custom SES Config
359
+ - [X] Fix logs
360
+ - [] Add dev
361
+ - [] Add Admin
362
+ - [] Cloudtrails
363
+ - [] Static site
364
+ - [] Deregistering in home region
365
+ - [] cf-templates s3 bucket creation
366
+
367
+ ## OPEN ITEMS
368
+
369
+ - Custom auth domain
370
+ - AWS requires ACM cert in us-east-1 for custom Cognito auth domain. Cloudformation does not allow for cross-region resource creation
371
+ - [Github AWS Issue](https://github.com/aws-cloudformation/cloudformation-coverage-roadmap/issues/523)
372
+
373
+
package/build.js CHANGED
@@ -1,21 +1,21 @@
1
- const fs = require('fs');
2
-
3
- const pckg = JSON.parse(fs.readFileSync('./package.json'));
4
-
5
- const branch = process.env.branch;
6
- const build = process.env.build;
7
-
8
- console.log(`Branch: ${branch}`);
9
- console.log(`Build: ${build}`);
10
-
11
- const branchParts = branch.split('/');
12
- const lastPart = branchParts[branchParts.length - 1];
13
- const majorVersion = lastPart.replaceAll(/[^0-9\.]/g, '');
14
-
15
- const version = `${majorVersion}.${build}`;
16
-
17
- pckg.version = version;
18
-
19
- console.log(`Version: ${version}`);
20
-
1
+ const fs = require('fs');
2
+
3
+ const pckg = JSON.parse(fs.readFileSync('./package.json'));
4
+
5
+ const branch = process.env.branch;
6
+ const build = process.env.build;
7
+
8
+ console.log(`Branch: ${branch}`);
9
+ console.log(`Build: ${build}`);
10
+
11
+ const branchParts = branch.split('/');
12
+ const lastPart = branchParts[branchParts.length - 1];
13
+ const majorVersion = lastPart.replaceAll(/[^0-9\.]/g, '');
14
+
15
+ const version = `${majorVersion}.${build}`;
16
+
17
+ pckg.version = version;
18
+
19
+ console.log(`Version: ${version}`);
20
+
21
21
  fs.writeFileSync('./package.json', JSON.stringify(pckg));
@@ -1,29 +1,68 @@
1
- const CF = require('./helpers/cf');
2
- const Params = require('./helpers/params');
3
-
4
-
5
- exports.delete_instance = async function(args){
6
- // Get App
7
- const app = await Params.getApp(args.app);
8
- if (!app){
9
- console.log('Err: No app named ' + args.app);
10
- throw new Error('Err: No app named ' + args.app)
11
- }
12
- // Get Instance
13
- const targetInstance = app.instances.find(ins=>{ return ins.name.toLowerCase() == args.i.toLowerCase() });
14
- if (!targetInstance){ console.log(`No instance of ${args.app} named ${args.i}`); throw new Error('Invalid Instance')}
15
-
16
- // Delete Stack
17
- const stackName = (`${args.app}-${args.i}`).toLowerCase();
18
- console.log(`Deleting ${args.app} instance ${args.i} in ${targetInstance.region}`)
19
- const delOK = await CF.delete(stackName, targetInstance.region);
20
- if (delOK){
21
- console.log('Delete Successful')
22
- } else {
23
- return;
24
- }
25
-
26
- // Update Params
27
- await Params.deleteInstance(args.app,args.i);
28
- return true;
1
+ const CF = require('./helpers/cf');
2
+ const Params = require('./helpers/params');
3
+ const S3 = require('./helpers/s3');
4
+ const Common = require('./helpers/common');
5
+
6
+ exports.delete_app = async function(args){
7
+ // Get App
8
+ const app = await Params.getApp(args.app);
9
+ if (!app){
10
+ console.log('Err: No app named ' + args.app);
11
+ throw new Error('Err: No app named ' + args.app)
12
+ }
13
+ // Check Instances
14
+ if (app.instances.length > 0){
15
+ console.log('Err: App has instances. Delete instances first');
16
+ throw new Error('Err: App has instances. Delete instances first')
17
+ }
18
+
19
+ // Delete S3 Files
20
+ console.log('Deleting S3 Content for ' + args.app)
21
+ await S3.deleteAppFolder(args.app);
22
+
23
+ // Deregister AMIs
24
+ await Common.remove_app_amis(args.app,process.env.orgRegion);
25
+
26
+ // Update Params
27
+ console.log('Updating SSM Params')
28
+ await Params.deleteApp(args.app);
29
+ console.log('Succesfully Deleted ' + args.app)
30
+ return true;
31
+ }
32
+
33
+ exports.delete_instance = async function(args){
34
+ // Get App
35
+ const app = await Params.getApp(args.app);
36
+ if (!app){
37
+ console.log('Err: No app named ' + args.app);
38
+ throw new Error('Err: No app named ' + args.app)
39
+ }
40
+ // Get Instance
41
+ const targetInstance = app.instances.find(ins=>{ return ins.domain.toLowerCase() == args.domain.toLowerCase() });
42
+ if (!targetInstance){ console.log(`No instance of ${args.app} named ${args.domain}`); throw new Error('Invalid Instance')}
43
+
44
+ // Check if Stack Exists
45
+ const stackExists = await CF.stackExists(targetInstance.stackName,targetInstance.region);
46
+ console.log(`Stack Exists: ${stackExists}`)
47
+ if (stackExists === true){
48
+ // Delete S3 App Bucket
49
+ const bucketName = await CF.getStackResource('s3',targetInstance.stackName,targetInstance.region);
50
+ console.log('Emptying S3 Bucket for ' + bucketName)
51
+ await S3.emptyBucket(bucketName,targetInstance.region);
52
+ // Delete Stack
53
+ const stackName = targetInstance.stackName;
54
+ console.log(`Deleting ${args.app} instance ${args.domain} in ${targetInstance.region}`)
55
+ const delOK = await CF.delete(stackName, targetInstance.region);
56
+ if (delOK){
57
+ console.log('Delete Successful')
58
+ } else {
59
+ return;
60
+ }
61
+ // Deregister AMIs
62
+ await Common.prune_amis(args.app,targetInstance.version,targetInstance.region,true);
63
+ }
64
+
65
+ // Update Params
66
+ await Params.deleteInstance(args.app,args.domain);
67
+ return true;
29
68
  }