Skip to content

Commit

Permalink
support deleting vpcs that are non-default (#243)
Browse files Browse the repository at this point in the history
  • Loading branch information
ekristen authored Nov 17, 2021
1 parent aeff0d3 commit e3a9c93
Show file tree
Hide file tree
Showing 4 changed files with 115 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ The currently supported functionality includes:
- Deleting all SQS queues in an AWS account
- Deleting all S3 buckets in an AWS account - except for buckets tagged with Key=cloud-nuke-excluded Value=true
- Deleting all default VPCs in an AWS account
- Deleting VPCs in an AWS Account (except for default VPCs which is handled by the dedicated `defaults-aws` subcommand)
- Deleting all IAM users in an AWS account
- Deleting all Secrets Manager Secrets in an AWS account
- Deleting all NAT Gateways in an AWS account
Expand Down
17 changes: 17 additions & 0 deletions aws/aws.go
Original file line number Diff line number Diff line change
Expand Up @@ -642,6 +642,22 @@ func GetAllResources(targetRegions []string, excludeAfter time.Time, resourceTyp
}
// End Dynamo DB tables

// EC2 VPCS
ec2Vpcs := EC2VPCs{}
if IsNukeable(ec2Vpcs.ResourceName(), resourceTypes) {
vpcids, vpcs, err := getAllVpcs(session, region)
if err != nil {
return nil, errors.WithStackTrace(err)
}

if len(vpcids) > 0 {
ec2Vpcs.VPCIds = awsgo.StringValueSlice(vpcids)
ec2Vpcs.VPCs = vpcs
resourcesInRegion.Resources = append(resourcesInRegion.Resources, ec2Vpcs)
}
}
// End EC2 VPCS

if len(resourcesInRegion.Resources) > 0 {
account.Resources[region] = resourcesInRegion
}
Expand Down Expand Up @@ -717,6 +733,7 @@ func ListResourceTypes() []string {
CloudWatchDashboards{}.ResourceName(),
AccessAnalyzer{}.ResourceName(),
DynamoDB{}.ResourceName(),
EC2VPCs{}.ResourceName(),
}
sort.Strings(resourceTypes)
return resourceTypes
Expand Down
29 changes: 29 additions & 0 deletions aws/ec2_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,32 @@ func (instance EC2Instances) Nuke(session *session.Session, identifiers []string

return nil
}

type EC2VPCs struct {
VPCIds []string
VPCs []Vpc
}

// ResourceName - the simple name of the aws resource
func (v EC2VPCs) ResourceName() string {
return "vpc"
}

// ResourceIdentifiers - The instance ids of the ec2 instances
func (v EC2VPCs) ResourceIdentifiers() []string {
return v.VPCIds
}

func (v EC2VPCs) MaxBatchSize() int {
// Tentative batch size to ensure AWS doesn't throttle
return 200
}

// Nuke - nuke 'em all!!!
func (v EC2VPCs) Nuke(session *session.Session, identifiers []string) error {
if err := nukeAllVPCs(session, identifiers, v.VPCs); err != nil {
return errors.WithStackTrace(err)
}

return nil
}
68 changes: 68 additions & 0 deletions aws/ec2_vpc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package aws

import (
awsgo "github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/gruntwork-io/cloud-nuke/logging"
"github.com/gruntwork-io/go-commons/errors"
"github.com/hashicorp/go-multierror"
)

func getAllVpcs(session *session.Session, region string) ([]*string, []Vpc, error) {
svc := ec2.New(session)

result, err := svc.DescribeVpcs(&ec2.DescribeVpcsInput{
Filters: []*ec2.Filter{
// Note: this filter omits the default since there is special
// handling for default resources already
{
Name: awsgo.String("is-default"),
Values: awsgo.StringSlice([]string{"false"}),
},
},
})
if err != nil {
return nil, nil, errors.WithStackTrace(err)
}

var ids []*string
var vpcs []Vpc
for _, vpc := range result.Vpcs {
ids = append(ids, vpc.VpcId)

vpcs = append(vpcs, Vpc{
VpcId: *vpc.VpcId,
Region: region,
svc: svc,
})
}

return ids, vpcs, nil
}

func nukeAllVPCs(session *session.Session, vpcIds []string, vpcs []Vpc) error {
if len(vpcIds) == 0 {
logging.Logger.Info("No VPCs to nuke")
return nil
}

logging.Logger.Info("Deleting all VPCs")

deletedVPCs := 0
multiErr := new(multierror.Error)

for _, vpc := range vpcs {
if err := vpc.nuke(); err != nil {
logging.Logger.Errorf("[Failed] %s", err)
multierror.Append(multiErr, err)
} else {
deletedVPCs++
logging.Logger.Infof("Deleted VPC: %s", vpc.VpcId)
}
}

logging.Logger.Infof("[OK] %d VPC terminated", deletedVPCs)

return nil
}

0 comments on commit e3a9c93

Please sign in to comment.