Skip to content

Commit

Permalink
More robust lift delete command
Browse files Browse the repository at this point in the history
  • Loading branch information
mnapoli committed Aug 28, 2020
1 parent 2e48675 commit bd8dd4c
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 3 deletions.
4 changes: 2 additions & 2 deletions lift.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: tmp-configtest
name: lift
region: us-east-1

s3:
Expand All @@ -8,4 +8,4 @@ s3:

#db:

static-website:
#static-website:
2 changes: 1 addition & 1 deletion serverless.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
service: tmp-configtest-app
service: lift-app

provider:
name: aws
Expand Down
37 changes: 37 additions & 0 deletions src/Deployer.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import CloudFormation, {StackEvent} from 'aws-sdk/clients/cloudformation';
import {Stack} from "./Stack";
import ora from "ora";
import {waitFor} from "./utils/wait";

class NeedToDeleteStack implements Error {
message = 'The stack is in a failed state because its creation failed. You need to delete it before attempting to deploy again.';
Expand Down Expand Up @@ -166,9 +167,45 @@ export class Deployer {
region: stack.region,
});

const response = await cloudFormation.describeStacks({
StackName: stack.name,
}).promise();
if (!response.Stacks || response.Stacks?.length === 0) {
console.log('Stack doesn\'t exist, nothing to delete');
return;
}
// Use the stack ID because it keeps working even after the stack is deleted
const stackId = response.Stacks[0].StackId;

const progress = ora('Deleting stack').start();

await cloudFormation.deleteStack({
StackName: stack.name,
}).promise();

try {
await waitFor(async () => {
progress.text = progress.text + '.';
const response = await cloudFormation.describeStacks({
StackName: stackId,
}).promise();
const status = response.Stacks![0].StackStatus;
const reason = response.Stacks![0].StackStatusReason ? response.Stacks![0].StackStatusReason : status;
switch (status) {
case 'DELETE_IN_PROGRESS':
return false;
case 'DELETE_COMPLETE':
return true;
default:
throw new Error(`Deletion failed. ${reason}`);
}
});
} catch (e) {
progress.fail();
throw e;
}

progress.succeed();
}

private async deployOperation(cloudFormation: CloudFormation, stackName: string): Promise<string> {
Expand Down
16 changes: 16 additions & 0 deletions src/utils/wait.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
export async function wait(delay: number) {
return new Promise(resolve => setTimeout(resolve, delay));
}

export async function waitFor(callback: () => Promise<boolean>, maxAttempts = 120, delay = 3000) {
let attempts = 0;
while (attempts < maxAttempts) {
const result = await callback();
if (result) {
return;
}
attempts++;
await wait(delay)
}
throw new Error('Waited for too long, something is up!')
}

0 comments on commit bd8dd4c

Please sign in to comment.