Skip to content

Commit 1e16003

Browse files
authored
Add scripts to easily destroy tfstate backend (#33)
* Add scripts to easily destroy tfstate backend * Improve annotations * Address CR * Fix formatting * Use variable for force_destroy * remove vim typo * Update instructions
1 parent ab1fb98 commit 1e16003

File tree

6 files changed

+86
-24
lines changed

6 files changed

+86
-24
lines changed

aws/tfstate-backend/Makefile

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
## Initialize the configuration (should only be run once)
2+
init:
3+
@scripts/$@.sh
4+
5+
## Destroy the configuration (only works if `force_destroy=true`)
6+
destroy:
7+
@scripts/$@.sh

aws/tfstate-backend/README.md

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,29 @@
11
# Bootstrap Process
22

3-
Run this process the very first time you setup the tfstate bucket.
3+
Perform these steps in each account, the very first time, in order to setup the tfstate bucket.
44

5-
**IMPORTANT:** This has already been performed for this account, so this is documented here just for reference.
5+
## Create
66

7-
Ensure the following environment variables have been set in the `Dockerfile`:
7+
Provision the bucket:
88
```
9-
ENV TF_BUCKET="cp-staging-terraform-state"
10-
ENV TF_BUCKET_REGION="us-west-2"
11-
ENV TF_DYNAMODB_TABLE="cp-staging-terraform-state-lock"
9+
make init
1210
```
1311

14-
Then run these commands:
15-
16-
1. Comment out the `s3 { ... }` section in `main.tf`
17-
18-
2. Run `init-terraform`
12+
Follow the instructions at the end. Ensure the environment variables have been set in the `Dockerfile`.
13+
They look something like this:
14+
```
15+
ENV TF_BUCKET="cpco-staging-terraform-state"
16+
ENV TF_BUCKET_REGION="us-west-2"
17+
ENV TF_DYNAMODB_TABLE="cpco-staging-terraform-state-lock"
18+
```
1919

20-
3. Run `terraform apply`
20+
## Destroy
2121

22-
4. Re-enable `s3 { ... }` section in `main.tf`
22+
To destroy the state bucket, first make sure all services in the account have already been destroyed.
2323

24-
5. Re-run `init-terraform`
24+
Then run:
25+
```
26+
make destroy
27+
```
2528

26-
6. Re-run `terraform apply`, answer `yes` when asked to import state
29+
**NOTE:** This will only work if the state was previously initialized with `force_destroy=true`. If not, set `force_destroy=true`, rerun `terraform apply`, then run `make destroy`.

aws/tfstate-backend/main.tf

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -51,12 +51,19 @@ variable "region" {
5151
default = "us-west-2"
5252
}
5353

54+
variable "force_destroy" {
55+
type = "string"
56+
description = "A boolean that indicates the S3 bucket can be destroyed even if it contains objects. These objects are not recoverable."
57+
default = "false"
58+
}
59+
5460
module "tfstate_backend" {
55-
source = "git::https://github.com/cloudposse/terraform-aws-tfstate-backend.git?ref=tags/0.1.1"
56-
namespace = "${var.namespace}"
57-
name = "${var.name}"
58-
stage = "${var.stage}"
59-
attributes = "${var.attributes}"
60-
tags = "${var.tags}"
61-
region = "${var.region}"
61+
source = "git::https://github.com/cloudposse/terraform-aws-tfstate-backend.git?ref=tags/0.1.1"
62+
namespace = "${var.namespace}"
63+
name = "${var.name}"
64+
stage = "${var.stage}"
65+
attributes = "${var.attributes}"
66+
tags = "${var.tags}"
67+
region = "${var.region}"
68+
force_destroy = "${var.force_destroy}"
6269
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Start with a clean slate
2+
rm -rf .terraform terraform.tfstate
3+
4+
# Init terraform with S3 state enabled. Assumes state was previously initialized.
5+
init-terraform
6+
7+
# Unmount remote bucket (if mounted)
8+
s3 unmount
9+
10+
# Store the current state so we can destroy resources without catch-22
11+
terraform state pull > terraform.tfstate
12+
13+
# Delete current state folder to remove all hints of local & remote state
14+
rm -rf .terraform
15+
16+
# Disable S3 state backend so that we use local state file
17+
sed -Ei 's/^(\s+backend\s+)/#\1/' main.tf
18+
19+
# Reintialize TF state without backend, using local `terraform.tfstate`
20+
terraform init
21+
22+
# Destroy terraform state. Note, only buckets that were created with `force_destroy=true` will successfully be destroyed.
23+
# https://github.com/hashicorp/terraform/issues/7854#issuecomment-293893541
24+
terraform destroy -auto-approve
25+
26+
# Re-enable S3 backend
27+
sed -Ei 's/^#(\s+backend\s+)/\1/' main.tf
28+
29+
# Clean up
30+
rm -rf .terraform terraform.tfstate
Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,41 @@
11
#!/usr/bin/env bash
2+
# This script automates the cold-start process of provisioning the Terraform state backend using terraform
23

34
DISABLE_ROLE_ARN=${DISABLE_ROLE_ARN:-0}
45

6+
# Start from a clean slate
7+
rm -rf .terraform terraform.tfstate
8+
9+
# Disable S3 backend
510
sed -Ei 's/^(\s+backend\s+)/#\1/' main.tf
11+
12+
# Disable Role ARN (necessary for root account on cold-start)
613
[ "${DISABLE_ROLE_ARN}" == "0" ] || sed -Ei 's/^(\s+role_arn\s+)/#\1/' main.tf
714

15+
# Initialize terraform modules and providers
816
init-terraform
9-
echo "yes" | terraform apply
17+
18+
# Provision S3 bucket and dynamodb tables
19+
terraform apply -auto-approve
1020

1121
export TF_BUCKET=$(terraform output -json | jq -r .tfstate_backend_s3_bucket_id.value)
1222
export TF_DYNAMODB_TABLE=$(terraform output -json | jq -r .tfstate_backend_dynamodb_table_id.value)
1323
export TF_BUCKET_REGION=${TF_VAR_region}
1424

25+
# Re-enable S3 backend
1526
sed -Ei 's/^#(\s+backend\s+)/\1/' main.tf
1627

28+
# Reinitialize terraform to import state to remote backend
1729
echo "yes" | init-terraform
1830

31+
# Re-enable Role ARN
1932
[ "${DISABLE_ROLE_ARN}" == "0" ] || sed -Ei 's/^#(\s+role_arn\s+)/\1/' main.tf
2033

34+
# Describe how to use the S3/DynamoDB resources with Geodesic
2135
echo "Add the following to the Geodesic Module's Dockerfile:"
2236
echo "#----------------------------------------------"
2337
echo "ENV TF_BUCKET=\"${TF_BUCKET}\""
2438
echo "ENV TF_BUCKET_REGION=\"${TF_BUCKET_REGION}\""
2539
echo "ENV TF_DYNAMODB_TABLE=\"${TF_DYNAMODB_TABLE}\""
2640
echo "#----------------------------------------------"
27-
echo "And rebuild the module"
41+
echo "...and rebuild the module"
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
namespace="cp"
22
stage="staging"
3+
force_destroy="false"

0 commit comments

Comments
 (0)