Introduction

The first thing you should do to any new AWS account is to run AWS Nuke. This tool deletes specified resources across all regions.

WARNING:

If you're not careful, this will delete things you don't want it to delete, proceed with caution

  • Use a normal run, which is actually a dry-run, to figure out which resources will be deleted.
  • Only once you're comfortable with this should you run it for real.

The GitHub repository for this is at rebuy-de/aws-nuke, and in the README, at the time of writing, it includes these words of warning:

  • We strongly advise you to not run this application on any AWS account, where you cannot afford to lose all resources.

Heed those words!

First we should cover the "Why"; After all those warnings, why should you run this? Then we can move on to the "How".

Why

When you create a new AWS account, it comes with Default VPCs and a whole plethora of surrounding resources. On the face of it this might not seem like an issue, but it is. If you execute Terraform without perfecting the code for calling a subnet or security group, it may default to creating resources in the default VPC, with a public IP, that you haven't locked down yet! This poses a security risk and could be quite dangerous.

Preparation

There are some things you should create when you make an account, that you shouldn't delete. These are:

  • Multi-factor authentication (MFA) to the root account
  • Create at least one other user, add MFA to that
  • You might also want to create a user for Terraform, this shouldn't have console access, just programmatic access

Note: When you run this, you will have to confirm the account alias. This is the account alias you set in the IAM console in AWS, if you haven't set one you won't be able to run this tool. This is an added safety measure to ensure you're not deleting resources in the wrong account.

How

So now you have a new account, you've done the preparation, you're ready to install and run AWS Nuke.

  1. Install AWS Nuke

Install on Linux

# Download and extract aws-nuke directly into /usr/local/bin
sudo wget -c https://github.com/rebuy-de/aws-nuke/releases/download/v2.25.0/aws-nuke-v2.25.0-linux-amd64.tar.gz -O - | sudo tar -xz -C /usr/local/bin

# Make sure aws-nuke is executable
sudo chmod +x /usr/local/bin/aws-nuke
  1. Configuring AWS Nuke

You may want to create a project directory, or you may already have one, either way, create a file called aws-nuke-config.yaml in the root of your project directory. The following is an example of what you could populate it with, which would be suitable for a brand-new account.

Regions

The configuration below has a list of all regions that AWS starts with as default. I think this is the same for most users but there may be some differences based on your geographical location.

Accounts

You can add a list of accounts you would like excluded from the nuke by adding an account-blocklist section. You should then add the accounts you want included in the accounts section.

Resource Types

You need to either define which resources should be included, which should be excluded, or a combination of both.

You can do this both ways, but if I'm honest, running this with ONLY excludes results in a bit of a messy output, as it attempts to check absolutely everything, and it results in a lot of error messages, it is possible to sift through them, the lines that say would remove do actually stand out, but it's not ideal and there's a lot of noise.

---
regions:
  - "global" # This is for all global resource types e.g. IAM
  - "us-east-1"
  - "us-east-2"
  - "us-west-1"
  - "us-west-2"
  - "ap-south-1"
  - "ap-northeast-3"
  - "ap-northeast-2"
  - "ap-southeast-1"
  - "ap-southeast-2"
  - "ap-northeast-1"
  - "ca-central-1"
  - "eu-central-1"
  - "eu-west-1"
  - "eu-west-2"
  - "eu-west-3"
  - "eu-north-1"
  - "sa-east-1"

account-blocklist:
  "123456789012"

accounts:
  "111111111111": {}
  "222222222222": {}

resource-types: #not mandatory
  targets:
    - EC2VPC
    - EC2DHCPOption
    - EC2SecurityGroup
    - EC2InternetGateway
    - EC2DefaultSecurityGroupRule
    - EC2Subnet
    - EC2RouteTable
    - EC2InternetGatewayAttachment
    - EC2NetworkACL

If you want to have it delete everything apart from IAM resources, so you won't lose your users, you can add excludes to the resource-types section. Here's an example:

resource-types: #not mandatory
  excludes:
    # EC2
    - EC2KeyPair
    # IAM
    - IAMUser
    - IAMUserAccessKey
    - IAMVirtualMFADevice
    - IAMAccountSummary
    - IAMUserGroupAttachment
    - IAMGroup
    - IAMGroupPolicyAttachment
    - IAMRole
    - IAMRolePolicyAttachment
    # Route53
    - Route53ResolverRule
    # OpenSearch
    - OSPackage
    # AppConfig
    - AppConfigDeploymentStrategy
    # Elasticache
    - ElasticacheUser
    - ElasticacheCacheParameterGroup
    # MemoryDB
    - MemoryDBUser
    - MemoryDBParameterGroup
    - MemoryDBACL
    # Athena
    - AthenaWorkGroup
    # AppStream
    - AppStreamImage
    # OpsWorks
    - OpsWorksUserProfile
    # MediaConvert
    - MediaConvertQueue
    # KMS
    - KMSAlias

Further examples of more fine-grained targeting of resources, including specifically targeting the Default VPC and it's associated resources can be found in example configs. Further syntax examples are available in the README.

Before we move on to How to run AWS Nuke, I want to add another Warning, there can't be too many with this tool.

WARNING, you should thoroughly check the output before committing to running this for real.

  1. Running AWS Nuke

You can run AWS Nuke with the following command. This will execute a dry-run because that is the default behaviour. This will show you what would be deleted, but won't actually delete anything.

aws-nuke -c aws-nuke-config.yaml --profile arryw-dev-dublin

If you have the suggested includes and excludes in your config, and you're working on a new account, when you run the command you might see an output like this (I've sampled a single region, you might see multiple):

$ aws-nuke -c aws-nuke-config.yaml --profile arryw-dev-dublin
aws-nuke version v2.25.0 - Mon Sep  4 07:22:03 UTC 2023 - 2bd22d5e5c0cf6a4011b3FaLsEFaLsEe2e6c75bd

Do you really want to nuke the account with the ID 111111111111 and the alias 'arryw'?
Do you want to continue? Enter account alias to continue.
> arryw

eu-west-1 - EC2NetworkACL - acl-0e287c84c73142e68 - [ID: "acl-0e287c84FaLsE2e68", OwnerID: "111111111111"] - cannot delete default VPC
eu-west-1 - EC2VPC - vpc-0d1807cf00e8a384c - [ID: "vpc-0d1807cfFaLsE384c", IsDefault: "true", OwnerID: "111111111111"] - would remove
eu-west-1 - EC2InternetGateway - igw-08accb57aFaLsE490 - [DefaultVPC: "true", OwnerID: "111111111111"] - would remove
eu-west-1 - EC2RouteTable - rtb-0107a10adFaLsE31d - [DefaultVPC: "true", OwnerID: "111111111111"] - Main RouteTables cannot be deleted
eu-west-1 - EC2DHCPOption - dopt-074d464305FaLsEa4 - [DefaultVPC: "true", OwnerID: "111111111111"] - would remove
eu-west-1 - EC2SecurityGroup - sg-051ee00FaLsE7d740 - [Name: "default", OwnerID: "111111111111"] - cannot delete group 'default'
eu-west-1 - EC2InternetGatewayAttachment - igw-08accb57aFaLsE490 -> vpc-0d1807cf00e8a384c - [DefaultVPC: "true", igw:OwnerID: "111111111111", vpc:OwnerID: "111111111111"] - would remove
eu-west-1 - EC2Subnet - subnet-0c4a72c5bFaLsEbaa - [DefaultForAz: "true", DefaultVPC: "true", OwnerID: "111111111111"] - would remove
eu-west-1 - EC2Subnet - subnet-0e7421910FaLsEf23 - [DefaultForAz: "true", DefaultVPC: "true", OwnerID: "111111111111"] - would remove
eu-west-1 - EC2Subnet - subnet-0f5c4dddfFaLsE77a - [DefaultForAz: "true", DefaultVPC: "true", OwnerID: "111111111111"] - would remove
eu-west-1 - EC2DefaultSecurityGroupRule - sgr-08ad76a6d04283d16 - [SecurityGroupId: "sg-051ee00FaLsE7d740"] - would remove
eu-west-1 - EC2DefaultSecurityGroupRule - sgr-09a8d6417aeafef89 - [SecurityGroupId: "sg-051ee00FaLsE7d740"] - would remove
Scan complete: 12 total, 9 nukeable, 3 filtered.

The above resources would be deleted with the supplied configuration. Provide --no-dry-run to actually destroy resources.

This is a dry-run, so it's not actually going to delete anything, but it's showing you what it would delete if you ran it for real. If you see some things you don't want to delete, you should add those resource types to the excludes in your config file.

If you're happy with the output, you can run it for real by adding --no-dry-run to the command. This will prompt you twice to confirm your account alias, the first time is prior to it showing you what it would delete, the second time is to request confirmation to go ahead with the resource deletion.

aws-nuke -c aws-nuke-config.yaml --profile arryw-dev-dublin --no-dry-run

Summary

In case this article doesn't contain enough warnings, I'll add another one. Be careful with this tool. It's powerful, and it can do a lot of damage if you're not careful. If you're not sure, don't run it, or at least run it in a new account that you don't mind losing everything in.

If you're sure, and you're ready, then go ahead, run it, and watch as your account is nuked!