Skip to content

Instantly share code, notes, and snippets.

@jokeru
Created March 31, 2018 15:14
Show Gist options
  • Star 45 You must be signed in to star a gist
  • Fork 16 You must be signed in to fork a gist
  • Save jokeru/e4a25bbd95080cfd00edf1fa67b06996 to your computer and use it in GitHub Desktop.
Save jokeru/e4a25bbd95080cfd00edf1fa67b06996 to your computer and use it in GitHub Desktop.
Script to delete all AWS default VPCs from all regions using AWS CLI
#!/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
@jenishdoshi
Copy link

I got below error while using the script. Kindly advise.

[cloudshell-user@ip-10-0-129-122 ~]$ ls
aws_delete-default-vpc.sh
[cloudshell-user@ip-10-0-129-122 ~]$ chmod +x aws_delete-default-vpc.sh
[cloudshell-user@ip-10-0-129-122 ~]$ ./aws_delete-default-vpc.sh
./aws_delete-default-vpc.sh: line 5:   echo: command not found
./aws_delete-default-vpc.sh: line 6:   exit: command not found
./aws_delete-default-vpc.sh: line 18: syntax error near unexpected token then' ./aws_delete-default-vpc.sh: line 18:   if [ "${vpc}" = "null" ]; then'
[cloudshell-user@ip-10-0-129-122 ~]$

@nmarchini
Copy link

if you are running in AWS cloudshell you might need to delete lines

if [ "$AWS_PROFILE" = "" ]; then
  echo "No AWS_PROFILE set"
  exit 1
fi


Also check if jq is installed or not. if not then see if you can install it. This runs fine from my laptop with jq installed.

I did have to set the default output to json on my aws profile

@Kirizan
Copy link

Kirizan commented Apr 6, 2021

syntax error near unexpected token then' ./aws_delete-default-vpc.sh: line 18: ` if [ "${vpc}" = "null" ]; then'

If anyone else has this issue, it was cause by wget/curl using the wrong space character. I used VS Code's search and replace to replace the spaces that were downloaded with regular spaces and everything worked fine after that.

@runesl
Copy link

runesl commented Sep 3, 2021

Some of the spaces in the file, are formated wrongly using 0xc2a0 (NBSP). Replace with regular spaces, and it works.

@pflugs30
Copy link

pflugs30 commented Sep 4, 2021

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

@devt
Copy link

devt commented Mar 16, 2022

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

@xyklex
Copy link

xyklex commented Apr 3, 2023

@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

@matt-slalom
Copy link

@devt, just a minor change: I had to use export AWS_REGION=$REGION for this to work correctly from a CloudShell.

@theshameless
Copy link

theshameless commented Jun 21, 2023

@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?

@matt-slalom
Copy link

@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

@theshameless
Copy link

theshameless commented Jun 22, 2023

@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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment