- 
      
 - 
        
Save jokeru/e4a25bbd95080cfd00edf1fa67b06996 to your computer and use it in GitHub Desktop.  
| #!/usr/bin/env bash | |
| if [ "$AWS_PROFILE" = "" ]; then | |
| echo "No AWS_PROFILE set" | |
| exit 1 | |
| fi | |
| for region in $(aws ec2 describe-regions --region eu-west-1 | jq -r .Regions[].RegionName); do | |
| echo "* Region ${region}" | |
| # get default vpc | |
| vpc=$(aws ec2 --region ${region} \ | |
| describe-vpcs --filter Name=isDefault,Values=true \ | |
| | jq -r .Vpcs[0].VpcId) | |
| if [ "${vpc}" = "null" ]; then | |
| echo "No default vpc found" | |
| continue | |
| fi | |
| echo "Found default vpc ${vpc}" | |
| # get internet gateway | |
| igw=$(aws ec2 --region ${region} \ | |
| describe-internet-gateways --filter Name=attachment.vpc-id,Values=${vpc} \ | |
| | jq -r .InternetGateways[0].InternetGatewayId) | |
| if [ "${igw}" != "null" ]; then | |
| echo "Detaching and deleting internet gateway ${igw}" | |
| aws ec2 --region ${region} \ | |
| detach-internet-gateway --internet-gateway-id ${igw} --vpc-id ${vpc} | |
| aws ec2 --region ${region} \ | |
| delete-internet-gateway --internet-gateway-id ${igw} | |
| fi | |
| # get subnets | |
| subnets=$(aws ec2 --region ${region} \ | |
| describe-subnets --filters Name=vpc-id,Values=${vpc} \ | |
| | jq -r .Subnets[].SubnetId) | |
| if [ "${subnets}" != "null" ]; then | |
| for subnet in ${subnets}; do | |
| echo "Deleting subnet ${subnet}" | |
| aws ec2 --region ${region} \ | |
| delete-subnet --subnet-id ${subnet} | |
| done | |
| fi | |
| # https://docs.aws.amazon.com/cli/latest/reference/ec2/delete-vpc.html | |
| # - You can't delete the main route table | |
| # - You can't delete the default network acl | |
| # - You can't delete the default security group | |
| # delete default vpc | |
| echo "Deleting vpc ${vpc}" | |
| aws ec2 --region ${region} \ | |
| delete-vpc --vpc-id ${vpc} | |
| done | 
I found that running this script on Windows failed with the error: ' doesn't match a supported format..
The root cause was jq separating each region name with a carriage return ('\r') and line feed ('\n') character as opposed to a single line feed.  Perhaps obvious in hindsight...
My solution was to strip the carriage return characters with an extra step:
Replace:
for region in $(aws ec2 describe-regions --region eu-west-1 | jq -r .Regions[].RegionName); do
With:
regions=$(aws ec2 describe-regions --region eu-west-1 | jq -r .Regions[].RegionName)
regions=${regions//[$'\r']}
for region in $regions; do
    Here is my version - removes need for jq and a couple of other changes
#!/usr/bin/env bash
# based on https://gist.github.com/jokeru/e4a25bbd95080cfd00edf1fa67b06996
# Made modifications to remove need for jq, set AWS_DEFAULT_REGION so you don't have to specify --region explicitly
#  Add region 'human-readable' names
REGIONS='us-east-1 (N. Virginia)
us-east-2 (Ohio)
us-west-1 (California)
us-west-2 (Oregon)
eu-central-1 (Frankfurt)
eu-west-1 (Ireland)
eu-west-2 (London)
eu-west-3 (Paris)
eu-north-1 (Stockholm)
ap-northeast-1 (Tokyo)
ap-northeast-2 (Seoul)
ap-south-1 (Mumbai)
ap-southeast-1 (Singapore)
ap-southeast-2 (Sydney)
ca-central-1 (Toronto)
sa-east-1 (Sao Paolo)
ap-northeast-3 (Osaka)
ap-east-1 (Honk Kong)
me-south-1 (Bahrain)
af-south-1 (Cape Town)
eu-south-1 (Milan)'
INDENT='    '
echo "Using profile $AWS_PROFILE"
aws ec2 describe-regions --output text --query 'Regions[].[RegionName, OptInStatus]' | sort -r \
| while read REGION OptInStatus; do
  export AWS_DEFAULT_REGION=$REGION
  RegName=$( echo "$REGIONS" | grep "^${REGION}" )
  [ -z "$RegName" ] && RegName="$REGION"
  echo "* Region ${RegName}"
  # get default vpc
  vpc=$( aws ec2  describe-vpcs --filter Name=isDefault,Values=true --output text --query 'Vpcs[0].VpcId' )
  if [ "${vpc}" = "None" ]; then
    echo "${INDENT}No default vpc found"
    continue
  fi
  echo "${INDENT}Found default vpc ${vpc}"
  # get internet gateway
  igw=$(aws ec2 describe-internet-gateways --filter Name=attachment.vpc-id,Values=${vpc}  --output text --query 'InternetGateways[0].InternetGatewayId' )
  if [ "${igw}" != "None" ]; then
    echo "${INDENT}Detaching and deleting internet gateway ${igw}"
    aws ec2 detach-internet-gateway --internet-gateway-id ${igw} --vpc-id ${vpc}
    aws ec2 delete-internet-gateway --internet-gateway-id ${igw}
  fi
  # get subnets
  subnets=$(aws ec2 describe-subnets --filters Name=vpc-id,Values=${vpc} --output text --query 'Subnets[].SubnetId' )
  if [ "${subnets}" != "None" ]; then
    for subnet in ${subnets}; do
      echo "${INDENT}Deleting subnet ${subnet}"
      aws ec2 delete-subnet --subnet-id ${subnet}
    done
  fi
  # https://docs.aws.amazon.com/cli/latest/reference/ec2/delete-vpc.html
  # - You can't delete the main route table
  # - You can't delete the default network acl
  # - You can't delete the default security group
  # delete default vpc
  echo "${INDENT}Deleting vpc ${vpc}"
  aws ec2 delete-vpc --vpc-id ${vpc}
done
@devt worked like a charm, I added before the last line done, and after the delete-vpc command, the next code block, it helps to delete the dhcp options resource.
  # get default dhcp options
  dhcp=$(aws ec2 describe-dhcp-options  --output text --query 'DhcpOptions[0].DhcpOptionsId')
  if [ "${dhcp}" != "None" ]; then
    echo "${INDENT}Deleting dhcp ${dhcp}"
    aws ec2 delete-dhcp-options --dhcp-options-id ${dhcp}
  fi@devt, just a minor change: I had to use export AWS_REGION=$REGION for this to work correctly from a CloudShell.
@devt @xyklex @matt-slalom
I tried specifying two or three regions only; however, it scans each and every region one by one. Can anyone please help me figure out where to modify it? Is it because the script is using the aws ec2 describe-regions command?
@theshameless, yes, it looks like the loop will execute for regions beyond what are specified at the top of @devt's script because of aws ec2 describe-regions. This update seems to do what you want:
#!/usr/bin/env bash
# based on https://gist.github.com/jokeru/e4a25bbd95080cfd00edf1fa67b06996
# Made modifications to remove need for jq, set AWS_DEFAULT_REGION so you don't have to specify --region explicitly
#  Add region 'human-readable' names
REGIONS='us-east-1 (N. Virginia)
us-east-2 (Ohio)
us-west-1 (California)
us-west-2 (Oregon)
eu-central-1 (Frankfurt)
eu-west-1 (Ireland)
eu-west-2 (London)
eu-west-3 (Paris)
eu-north-1 (Stockholm)
ap-northeast-1 (Tokyo)
ap-northeast-2 (Seoul)
ap-south-1 (Mumbai)
ap-southeast-1 (Singapore)
ap-southeast-2 (Sydney)
ca-central-1 (Toronto)
sa-east-1 (Sao Paolo)
ap-northeast-3 (Osaka)
ap-east-1 (Honk Kong)
me-south-1 (Bahrain)
af-south-1 (Cape Town)
eu-south-1 (Milan)'
INDENT='    '
echo "Using profile $AWS_PROFILE"
aws ec2 describe-regions --output text --query 'Regions[].[RegionName, OptInStatus]' | sort -r |
  while read REGION OptInStatus; do
    export AWS_REGION=$REGION
    RegName=$(echo "$REGIONS" | grep "^${REGION}")
    if [ ! -z "$RegName" ] && RegName="$REGION"; then
      echo "* Region ${RegName}"
      # get default vpc
      vpc=$(aws ec2 describe-vpcs --filter Name=isDefault,Values=true --output text --query 'Vpcs[0].VpcId')
      if [ "${vpc}" = "None" ]; then
        echo "${INDENT}No default vpc found"
        continue
      fi
      echo "${INDENT}Found default vpc ${vpc}"
      # get internet gateway
      igw=$(aws ec2 describe-internet-gateways --filter Name=attachment.vpc-id,Values=${vpc} --output text --query 'InternetGateways[0].InternetGatewayId')
      if [ "${igw}" != "None" ]; then
        echo "${INDENT}Detaching and deleting internet gateway ${igw}"
        aws ec2 detach-internet-gateway --internet-gateway-id ${igw} --vpc-id ${vpc}
        aws ec2 delete-internet-gateway --internet-gateway-id ${igw}
      fi
      # get subnets
      subnets=$(aws ec2 describe-subnets --filters Name=vpc-id,Values=${vpc} --output text --query 'Subnets[].SubnetId')
      if [ "${subnets}" != "None" ]; then
        for subnet in ${subnets}; do
          echo "${INDENT}Deleting subnet ${subnet}"
          aws ec2 delete-subnet --subnet-id ${subnet}
        done
      fi
      # https://docs.aws.amazon.com/cli/latest/reference/ec2/delete-vpc.html
      # - You can't delete the main route table
      # - You can't delete the default network acl
      # - You can't delete the default security group
      # delete default vpc
      echo "${INDENT}Deleting vpc ${vpc}"
      aws ec2 delete-vpc --vpc-id ${vpc}
      # get default dhcp options
      dhcp=$(aws ec2 describe-dhcp-options --output text --query 'DhcpOptions[0].DhcpOptionsId')
      if [ "${dhcp}" != "None" ]; then
        echo "${INDENT}Deleting dhcp ${dhcp}"
        aws ec2 delete-dhcp-options --dhcp-options-id ${dhcp}
      fi
    fi
  done@matt-slalom
Thank you for the update, but it didn't work, so I made a slight modification to the script (also removed human-readable names) and now it works well. Here is the modified version.
#!/usr/bin/env bash
REGIONS='us-east-1
us-east-2
us-west-1'
INDENT='    '
echo "Using profile $AWS_PROFILE"
for region in $REGIONS; do
  export AWS_REGION=$region
  echo "* Region $region"
      # get default vpc
      vpc=$(aws ec2 describe-vpcs --filter Name=isDefault,Values=true --output text --query 'Vpcs[0].VpcId')
      if [ "${vpc}" = "None" ]; then
        echo "${INDENT}No default vpc found"
        continue
      fi
      echo "${INDENT}Found default vpc ${vpc}"
      # get internet gateway
      igw=$(aws ec2 describe-internet-gateways --filter Name=attachment.vpc-id,Values=${vpc} --output text --query 'InternetGateways[0].InternetGatewayId')
      if [ "${igw}" != "None" ]; then
        echo "${INDENT}Detaching and deleting internet gateway ${igw}"
        aws ec2 detach-internet-gateway --internet-gateway-id ${igw} --vpc-id ${vpc}
        aws ec2 delete-internet-gateway --internet-gateway-id ${igw}
      fi
      # get subnets
      subnets=$(aws ec2 describe-subnets --filters Name=vpc-id,Values=${vpc} --output text --query 'Subnets[].SubnetId')
      if [ "${subnets}" != "None" ]; then
        for subnet in ${subnets}; do
          echo "${INDENT}Deleting subnet ${subnet}"
          aws ec2 delete-subnet --subnet-id ${subnet}
        done
      fi
      # delete default vpc
      echo "${INDENT}Deleting vpc ${vpc}"
      aws ec2 delete-vpc --vpc-id ${vpc}
done
    Here is my version - removes need for jq and a couple of other changes
#!/usr/bin/env bash # based on https://gist.github.com/jokeru/e4a25bbd95080cfd00edf1fa67b06996 # Made modifications to remove need for jq, set AWS_DEFAULT_REGION so you don't have to specify --region explicitly # Add region 'human-readable' names REGIONS='us-east-1 (N. Virginia) us-east-2 (Ohio) us-west-1 (California) us-west-2 (Oregon) eu-central-1 (Frankfurt) eu-west-1 (Ireland) eu-west-2 (London) eu-west-3 (Paris) eu-north-1 (Stockholm) ap-northeast-1 (Tokyo) ap-northeast-2 (Seoul) ap-south-1 (Mumbai) ap-southeast-1 (Singapore) ap-southeast-2 (Sydney) ca-central-1 (Toronto) sa-east-1 (Sao Paolo) ap-northeast-3 (Osaka) ap-east-1 (Honk Kong) me-south-1 (Bahrain) af-south-1 (Cape Town) eu-south-1 (Milan)' INDENT=' ' echo "Using profile $AWS_PROFILE" aws ec2 describe-regions --output text --query 'Regions[].[RegionName, OptInStatus]' | sort -r \ | while read REGION OptInStatus; do export AWS_DEFAULT_REGION=$REGION RegName=$( echo "$REGIONS" | grep "^${REGION}" ) [ -z "$RegName" ] && RegName="$REGION" echo "* Region ${RegName}" # get default vpc vpc=$( aws ec2 describe-vpcs --filter Name=isDefault,Values=true --output text --query 'Vpcs[0].VpcId' ) if [ "${vpc}" = "None" ]; then echo "${INDENT}No default vpc found" continue fi echo "${INDENT}Found default vpc ${vpc}" # get internet gateway igw=$(aws ec2 describe-internet-gateways --filter Name=attachment.vpc-id,Values=${vpc} --output text --query 'InternetGateways[0].InternetGatewayId' ) if [ "${igw}" != "None" ]; then echo "${INDENT}Detaching and deleting internet gateway ${igw}" aws ec2 detach-internet-gateway --internet-gateway-id ${igw} --vpc-id ${vpc} aws ec2 delete-internet-gateway --internet-gateway-id ${igw} fi # get subnets subnets=$(aws ec2 describe-subnets --filters Name=vpc-id,Values=${vpc} --output text --query 'Subnets[].SubnetId' ) if [ "${subnets}" != "None" ]; then for subnet in ${subnets}; do echo "${INDENT}Deleting subnet ${subnet}" aws ec2 delete-subnet --subnet-id ${subnet} done fi # https://docs.aws.amazon.com/cli/latest/reference/ec2/delete-vpc.html # - You can't delete the main route table # - You can't delete the default network acl # - You can't delete the default security group # delete default vpc echo "${INDENT}Deleting vpc ${vpc}" aws ec2 delete-vpc --vpc-id ${vpc} done
thank you
Some of the spaces in the file, are formated wrongly using 0xc2a0 (NBSP). Replace with regular spaces, and it works.