CMSgov/macpro-platform-doc-conversion

View on GitHub
destroy.sh

Summary

Maintainability
Test Coverage
#!/bin/bash
set -e

if [[ $1 == "" ]] ; then
    echo 'ERROR:  You must pass a stage to destroy.  Ex. sh destroy.sh my-stage-name'
    exit 1
fi
stage=$1

# A list of protected/important branches/environments/stages.
protected_stage_regex="(^master$|^val$|^production)"
if [[ $stage =~ $protected_stage_regex ]] ; then
    echo """
      ---------------------------------------------------------------------------------------------
      ERROR:  Please read below
      ---------------------------------------------------------------------------------------------
      The regex used to denote protected stages matched the stage name you passed.
      The regex holds names commonly used for important branches/environments/stages.
      This indicates you're trying to destroy a stage that you likely don't really want to destroy.
      Out of caution, this script will not continue.

      If you really do want to destroy $stage, modify this script as necessary and run again.

      Be careful.
      ---------------------------------------------------------------------------------------------
    """
    exit 1
fi
echo "\nCollecting information on stage $stage before attempting a destroy... This can take a minute or two..."

set -e

# Find cloudformation stacks associated with stage
stackList=(`aws cloudformation describe-stacks | jq -r ".Stacks[] | select(.Tags[] | select(.Key==\"STAGE\") | select(.Value==\"$stage\")) | .StackName"`)

# Find buckets attached to any of the stages, so we can empty them before removal.
bucketList=()
set +e
for i in "${stackList[@]}"
do
  buckets=(`aws cloudformation list-stack-resources --stack-name $i | jq -r ".StackResourceSummaries[] | select(.ResourceType==\"AWS::S3::Bucket\") | .PhysicalResourceId"`)
  for j in "${buckets[@]}"
  do
    # Sometimes a bucket has been deleted outside of CloudFormation; here we check that it exists.
    if aws s3api head-bucket --bucket $j > /dev/null 2>&1; then
      bucketList+=($j)
    fi
  done
done

echo """
********************************************************************************
- Check the following carefully -
********************************************************************************
"""

echo "The following buckets will be emptied"
printf '%s\n' "${bucketList[@]}"

echo "The following stacks will be destroyed:"
printf '%s\n' "${stackList[@]}"

echo """
********************************************************************************
- Scroll up and check carefully -
********************************************************************************
"""
if [ "$CI" != "true" ]; then
  read -p "Do you wish to continue?  Re-enter the stage name to continue:  " -r
  echo
  if [[ ! $REPLY == "$stage" ]]
  then
      echo "Stage name not re-entered.  Doing nothing and exiting."
      exit 1
  fi
fi

for i in "${bucketList[@]}"
do
  echo $i
  set -e

  # Suspend bucket versioning.
  aws s3api put-bucket-versioning --bucket $i --versioning-configuration Status=Suspended

  # Remove all bucket versions.
  versions=`aws s3api list-object-versions \
    --bucket "$i" \
    --output=json \
    --query='{Objects: Versions[].{Key:Key,VersionId:VersionId}}'`
  if ! echo $versions | grep -q '"Objects": null'; then
    aws s3api delete-objects \
      --bucket $i \
      --delete "$versions" > /dev/null 2>&1
  fi

  # Remove all bucket delete markers.
  markers=`aws s3api list-object-versions \
    --bucket "$i" \
    --output=json \
    --query='{Objects: DeleteMarkers[].{Key:Key,VersionId:VersionId} }'`
  if ! echo $markers | grep -q '"Objects": null'; then
    aws s3api delete-objects \
      --bucket $i \
      --delete "$markers" > /dev/null 2>&1
  fi

  # Empty the bucket
  aws s3 rm s3://$i/ --recursive
done

# Trigger a delete for each cloudformation stack
for i in "${stackList[@]}"
do
  echo $i
  aws cloudformation delete-stack --stack-name $i
done