Skip to content

Commit

Permalink
Support tags exclusion filtering on resources (gruntwork-io#573)
Browse files Browse the repository at this point in the history
  • Loading branch information
james03160927 authored Aug 31, 2023
1 parent 6902144 commit 0961f3e
Show file tree
Hide file tree
Showing 12 changed files with 77 additions and 16 deletions.
25 changes: 13 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -428,14 +428,15 @@ s3:

#### Tag Filter

You can also filter resources by tags. The following config will delete all s3 buckets that have a tag with key `foo`
You can also exclude resources by tags. The following config will delete all s3 buckets that have a tag with key `foo`
```yaml
s3:
include:
exclude:
tag: 'foo'
```

By default, it will use the exclusion default tag: `cloud-nuke-excluded` to exclude resources.
_Note: it doesn't support including resources by tags._

### What's supported?

Expand All @@ -450,7 +451,7 @@ of the file that are supported are listed here.
| apigateway | APIGateway | ✅ (API Name) | ✅ (Created Time) | ❌ |
| apigatewayv2 | APIGatewayV2 | ✅ (API Name) | ✅ (Created Time) | ❌ |
| accessanalyzer | AccessAnalyzer | ✅ (Analyzer Name) | ✅ (Created Time) | ❌ |
| asg | AutoScalingGroup | ✅ (ASG Name) | ✅ (Created Time) | |
| asg | AutoScalingGroup | ✅ (ASG Name) | ✅ (Created Time) | |
| backup-vault | BackupVault | ✅ (Backup Vault Name) | ✅ (Created Time) | ❌ |
| cloudwatch-alarm | CloudWatchAlarm | ✅ (Alarm Name) | ✅ (AlarmConfigurationUpdated Time) | ❌ |
| cloudwatch-dashboard | CloudWatchDashboard | ✅ (Dashboard Name) | ✅ (LastModified Time) | ❌ |
Expand All @@ -459,22 +460,22 @@ of the file that are supported are listed here.
| codedeploy-application | CodeDeployApplications | ✅ (Application Name) | ✅ (Creation Time) | ❌ |
| config-recorders | ConfigServiceRecorder | ✅ (Recorder Name) | ❌ | ❌ |
| config-rules | ConfigServiceRule | ✅ (Rule Name) | ❌ | ❌ |
| rds-cluster | DBClusters | ✅ (DB Cluster Identifier ) | ✅ (Creation Time) | |
| rds | DBInstances | ✅ (DB Name) | ✅ (Creation Time) | |
| rds-cluster | DBClusters | ✅ (DB Cluster Identifier ) | ✅ (Creation Time) | |
| rds | DBInstances | ✅ (DB Name) | ✅ (Creation Time) | |
| rds-subnet-group | DBSubnetGroups | ✅ (DB Subnet Group Name) | ❌ | ❌ |
| dynamodb | DynamoDB | ✅ (Table Name) | ✅ (Creation Time) | ❌ |
| ebs | EBSVolume | ✅ (Volume Name) | ✅ (Creation Time) | |
| ec2 | EC2 | ✅ (Instance Name) | ✅ (Launch Time) | |
| ebs | EBSVolume | ✅ (Volume Name) | ✅ (Creation Time) | |
| ec2 | EC2 | ✅ (Instance Name) | ✅ (Launch Time) | |
| ec2-dedicated-hosts | EC2DedicatedHosts | ✅ (EC2 Name Tag) | ✅ (Allocation Time) | ❌ |
| ec2-keypairs | EC2KeyPairs | ✅ (Key Pair Name) | ✅ (Creation Time) | ❌ |
| ecr | ECRRepository | ✅ (Repository Name) | ✅ (Creation Time) | ❌ |
| ecscluster | ECSCluster | ✅ (Cluster Name) | ❌ | ❌ |
| ecsserv | ECSService | ✅ (Service Name) | ✅ (Creation Time) | ❌ |
| ekscluster | EKSCluster | ✅ (Cluster Name) | ✅ (Creation Time) | |
| ekscluster | EKSCluster | ✅ (Cluster Name) | ✅ (Creation Time) | |
| elb | ELBv1 | ✅ (Load Balancer Name) | ✅ (Created Time) | ❌ |
| elbv2 | ELBv2 | ✅ (Load Balancer Name) | ✅ (Created Time) | ❌ |
| efs | ElasticFileSystem | ✅ (File System Name) | ✅ (Creation Time) | ❌ |
| eip | ElasticIP | ✅ (Elastic IP Allocation Name) | ✅ (First Seen Tag Time) | |
| eip | ElasticIP | ✅ (Elastic IP Allocation Name) | ✅ (First Seen Tag Time) | |
| elasticache | Elasticache | ✅ (Cluster ID & Replication Group ID) | ✅ (Creation Time) | ❌ |
| elasticacheparametergroups | ElasticacheParameterGroups | ✅ (Parameter Group Name) | ❌ | ❌ |
| elasticachesubnetgroups | ElasticacheSubnetGroups | ✅ (Subnet Group Name) | ❌ | ❌ |
Expand All @@ -483,15 +484,15 @@ of the file that are supported are listed here.
| iam-policy | IAMPolicies | ✅ (Policy Name) | ✅ (Creation Time) | ❌ |
| iam-role | IAMRoles | ✅ (Role Name) | ✅ (Creation Time) | ❌ |
| iam-service-linked-role | IAMServiceLinkedRoles | ✅ (Service Linked Role Name) | ✅ (Creation Time) | ❌ |
| iam | IAMUsers | ✅ (User Name) | ✅ (Creation Time) | |
| iam | IAMUsers | ✅ (User Name) | ✅ (Creation Time) | |
| kmscustomerkeys | KMSCustomerKeys | ✅ (Key Name) | ✅ (Creation Time) | ❌ |
| kinesis-stream | KinesisStream | ✅ (Stream Name) | ❌ | ❌ |
| lambda | LambdaFunction | ✅ (Function Name) | ✅ (Last Modified Time) | ❌ |
| lc | LaunchConfiguration | ✅ (Launch Configuration Name) | ✅ (Created Time) | ❌ |
| lt | LaunchTemplate | ✅ (Launch Template Name) | ✅ (Created Time) | ❌ |
| macie-member | MacieMember | ❌ | ✅ (Creation Time) | ❌ |
| msk-cluster | MskCluster | ✅ (Cluster Name) | ✅ (Creation Time) | ❌ |
| nat-gateway | NatGateway | ✅ (EC2 Name Tag) | ✅ (Creation Time) | |
| nat-gateway | NatGateway | ✅ (EC2 Name Tag) | ✅ (Creation Time) | |
| oidcprovider | OIDCProvider | ✅ (Provider URL) | ✅ (Creation Time) | ❌ |
| opensearchdomain | OpenSearchDomain | ✅ (Domain Name) | ✅ (First Seen Tag Time) | ❌ |
| redshift | Redshift | ✅ (Cluster Identifier) | ✅ (Creation Time) | ❌ |
Expand All @@ -501,7 +502,7 @@ of the file that are supported are listed here.
| sagemaker-notebook-smni | SageMakerNotebook | ✅ (Notebook Instnace Name) | ✅ (Creation Time) | ❌ |
| secretsmanager | SecretsManagerSecrets | ✅ (Secret Name) | ✅ (Last Accessed or Creation Time) | ❌ |
| security-hub | SecurityHub | ❌ | ✅ (Created Time) | ❌ |
| snap | Snapshots | ❌ | ✅ (Creation Time) | |
| snap | Snapshots | ❌ | ✅ (Creation Time) | |
| transit-gateway | TransitGateway | ❌ | ✅ (Creation Time) | ❌ |
| transit-gateway-route-table | TransitGatewayRouteTable | ❌ | ✅ (Creation Time) | ❌ |
| transit-gateway-attachment | TransitGatewaysVpcAttachment | ❌ | ✅ (Creation Time) | ❌ |
Expand Down
2 changes: 2 additions & 0 deletions aws/resources/asg.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"github.com/gruntwork-io/cloud-nuke/logging"
"github.com/gruntwork-io/cloud-nuke/report"
"github.com/gruntwork-io/cloud-nuke/telemetry"
"github.com/gruntwork-io/cloud-nuke/util"
"github.com/gruntwork-io/go-commons/errors"
commonTelemetry "github.com/gruntwork-io/go-commons/telemetry"
)
Expand All @@ -23,6 +24,7 @@ func (ag *ASGroups) getAll(configObj config.Config) ([]*string, error) {
if configObj.AutoScalingGroup.ShouldInclude(config.ResourceValue{
Time: group.CreatedTime,
Name: group.AutoScalingGroupName,
Tags: util.ConvertAutoScalingTagsToMap(group.Tags),
}) {
groupNames = append(groupNames, group.AutoScalingGroupName)
}
Expand Down
2 changes: 2 additions & 0 deletions aws/resources/ebs.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package resources

import (
"github.com/gruntwork-io/cloud-nuke/telemetry"
"github.com/gruntwork-io/cloud-nuke/util"
commonTelemetry "github.com/gruntwork-io/go-commons/telemetry"

"github.com/aws/aws-sdk-go/aws"
Expand Down Expand Up @@ -49,6 +50,7 @@ func shouldIncludeEBSVolume(volume *ec2.Volume, configObj config.Config) bool {
return configObj.EBSVolume.ShouldInclude(config.ResourceValue{
Name: &name,
Time: volume.CreateTime,
Tags: util.ConvertEC2TagsToMap(volume.Tags),
})
}

Expand Down
2 changes: 2 additions & 0 deletions aws/resources/ec2.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"
"github.com/gruntwork-io/cloud-nuke/externalcreds"
"github.com/gruntwork-io/cloud-nuke/telemetry"
"github.com/gruntwork-io/cloud-nuke/util"
commonTelemetry "github.com/gruntwork-io/go-commons/telemetry"
"time"

Expand Down Expand Up @@ -82,6 +83,7 @@ func shouldIncludeInstanceId(instance *ec2.Instance, protected bool, configObj c
return configObj.EC2.ShouldInclude(config.ResourceValue{
Name: instanceName,
Time: instance.LaunchTime,
Tags: util.ConvertEC2TagsToMap(instance.Tags),
})
}

Expand Down
1 change: 1 addition & 0 deletions aws/resources/eip.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ func (ea *EIPAddresses) shouldInclude(address *ec2.Address, firstSeenTime time.T
return configObj.ElasticIP.ShouldInclude(config.ResourceValue{
Time: &firstSeenTime,
Name: allocationName,
Tags: util.ConvertEC2TagsToMap(address.Tags),
})
}

Expand Down
7 changes: 5 additions & 2 deletions aws/resources/eks.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"github.com/gruntwork-io/cloud-nuke/logging"
"github.com/gruntwork-io/cloud-nuke/report"
"github.com/gruntwork-io/cloud-nuke/telemetry"
"github.com/gruntwork-io/cloud-nuke/util"
"github.com/gruntwork-io/go-commons/errors"
commonTelemetry "github.com/gruntwork-io/go-commons/telemetry"
"github.com/hashicorp/go-multierror"
Expand Down Expand Up @@ -44,8 +45,10 @@ func (clusters *EKSClusters) filter(clusterNames []*string, configObj config.Con
return nil, errors.WithStackTrace(err)
}

// TODO: use resourceType function for shouldInclude
if !configObj.EKSCluster.ShouldInclude(config.ResourceValue{Time: describeResult.Cluster.CreatedAt}) {
if !configObj.EKSCluster.ShouldInclude(config.ResourceValue{
Time: describeResult.Cluster.CreatedAt,
Tags: util.ConvertStringPtrTagsToMap(describeResult.Cluster.Tags),
}) {
continue
}

Expand Down
2 changes: 2 additions & 0 deletions aws/resources/iam.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package resources
import (
"fmt"
"github.com/gruntwork-io/cloud-nuke/telemetry"
"github.com/gruntwork-io/cloud-nuke/util"
commonTelemetry "github.com/gruntwork-io/go-commons/telemetry"
"time"

Expand All @@ -27,6 +28,7 @@ func (iu *IAMUsers) getAll(configObj config.Config) ([]*string, error) {
if configObj.IAMUsers.ShouldInclude(config.ResourceValue{
Name: user.UserName,
Time: user.CreateDate,
Tags: util.ConvertIAMTagsToMap(user.Tags),
}) {
userNames = append(userNames, user.UserName)
}
Expand Down
2 changes: 2 additions & 0 deletions aws/resources/nat_gateway.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package resources
import (
"fmt"
"github.com/gruntwork-io/cloud-nuke/telemetry"
"github.com/gruntwork-io/cloud-nuke/util"
commonTelemetry "github.com/gruntwork-io/go-commons/telemetry"
"sync"
"time"
Expand Down Expand Up @@ -49,6 +50,7 @@ func shouldIncludeNatGateway(ngw *ec2.NatGateway, configObj config.Config) bool
return configObj.NatGateway.ShouldInclude(config.ResourceValue{
Time: ngw.CreateTime,
Name: getNatGatewayName(ngw),
Tags: util.ConvertEC2TagsToMap(ngw.Tags),
})
}

Expand Down
2 changes: 2 additions & 0 deletions aws/resources/rds.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/gruntwork-io/cloud-nuke/logging"
"github.com/gruntwork-io/cloud-nuke/report"
"github.com/gruntwork-io/cloud-nuke/telemetry"
"github.com/gruntwork-io/cloud-nuke/util"
"github.com/gruntwork-io/go-commons/errors"
commonTelemetry "github.com/gruntwork-io/go-commons/telemetry"
)
Expand All @@ -24,6 +25,7 @@ func (di *DBInstances) getAll(configObj config.Config) ([]*string, error) {
if configObj.DBInstances.ShouldInclude(config.ResourceValue{
Time: database.InstanceCreateTime,
Name: database.DBName,
Tags: util.ConvertRDSTagsToMap(database.TagList),
}) {
names = append(names, database.DBInstanceIdentifier)
}
Expand Down
2 changes: 2 additions & 0 deletions aws/resources/rds_cluster.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package resources

import (
"github.com/gruntwork-io/cloud-nuke/util"
"time"

awsgo "github.com/aws/aws-sdk-go/aws"
Expand Down Expand Up @@ -46,6 +47,7 @@ func (instance *DBClusters) getAll(configObj config.Config) ([]*string, error) {
if configObj.DBClusters.ShouldInclude(config.ResourceValue{
Name: database.DBClusterIdentifier,
Time: database.ClusterCreateTime,
Tags: util.ConvertRDSTagsToMap(database.TagList),
}) {
names = append(names, database.DBClusterIdentifier)
}
Expand Down
7 changes: 5 additions & 2 deletions aws/resources/snapshot.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package resources
import (
"github.com/gruntwork-io/cloud-nuke/config"
"github.com/gruntwork-io/cloud-nuke/telemetry"
"github.com/gruntwork-io/cloud-nuke/util"
commonTelemetry "github.com/gruntwork-io/go-commons/telemetry"

"github.com/aws/aws-sdk-go/aws"
Expand Down Expand Up @@ -33,8 +34,10 @@ func (s *Snapshots) getAll(configObj config.Config) ([]*string, error) {

var snapshotIds []*string
for _, snapshot := range output.Snapshots {
if configObj.Snapshots.ShouldInclude(config.ResourceValue{Time: snapshot.StartTime}) &&
!SnapshotHasAWSBackupTag(snapshot.Tags) {
if configObj.Snapshots.ShouldInclude(config.ResourceValue{
Time: snapshot.StartTime,
Tags: util.ConvertEC2TagsToMap(snapshot.Tags),
}) && !SnapshotHasAWSBackupTag(snapshot.Tags) {
snapshotIds = append(snapshotIds, snapshot.SnapshotId)
}
}
Expand Down
39 changes: 39 additions & 0 deletions util/tag.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package util

import (
"github.com/aws/aws-sdk-go/service/autoscaling"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/aws/aws-sdk-go/service/iam"
"github.com/aws/aws-sdk-go/service/rds"
"github.com/aws/aws-sdk-go/service/s3"
)

Expand All @@ -22,3 +25,39 @@ func ConvertEC2TagsToMap(tags []*ec2.Tag) map[string]string {

return tagMap
}

func ConvertAutoScalingTagsToMap(tags []*autoscaling.TagDescription) map[string]string {
tagMap := make(map[string]string)
for _, tag := range tags {
tagMap[*tag.Key] = *tag.Value
}

return tagMap
}

func ConvertStringPtrTagsToMap(tags map[string]*string) map[string]string {
tagMap := make(map[string]string)
for key, value := range tags {
tagMap[key] = *value
}

return tagMap
}

func ConvertIAMTagsToMap(tags []*iam.Tag) map[string]string {
tagMap := make(map[string]string)
for _, tag := range tags {
tagMap[*tag.Key] = *tag.Value
}

return tagMap
}

func ConvertRDSTagsToMap(tags []*rds.Tag) map[string]string {
tagMap := make(map[string]string)
for _, tag := range tags {
tagMap[*tag.Key] = *tag.Value
}

return tagMap
}

0 comments on commit 0961f3e

Please sign in to comment.