Skip to content

Commit

Permalink
add delete-default-vpc
Browse files Browse the repository at this point in the history
  • Loading branch information
sosimon committed Dec 13, 2020
1 parent 5bc0bc6 commit a7d08e1
Show file tree
Hide file tree
Showing 2 changed files with 222 additions and 0 deletions.
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# delete-default-vpc

Delete default VPC in all regions in an AWS account.

There are Python and Bash scripts that do this like [this](https://github.com/davidobrien1985/delete-aws-default-vpc) and [this](https://gist.github.com/jokeru/e4a25bbd95080cfd00edf1fa67b06996), but Python requires Python to be installed, and Bash is quite slow.

## Requirements

* `go >= 1.15.2`
* AWS credentials with appropriate permissions to delete VPC, IGW, and Subnets


## Build

`go build -o delete-default-vpc`

## Run

`./delete-default-vpc`
203 changes: 203 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
package main

import (
"fmt"
"sync"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/aws/client"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/aws/aws-sdk-go/service/sts"
)

// https://docs.aws.amazon.com/sdk-for-go/api/service/sts/#STS.GetCallerIdentity
func getCallerIdentity(session client.ConfigProvider) error {
stsSvc := sts.New(session)
result, err := stsSvc.GetCallerIdentity(&sts.GetCallerIdentityInput{})
if err != nil {
handleError(err)
}
if result.Arn != nil {
fmt.Printf("Logged in as: %s\n", *result.Arn)
}
return err
}

func getRegions(svc *ec2.EC2) []string {
result, err := svc.DescribeRegions(&ec2.DescribeRegionsInput{})
if err != nil {
handleError(err)
return nil
}

if result != nil {
output := []string{}
for _, region := range result.Regions {
output = append(output, *region.RegionName)
}
return output
}

fmt.Println("Error: no regions found")
return nil
}

func deleteDefaultVpc(wg *sync.WaitGroup, sess client.ConfigProvider, region string) {
defer wg.Done()
svc := ec2.New(sess, aws.NewConfig().WithRegion(region))
result, err := svc.DescribeVpcs(&ec2.DescribeVpcsInput{
Filters: []*ec2.Filter{
{
Name: aws.String("isDefault"),
Values: []*string{aws.String("true")},
},
},
})
if err != nil {
handleError(err)
return
}
if result != nil && len(result.Vpcs) > 0 {
vpcID := *result.Vpcs[0].VpcId
fmt.Printf("[%s] Found default VPC: %v\n", region, vpcID)
deleteInternetGateway(svc, region, vpcID)
deleteSubnets(svc, region, vpcID)
deleteVpc(svc, region, vpcID)
} else {
fmt.Printf("[%s] No default VPC found\n", region)
}
}

func deleteInternetGateway(svc *ec2.EC2, region string, vpcID string) {
result, err := svc.DescribeInternetGateways(&ec2.DescribeInternetGatewaysInput{
Filters: []*ec2.Filter{
{
Name: aws.String("attachment.vpc-id"),
Values: []*string{
aws.String(vpcID),
},
},
},
})
if err != nil {
handleError(err)
return
}
if result != nil && len(result.InternetGateways) > 0 {
igw := *result.InternetGateways[0].InternetGatewayId

fmt.Printf("[%s] Detaching and deleting internet gateway: %v\n", region, igw)

_, err := svc.DetachInternetGateway(&ec2.DetachInternetGatewayInput{
InternetGatewayId: aws.String(igw),
VpcId: aws.String(vpcID),
})
if err != nil {
handleError(err)
return
}

_, err = svc.DeleteInternetGateway(&ec2.DeleteInternetGatewayInput{
InternetGatewayId: aws.String(igw),
})
if err != nil {
handleError(err)
return
}
} else {
fmt.Printf("[%s] No internet gateway found for vpc %s\n", region, vpcID)
}
}

func deleteSubnets(svc *ec2.EC2, region string, vpcID string) {
result, err := svc.DescribeSubnets(&ec2.DescribeSubnetsInput{
Filters: []*ec2.Filter{
{
Name: aws.String("vpc-id"),
Values: []*string{
aws.String(vpcID),
},
},
},
})
if err != nil {
handleError(err)
return
}
if result != nil && len(result.Subnets) > 0 {
subnets := result.Subnets
for _, subnet := range subnets {
s := *subnet.SubnetId
fmt.Printf("[%s] Deleting subnet: %v\n", region, s)
_, err := svc.DeleteSubnet(&ec2.DeleteSubnetInput{
SubnetId: aws.String(s),
})
if err != nil {
handleError(err)
return
}
}
} else {
fmt.Printf("[%s] No subnets found for vpc %s\n", region, vpcID)
}
}

func deleteVpc(svc *ec2.EC2, region string, vpcID string) {
fmt.Printf("[%s] Deleting VPC: %s\n", region, vpcID)
_, err := svc.DeleteVpc(&ec2.DeleteVpcInput{
VpcId: aws.String(vpcID),
})
if err != nil {
handleError(err)
return
}
}

func handleError(err error) {
if aerr, ok := err.(awserr.Error); ok {
switch aerr.Code() {
default:
fmt.Println(aerr.Error())
}
} else {
fmt.Println(err.Error())
}
}

func main() {
// Creat new AWS Session
sess, err := session.NewSession()
if err != nil {
fmt.Printf("Error creating session: %s\n", err)
return
}

// Display Account, Role, ARN information
err = getCallerIdentity(sess)
if err != nil {
fmt.Printf("Error getting caller identity: %s\n", err)
return
}

svc := ec2.New(sess, aws.NewConfig().WithRegion("us-east-1"))

regions := getRegions(svc)
fmt.Printf("Regions: %v\n", regions)

r := make(chan string)
go func() {
for _, region := range regions {
r <- region
}
close(r)
}()

var wg sync.WaitGroup
for region := range r {
wg.Add(1)
go deleteDefaultVpc(&wg, sess, region)
}
wg.Wait()
}

0 comments on commit a7d08e1

Please sign in to comment.