Repository: gruntwork-io/cloud-nuke
Pull request #777 (2024-10-31 22:15:07)

change port ebs, ecr, ecs cluster, ecs service, efs, eip, eks, elastic beanstalk, elasticache, elb, elbv2, guardduty to awsSDKv2 #770
## Description
port the below resources to AWS SDKv2 (part of work for #770)
- ebs
- ecr
- ecs cluster
- ecs service
- efs
- eip
- eks
- elastic beanstalk
- elasticache
- elb
- elbv2
- guardduty

## TODOs
Read the [Gruntwork contribution guidelines](https://gruntwork.notion.site/Gruntwork-Coding-Methodology-02fdcd6e4b004e818553684760bf691e).

- [x] Update the docs.
- [x] Run the relevant tests successfully, including pre-commit checks.
- [x] Ensure any 3rd party code adheres with our [license policy](https://www.notion.so/gruntwork/Gruntwork-licenses-and-open-source-usage-policy-f7dece1f780341c7b69c1763f22b1378) or delete this line if its not applicable.
- [x] Include release notes. If this PR is backward incompatible, include a migration guide.
- [ ] Attention Grunts - if this PR adds support for a new resource, ensure the `nuke_sandbox` and `nuke_phxdevops` jobs in `.circleci/config.yml` have been updated with appropriate exclusions (either directly in the job or via the `.circleci/nuke_config.yml` file) to prevent nuking IAM roles, groups, resources, etc that are important for the test accounts.


## Release Notes (draft)
Updated ebs, ecr, ecs cluster, ecs service, efs, eip, eks, elastic beanstalk, elasticache, elb, elbv2, guardduty to AWS SDK v2 #770.

### Migration Guide
n/a



Patch:
diff --git a/aws/resources/ebs.go b/aws/resources/ebs.go
index e543f95..ee2541b 100644
--- a/aws/resources/ebs.go
+++ b/aws/resources/ebs.go
@@ -2,11 +2,13 @@ package resources
 
 import (
 	"context"
+	goerr "errors"
+	"time"
 
-	"github.com/aws/aws-sdk-go/aws"
-	awsgo "github.com/aws/aws-sdk-go/aws"
-	"github.com/aws/aws-sdk-go/aws/awserr"
-	"github.com/aws/aws-sdk-go/service/ec2"
+	"github.com/aws/aws-sdk-go-v2/aws"
+	"github.com/aws/aws-sdk-go-v2/service/ec2"
+	"github.com/aws/aws-sdk-go-v2/service/ec2/types"
+	"github.com/aws/smithy-go"
 	"github.com/gruntwork-io/cloud-nuke/config"
 	"github.com/gruntwork-io/cloud-nuke/logging"
 	"github.com/gruntwork-io/cloud-nuke/report"
@@ -20,9 +22,9 @@ func (ev *EBSVolumes) getAll(c context.Context, configObj config.Config) ([]*str
 	// Since the output of this function is used to delete the returned volumes
 	// We want to only list EBS volumes with a status of "available" or "creating"
 	// Since those are the only statuses that are eligible for deletion
-	statusFilter := ec2.Filter{Name: aws.String("status"), Values: aws.StringSlice([]string{"available", "creating", "error"})}
-	result, err := ev.Client.DescribeVolumesWithContext(ev.Context, &ec2.DescribeVolumesInput{
-		Filters: []*ec2.Filter{&statusFilter},
+	statusFilter := types.Filter{Name: aws.String("status"), Values: []string{"available", "creating", "error"}}
+	result, err := ev.Client.DescribeVolumes(ev.Context, &ec2.DescribeVolumesInput{
+		Filters: []types.Filter{statusFilter},
 	})
 
 	if err != nil {
@@ -38,9 +40,9 @@ func (ev *EBSVolumes) getAll(c context.Context, configObj config.Config) ([]*str
 
 	// checking the nukable permissions
 	ev.VerifyNukablePermissions(volumeIds, func(id *string) error {
-		_, err := ev.Client.DeleteVolumeWithContext(ev.Context, &ec2.DeleteVolumeInput{
+		_, err := ev.Client.DeleteVolume(ev.Context, &ec2.DeleteVolumeInput{
 			VolumeId: id,
-			DryRun:   awsgo.Bool(true),
+			DryRun:   aws.Bool(true),
 		})
 		return err
 	})
@@ -48,18 +50,18 @@ func (ev *EBSVolumes) getAll(c context.Context, configObj config.Config) ([]*str
 	return volumeIds, nil
 }
 
-func shouldIncludeEBSVolume(volume *ec2.Volume, configObj config.Config) bool {
+func shouldIncludeEBSVolume(volume types.Volume, configObj config.Config) bool {
 	name := ""
 	for _, tag := range volume.Tags {
-		if tag != nil && aws.StringValue(tag.Key) == "Name" {
-			name = aws.StringValue(tag.Value)
+		if aws.ToString(tag.Key) == "Name" {
+			name = aws.ToString(tag.Value)
 		}
 	}
 
 	return configObj.EBSVolume.ShouldInclude(config.ResourceValue{
 		Name: &name,
 		Time: volume.CreateTime,
-		Tags: util.ConvertEC2TagsToMap(volume.Tags),
+		Tags: util.ConvertTypesTagsToMap(volume.Tags),
 	})
 }
 
@@ -75,8 +77,8 @@ func (ev *EBSVolumes) nukeAll(volumeIds []*string) error {
 
 	for _, volumeID := range volumeIds {
 
-		if nukable, reason := ev.IsNukable(awsgo.StringValue(volumeID)); !nukable {
-			logging.Debugf("[Skipping] %s nuke because %v", awsgo.StringValue(volumeID), reason)
+		if nukable, reason := ev.IsNukable(aws.ToString(volumeID)); !nukable {
+			logging.Debugf("[Skipping] %s nuke because %v", aws.ToString(volumeID), reason)
 			continue
 		}
 
@@ -84,23 +86,27 @@ func (ev *EBSVolumes) nukeAll(volumeIds []*string) error {
 			VolumeId: volumeID,
 		}
 
-		_, err := ev.Client.DeleteVolumeWithContext(ev.Context, params)
+		_, err := ev.Client.DeleteVolume(ev.Context, params)
 
 		// Record status of this resource
 		e := report.Entry{
-			Identifier:   aws.StringValue(volumeID),
+			Identifier:   aws.ToString(volumeID),
 			ResourceType: "EBS Volume",
 			Error:        err,
 		}
 		report.Record(e)
 
 		if err != nil {
-			if awsErr, isAwsErr := err.(awserr.Error); isAwsErr && awsErr.Code() == "VolumeInUse" {
-				logging.Debugf("EBS volume %s can't be deleted, it is still attached to an active resource", *volumeID)
-			} else if awsErr, isAwsErr := err.(awserr.Error); isAwsErr && awsErr.Code() == "InvalidVolume.NotFound" {
-				logging.Debugf("EBS volume %s has already been deleted", *volumeID)
-			} else {
-				logging.Debugf("[Failed] %s", err)
+			var apiErr smithy.APIError
+			if goerr.As(err, &apiErr) {
+				switch apiErr.ErrorCode() {
+				case "VolumeInUse":
+					logging.Debugf("EBS volume %s can't be deleted, it is still attached to an active resource", *volumeID)
+				case "InvalidVolume.NotFound":
+					logging.Debugf("EBS volume %s has already been deleted", *volumeID)
+				default:
+					logging.Debugf("[Failed] %s", err)
+				}
 			}
 		} else {
 			deletedVolumeIDs = append(deletedVolumeIDs, volumeID)
@@ -109,9 +115,10 @@ func (ev *EBSVolumes) nukeAll(volumeIds []*string) error {
 	}
 
 	if len(deletedVolumeIDs) > 0 {
-		err := ev.Client.WaitUntilVolumeDeletedWithContext(ev.Context, &ec2.DescribeVolumesInput{
-			VolumeIds: deletedVolumeIDs,
-		})
+		waiter := ec2.NewVolumeDeletedWaiter(ev.Client)
+		err := waiter.Wait(ev.Context, &ec2.DescribeVolumesInput{
+			VolumeIds: aws.ToStringSlice(deletedVolumeIDs),
+		}, 5*time.Minute)
 		if err != nil {
 			logging.Debugf("[Failed] %s", err)
 			return errors.WithStackTrace(err)
diff --git a/aws/resources/ebs_types.go b/aws/resources/ebs_types.go
index 4eae8a9..06eca7b 100644
--- a/aws/resources/ebs_types.go
+++ b/aws/resources/ebs_types.go
@@ -3,26 +3,31 @@ package resources
 import (
 	"context"
 
-	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/aws/aws-sdk-go/service/ec2/ec2iface"
+	"github.com/aws/aws-sdk-go-v2/aws"
+	"github.com/aws/aws-sdk-go-v2/service/ec2"
 	"github.com/gruntwork-io/cloud-nuke/config"
 	"github.com/gruntwork-io/go-commons/errors"
 )
 
+type EBSVolumesAPI interface {
+	DescribeVolumes(ctx context.Context, params *ec2.DescribeVolumesInput, optFns ...func(*ec2.Options)) (*ec2.DescribeVolumesOutput, error)
+	DeleteVolume(ctx context.Context, params *ec2.DeleteVolumeInput, optFns ...func(*ec2.Options)) (*ec2.DeleteVolumeOutput, error)
+}
+
 // EBSVolumes - represents all ebs volumes
 type EBSVolumes struct {
 	BaseAwsResource
-	Client    ec2iface.EC2API
+	Client    EBSVolumesAPI
 	Region    string
 	VolumeIds []string
 }
 
-func (ev *EBSVolumes) Init(session *session.Session) {
-	ev.Client = ec2.New(session)
+func (ev *EBSVolumes) InitV2(cfg aws.Config) {
+	ev.Client = ec2.NewFromConfig(cfg)
 }
 
+func (ev *EBSVolumes) IsUsingV2() bool { return true }
+
 // ResourceName - the simple name of the aws resource
 func (ev *EBSVolumes) ResourceName() string {
 	return "ebs"
@@ -48,13 +53,13 @@ func (ev *EBSVolumes) GetAndSetIdentifiers(c context.Context, configObj config.C
 		return nil, err
 	}
 
-	ev.VolumeIds = awsgo.StringValueSlice(identifiers)
+	ev.VolumeIds = aws.ToStringSlice(identifiers)
 	return ev.VolumeIds, nil
 }
 
 // Nuke - nuke 'em all!!!
 func (ev *EBSVolumes) Nuke(identifiers []string) error {
-	if err := ev.nukeAll(awsgo.StringSlice(identifiers)); err != nil {
+	if err := ev.nukeAll(aws.StringSlice(identifiers)); err != nil {
 		return errors.WithStackTrace(err)
 	}
 
diff --git a/aws/resources/ecr.go b/aws/resources/ecr.go
index 87ff25b..6231434 100644
--- a/aws/resources/ecr.go
+++ b/aws/resources/ecr.go
@@ -3,8 +3,8 @@ package resources
 import (
 	"context"
 
-	"github.com/aws/aws-sdk-go/aws"
-	"github.com/aws/aws-sdk-go/service/ecr"
+	"github.com/aws/aws-sdk-go-v2/aws"
+	"github.com/aws/aws-sdk-go-v2/service/ecr"
 	"github.com/gruntwork-io/cloud-nuke/config"
 	"github.com/gruntwork-io/cloud-nuke/logging"
 	"github.com/gruntwork-io/cloud-nuke/report"
@@ -12,9 +12,15 @@ import (
 )
 
 func (registry *ECR) getAll(c context.Context, configObj config.Config) ([]*string, error) {
-	repositoryNames := []*string{}
+	var repositoryNames []*string
+
+	paginator := ecr.NewDescribeRepositoriesPaginator(registry.Client, &ecr.DescribeRepositoriesInput{})
+	for paginator.HasMorePages() {
+		output, err := paginator.NextPage(c)
+		if err != nil {
+			return nil, errors.WithStackTrace(err)
+		}
 
-	paginator := func(output *ecr.DescribeRepositoriesOutput, lastPage bool) bool {
 		for _, repository := range output.Repositories {
 			if configObj.ECRRepository.ShouldInclude(config.ResourceValue{
 				Time: repository.CreatedAt,
@@ -23,13 +29,6 @@ func (registry *ECR) getAll(c context.Context, configObj config.Config) ([]*stri
 				repositoryNames = append(repositoryNames, repository.RepositoryName)
 			}
 		}
-		return !lastPage
-	}
-
-	param := &ecr.DescribeRepositoriesInput{}
-	err := registry.Client.DescribeRepositoriesPagesWithContext(registry.Context, param, paginator)
-	if err != nil {
-		return nil, errors.WithStackTrace(err)
 	}
 
 	return repositoryNames, nil
@@ -45,11 +44,11 @@ func (registry *ECR) nukeAll(repositoryNames []string) error {
 
 	for _, repositoryName := range repositoryNames {
 		params := &ecr.DeleteRepositoryInput{
-			Force:          aws.Bool(true),
+			Force:          true,
 			RepositoryName: aws.String(repositoryName),
 		}
 
-		_, err := registry.Client.DeleteRepositoryWithContext(registry.Context, params)
+		_, err := registry.Client.DeleteRepository(registry.Context, params)
 
 		// Record status of this resource
 		e := report.Entry{
diff --git a/aws/resources/ecr_types.go b/aws/resources/ecr_types.go
index c928892..2a875cb 100644
--- a/aws/resources/ecr_types.go
+++ b/aws/resources/ecr_types.go
@@ -3,25 +3,30 @@ package resources
 import (
 	"context"
 
-	awsgo "github.com/aws/aws-sdk-go/aws"
-	"github.com/aws/aws-sdk-go/aws/session"
-	"github.com/aws/aws-sdk-go/service/ecr"
-	"github.com/aws/aws-sdk-go/service/ecr/ecriface"
+	"github.com/aws/aws-sdk-go-v2/aws"
+	"github.com/aws/aws-sdk-go-v2/service/ecr"
 	"github.com/gruntwork-io/cloud-nuke/config"
 	"github.com/gruntwork-io/go-commons/errors"
 )
 
+type ECRAPI interface {
+	DescribeRepositories(ctx context.Context, params *ecr.DescribeRepositoriesInput, optFns ...func(*ecr.Options)) (*ecr.DescribeRepositoriesOutput, error)
+	DeleteRepository(ctx context.Context, params *ecr.DeleteRepositoryInput, optFns ...func(*ecr.Options)) (*ecr.DeleteRepositoryOutput, error)
+}
+
 type ECR struct {
 	BaseAwsResource
-	Client          ecriface.ECRAPI
+	Client          ECRAPI
 	Region          string
 	RepositoryNames []string
 }
 
-func (registry *ECR) Init(session *session.Session) {
-	registry.Client = ecr.New(session)
+func (registry *ECR) InitV2(cfg aws.Config) {
+	registry.Client = ecr.NewFromConfig(cfg)
 }
 
+func (registry *ECR) IsUsingV2() bool { return true }
+
 func (registry *ECR) ResourceName() string {
 	return "ecr"
 }
@@ -44,7 +49,7 @@ func (registry *ECR) GetAndSetIdentifiers(c context.Context, configObj config.Co
 		return nil, err
 	}
 
-	registry.RepositoryNames = awsgo.StringValueSlice(identifiers)
+	registry.RepositoryNames = aws.ToStringSlice(identifiers)
 	return registry.RepositoryNames, nil
 }
 
diff --git a/aws/resources/ecs_cluster.go b/aws/resources/ecs_cluster.go
index c5d02d5..b80b4e8 100644
--- a/aws/resources/ecs_cluster.go
+++ b/aws/resources/ecs_cluster.go
@@ -4,14 +4,13 @@ import (
 	"context"
 	"time"
 
-	"github.com/gruntwork-io/cloud-nuke/util"
-
-	"github.com/aws/aws-sdk-go/aws"
-	awsgo "github.com/aws/aws-sdk-go/aws"
-	"github.com/aws/aws-sdk-go/service/ecs"
+	"github.com/aws/aws-sdk-go-v2/aws"
+	"github.com/aws/aws-sdk-go-v2/service/ecs"
+	"github.com/aws/aws-sdk-go-v2/service/ecs/types"
 	"github.com/gruntwork-io/cloud-nuke/config"
 	"github.com/gruntwork-io/cloud-nuke/logging"
 	"github.com/gruntwork-io/cloud-nuke/report"
+	"github.com/gruntwork-io/cloud-nuke/util"
 	"github.com/gruntwork-io/go-commons/errors"
 )
 
@@ -26,23 +25,23 @@ const describeClustersRequestBatchSize = 100
 // getAllEcsClusters - Returns a string of ECS Cluster ARNs, which uniquely identifies the cluster.
 // We need to get all clusters before we can get all services.
 func (clusters *ECSClusters) getAllEcsClusters() ([]*string, error) {
-	clusterArns := []*string{}
-	result, err := clusters.Client.ListClustersWithContext(clusters.Context, &ecs.ListClustersInput{})
+	var clusterArns []string
+	result, err := clusters.Client.ListClusters(clusters.Context, &ecs.ListClustersInput{})
 	if err != nil {
 		return nil, errors.WithStackTrace(err)
 	}
 	clusterArns = append(clusterArns, result.ClusterArns...)
 
 	// Handle pagination: continuously pull the next page if nextToken is set
-	for awsgo.StringValue(result.NextToken) != "" {
-		result, err = clusters.Client.ListClustersWithContext(clusters.Context, &ecs.ListClustersInput{NextToken: result.NextToken})
+	for aws.ToString(result.NextToken) != "" {
+		result, err = clusters.Client.ListClusters(clusters.Context, &ecs.ListClustersInput{NextToken: result.NextToken})
 		if err != nil {
 			return nil, errors.WithStackTrace(err)
 		}
 		clusterArns = append(clusterArns, result.ClusterArns...)
 	}
 
-	return clusterArns, nil
+	return aws.StringSlice(clusterArns), nil
 }
 
 // Filter all active ecs clusters
@@ -55,20 +54,20 @@ func (clusters *ECSClusters) getAllActiveEcsClusterArns(configObj config.Config)
 
 	var filteredEcsClusterArns []*string
 
-	batches := util.Split(aws.StringValueSlice(allClusters), describeClustersRequestBatchSize)
+	batches := util.Split(aws.ToStringSlice(allClusters), describeClustersRequestBatchSize)
 	for _, batch := range batches {
 		input := &ecs.DescribeClustersInput{
-			Clusters: awsgo.StringSlice(batch),
+			Clusters: batch,
 		}
 
-		describedClusters, describeErr := clusters.Client.DescribeClustersWithContext(clusters.Context, input)
+		describedClusters, describeErr := clusters.Client.DescribeClusters(clusters.Context, input)
 		if describeErr != nil {
 			logging.Debugf("Error describing ECS clusters from input %s: ", input)
 			return nil, errors.WithStackTrace(describeErr)
 		}
 
 		for _, cluster := range describedClusters.Clusters {
-			if shouldIncludeECSCluster(cluster, configObj) {
+			if shouldIncludeECSCluster(&cluster, configObj) {
 				filteredEcsClusterArns = append(filteredEcsClusterArns, cluster.ClusterArn)
 			}
 		}
@@ -77,16 +76,16 @@ func (clusters *ECSClusters) getAllActiveEcsClusterArns(configObj config.Config)
 	return filteredEcsClusterArns, nil
 }
 
-func shouldIncludeECSCluster(cluster *ecs.Cluster, configObj config.Config) bool {
+func shouldIncludeECSCluster(cluster *types.Cluster, configObj config.Config) bool {
 	if cluster == nil {
 		return false
 	}
 
 	// Filter out invalid state ECS Clusters (will return only `ACTIVE` state clusters)
 	// `cloud-nuke` needs to tag ECS Clusters it sees for the first time.
-	// Therefore to tag a cluster, that cluster must be in the `ACTIVE` state.
-	logging.Debugf("Status for ECS Cluster %s is %s", aws.StringValue(cluster.ClusterArn), aws.StringValue(cluster.Status))
-	if aws.StringValue(cluster.Status) != activeEcsClusterStatus {
+	// Therefore, to tag a cluster, that cluster must be in the `ACTIVE` state.
+	logging.Debugf("Status for ECS Cluster %s is %s", aws.ToString(cluster.ClusterArn), aws.ToString(cluster.Status))
+	if aws.ToString(cluster.Status) != activeEcsClusterStatus {
 		return false
 	}
 
@@ -110,14 +109,14 @@ func (clusters *ECSClusters) getAll(c context.Context, configObj config.Config)
 		if !excludeFirstSeenTag {
 			firstSeenTime, err := clusters.getFirstSeenTag(clusterArn)
 			if err != nil {
-				logging.Debugf("Error getting the `cloud-nuke-first-seen` tag for ECS cluster with ARN %s", aws.StringValue(clusterArn))
+				logging.Debugf("Error getting the `cloud-nuke-first-seen` tag for ECS cluster with ARN %s", aws.ToString(clusterArn))
 				return nil, errors.WithStackTrace(err)
 			}
 
 			if firstSeenTime == nil {
 				err := clusters.setFirstSeenTag(clusterArn, time.Now().UTC())
 				if err != nil {
-					logging.Debugf("Error tagging the ECS cluster with ARN %s", aws.StringValue(clusterArn))
+					logging.Debugf("Error tagging the ECS cluster with ARN %s", aws.ToString(clusterArn))
 					return nil, errors.WithStackTrace(err)
 				}
 			} else if configObj.ECSCluster.ShouldInclude(config.ResourceValue{Time: firstSeenTime}) {
@@ -131,9 +130,9 @@ func (clusters *ECSClusters) getAll(c context.Context, configObj config.Config)
 func (clusters *ECSClusters) stopClusterRunningTasks(clusterArn *string) error {
 	logging.Debugf("[TASK] stopping tasks running on cluster %v", *clusterArn)
 	// before deleting the cluster, remove the active tasks on that cluster
-	runningTasks, err := clusters.Client.ListTasksWithContext(clusters.Context, &ecs.ListTasksInput{
+	runningTasks, err := clusters.Client.ListTasks(clusters.Context, &ecs.ListTasksInput{
 		Cluster:       clusterArn,
-		DesiredStatus: aws.String("RUNNING"),
+		DesiredStatus: types.DesiredStatusRunning,
 	})
 
 	if err != nil {
@@ -142,16 +141,16 @@ func (clusters *ECSClusters) stopClusterRunningTasks(clusterArn *string) error {
 
 	// stop the listed tasks
 	for _, task := range runningTasks.TaskArns {
-		_, err := clusters.Client.StopTaskWithContext(clusters.Context, &ecs.StopTaskInput{
+		_, err := clusters.Client.StopTask(clusters.Context, &ecs.StopTaskInput{
 			Cluster: clusterArn,
-			Task:    task,
+			Task:    aws.String(task),
 			Reason:  aws.String("Terminating task due to cluster deletion"),
 		})
 		if err != nil {
-			logging.Debugf("[TASK] Unable to stop the task %s on cluster %s. Reason: %v", *task, *clusterArn, err)
+			logging.Debugf("[TASK] Unable to stop the task %s on cluster %s. Reason: %v", task, *clusterArn, err)
 			return errors.WithStackTrace(err)
 		}
-		logging.Debugf("[TASK] Success, stopped task %v", *task)
+		logging.Debugf("[TASK] Success, stopped task %v", task)
 	}
 	return nil
 }
@@ -172,29 +171,29 @@ func (clusters *ECSClusters) nukeAll(ecsClusterArns []*string) error {
 		// before nuking the clusters, do check active tasks on the cluster and stop all of them
 		err := clusters.stopClusterRunningTasks(clusterArn)
 		if err != nil {
-			logging.Debugf("Error, unable to stop the running stasks on the cluster %s %s", aws.StringValue(clusterArn), err)
+			logging.Debugf("Error, unable to stop the running stasks on the cluster %s %s", aws.ToString(clusterArn), err)
 			return errors.WithStackTrace(err)
 		}
 
 		params := &ecs.DeleteClusterInput{
 			Cluster: clusterArn,
 		}
-		_, err = clusters.Client.DeleteClusterWithContext(clusters.Context, params)
+		_, err = clusters.Client.DeleteCluster(clusters.Context, params)
 
 		// Record status of this resource
 		e := report.Entry{
-			Identifier:   aws.StringValue(clusterArn),
+			Identifier:   aws.ToString(clusterArn),
 			ResourceType: "ECS Cluster",
 			Error:        err,
 		}
 		report.Record(e)
 
 		if err != nil {
-			logging.Debugf("Error, failed to delete cluster with ARN %s %s", aws.StringValue(clusterArn), err)
+			logging.Debugf("Error, failed to delete cluster with ARN %s %s", aws.ToString(clusterArn), err)
 			return errors.WithStackTrace(err)
 		}
 
-		logging.Debugf("Success, deleted cluster: %s", aws.StringValue(clusterArn))
+		logging.Debugf("Success, deleted cluster: %s", aws.ToString(clusterArn))
 		nukedEcsClusters = append(nukedEcsClusters, clusterArn)
 	}
 
@@ -210,7 +209,7 @@ func (clusters *ECSClusters) setFirstSeenTag(clusterArn *string, timestamp time.
 
 	input := &ecs.TagResourceInput{
 		ResourceArn: clusterArn,
-		Tags: []*ecs.Tag{
+		Tags: []types.Tag{
 			{
 				Key:   aws.String(firstSeenTagKey),
 				Value: aws.String(firstSeenTime),
@@ -218,7 +217,7 @@ func (clusters *ECSClusters) setFirstSeenTag(clusterArn *string, timestamp time.
 		},
 	}
 
-	_, err := clusters.Client.TagResource(input)
+	_, err := clusters.Client.TagResource(clusters.Context, input)
 	if err != nil {
 		return errors.WithStackTrace(err)
 	}
@@ -234,9 +233,9 @@ func (clusters *ECSClusters) getFirstSeenTag(clusterArn *string) (*time.Time, er
 		ResourceArn: clusterArn,
 	}
 
-	clusterTags, err := clusters.Client.ListTagsForResource(input)
+	clusterTags, err := clusters.Client.ListTagsForResource(clusters.Context, input)
 	if err != nil {
-		logging.Debugf("Error getting the tags for ECS cluster with ARN %s", aws.StringValue(clusterArn))
+		logging.Debugf("Error getting the tags for ECS cluster with ARN %s", aws.ToString(clusterArn))
 		return firstSeenTime, errors.WithStackTrace(err)
 	}
 
@@ -245,7 +244,7 @@ func (clusters *ECSClusters) getFirstSeenTag(clusterArn *string) (*time.Time, er
 
 			firstSeenTime, err := util.ParseTimestamp(tag.Value)
 			if err != nil {
-				logging.Debugf("Error parsing the `cloud-nuke-first-seen` tag for ECS cluster with ARN %s", aws.StringValue(clusterArn))
+				logging.Debugf("Error parsing the `cloud-nuke-first-seen` tag for ECS cluster with ARN %s", aws.ToString(clusterArn))
 				return firstSeenTime, errors.WithStackTrace(err)
 			}
 
diff --git a/aws/resources/ecs_cluster_types.go b/aws/resources/ecs_cluster_types.go
index 0cac8c2..74fb75e 100644
--- a/aws/resources/ecs_cluster_types.go
+++ b/aws/resources/ecs_cluster_types.go
@@ -3,26 +3,36 @@ package resources
 import (
 	"context"
 
-	awsgo "github.com/aws/aws-sdk-go/aws"
-	"github.com/aws/aws-sdk-go/aws/session"
-	"github.com/aws/aws-sdk-go/service/ecs"
-	"github.com/aws/aws-sdk-go/service/ecs/ecsiface"
+	"github.com/aws/aws-sdk-go-v2/aws"
+	"github.com/aws/aws-sdk-go-v2/service/ecs"
 	"github.com/gruntwork-io/cloud-nuke/config"
 	"github.com/gruntwork-io/go-commons/errors"
 )
 
+type ECSClustersAPI interface {
+	DescribeClusters(ctx context.Context, params *ecs.DescribeClustersInput, optFns ...func(*ecs.Options)) (*ecs.DescribeClustersOutput, error)
+	DeleteCluster(ctx context.Context, params *ecs.DeleteClusterInput, optFns ...func(*ecs.Options)) (*ecs.DeleteClusterOutput, error)
+	ListClusters(ctx context.Context, params *ecs.ListClustersInput, optFns ...func(*ecs.Options)) (*ecs.ListClustersOutput, error)
+	ListTagsForResource(ctx context.Context, params *ecs.ListTagsForResourceInput, optFns ...func(*ecs.Options)) (*ecs.ListTagsForResourceOutput, error)
+	ListTasks(ctx context.Context, params *ecs.ListTasksInput, optFns ...func(*ecs.Options)) (*ecs.ListTasksOutput, error)
+	StopTask(ctx context.Context, params *ecs.StopTaskInput, optFns ...func(*ecs.Options)) (*ecs.StopTaskOutput, error)
+	TagResource(ctx context.Context, params *ecs.TagResourceInput, optFns ...func(*ecs.Options)) (*ecs.TagResourceOutput, error)
+}
+
 // ECSClusters - Represents all ECS clusters found in a region
 type ECSClusters struct {
 	BaseAwsResource
-	Client      ecsiface.ECSAPI
+	Client      ECSClustersAPI
 	Region      string
 	ClusterArns []string
 }
 
-func (clusters *ECSClusters) Init(session *session.Session) {
-	clusters.Client = ecs.New(session)
+func (clusters *ECSClusters) InitV2(cfg aws.Config) {
+	clusters.Client = ecs.NewFromConfig(cfg)
 }
 
+func (clusters *ECSClusters) IsUsingV2() bool { return true }
+
 // ResourceName - The simple name of the aws resource
 func (clusters *ECSClusters) ResourceName() string {
 	return "ecscluster"
@@ -47,13 +57,13 @@ func (clusters *ECSClusters) GetAndSetIdentifiers(c context.Context, configObj c
 		return nil, err
 	}
 
-	clusters.ClusterArns = awsgo.StringValueSlice(identifiers)
+	clusters.ClusterArns = aws.ToStringSlice(identifiers)
 	return clusters.ClusterArns, nil
 }
 
 // Nuke - nuke all ECS Cluster resources
 func (clusters *ECSClusters) Nuke(identifiers []string) error {
-	if err := clusters.nukeAll(awsgo.StringSlice(identifiers)); err != nil {
+	if err := clusters.nukeAll(aws.StringSlice(identifiers)); err != nil {
 		return errors.WithStackTrace(err)
 	}
 	return nil
diff --git a/aws/resources/ecs_service.go b/aws/resources/ecs_service.go
index 7df13b3..20a46dc 100644
--- a/aws/resources/ecs_service.go
+++ b/aws/resources/ecs_service.go
@@ -2,38 +2,38 @@ package resources
 
 import (
 	"context"
+	"time"
 
-	"github.com/gruntwork-io/cloud-nuke/util"
-
-	"github.com/aws/aws-sdk-go/aws"
-	awsgo "github.com/aws/aws-sdk-go/aws"
-	"github.com/aws/aws-sdk-go/service/ecs"
+	"github.com/aws/aws-sdk-go-v2/aws"
+	"github.com/aws/aws-sdk-go-v2/service/ecs"
+	"github.com/aws/aws-sdk-go-v2/service/ecs/types"
 	"github.com/gruntwork-io/cloud-nuke/config"
 	"github.com/gruntwork-io/cloud-nuke/logging"
 	"github.com/gruntwork-io/cloud-nuke/report"
+	"github.com/gruntwork-io/cloud-nuke/util"
 	"github.com/gruntwork-io/go-commons/errors"
 )
 
 // getAllEcsClusters - Returns a string of ECS Cluster ARNs, which uniquely identifies the cluster.
 // We need to get all clusters before we can get all services.
 func (services *ECSServices) getAllEcsClusters() ([]*string, error) {
-	clusterArns := []*string{}
-	result, err := services.Client.ListClustersWithContext(services.Context, &ecs.ListClustersInput{})
+	var clusterArns []string
+	result, err := services.Client.ListClusters(services.Context, &ecs.ListClustersInput{})
 	if err != nil {
 		return nil, errors.WithStackTrace(err)
 	}
 	clusterArns = append(clusterArns, result.ClusterArns...)
 
 	// Handle pagination: continuously pull the next page if nextToken is set
-	for awsgo.StringValue(result.NextToken) != "" {
-		result, err = services.Client.ListClustersWithContext(services.Context, &ecs.ListClustersInput{NextToken: result.NextToken})
+	for aws.ToString(result.NextToken) != "" {
+		result, err = services.Client.ListClusters(services.Context, &ecs.ListClustersInput{NextToken: result.NextToken})
 		if err != nil {
 			return nil, errors.WithStackTrace(err)
 		}
 		clusterArns = append(clusterArns, result.ClusterArns...)
 	}
 
-	return clusterArns, nil
+	return aws.StringSlice(clusterArns), nil
 }
 
 // filterOutRecentServices - Given a list of services and an excludeAfter
@@ -47,9 +47,9 @@ func (services *ECSServices) filterOutRecentServices(clusterArn *string, ecsServ
 	for _, batch := range batches {
 		params := &ecs.DescribeServicesInput{
 			Cluster:  clusterArn,
-			Services: awsgo.StringSlice(batch),
+			Services: batch,
 		}
-		describeResult, err := services.Client.DescribeServicesWithContext(services.Context, params)
+		describeResult, err := services.Client.DescribeServices(services.Context, params)
 		if err != nil {
 			return nil, errors.WithStackTrace(err)
 		}
@@ -82,11 +82,11 @@ func (services *ECSServices) getAll(c context.Context, configObj config.Config)
 	// ones.
 	var ecsServiceArns []*string
 	for _, clusterArn := range ecsClusterArns {
-		result, err := services.Client.ListServicesWithContext(services.Context, &ecs.ListServicesInput{Cluster: clusterArn})
+		result, err := services.Client.ListServices(services.Context, &ecs.ListServicesInput{Cluster: clusterArn})
 		if err != nil {
 			return nil, errors.WithStackTrace(err)
 		}
-		filteredServiceArns, err := services.filterOutRecentServices(clusterArn, awsgo.StringValueSlice(result.ServiceArns), configObj)
+		filteredServiceArns, err := services.filterOutRecentServices(clusterArn, result.ServiceArns, configObj)
 		if err != nil {
 			return nil, errors.WithStackTrace(err)
 		}
@@ -109,24 +109,24 @@ func (services *ECSServices) drainEcsServices(ecsServiceArns []*string) []*strin
 	for _, ecsServiceArn := range ecsServiceArns {
 
 		describeParams := &ecs.DescribeServicesInput{
-			Cluster:  awsgo.String(services.ServiceClusterMap[*ecsServiceArn]),
-			Services: []*string{ecsServiceArn},
+			Cluster:  aws.String(services.ServiceClusterMap[*ecsServiceArn]),
+			Services: []string{*ecsServiceArn},
 		}
-		describeServicesOutput, err := services.Client.DescribeServicesWithContext(services.Context, describeParams)
+		describeServicesOutput, err := services.Client.DescribeServices(services.Context, describeParams)
 		if err != nil {
 			logging.Errorf("[Failed] Failed to describe service %s: %s", *ecsServiceArn, err)
 		} else {
 
-			schedulingStrategy := *describeServicesOutput.Services[0].SchedulingStrategy
-			if schedulingStrategy == "DAEMON" {
+			schedulingStrategy := describeServicesOutput.Services[0].SchedulingStrategy
+			if schedulingStrategy == types.SchedulingStrategyDaemon {
 				requestedDrains = append(requestedDrains, ecsServiceArn)
 			} else {
 				params := &ecs.UpdateServiceInput{
-					Cluster:      awsgo.String(services.ServiceClusterMap[*ecsServiceArn]),
+					Cluster:      aws.String(services.ServiceClusterMap[*ecsServiceArn]),
 					Service:      ecsServiceArn,
-					DesiredCount: awsgo.Int64(0),
+					DesiredCount: aws.Int32(0),
 				}
-				_, err = services.Client.UpdateServiceWithContext(services.Context, params)
+				_, err = services.Client.UpdateService(services.Context, params)
 				if err != nil {
 					logging.Errorf("[Failed] Failed to drain service %s: %s", *ecsServiceArn, err)
 				} else {
@@ -146,10 +146,12 @@ func (services *ECSServices) waitUntilServicesDrained(ecsServiceArns []*string)
 	var successfullyDrained []*string
 	for _, ecsServiceArn := range ecsServiceArns {
 		params := &ecs.DescribeServicesInput{
-			Cluster:  awsgo.String(services.ServiceClusterMap[*ecsServiceArn]),
-			Services: []*string{ecsServiceArn},
+			Cluster:  aws.String(services.ServiceClusterMap[*ecsServiceArn]),
+			Services: []string{*ecsServiceArn},
 		}
-		err := services.Client.WaitUntilServicesStableWithContext(services.Context, params)
+
+		waiter := ecs.NewServicesStableWaiter(services.Client)
+		err := waiter.Wait(services.Context, params, 15*time.Minute)
 		if err != nil {
 			logging.Debugf("[Failed] Failed waiting for service to be stable %s: %s", *ecsServiceArn, err)
 		} else {
@@ -166,10 +168,10 @@ func (services *ECSServices) deleteEcsServices(ecsServiceArns []*string) []*stri
 	var requestedDeletes []*string
 	for _, ecsServiceArn := range ecsServiceArns {
 		params := &ecs.DeleteServiceInput{
-			Cluster: awsgo.String(services.ServiceClusterMap[*ecsServiceArn]),
+			Cluster: aws.String(services.ServiceClusterMap[*ecsServiceArn]),
 			Service: ecsServiceArn,
 		}
-		_, err := services.Client.DeleteServiceWithContext(services.Context, params)
+		_, err := services.Client.DeleteService(services.Context, params)
 		if err != nil {
 			logging.Debugf("[Failed] Failed deleting service %s: %s", *ecsServiceArn, err)
 		} else {
@@ -186,14 +188,16 @@ func (services *ECSServices) waitUntilServicesDeleted(ecsServiceArns []*string)
 	var successfullyDeleted []*string
 	for _, ecsServiceArn := range ecsServiceArns {
 		params := &ecs.DescribeServicesInput{
-			Cluster:  awsgo.String(services.ServiceClusterMap[*ecsServiceArn]),
-			Services: []*string{ecsServiceArn},
+			Cluster:  aws.String(services.ServiceClusterMap[*ecsServiceArn]),
+			Services: []string{*ecsServiceArn},
 		}
-		err := services.Client.WaitUntilServicesInactiveWithContext(services.Context, params)
+
+		waiter := ecs.NewServicesInactiveWaiter(services.Client)
+		err := waiter.Wait(services.Context, params, 15*time.Minute)
 
 		// Record status of this resource
 		e := report.Entry{
-			Identifier:   aws.StringValue(ecsServiceArn),
+			Identifier:   aws.ToString(ecsServiceArn),
 			ResourceType: "ECS Service",
 			Error:        err,
 		}
diff --git a/aws/resources/ecs_service_types.go b/aws/resources/ecs_service_types.go
index 8f508be..d6bd351 100644
--- a/aws/resources/ecs_service_types.go
+++ b/aws/resources/ecs_service_types.go
@@ -3,27 +3,35 @@ package resources
 import (
 	"context"
 
-	awsgo "github.com/aws/aws-sdk-go/aws"
-	"github.com/aws/aws-sdk-go/aws/session"
-	"github.com/aws/aws-sdk-go/service/ecs"
-	"github.com/aws/aws-sdk-go/service/ecs/ecsiface"
+	"github.com/aws/aws-sdk-go-v2/aws"
+	"github.com/aws/aws-sdk-go-v2/service/ecs"
 	"github.com/gruntwork-io/cloud-nuke/config"
 	"github.com/gruntwork-io/go-commons/errors"
 )
 
+type ECSServicesAPI interface {
+	ListClusters(ctx context.Context, params *ecs.ListClustersInput, optFns ...func(*ecs.Options)) (*ecs.ListClustersOutput, error)
+	ListServices(ctx context.Context, params *ecs.ListServicesInput, optFns ...func(*ecs.Options)) (*ecs.ListServicesOutput, error)
+	DescribeServices(ctx context.Context, params *ecs.DescribeServicesInput, optFns ...func(*ecs.Options)) (*ecs.DescribeServicesOutput, error)
+	DeleteService(ctx context.Context, params *ecs.DeleteServiceInput, optFns ...func(*ecs.Options)) (*ecs.DeleteServiceOutput, error)
+	UpdateService(ctx context.Context, params *ecs.UpdateServiceInput, optFns ...func(*ecs.Options)) (*ecs.UpdateServiceOutput, error)
+}
+
 // ECSServices - Represents all ECS services found in a region
 type ECSServices struct {
 	BaseAwsResource
-	Client            ecsiface.ECSAPI
+	Client            ECSServicesAPI
 	Region            string
 	Services          []string
 	ServiceClusterMap map[string]string
 }
 
-func (services *ECSServices) Init(session *session.Session) {
-	services.Client = ecs.New(session)
+func (services *ECSServices) InitV2(cfg aws.Config) {
+	services.Client = ecs.NewFromConfig(cfg)
 }
 
+func (services *ECSServices) IsUsingV2() bool { return true }
+
 // ResourceName - The simple name of the aws resource
 func (services *ECSServices) ResourceName() string {
 	return "ecsserv"
@@ -48,13 +56,13 @@ func (services *ECSServices) GetAndSetIdentifiers(c context.Context, configObj c
 		return nil, err
 	}
 
-	services.Services = awsgo.StringValueSlice(identifiers)
+	services.Services = aws.ToStringSlice(identifiers)
 	return services.Services, nil
 }
 
 // Nuke - nuke all ECS service resources
 func (services *ECSServices) Nuke(identifiers []string) error {
-	if err := services.nukeAll(awsgo.StringSlice(identifiers)); err != nil {
+	if err := services.nukeAll(aws.StringSlice(identifiers)); err != nil {
 		return errors.WithStackTrace(err)
 	}
 	return nil
diff --git a/aws/resources/efs.go b/aws/resources/efs.go
index b4a860f..4502964 100644
--- a/aws/resources/efs.go
+++ b/aws/resources/efs.go
@@ -5,8 +5,8 @@ import (
 	"sync"
 	"time"
 
-	"github.com/aws/aws-sdk-go/aws"
-	"github.com/aws/aws-sdk-go/service/efs"
+	"github.com/aws/aws-sdk-go-v2/aws"
+	"github.com/aws/aws-sdk-go-v2/service/efs"
 	"github.com/gruntwork-io/cloud-nuke/config"
 	"github.com/gruntwork-io/cloud-nuke/logging"
 	"github.com/gruntwork-io/cloud-nuke/report"
@@ -15,24 +15,26 @@ import (
 )
 
 func (ef *ElasticFileSystem) getAll(c context.Context, configObj config.Config) ([]*string, error) {
+	var allEfs []*string
 
-	allEfs := []*string{}
-	err := ef.Client.DescribeFileSystemsPagesWithContext(
-		ef.Context,
-		&efs.DescribeFileSystemsInput{}, func(page *efs.DescribeFileSystemsOutput, lastPage bool) bool {
-			for _, system := range page.FileSystems {
-				if configObj.ElasticFileSystem.ShouldInclude(config.ResourceValue{
-					Name: system.Name,
-					Time: system.CreationTime,
-				}) {
-					allEfs = append(allEfs, system.FileSystemId)
-				}
-			}
+	paginator := efs.NewDescribeFileSystemsPaginator(ef.Client, &efs.DescribeFileSystemsInput{})
+	for paginator.HasMorePages() {
+		page, err := paginator.NextPage(c)
+		if err != nil {
+			return nil, errors.WithStackTrace(err)
+		}
 
-			return !lastPage
-		})
+		for _, system := range page.FileSystems {
+			if configObj.ElasticFileSystem.ShouldInclude(config.ResourceValue{
+				Name: system.Name,
+				Time: system.CreationTime,
+			}) {
+				allEfs = append(allEfs, system.FileSystemId)
+			}
+		}
+	}
 
-	return allEfs, err
+	return allEfs, nil
 }
 
 func (ef *ElasticFileSystem) nukeAll(identifiers []*string) error {
@@ -79,13 +81,13 @@ func (ef *ElasticFileSystem) deleteAsync(wg *sync.WaitGroup, errChan chan error,
 	// First, we need to check if the Elastic FileSystem is "in-use", because an in-use file system cannot be deleted
 	// An Elastic FileSystem is considered in-use if it has any access points, or any mount targets
 	// Here, we first look up and delete any and all access points for the given Elastic FileSystem
-	accessPointIds := []*string{}
+	var accessPointIds []*string
 
 	accessPointParam := &efs.DescribeAccessPointsInput{
 		FileSystemId: efsID,
 	}
 
-	out, err := ef.Client.DescribeAccessPointsWithContext(ef.Context, accessPointParam)
+	out, err := ef.Client.DescribeAccessPoints(ef.Context, accessPointParam)
 	if err != nil {
 		allErrs = multierror.Append(allErrs, err)
 	}
@@ -100,13 +102,13 @@ func (ef *ElasticFileSystem) deleteAsync(wg *sync.WaitGroup, errChan chan error,
 			AccessPointId: apID,
 		}
 
-		logging.Debugf("Deleting access point (id=%s) for Elastic FileSystem (%s) in region: %s", aws.StringValue(apID), aws.StringValue(efsID), ef.Region)
+		logging.Debugf("Deleting access point (id=%s) for Elastic FileSystem (%s) in region: %s", aws.ToString(apID), aws.ToString(efsID), ef.Region)
 
-		_, err := ef.Client.DeleteAccessPointWithContext(ef.Context, deleteParam)
+		_, err := ef.Client.DeleteAccessPoint(ef.Context, deleteParam)
 		if err != nil {
 			allErrs = multierror.Append(allErrs, err)
 		} else {
-			logging.Debugf("[OK] Deleted access point (id=%s) for Elastic FileSystem (%s) in region: %s", aws.StringValue(apID), aws.StringValue(efsID), ef.Region)
+			logging.Debugf("[OK] Deleted access point (id=%s) for Elastic FileSystem (%s) in region: %s", aws.ToString(apID), aws.ToString(efsID), ef.Region)
 		}
 	}
 
@@ -117,7 +119,7 @@ func (ef *ElasticFileSystem) deleteAsync(wg *sync.WaitGroup, errChan chan error,
 	done := false
 	var marker *string
 
-	mountTargetIds := []*string{}
+	var mountTargetIds []*string
 
 	for !done {
 
@@ -126,11 +128,11 @@ func (ef *ElasticFileSystem) deleteAsync(wg *sync.WaitGroup, errChan chan error,
 		}
 
 		// If the last iteration had a marker set, use it
-		if aws.StringValue(marker) != "" {
+		if aws.ToString(marker) != "" {
 			mountTargetParam.Marker = marker
 		}
 
-		mountTargetsOutput, describeMountsErr := ef.Client.DescribeMountTargetsWithContext(ef.Context, mountTargetParam)
+		mountTargetsOutput, describeMountsErr := ef.Client.DescribeMountTargets(ef.Context, mountTargetParam)
 		if describeMountsErr != nil {
 			allErrs = multierror.Append(allErrs, err)
 		}
@@ -140,7 +142,7 @@ func (ef *ElasticFileSystem) deleteAsync(wg *sync.WaitGroup, errChan chan error,
 		}
 
 		// If the response contained a NextMarker field, set it as the next iteration's marker
-		if aws.StringValue(mountTargetsOutput.NextMarker) != "" {
+		if aws.ToString(mountTargetsOutput.NextMarker) != "" {
 			marker = mountTargetsOutput.NextMarker
 		} else {
 			// There's no NextMarker set on the response, so we're done enumerating mount targets
@@ -153,13 +155,13 @@ func (ef *ElasticFileSystem) deleteAsync(wg *sync.WaitGroup, errChan chan error,
 			MountTargetId: mtID,
 		}
 
-		logging.Debugf("Deleting mount target (id=%s) for Elastic FileSystem (%s) in region: %s", aws.StringValue(mtID), aws.StringValue(efsID), ef.Region)
+		logging.Debugf("Deleting mount target (id=%s) for Elastic FileSystem (%s) in region: %s", aws.ToString(mtID), aws.ToString(efsID), ef.Region)
 
-		_, err := ef.Client.DeleteMountTargetWithContext(ef.Context, deleteMtParam)
+		_, err := ef.Client.DeleteMountTarget(ef.Context, deleteMtParam)
 		if err != nil {
 			allErrs = multierror.Append(allErrs, err)
 		} else {
-			logging.Debugf("[OK] Deleted mount target (id=%s) for Elastic FileSystem (%s) in region: %s", aws.StringValue(mtID), aws.StringValue(efsID), ef.Region)
+			logging.Debugf("[OK] Deleted mount target (id=%s) for Elastic FileSystem (%s) in region: %s", aws.ToString(mtID), aws.ToString(efsID), ef.Region)
 		}
 	}
 
@@ -171,10 +173,10 @@ func (ef *ElasticFileSystem) deleteAsync(wg *sync.WaitGroup, errChan chan error,
 		FileSystemId: efsID,
 	}
 
-	_, deleteErr := ef.Client.DeleteFileSystemWithContext(ef.Context, deleteEfsParam)
+	_, deleteErr := ef.Client.DeleteFileSystem(ef.Context, deleteEfsParam)
 	// Record status of this resource
 	e := report.Entry{
-		Identifier:   aws.StringValue(efsID),
+		Identifier:   aws.ToString(efsID),
 		ResourceType: "Elastic FileSystem (EFS)",
 		Error:        err,
 	}
@@ -185,8 +187,8 @@ func (ef *ElasticFileSystem) deleteAsync(wg *sync.WaitGroup, errChan chan error,
 	}
 
 	if err == nil {
-		logging.Debugf("[OK] Elastic FileSystem (efs) %s deleted in %s", aws.StringValue(efsID), ef.Region)
+		logging.Debugf("[OK] Elastic FileSystem (efs) %s deleted in %s", aws.ToString(efsID), ef.Region)
 	} else {
-		logging.Debugf("[Failed] Error deleting Elastic FileSystem (efs) %s in %s", aws.StringValue(efsID), ef.Region)
+		logging.Debugf("[Failed] Error deleting Elastic FileSystem (efs) %s in %s", aws.ToString(efsID), ef.Region)
 	}
 }
diff --git a/aws/resources/efs_types.go b/aws/resources/efs_types.go
index a88fcd6..50187c3 100644
--- a/aws/resources/efs_types.go
+++ b/aws/resources/efs_types.go
@@ -3,25 +3,34 @@ package resources
 import (
 	"context"
 
-	awsgo "github.com/aws/aws-sdk-go/aws"
-	"github.com/aws/aws-sdk-go/aws/session"
-	"github.com/aws/aws-sdk-go/service/efs"
-	"github.com/aws/aws-sdk-go/service/efs/efsiface"
+	"github.com/aws/aws-sdk-go-v2/aws"
+	"github.com/aws/aws-sdk-go-v2/service/efs"
 	"github.com/gruntwork-io/cloud-nuke/config"
 	"github.com/gruntwork-io/go-commons/errors"
 )
 
+type ElasticFileSystemAPI interface {
+	DeleteAccessPoint(ctx context.Context, params *efs.DeleteAccessPointInput, optFns ...func(*efs.Options)) (*efs.DeleteAccessPointOutput, error)
+	DeleteFileSystem(ctx context.Context, params *efs.DeleteFileSystemInput, optFns ...func(*efs.Options)) (*efs.DeleteFileSystemOutput, error)
+	DeleteMountTarget(ctx context.Context, params *efs.DeleteMountTargetInput, optFns ...func(*efs.Options)) (*efs.DeleteMountTargetOutput, error)
+	DescribeAccessPoints(ctx context.Context, params *efs.DescribeAccessPointsInput, optFns ...func(*efs.Options)) (*efs.DescribeAccessPointsOutput, error)
+	DescribeMountTargets(ctx context.Context, params *efs.DescribeMountTargetsInput, optFns ...func(*efs.Options)) (*efs.DescribeMountTargetsOutput, error)
+	DescribeFileSystems(ctx context.Context, params *efs.DescribeFileSystemsInput, optFns ...func(*efs.Options)) (*efs.DescribeFileSystemsOutput, error)
+}
+
 type ElasticFileSystem struct {
 	BaseAwsResource
-	Client efsiface.EFSAPI
+	Client ElasticFileSystemAPI
 	Region string
 	Ids    []string
 }
 
-func (ef *ElasticFileSystem) Init(session *session.Session) {
-	ef.Client = efs.New(session)
+func (ef *ElasticFileSystem) InitV2(cfg aws.Config) {
+	ef.Client = efs.NewFromConfig(cfg)
 }
 
+func (ef *ElasticFileSystem) IsUsingV2() bool { return true }
+
 func (ef *ElasticFileSystem) ResourceName() string {
 	return "efs"
 }
@@ -44,12 +53,12 @@ func (ef *ElasticFileSystem) GetAndSetIdentifiers(c context.Context, configObj c
 		return nil, err
 	}
 
-	ef.Ids = awsgo.StringValueSlice(identifiers)
+	ef.Ids = aws.ToStringSlice(identifiers)
 	return ef.Ids, nil
 }
 
 func (ef *ElasticFileSystem) Nuke(identifiers []string) error {
-	if err := ef.nukeAll(awsgo.StringSlice(identifiers)); err != nil {
+	if err := ef.nukeAll(aws.StringSlice(identifiers)); err != nil {
 		return errors.WithStackTrace(err)
 	}
 
diff --git a/aws/resources/eip.go b/aws/resources/eip.go
index 644f75b..ff0f457 100644
--- a/aws/resources/eip.go
+++ b/aws/resources/eip.go
@@ -2,12 +2,13 @@ package resources
 
 import (
 	"context"
+	goerr "errors"
 	"time"
 
-	"github.com/aws/aws-sdk-go/aws"
-	awsgo "github.com/aws/aws-sdk-go/aws"
-	"github.com/aws/aws-sdk-go/aws/awserr"
-	"github.com/aws/aws-sdk-go/service/ec2"
+	"github.com/aws/aws-sdk-go-v2/aws"
+	"github.com/aws/aws-sdk-go-v2/service/ec2"
+	"github.com/aws/aws-sdk-go-v2/service/ec2/types"
+	"github.com/aws/smithy-go"
 	"github.com/gruntwork-io/cloud-nuke/config"
 	"github.com/gruntwork-io/cloud-nuke/logging"
 	"github.com/gruntwork-io/cloud-nuke/report"
@@ -16,33 +17,33 @@ import (
 )
 
 // Returns a formatted string of EIP allocation ids
-func (ea *EIPAddresses) getAll(c context.Context, configObj config.Config) ([]*string, error) {
+func (eip *EIPAddresses) getAll(c context.Context, configObj config.Config) ([]*string, error) {
 
 	var firstSeenTime *time.Time
 	var err error
-	result, err := ea.Client.DescribeAddressesWithContext(ea.Context, &ec2.DescribeAddressesInput{})
+	result, err := eip.Client.DescribeAddresses(eip.Context, &ec2.DescribeAddressesInput{})
 	if err != nil {
 		return nil, errors.WithStackTrace(err)
 	}
 
 	var allocationIds []*string
 	for _, address := range result.Addresses {
-		firstSeenTime, err = util.GetOrCreateFirstSeen(c, ea.Client, address.AllocationId, util.ConvertEC2TagsToMap(address.Tags))
+		firstSeenTime, err = util.GetOrCreateFirstSeen(c, eip.Client, address.AllocationId, util.ConvertTypesTagsToMap(address.Tags))
 		if err != nil {
 			logging.Error("unable to retrieve first seen tag")
 			return nil, errors.WithStackTrace(err)
 		}
 
-		if ea.shouldInclude(address, firstSeenTime, configObj) {
+		if eip.shouldInclude(address, firstSeenTime, configObj) {
 			allocationIds = append(allocationIds, address.AllocationId)
 		}
 	}
 
 	// checking the nukable permissions
-	ea.VerifyNukablePermissions(allocationIds, func(id *string) error {
-		_, err := ea.Client.ReleaseAddressWithContext(ea.Context, &ec2.ReleaseAddressInput{
+	eip.VerifyNukablePermissions(allocationIds, func(id *string) error {
+		_, err := eip.Client.ReleaseAddress(eip.Context, &ec2.ReleaseAddressInput{
 			AllocationId: id,
-			DryRun:       awsgo.Bool(true),
+			DryRun:       aws.Bool(true),
 		})
 		return err
 	})
@@ -50,52 +51,56 @@ func (ea *EIPAddresses) getAll(c context.Context, configObj config.Config) ([]*s
 	return allocationIds, nil
 }
 
-func (ea *EIPAddresses) shouldInclude(address *ec2.Address, firstSeenTime *time.Time, configObj config.Config) bool {
+func (eip *EIPAddresses) shouldInclude(address types.Address, firstSeenTime *time.Time, configObj config.Config) bool {
 	// If Name is unset, GetEC2ResourceNameTagValue returns error and zero value string
 	// Ignore this error and pass empty string to config.ShouldInclude
 	allocationName := util.GetEC2ResourceNameTagValue(address.Tags)
 	return configObj.ElasticIP.ShouldInclude(config.ResourceValue{
 		Time: firstSeenTime,
 		Name: allocationName,
-		Tags: util.ConvertEC2TagsToMap(address.Tags),
+		Tags: util.ConvertTypesTagsToMap(address.Tags),
 	})
 }
 
 // Deletes all EIP allocation ids
-func (ea *EIPAddresses) nukeAll(allocationIds []*string) error {
+func (eip *EIPAddresses) nukeAll(allocationIds []*string) error {
 	if len(allocationIds) == 0 {
-		logging.Debugf("No Elastic IPs to nuke in region %s", ea.Region)
+		logging.Debugf("No Elastic IPs to nuke in region %s", eip.Region)
 		return nil
 	}
 
-	logging.Debugf("Deleting all Elastic IPs in region %s", ea.Region)
+	logging.Debugf("Deleting all Elastic IPs in region %s", eip.Region)
 	var deletedAllocationIDs []*string
 
 	for _, allocationID := range allocationIds {
 
-		if nukable, reason := ea.IsNukable(awsgo.StringValue(allocationID)); !nukable {
-			logging.Debugf("[Skipping] %s nuke because %v", awsgo.StringValue(allocationID), reason)
+		if nukable, reason := eip.IsNukable(aws.ToString(allocationID)); !nukable {
+			logging.Debugf("[Skipping] %s nuke because %v", aws.ToString(allocationID), reason)
 			continue
 		}
 
-		_, err := ea.Client.ReleaseAddressWithContext(ea.Context, &ec2.ReleaseAddressInput{
+		_, err := eip.Client.ReleaseAddress(eip.Context, &ec2.ReleaseAddressInput{
 			AllocationId: allocationID,
 		})
 
 		// Record status of this resource
 		e := report.Entry{
-			Identifier:   aws.StringValue(allocationID),
+			Identifier:   aws.ToString(allocationID),
 			ResourceType: "Elastic IP Address (EIP)",
 			Error:        err,
 		}
 		report.Record(e)
 
 		if err != nil {
-			if awsErr, isAwsErr := err.(awserr.Error); isAwsErr && awsErr.Code() == "AuthFailure" {
-				// TODO: Figure out why we get an AuthFailure
-				logging.Debugf("EIP %s can't be deleted, it is still attached to an active resource", *allocationID)
-			} else {
-				logging.Debugf("[Failed] %s", err)
+			var apiErr smithy.APIError
+			if goerr.As(err, &apiErr) {
+				switch apiErr.ErrorCode() {
+				case "AuthFailure":
+					// TODO: Figure out why we get an AuthFailure
+					logging.Debugf("EIP %s can't be deleted, it is still attached to an active resource", *allocationID)
+				default:
+					logging.Debugf("[Failed] %s", err)
+				}
 			}
 		} else {
 			deletedAllocationIDs = append(deletedAllocationIDs, allocationID)
@@ -103,6 +108,6 @@ func (ea *EIPAddresses) nukeAll(allocationIds []*string) error {
 		}
 	}
 
-	logging.Debugf("[OK] %d Elastic IP(s) deleted in %s", len(deletedAllocationIDs), ea.Region)
+	logging.Debugf("[OK] %d Elastic IP(s) deleted in %s", len(deletedAllocationIDs), eip.Region)
 	return nil
 }
diff --git a/aws/resources/eip_types.go b/aws/resources/eip_types.go
index 8a5600d..121a592 100644
--- a/aws/resources/eip_types.go
+++ b/aws/resources/eip_types.go
@@ -3,58 +3,63 @@ package resources
 import (
 	"context"
 
-	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/aws/aws-sdk-go/service/ec2/ec2iface"
+	"github.com/aws/aws-sdk-go-v2/aws"
+	"github.com/aws/aws-sdk-go-v2/service/ec2"
 	"github.com/gruntwork-io/cloud-nuke/config"
 	"github.com/gruntwork-io/go-commons/errors"
 )
 
-// EBSVolumes - represents all ebs volumes
+type EIPAddressesAPI interface {
+	ReleaseAddress(ctx context.Context, params *ec2.ReleaseAddressInput, optFns ...func(*ec2.Options)) (*ec2.ReleaseAddressOutput, error)
+	DescribeAddresses(ctx context.Context, params *ec2.DescribeAddressesInput, optFns ...func(*ec2.Options)) (*ec2.DescribeAddressesOutput, error)
+}
+
+// EIPAddresses - represents all ebs volumes
 type EIPAddresses struct {
 	BaseAwsResource
-	Client        ec2iface.EC2API
+	Client        EIPAddressesAPI
 	Region        string
 	AllocationIds []string
 }
 
-func (address *EIPAddresses) Init(session *session.Session) {
-	address.Client = ec2.New(session)
+func (eip *EIPAddresses) InitV2(cfg aws.Config) {
+	eip.Client = ec2.NewFromConfig(cfg)
 }
 
+func (eip *EIPAddresses) IsUsingV2() bool { return true }
+
 // ResourceName - the simple name of the aws resource
-func (address *EIPAddresses) ResourceName() string {
+func (eip *EIPAddresses) ResourceName() string {
 	return "eip"
 }
 
 // ResourceIdentifiers - The instance ids of the eip addresses
-func (address *EIPAddresses) ResourceIdentifiers() []string {
-	return address.AllocationIds
+func (eip *EIPAddresses) ResourceIdentifiers() []string {
+	return eip.AllocationIds
 }
 
-func (address *EIPAddresses) MaxBatchSize() int {
+func (eip *EIPAddresses) MaxBatchSize() int {
 	// Tentative batch size to ensure AWS doesn't throttle
 	return 49
 }
 
-func (address *EIPAddresses) GetAndSetResourceConfig(configObj config.Config) config.ResourceType {
+func (eip *EIPAddresses) GetAndSetResourceConfig(configObj config.Config) config.ResourceType {
 	return configObj.ElasticIP
 }
 
-func (address *EIPAddresses) GetAndSetIdentifiers(c context.Context, configObj config.Config) ([]string, error) {
-	identifiers, err := address.getAll(c, configObj)
+func (eip *EIPAddresses) GetAndSetIdentifiers(c context.Context, configObj config.Config) ([]string, error) {
+	identifiers, err := eip.getAll(c, configObj)
 	if err != nil {
 		return nil, err
 	}
 
-	address.AllocationIds = awsgo.StringValueSlice(identifiers)
-	return address.AllocationIds, nil
+	eip.AllocationIds = aws.ToStringSlice(identifiers)
+	return eip.AllocationIds, nil
 }
 
 // Nuke - nuke 'em all!!!
-func (address *EIPAddresses) Nuke(identifiers []string) error {
-	if err := address.nukeAll(awsgo.StringSlice(identifiers)); err != nil {
+func (eip *EIPAddresses) Nuke(identifiers []string) error {
+	if err := eip.nukeAll(aws.StringSlice(identifiers)); err != nil {
 		return errors.WithStackTrace(err)
 	}
 
diff --git a/aws/resources/eks.go b/aws/resources/eks.go
index 5bf2d86..539f7d1 100644
--- a/aws/resources/eks.go
+++ b/aws/resources/eks.go
@@ -3,9 +3,10 @@ package resources
 import (
 	"context"
 	"sync"
+	"time"
 
-	"github.com/aws/aws-sdk-go/aws"
-	"github.com/aws/aws-sdk-go/service/eks"
+	"github.com/aws/aws-sdk-go-v2/aws"
+	"github.com/aws/aws-sdk-go-v2/service/eks"
 	"github.com/gruntwork-io/cloud-nuke/config"
 	"github.com/gruntwork-io/cloud-nuke/logging"
 	"github.com/gruntwork-io/cloud-nuke/report"
@@ -16,12 +17,12 @@ import (
 
 // getAll returns a list of strings of EKS Cluster Names that uniquely identify each cluster.
 func (clusters *EKSClusters) getAll(c context.Context, configObj config.Config) ([]*string, error) {
-	result, err := clusters.Client.ListClustersWithContext(clusters.Context, &eks.ListClustersInput{})
+	result, err := clusters.Client.ListClusters(clusters.Context, &eks.ListClustersInput{})
 	if err != nil {
 		return nil, errors.WithStackTrace(err)
 	}
 
-	filteredClusters, err := clusters.filter(result.Clusters, configObj)
+	filteredClusters, err := clusters.filter(aws.StringSlice(result.Clusters), configObj)
 	if err != nil {
 		return nil, errors.WithStackTrace(err)
 	}
@@ -39,7 +40,7 @@ func (clusters *EKSClusters) filter(clusterNames []*string, configObj config.Con
 			continue
 		}
 
-		describeResult, err := clusters.Client.DescribeClusterWithContext(
+		describeResult, err := clusters.Client.DescribeCluster(
 			clusters.Context,
 			&eks.DescribeClusterInput{Name: clusterName})
 		if err != nil {
@@ -48,7 +49,7 @@ func (clusters *EKSClusters) filter(clusterNames []*string, configObj config.Con
 
 		if !configObj.EKSCluster.ShouldInclude(config.ResourceValue{
 			Time: describeResult.Cluster.CreatedAt,
-			Tags: util.ConvertStringPtrTagsToMap(describeResult.Cluster.Tags),
+			Tags: util.ConvertStringPtrTagsToMap(aws.StringMap(describeResult.Cluster.Tags)),
 		}) {
 			continue
 		}
@@ -82,15 +83,17 @@ func (clusters *EKSClusters) deleteAsync(wg *sync.WaitGroup, errChan chan error,
 
 	// Make sure the node groups are actually deleted before returning.
 	for _, nodeGroup := range deletedNodeGroups {
-		err := clusters.Client.WaitUntilNodegroupDeletedWithContext(clusters.Context, &eks.DescribeNodegroupInput{
+
+		waiter := eks.NewNodegroupDeletedWaiter(clusters.Client)
+		err := waiter.Wait(clusters.Context, &eks.DescribeNodegroupInput{
 			ClusterName:   aws.String(eksClusterName),
 			NodegroupName: nodeGroup,
-		})
+		}, 15*time.Minute)
 		if err != nil {
-			logging.Debugf("[Failed] Failed waiting for Node Group %s associated with cluster %s to be deleted: %s", aws.StringValue(nodeGroup), eksClusterName, err)
+			logging.Debugf("[Failed] Failed waiting for Node Group %s associated with cluster %s to be deleted: %s", aws.ToString(nodeGroup), eksClusterName, err)
 			allSubResourceErrs = multierror.Append(allSubResourceErrs, err)
 		} else {
-			logging.Debugf("Deleted Node Group %s associated with cluster %s", aws.StringValue(nodeGroup), eksClusterName)
+			logging.Debugf("Deleted Node Group %s associated with cluster %s", aws.ToString(nodeGroup), eksClusterName)
 		}
 	}
 	if allSubResourceErrs != nil {
@@ -100,7 +103,7 @@ func (clusters *EKSClusters) deleteAsync(wg *sync.WaitGroup, errChan chan error,
 
 	// At this point, all the sub resources of the EKS cluster has been confirmed to be deleted, so we can go ahead to
 	// request to delete the EKS cluster.
-	_, deleteErr := clusters.Client.DeleteClusterWithContext(clusters.Context, &eks.DeleteClusterInput{Name: aws.String(eksClusterName)})
+	_, deleteErr := clusters.Client.DeleteCluster(clusters.Context, &eks.DeleteClusterInput{Name: aws.String(eksClusterName)})
 	if deleteErr != nil {
 		logging.Debugf("[Failed] Failed deleting EKS cluster %s: %s", eksClusterName, deleteErr)
 	}
@@ -111,17 +114,18 @@ func (clusters *EKSClusters) deleteAsync(wg *sync.WaitGroup, errChan chan error,
 // and requests each one to be deleted. Note that this function will not wait for the Node Groups to be deleted. This
 // will return the list of Node Groups that were successfully scheduled for deletion.
 func (clusters *EKSClusters) scheduleDeleteEKSClusterManagedNodeGroup(eksClusterName string) ([]*string, error) {
-	allNodeGroups := []*string{}
-	err := clusters.Client.ListNodegroupsPagesWithContext(
-		clusters.Context,
-		&eks.ListNodegroupsInput{ClusterName: aws.String(eksClusterName)},
-		func(page *eks.ListNodegroupsOutput, lastPage bool) bool {
-			allNodeGroups = append(allNodeGroups, page.Nodegroups...)
-			return !lastPage
-		},
-	)
-	if err != nil {
-		return nil, err
+	var allNodeGroups []*string
+
+	paginator := eks.NewListNodegroupsPaginator(clusters.Client, &eks.ListNodegroupsInput{
+		ClusterName: aws.String(eksClusterName),
+	})
+	for paginator.HasMorePages() {
+		page, err := paginator.NextPage(context.Background())
+		if err != nil {
+			return nil, errors.WithStackTrace(err)
+		}
+
+		allNodeGroups = append(allNodeGroups, aws.StringSlice(page.Nodegroups)...)
 	}
 
 	// Since there isn't a bulk node group delete, we make the requests to delete node groups in a tight loop. This
@@ -129,16 +133,16 @@ func (clusters *EKSClusters) scheduleDeleteEKSClusterManagedNodeGroup(eksCluster
 	// cloud-nuke should be fairly small due to its use case. We can improve this if anyone runs into scalability
 	// issues with this implementation.
 	var allDeleteErrs error
-	deletedNodeGroups := []*string{}
+	var deletedNodeGroups []*string
 	for _, nodeGroup := range allNodeGroups {
-		_, err := clusters.Client.DeleteNodegroupWithContext(
+		_, err := clusters.Client.DeleteNodegroup(
 			clusters.Context,
 			&eks.DeleteNodegroupInput{
 				ClusterName:   aws.String(eksClusterName),
 				NodegroupName: nodeGroup,
 			})
 		if err != nil {
-			logging.Debugf("[Failed] Failed deleting Node Group %s associated with cluster %s: %s", aws.StringValue(nodeGroup), eksClusterName, err)
+			logging.Debugf("[Failed] Failed deleting Node Group %s associated with cluster %s: %s", aws.ToString(nodeGroup), eksClusterName, err)
 			allDeleteErrs = multierror.Append(allDeleteErrs, err)
 		} else {
 			deletedNodeGroups = append(deletedNodeGroups, nodeGroup)
@@ -151,17 +155,16 @@ func (clusters *EKSClusters) scheduleDeleteEKSClusterManagedNodeGroup(eksCluster
 // each one to be deleted. Since only one Fargate Profile can be deleted at a time, this function will wait until the
 // Fargate Profile is actually deleted for each one before moving on to the next one.
 func (clusters *EKSClusters) deleteEKSClusterFargateProfiles(eksClusterName string) error {
-	allFargateProfiles := []*string{}
-	err := clusters.Client.ListFargateProfilesPagesWithContext(
-		clusters.Context,
-		&eks.ListFargateProfilesInput{ClusterName: aws.String(eksClusterName)},
-		func(page *eks.ListFargateProfilesOutput, lastPage bool) bool {
-			allFargateProfiles = append(allFargateProfiles, page.FargateProfileNames...)
-			return !lastPage
-		},
-	)
-	if err != nil {
-		return err
+	var allFargateProfiles []*string
+
+	paginator := eks.NewListFargateProfilesPaginator(clusters.Client, &eks.ListFargateProfilesInput{ClusterName: aws.String(eksClusterName)})
+	for paginator.HasMorePages() {
+		page, err := paginator.NextPage(context.Background())
+		if err != nil {
+			return errors.WithStackTrace(err)
+		}
+
+		allFargateProfiles = append(allFargateProfiles, aws.StringSlice(page.FargateProfileNames)...)
 	}
 
 	// We can't delete Fargate profiles in parallel, so we delete them sequentially, waiting until the profile has been
@@ -172,31 +175,31 @@ func (clusters *EKSClusters) deleteEKSClusterFargateProfiles(eksClusterName stri
 	// Note that we aggregate deletion errors so that we at least attempt to delete all of them once.
 	var allDeleteErrs error
 	for _, fargateProfile := range allFargateProfiles {
-		_, err := clusters.Client.DeleteFargateProfileWithContext(
+		_, err := clusters.Client.DeleteFargateProfile(
 			clusters.Context,
 			&eks.DeleteFargateProfileInput{
 				ClusterName:        aws.String(eksClusterName),
 				FargateProfileName: fargateProfile,
 			})
 		if err != nil {
-			logging.Debugf("[Failed] Failed deleting Fargate Profile %s associated with cluster %s: %s", aws.StringValue(fargateProfile), eksClusterName, err)
+			logging.Debugf("[Failed] Failed deleting Fargate Profile %s associated with cluster %s: %s", aws.ToString(fargateProfile), eksClusterName, err)
 			allDeleteErrs = multierror.Append(allDeleteErrs, err)
 			continue
 		}
 
-		waitErr := clusters.Client.WaitUntilFargateProfileDeletedWithContext(
-			clusters.Context,
-			&eks.DescribeFargateProfileInput{
-				ClusterName:        aws.String(eksClusterName),
-				FargateProfileName: fargateProfile,
-			})
+		waiter := eks.NewFargateProfileDeletedWaiter(clusters.Client)
+		waitErr := waiter.Wait(clusters.Context, &eks.DescribeFargateProfileInput{
+			ClusterName:        aws.String(eksClusterName),
+			FargateProfileName: fargateProfile,
+		}, 15*time.Minute)
 		if waitErr != nil {
-			logging.Debugf("[Failed] Failed waiting for Fargate Profile %s associated with cluster %s to be deleted: %s", aws.StringValue(fargateProfile), eksClusterName, waitErr)
+			logging.Debugf("[Failed] Failed waiting for Fargate Profile %s associated with cluster %s to be deleted: %s", aws.ToString(fargateProfile), eksClusterName, waitErr)
 			allDeleteErrs = multierror.Append(allDeleteErrs, waitErr)
 		} else {
-			logging.Debugf("Deleted Fargate Profile %s associated with cluster %s", aws.StringValue(fargateProfile), eksClusterName)
+			logging.Debugf("Deleted Fargate Profile %s associated with cluster %s", aws.ToString(fargateProfile), eksClusterName)
 		}
 	}
+
 	return allDeleteErrs
 }
 
@@ -205,11 +208,15 @@ func (clusters *EKSClusters) deleteEKSClusterFargateProfiles(eksClusterName stri
 func (clusters *EKSClusters) waitUntilEksClustersDeleted(eksClusterNames []*string) []*string {
 	var successfullyDeleted []*string
 	for _, eksClusterName := range eksClusterNames {
-		err := clusters.Client.WaitUntilClusterDeletedWithContext(clusters.Context, &eks.DescribeClusterInput{Name: eksClusterName})
+
+		waiter := eks.NewClusterDeletedWaiter(clusters.Client)
+		err := waiter.Wait(clusters.Context, &eks.DescribeClusterInput{
+			Name: eksClusterName,
+		}, 15*time.Minute)
 
 		// Record status of this resource
 		e := report.Entry{
-			Identifier:   aws.StringValue(eksClusterName),
+			Identifier:   aws.ToString(eksClusterName),
 			ResourceType: "EKS Cluster",
 			Error:        err,
 		}
@@ -218,7 +225,7 @@ func (clusters *EKSClusters) waitUntilEksClustersDeleted(eksClusterNames []*stri
 		if err != nil {
 			logging.Debugf("[Failed] Failed waiting for EKS cluster to be deleted %s: %s", *eksClusterName, err)
 		} else {
-			logging.Debugf("Deleted EKS cluster: %s", aws.StringValue(eksClusterName))
+			logging.Debugf("Deleted EKS cluster: %s", aws.ToString(eksClusterName))
 			successfullyDeleted = append(successfullyDeleted, eksClusterName)
 		}
 	}
@@ -242,7 +249,7 @@ func (clusters *EKSClusters) nukeAll(eksClusterNames []*string) error {
 		return TooManyEKSClustersErr{}
 	}
 
-	// We need to delete subresources associated with the EKS Cluster before being able to delete the cluster, so we
+	// We need to delete sub-resources associated with the EKS Cluster before being able to delete the cluster, so we
 	// spawn goroutines to drive the deletion of each EKS cluster.
 	logging.Debugf("Deleting %d EKS clusters in region %s", numNuking, clusters.Region)
 	wg := new(sync.WaitGroup)
@@ -250,7 +257,7 @@ func (clusters *EKSClusters) nukeAll(eksClusterNames []*string) error {
 	errChans := make([]chan error, numNuking)
 	for i, eksClusterName := range eksClusterNames {
 		errChans[i] = make(chan error, 1)
-		go clusters.deleteAsync(wg, errChans[i], aws.StringValue(eksClusterName))
+		go clusters.deleteAsync(wg, errChans[i], aws.ToString(eksClusterName))
 	}
 	wg.Wait()
 
diff --git a/aws/resources/eks_types.go b/aws/resources/eks_types.go
index 732694d..78655ba 100644
--- a/aws/resources/eks_types.go
+++ b/aws/resources/eks_types.go
@@ -3,26 +3,38 @@ package resources
 import (
 	"context"
 
-	awsgo "github.com/aws/aws-sdk-go/aws"
-	"github.com/aws/aws-sdk-go/aws/session"
-	"github.com/aws/aws-sdk-go/service/eks"
-	"github.com/aws/aws-sdk-go/service/eks/eksiface"
+	"github.com/aws/aws-sdk-go-v2/aws"
+	"github.com/aws/aws-sdk-go-v2/service/eks"
 	"github.com/gruntwork-io/cloud-nuke/config"
 	"github.com/gruntwork-io/go-commons/errors"
 )
 
+type EKSClustersAPI interface {
+	DeleteCluster(ctx context.Context, params *eks.DeleteClusterInput, optFns ...func(*eks.Options)) (*eks.DeleteClusterOutput, error)
+	DeleteFargateProfile(ctx context.Context, params *eks.DeleteFargateProfileInput, optFns ...func(*eks.Options)) (*eks.DeleteFargateProfileOutput, error)
+	DeleteNodegroup(ctx context.Context, params *eks.DeleteNodegroupInput, optFns ...func(*eks.Options)) (*eks.DeleteNodegroupOutput, error)
+	DescribeCluster(ctx context.Context, params *eks.DescribeClusterInput, optFns ...func(*eks.Options)) (*eks.DescribeClusterOutput, error)
+	DescribeFargateProfile(ctx context.Context, params *eks.DescribeFargateProfileInput, optFns ...func(*eks.Options)) (*eks.DescribeFargateProfileOutput, error)
+	DescribeNodegroup(ctx context.Context, params *eks.DescribeNodegroupInput, optFns ...func(*eks.Options)) (*eks.DescribeNodegroupOutput, error)
+	ListClusters(ctx context.Context, params *eks.ListClustersInput, optFns ...func(*eks.Options)) (*eks.ListClustersOutput, error)
+	ListFargateProfiles(ctx context.Context, params *eks.ListFargateProfilesInput, optFns ...func(*eks.Options)) (*eks.ListFargateProfilesOutput, error)
+	ListNodegroups(ctx context.Context, params *eks.ListNodegroupsInput, optFns ...func(*eks.Options)) (*eks.ListNodegroupsOutput, error)
+}
+
 // EKSClusters - Represents all EKS clusters found in a region
 type EKSClusters struct {
 	BaseAwsResource
-	Client   eksiface.EKSAPI
+	Client   EKSClustersAPI
 	Region   string
 	Clusters []string
 }
 
-func (clusters *EKSClusters) Init(session *session.Session) {
-	clusters.Client = eks.New(session)
+func (clusters *EKSClusters) InitV2(cfg aws.Config) {
+	clusters.Client = eks.NewFromConfig(cfg)
 }
 
+func (clusters *EKSClusters) IsUsingV2() bool { return true }
+
 // ResourceName - The simple name of the aws resource
 func (clusters *EKSClusters) ResourceName() string {
 	return "ekscluster"
@@ -50,13 +62,13 @@ func (clusters *EKSClusters) GetAndSetIdentifiers(c context.Context, configObj c
 		return nil, err
 	}
 
-	clusters.Clusters = awsgo.StringValueSlice(identifiers)
+	clusters.Clusters = aws.ToStringSlice(identifiers)
 	return clusters.Clusters, nil
 }
 
 // Nuke - nuke all EKS Cluster resources
 func (clusters *EKSClusters) Nuke(identifiers []string) error {
-	if err := clusters.nukeAll(awsgo.StringSlice(identifiers)); err != nil {
+	if err := clusters.nukeAll(aws.StringSlice(identifiers)); err != nil {
 		return errors.WithStackTrace(err)
 	}
 	return nil
diff --git a/aws/resources/elastic_beanstalk.go b/aws/resources/elastic_beanstalk.go
index 63c67a6..b86ea18 100644
--- a/aws/resources/elastic_beanstalk.go
+++ b/aws/resources/elastic_beanstalk.go
@@ -3,15 +3,16 @@ package resources
 import (
 	"context"
 
-	"github.com/aws/aws-sdk-go/aws"
-	"github.com/aws/aws-sdk-go/service/elasticbeanstalk"
+	"github.com/aws/aws-sdk-go-v2/aws"
+	"github.com/aws/aws-sdk-go-v2/service/elasticbeanstalk"
+	"github.com/aws/aws-sdk-go-v2/service/elasticbeanstalk/types"
 	"github.com/gruntwork-io/cloud-nuke/config"
 	"github.com/gruntwork-io/cloud-nuke/logging"
 	"github.com/gruntwork-io/cloud-nuke/report"
 	"github.com/gruntwork-io/go-commons/errors"
 )
 
-func shouldIncludeEBApplication(app *elasticbeanstalk.ApplicationDescription, configObj config.Config) bool {
+func shouldIncludeEBApplication(app *types.ApplicationDescription, configObj config.Config) bool {
 	return configObj.ElasticBeanstalk.ShouldInclude(config.ResourceValue{
 		Name: app.ApplicationName,
 		Time: app.DateCreated,
@@ -20,13 +21,13 @@ func shouldIncludeEBApplication(app *elasticbeanstalk.ApplicationDescription, co
 
 // Returns a formatted string of EB application ids
 func (eb *EBApplications) getAll(c context.Context, configObj config.Config) ([]*string, error) {
-	output, err := eb.Client.DescribeApplicationsWithContext(eb.Context, &elasticbeanstalk.DescribeApplicationsInput{})
+	output, err := eb.Client.DescribeApplications(eb.Context, &elasticbeanstalk.DescribeApplicationsInput{})
 	if err != nil {
 		return nil, errors.WithStackTrace(err)
 	}
 	var appIds []*string
 	for _, app := range output.Applications {
-		if shouldIncludeEBApplication(app, configObj) {
+		if shouldIncludeEBApplication(&app, configObj) {
 			appIds = append(appIds, app.ApplicationName)
 		}
 	}
@@ -44,13 +45,13 @@ func (eb *EBApplications) nukeAll(appIds []*string) error {
 	var deletedApps []*string
 
 	for _, id := range appIds {
-		_, err := eb.Client.DeleteApplicationWithContext(eb.Context, &elasticbeanstalk.DeleteApplicationInput{
+		_, err := eb.Client.DeleteApplication(eb.Context, &elasticbeanstalk.DeleteApplicationInput{
 			ApplicationName:     id,
 			TerminateEnvByForce: aws.Bool(true),
 		})
 		// Record status of this resource
 		e := report.Entry{
-			Identifier:   aws.StringValue(id),
+			Identifier:   aws.ToString(id),
 			ResourceType: "Elastic Beanstalk Application",
 			Error:        err,
 		}
diff --git a/aws/resources/elastic_beanstalk_types.go b/aws/resources/elastic_beanstalk_types.go
index 9473552..9596cd9 100644
--- a/aws/resources/elastic_beanstalk_types.go
+++ b/aws/resources/elastic_beanstalk_types.go
@@ -3,26 +3,31 @@ package resources
 import (
 	"context"
 
-	awsgo "github.com/aws/aws-sdk-go/aws"
-	"github.com/aws/aws-sdk-go/aws/session"
-	"github.com/aws/aws-sdk-go/service/elasticbeanstalk"
-	"github.com/aws/aws-sdk-go/service/elasticbeanstalk/elasticbeanstalkiface"
+	"github.com/aws/aws-sdk-go-v2/aws"
+	"github.com/aws/aws-sdk-go-v2/service/elasticbeanstalk"
 	"github.com/gruntwork-io/cloud-nuke/config"
 	"github.com/gruntwork-io/go-commons/errors"
 )
 
+type EBApplicationsAPI interface {
+	DescribeApplications(ctx context.Context, params *elasticbeanstalk.DescribeApplicationsInput, optFns ...func(*elasticbeanstalk.Options)) (*elasticbeanstalk.DescribeApplicationsOutput, error)
+	DeleteApplication(ctx context.Context, params *elasticbeanstalk.DeleteApplicationInput, optFns ...func(*elasticbeanstalk.Options)) (*elasticbeanstalk.DeleteApplicationOutput, error)
+}
+
 // EBApplications - represents all elastic beanstalk applications
 type EBApplications struct {
 	BaseAwsResource
-	Client elasticbeanstalkiface.ElasticBeanstalkAPI
+	Client EBApplicationsAPI
 	Region string
 	appIds []string
 }
 
-func (eb *EBApplications) Init(session *session.Session) {
-	eb.Client = elasticbeanstalk.New(session)
+func (eb *EBApplications) InitV2(cfg aws.Config) {
+	eb.Client = elasticbeanstalk.NewFromConfig(cfg)
 }
 
+func (eb *EBApplications) IsUsingV2() bool { return true }
+
 // ResourceName - the simple name of the aws resource
 func (eb *EBApplications) ResourceName() string {
 	return "elastic-beanstalk"
@@ -48,13 +53,13 @@ func (eb *EBApplications) GetAndSetIdentifiers(c context.Context, configObj conf
 		return nil, err
 	}
 
-	eb.appIds = awsgo.StringValueSlice(identifiers)
+	eb.appIds = aws.ToStringSlice(identifiers)
 	return eb.appIds, nil
 }
 
 // Nuke - nuke 'em all!!!
 func (eb *EBApplications) Nuke(identifiers []string) error {
-	if err := eb.nukeAll(awsgo.StringSlice(identifiers)); err != nil {
+	if err := eb.nukeAll(aws.StringSlice(identifiers)); err != nil {
 		return errors.WithStackTrace(err)
 	}
 
diff --git a/aws/resources/elasticache.go b/aws/resources/elasticache.go
index 7d0152b..e9b1def 100644
--- a/aws/resources/elasticache.go
+++ b/aws/resources/elasticache.go
@@ -2,36 +2,38 @@ package resources
 
 import (
 	"context"
+	"errors"
 	"fmt"
 	"strings"
+	"time"
 
-	"github.com/aws/aws-sdk-go/aws"
-	"github.com/aws/aws-sdk-go/aws/awserr"
-	"github.com/aws/aws-sdk-go/service/elasticache"
+	"github.com/aws/aws-sdk-go-v2/aws"
+	"github.com/aws/aws-sdk-go-v2/service/elasticache"
+	"github.com/aws/aws-sdk-go-v2/service/elasticache/types"
 	"github.com/gruntwork-io/cloud-nuke/config"
 	"github.com/gruntwork-io/cloud-nuke/logging"
 	"github.com/gruntwork-io/cloud-nuke/report"
-	"github.com/gruntwork-io/go-commons/errors"
+	goerrors "github.com/gruntwork-io/go-commons/errors"
 )
 
 // Returns a formatted string of Elasticache cluster Ids
 func (cache *Elasticaches) getAll(c context.Context, configObj config.Config) ([]*string, error) {
 	// First, get any cache clusters that are replication groups, which will be the case for all multi-node Redis clusters
-	replicationGroupsResult, replicationGroupsErr := cache.Client.DescribeReplicationGroupsWithContext(cache.Context, &elasticache.DescribeReplicationGroupsInput{})
+	replicationGroupsResult, replicationGroupsErr := cache.Client.DescribeReplicationGroups(cache.Context, &elasticache.DescribeReplicationGroupsInput{})
 	if replicationGroupsErr != nil {
-		return nil, errors.WithStackTrace(replicationGroupsErr)
+		return nil, goerrors.WithStackTrace(replicationGroupsErr)
 	}
 
 	// Next, get any cache clusters that are not members of a replication group: meaning:
-	// 1. any cache clusters with a Engine of "memcached"
+	// 1. any cache clusters with an Engine of "memcached"
 	// 2. any single node Redis clusters
-	cacheClustersResult, cacheClustersErr := cache.Client.DescribeCacheClustersWithContext(
+	cacheClustersResult, cacheClustersErr := cache.Client.DescribeCacheClusters(
 		cache.Context,
 		&elasticache.DescribeCacheClustersInput{
 			ShowCacheClustersNotInReplicationGroups: aws.Bool(true),
 		})
 	if cacheClustersErr != nil {
-		return nil, errors.WithStackTrace(cacheClustersErr)
+		return nil, goerrors.WithStackTrace(cacheClustersErr)
 	}
 
 	var clusterIds []*string
@@ -68,14 +70,14 @@ func (cache *Elasticaches) determineCacheClusterType(clusterId *string) (*string
 		ReplicationGroupId: clusterId,
 	}
 
-	replicationGroupOutput, describeReplicationGroupsErr := cache.Client.DescribeReplicationGroupsWithContext(cache.Context, replicationGroupDescribeParams)
+	replicationGroupOutput, describeReplicationGroupsErr := cache.Client.DescribeReplicationGroups(cache.Context, replicationGroupDescribeParams)
 	if describeReplicationGroupsErr != nil {
-		if awsErr, ok := describeReplicationGroupsErr.(awserr.Error); ok {
-			if awsErr.Code() == elasticache.ErrCodeReplicationGroupNotFoundFault {
-				// It's possible that we're looking at a cache cluster, in which case we can safely ignore this error
-			} else {
-				return nil, Single, describeReplicationGroupsErr
-			}
+		// GlobalReplicationGroupNotFoundFault
+		var eRG404 *types.ReplicationGroupNotFoundFault
+		if errors.As(describeReplicationGroupsErr, &eRG404) {
+			// It's possible that we're looking at a cache cluster, in which case we can safely ignore this error
+		} else {
+			return nil, Single, describeReplicationGroupsErr
 		}
 	}
 
@@ -90,14 +92,13 @@ func (cache *Elasticaches) determineCacheClusterType(clusterId *string) (*string
 		CacheClusterId: clusterId,
 	}
 
-	cacheClustersOutput, describeErr := cache.Client.DescribeCacheClustersWithContext(cache.Context, describeParams)
+	cacheClustersOutput, describeErr := cache.Client.DescribeCacheClusters(cache.Context, describeParams)
 	if describeErr != nil {
-		if awsErr, ok := describeErr.(awserr.Error); ok {
-			if awsErr.Code() == elasticache.ErrCodeCacheClusterNotFoundFault {
-				// It's possible that we're looking at a replication group, in which case we can safely ignore this error
-			} else {
-				return nil, Single, describeErr
-			}
+		var eC404 *types.CacheClusterNotFoundFault
+		if errors.As(describeErr, &eC404) {
+			// It's possible that we're looking at a replication group, in which case we can safely ignore this error
+		} else {
+			return nil, Single, describeErr
 		}
 	}
 
@@ -109,40 +110,49 @@ func (cache *Elasticaches) determineCacheClusterType(clusterId *string) (*string
 }
 
 func (cache *Elasticaches) nukeNonReplicationGroupElasticacheCluster(clusterId *string) error {
-	logging.Debugf("Deleting Elasticache cluster Id: %s which is not a member of a replication group", aws.StringValue(clusterId))
+	logging.Debugf("Deleting Elasticache cluster Id: %s which is not a member of a replication group", aws.ToString(clusterId))
 	params := elasticache.DeleteCacheClusterInput{
 		CacheClusterId: clusterId,
 	}
-	_, err := cache.Client.DeleteCacheClusterWithContext(cache.Context, &params)
+	_, err := cache.Client.DeleteCacheCluster(cache.Context, &params)
 	if err != nil {
 		return err
 	}
 
-	return cache.Client.WaitUntilCacheClusterDeletedWithContext(cache.Context, &elasticache.DescribeCacheClustersInput{
-		CacheClusterId: clusterId,
-	})
+	waiter := elasticache.NewCacheClusterDeletedWaiter(cache.Client)
+
+	return waiter.Wait(
+		cache.Context,
+		&elasticache.DescribeCacheClustersInput{
+			CacheClusterId: clusterId,
+		},
+		15*time.Minute,
+	)
 }
 
 func (cache *Elasticaches) nukeReplicationGroupMemberElasticacheCluster(clusterId *string) error {
-	logging.Debugf("Elasticache cluster Id: %s is a member of a replication group. Therefore, deleting its replication group", aws.StringValue(clusterId))
+	logging.Debugf("Elasticache cluster Id: %s is a member of a replication group. Therefore, deleting its replication group", aws.ToString(clusterId))
 
 	params := &elasticache.DeleteReplicationGroupInput{
 		ReplicationGroupId: clusterId,
 	}
-	_, err := cache.Client.DeleteReplicationGroupWithContext(cache.Context, params)
+	_, err := cache.Client.DeleteReplicationGroup(cache.Context, params)
 	if err != nil {
 		return err
 	}
 
-	waitErr := cache.Client.WaitUntilReplicationGroupDeletedWithContext(cache.Context, &elasticache.DescribeReplicationGroupsInput{
-		ReplicationGroupId: clusterId,
-	})
+	waiter := elasticache.NewReplicationGroupDeletedWaiter(cache.Client)
+	waitErr := waiter.Wait(
+		cache.Context,
+		&elasticache.DescribeReplicationGroupsInput{ReplicationGroupId: clusterId},
+		15*time.Minute,
+	)
 
 	if waitErr != nil {
 		return waitErr
 	}
 
-	logging.Debugf("Successfully deleted replication group Id: %s", aws.StringValue(clusterId))
+	logging.Debugf("Successfully deleted replication group Id: %s", aws.ToString(clusterId))
 
 	return nil
 }
@@ -175,7 +185,7 @@ func (cache *Elasticaches) nukeAll(clusterIds []*string) error {
 
 		// Record status of this resource
 		e := report.Entry{
-			Identifier:   aws.StringValue(clusterId),
+			Identifier:   aws.ToString(clusterId),
 			ResourceType: "Elasticache",
 			Error:        err,
 		}
@@ -200,7 +210,7 @@ type CouldNotLookupCacheClusterErr struct {
 }
 
 func (err CouldNotLookupCacheClusterErr) Error() string {
-	return fmt.Sprintf("Failed to lookup clusterId: %s", aws.StringValue(err.ClusterId))
+	return fmt.Sprintf("Failed to lookup clusterId: %s", aws.ToString(err.ClusterId))
 }
 
 /*
@@ -209,27 +219,30 @@ Elasticache Parameter Groups
 
 func (pg *ElasticacheParameterGroups) getAll(c context.Context, configObj config.Config) ([]*string, error) {
 	var paramGroupNames []*string
-	err := pg.Client.DescribeCacheParameterGroupsPages(
-		&elasticache.DescribeCacheParameterGroupsInput{},
-		func(page *elasticache.DescribeCacheParameterGroupsOutput, lastPage bool) bool {
-			for _, paramGroup := range page.CacheParameterGroups {
-				if pg.shouldInclude(paramGroup, configObj) {
-					paramGroupNames = append(paramGroupNames, paramGroup.CacheParameterGroupName)
-				}
+
+	paginator := elasticache.NewDescribeCacheParameterGroupsPaginator(pg.Client, &elasticache.DescribeCacheParameterGroupsInput{})
+	for paginator.HasMorePages() {
+		page, err := paginator.NextPage(c)
+		if err != nil {
+			return nil, goerrors.WithStackTrace(err)
+		}
+
+		for _, paramGroup := range page.CacheParameterGroups {
+			if pg.shouldInclude(&paramGroup, configObj) {
+				paramGroupNames = append(paramGroupNames, paramGroup.CacheParameterGroupName)
 			}
-			return !lastPage
-		},
-	)
+		}
+	}
 
-	return paramGroupNames, errors.WithStackTrace(err)
+	return paramGroupNames, nil
 }
 
-func (pg *ElasticacheParameterGroups) shouldInclude(paramGroup *elasticache.CacheParameterGroup, configObj config.Config) bool {
+func (pg *ElasticacheParameterGroups) shouldInclude(paramGroup *types.CacheParameterGroup, configObj config.Config) bool {
 	if paramGroup == nil {
 		return false
 	}
-	//Exclude AWS managed resources. user defined resources are unable to begin with "default."
-	if strings.HasPrefix(aws.StringValue(paramGroup.CacheParameterGroupName), "default.") {
+	// Exclude AWS managed resources. user defined resources are unable to begin with "default."
+	if strings.HasPrefix(aws.ToString(paramGroup.CacheParameterGroupName), "default.") {
 		return false
 	}
 
@@ -245,11 +258,11 @@ func (pg *ElasticacheParameterGroups) nukeAll(paramGroupNames []*string) error {
 	}
 	var deletedGroupNames []*string
 	for _, pgName := range paramGroupNames {
-		_, err := pg.Client.DeleteCacheParameterGroup(&elasticache.DeleteCacheParameterGroupInput{CacheParameterGroupName: pgName})
+		_, err := pg.Client.DeleteCacheParameterGroup(pg.Context, &elasticache.DeleteCacheParameterGroupInput{CacheParameterGroupName: pgName})
 
 		// Record status of this resource
 		e := report.Entry{
-			Identifier:   aws.StringValue(pgName),
+			Identifier:   aws.ToString(pgName),
 			ResourceType: "Elasticache Parameter Group",
 			Error:        err,
 		}
@@ -258,7 +271,7 @@ func (pg *ElasticacheParameterGroups) nukeAll(paramGroupNames []*string) error {
 			logging.Debugf("[Failed] %s", err)
 		} else {
 			deletedGroupNames = append(deletedGroupNames, pgName)
-			logging.Debugf("Deleted Elasticache parameter group: %s", aws.StringValue(pgName))
+			logging.Debugf("Deleted Elasticache parameter group: %s", aws.ToString(pgName))
 		}
 	}
 	logging.Debugf("[OK] %d Elasticache parameter groups deleted in %s", len(deletedGroupNames), pg.Region)
@@ -270,23 +283,25 @@ Elasticache Subnet Groups
 */
 func (sg *ElasticacheSubnetGroups) getAll(c context.Context, configObj config.Config) ([]*string, error) {
 	var subnetGroupNames []*string
-	err := sg.Client.DescribeCacheSubnetGroupsPages(
-		&elasticache.DescribeCacheSubnetGroupsInput{},
-		func(page *elasticache.DescribeCacheSubnetGroupsOutput, lastPage bool) bool {
-			for _, subnetGroup := range page.CacheSubnetGroups {
-				if !strings.Contains(*subnetGroup.CacheSubnetGroupName, "default") &&
-					configObj.ElasticacheSubnetGroups.ShouldInclude(config.ResourceValue{
-						Name: subnetGroup.CacheSubnetGroupName,
-					}) {
-					subnetGroupNames = append(subnetGroupNames, subnetGroup.CacheSubnetGroupName)
-				}
-			}
 
-			return !lastPage
-		},
-	)
+	paginator := elasticache.NewDescribeCacheSubnetGroupsPaginator(sg.Client, &elasticache.DescribeCacheSubnetGroupsInput{})
+	for paginator.HasMorePages() {
+		page, err := paginator.NextPage(c)
+		if err != nil {
+			return nil, goerrors.WithStackTrace(err)
+		}
+
+		for _, subnetGroup := range page.CacheSubnetGroups {
+			if !strings.Contains(*subnetGroup.CacheSubnetGroupName, "default") &&
+				configObj.ElasticacheSubnetGroups.ShouldInclude(config.ResourceValue{
+					Name: subnetGroup.CacheSubnetGroupName,
+				}) {
+				subnetGroupNames = append(subnetGroupNames, subnetGroup.CacheSubnetGroupName)
+			}
+		}
+	}
 
-	return subnetGroupNames, errors.WithStackTrace(err)
+	return subnetGroupNames, nil
 }
 
 func (sg *ElasticacheSubnetGroups) nukeAll(subnetGroupNames []*string) error {
@@ -296,11 +311,11 @@ func (sg *ElasticacheSubnetGroups) nukeAll(subnetGroupNames []*string) error {
 	}
 	var deletedGroupNames []*string
 	for _, sgName := range subnetGroupNames {
-		_, err := sg.Client.DeleteCacheSubnetGroup(&elasticache.DeleteCacheSubnetGroupInput{CacheSubnetGroupName: sgName})
+		_, err := sg.Client.DeleteCacheSubnetGroup(sg.Context, &elasticache.DeleteCacheSubnetGroupInput{CacheSubnetGroupName: sgName})
 
 		// Record status of this resource
 		e := report.Entry{
-			Identifier:   aws.StringValue(sgName),
+			Identifier:   aws.ToString(sgName),
 			ResourceType: "Elasticache Subnet Group",
 			Error:        err,
 		}
@@ -309,7 +324,7 @@ func (sg *ElasticacheSubnetGroups) nukeAll(subnetGroupNames []*string) error {
 			logging.Debugf("[Failed] %s", err)
 		} else {
 			deletedGroupNames = append(deletedGroupNames, sgName)
-			logging.Debugf("Deleted Elasticache subnet group: %s", aws.StringValue(sgName))
+			logging.Debugf("Deleted Elasticache subnet group: %s", aws.ToString(sgName))
 		}
 	}
 	logging.Debugf("[OK] %d Elasticache subnet groups deleted in %s", len(deletedGroupNames), sg.Region)
diff --git a/aws/resources/elasticache_types.go b/aws/resources/elasticache_types.go
index 5790312..9d14b62 100644
--- a/aws/resources/elasticache_types.go
+++ b/aws/resources/elasticache_types.go
@@ -3,26 +3,33 @@ package resources
 import (
 	"context"
 
-	awsgo "github.com/aws/aws-sdk-go/aws"
-	"github.com/aws/aws-sdk-go/aws/session"
-	"github.com/aws/aws-sdk-go/service/elasticache"
-	"github.com/aws/aws-sdk-go/service/elasticache/elasticacheiface"
+	"github.com/aws/aws-sdk-go-v2/aws"
+	"github.com/aws/aws-sdk-go-v2/service/elasticache"
 	"github.com/gruntwork-io/cloud-nuke/config"
 	"github.com/gruntwork-io/go-commons/errors"
 )
 
+type ElasticachesAPI interface {
+	DescribeReplicationGroups(ctx context.Context, params *elasticache.DescribeReplicationGroupsInput, optFns ...func(*elasticache.Options)) (*elasticache.DescribeReplicationGroupsOutput, error)
+	DescribeCacheClusters(ctx context.Context, params *elasticache.DescribeCacheClustersInput, optFns ...func(*elasticache.Options)) (*elasticache.DescribeCacheClustersOutput, error)
+	DeleteCacheCluster(ctx context.Context, params *elasticache.DeleteCacheClusterInput, optFns ...func(*elasticache.Options)) (*elasticache.DeleteCacheClusterOutput, error)
+	DeleteReplicationGroup(ctx context.Context, params *elasticache.DeleteReplicationGroupInput, optFns ...func(*elasticache.Options)) (*elasticache.DeleteReplicationGroupOutput, error)
+}
+
 // Elasticaches - represents all Elasticache clusters
 type Elasticaches struct {
 	BaseAwsResource
-	Client     elasticacheiface.ElastiCacheAPI
+	Client     ElasticachesAPI
 	Region     string
 	ClusterIds []string
 }
 
-func (cache *Elasticaches) Init(session *session.Session) {
-	cache.Client = elasticache.New(session)
+func (cache *Elasticaches) InitV2(cfg aws.Config) {
+	cache.Client = elasticache.NewFromConfig(cfg)
 }
 
+func (cache *Elasticaches) IsUsingV2() bool { return true }
+
 // ResourceName - the simple name of the aws resource
 func (cache *Elasticaches) ResourceName() string {
 	return "elasticache"
@@ -48,13 +55,13 @@ func (cache *Elasticaches) GetAndSetIdentifiers(c context.Context, configObj con
 		return nil, err
 	}
 
-	cache.ClusterIds = awsgo.StringValueSlice(identifiers)
+	cache.ClusterIds = aws.ToStringSlice(identifiers)
 	return cache.ClusterIds, nil
 }
 
 // Nuke - nuke 'em all!!!
 func (cache *Elasticaches) Nuke(identifiers []string) error {
-	if err := cache.nukeAll(awsgo.StringSlice(identifiers)); err != nil {
+	if err := cache.nukeAll(aws.StringSlice(identifiers)); err != nil {
 		return errors.WithStackTrace(err)
 	}
 
@@ -64,18 +71,24 @@ func (cache *Elasticaches) Nuke(identifiers []string) error {
 /*
 Elasticache Parameter Groups
 */
+type ElasticacheParameterGroupsAPI interface {
+	DescribeCacheParameterGroups(ctx context.Context, params *elasticache.DescribeCacheParameterGroupsInput, optFns ...func(*elasticache.Options)) (*elasticache.DescribeCacheParameterGroupsOutput, error)
+	DeleteCacheParameterGroup(ctx context.Context, params *elasticache.DeleteCacheParameterGroupInput, optFns ...func(*elasticache.Options)) (*elasticache.DeleteCacheParameterGroupOutput, error)
+}
 
 type ElasticacheParameterGroups struct {
 	BaseAwsResource
-	Client     elasticacheiface.ElastiCacheAPI
+	Client     ElasticacheParameterGroupsAPI
 	Region     string
 	GroupNames []string
 }
 
-func (pg *ElasticacheParameterGroups) Init(session *session.Session) {
-	pg.Client = elasticache.New(session)
+func (pg *ElasticacheParameterGroups) InitV2(cfg aws.Config) {
+	pg.Client = elasticache.NewFromConfig(cfg)
 }
 
+func (pg *ElasticacheParameterGroups) IsUsingV2() bool { return true }
+
 // ResourceName - the simple name of the aws resource
 func (pg *ElasticacheParameterGroups) ResourceName() string {
 	return "elasticacheParameterGroups"
@@ -97,13 +110,13 @@ func (pg *ElasticacheParameterGroups) GetAndSetIdentifiers(c context.Context, co
 		return nil, err
 	}
 
-	pg.GroupNames = awsgo.StringValueSlice(identifiers)
+	pg.GroupNames = aws.ToStringSlice(identifiers)
 	return pg.GroupNames, nil
 }
 
 // Nuke - nuke 'em all!!!
 func (pg *ElasticacheParameterGroups) Nuke(identifiers []string) error {
-	if err := pg.nukeAll(awsgo.StringSlice(identifiers)); err != nil {
+	if err := pg.nukeAll(aws.StringSlice(identifiers)); err != nil {
 		return errors.WithStackTrace(err)
 	}
 
@@ -113,18 +126,24 @@ func (pg *ElasticacheParameterGroups) Nuke(identifiers []string) error {
 /*
 Elasticache Subnet Groups
 */
+type ElasticacheSubnetGroupsAPI interface {
+	DescribeCacheSubnetGroups(ctx context.Context, params *elasticache.DescribeCacheSubnetGroupsInput, optFns ...func(*elasticache.Options)) (*elasticache.DescribeCacheSubnetGroupsOutput, error)
+	DeleteCacheSubnetGroup(ctx context.Context, params *elasticache.DeleteCacheSubnetGroupInput, optFns ...func(*elasticache.Options)) (*elasticache.DeleteCacheSubnetGroupOutput, error)
+}
 
 type ElasticacheSubnetGroups struct {
 	BaseAwsResource
-	Client     elasticacheiface.ElastiCacheAPI
+	Client     ElasticacheSubnetGroupsAPI
 	Region     string
 	GroupNames []string
 }
 
-func (sg *ElasticacheSubnetGroups) Init(session *session.Session) {
-	sg.Client = elasticache.New(session)
+func (sg *ElasticacheSubnetGroups) InitV2(cfg aws.Config) {
+	sg.Client = elasticache.NewFromConfig(cfg)
 }
 
+func (sg *ElasticacheSubnetGroups) IsUsingV2() bool { return true }
+
 func (sg *ElasticacheSubnetGroups) ResourceName() string {
 	return "elasticacheSubnetGroups"
 }
@@ -145,13 +164,13 @@ func (sg *ElasticacheSubnetGroups) GetAndSetIdentifiers(c context.Context, confi
 		return nil, err
 	}
 
-	sg.GroupNames = awsgo.StringValueSlice(identifiers)
+	sg.GroupNames = aws.ToStringSlice(identifiers)
 	return sg.GroupNames, nil
 }
 
 // Nuke - nuke 'em all!!!
 func (sg *ElasticacheSubnetGroups) Nuke(identifiers []string) error {
-	if err := sg.nukeAll(awsgo.StringSlice(identifiers)); err != nil {
+	if err := sg.nukeAll(aws.StringSlice(identifiers)); err != nil {
 		return errors.WithStackTrace(err)
 	}
 
diff --git a/aws/resources/elb.go b/aws/resources/elb.go
index be15253..52262b4 100644
--- a/aws/resources/elb.go
+++ b/aws/resources/elb.go
@@ -4,27 +4,25 @@ import (
 	"context"
 	"time"
 
+	"github.com/aws/aws-sdk-go-v2/aws"
+	"github.com/aws/aws-sdk-go-v2/service/elasticloadbalancing"
 	"github.com/gruntwork-io/cloud-nuke/config"
-
-	"github.com/aws/aws-sdk-go/aws"
-	"github.com/aws/aws-sdk-go/aws/awserr"
-	"github.com/aws/aws-sdk-go/service/elb"
 	"github.com/gruntwork-io/cloud-nuke/logging"
 	"github.com/gruntwork-io/cloud-nuke/report"
 	"github.com/gruntwork-io/go-commons/errors"
 )
 
-func (balancer *LoadBalancers) waitUntilElbDeleted(input *elb.DescribeLoadBalancersInput) error {
+func (balancer *LoadBalancers) waitUntilElbDeleted(input *elasticloadbalancing.DescribeLoadBalancersInput) error {
 	for i := 0; i < 30; i++ {
-		_, err := balancer.Client.DescribeLoadBalancersWithContext(balancer.Context, input)
+		output, err := balancer.Client.DescribeLoadBalancers(balancer.Context, input)
 		if err != nil {
-			if awsErr, isAwsErr := err.(awserr.Error); isAwsErr && awsErr.Code() == "LoadBalancerNotFound" {
-				return nil
-			}
-
 			return err
 		}
 
+		if len(output.LoadBalancerDescriptions) == 0 {
+			return nil
+		}
+
 		time.Sleep(1 * time.Second)
 		logging.Debug("Waiting for ELB to be deleted")
 	}
@@ -34,7 +32,7 @@ func (balancer *LoadBalancers) waitUntilElbDeleted(input *elb.DescribeLoadBalanc
 
 // Returns a formatted string of ELB names
 func (balancer *LoadBalancers) getAll(c context.Context, configObj config.Config) ([]*string, error) {
-	result, err := balancer.Client.DescribeLoadBalancersWithContext(balancer.Context, &elb.DescribeLoadBalancersInput{})
+	result, err := balancer.Client.DescribeLoadBalancers(balancer.Context, &elasticloadbalancing.DescribeLoadBalancersInput{})
 	if err != nil {
 		return nil, errors.WithStackTrace(err)
 	}
@@ -63,15 +61,15 @@ func (balancer *LoadBalancers) nukeAll(names []*string) error {
 	var deletedNames []*string
 
 	for _, name := range names {
-		params := &elb.DeleteLoadBalancerInput{
+		params := &elasticloadbalancing.DeleteLoadBalancerInput{
 			LoadBalancerName: name,
 		}
 
-		_, err := balancer.Client.DeleteLoadBalancerWithContext(balancer.Context, params)
+		_, err := balancer.Client.DeleteLoadBalancer(balancer.Context, params)
 
 		// Record status of this resource
 		e := report.Entry{
-			Identifier:   aws.StringValue(name),
+			Identifier:   aws.ToString(name),
 			ResourceType: "Load Balancer (v1)",
 			Error:        err,
 		}
@@ -86,8 +84,8 @@ func (balancer *LoadBalancers) nukeAll(names []*string) error {
 	}
 
 	if len(deletedNames) > 0 {
-		err := balancer.waitUntilElbDeleted(&elb.DescribeLoadBalancersInput{
-			LoadBalancerNames: deletedNames,
+		err := balancer.waitUntilElbDeleted(&elasticloadbalancing.DescribeLoadBalancersInput{
+			LoadBalancerNames: aws.ToStringSlice(deletedNames),
 		})
 		if err != nil {
 			logging.Debugf("[Failed] %s", err)
diff --git a/aws/resources/elb_types.go b/aws/resources/elb_types.go
index 3360ce8..34ec278 100644
--- a/aws/resources/elb_types.go
+++ b/aws/resources/elb_types.go
@@ -3,26 +3,31 @@ package resources
 import (
 	"context"
 
-	awsgo "github.com/aws/aws-sdk-go/aws"
-	"github.com/aws/aws-sdk-go/aws/session"
-	"github.com/aws/aws-sdk-go/service/elb"
-	"github.com/aws/aws-sdk-go/service/elb/elbiface"
+	"github.com/aws/aws-sdk-go-v2/aws"
+	"github.com/aws/aws-sdk-go-v2/service/elasticloadbalancing"
 	"github.com/gruntwork-io/cloud-nuke/config"
 	"github.com/gruntwork-io/go-commons/errors"
 )
 
+type LoadBalancersAPI interface {
+	DescribeLoadBalancers(ctx context.Context, params *elasticloadbalancing.DescribeLoadBalancersInput, optFns ...func(*elasticloadbalancing.Options)) (*elasticloadbalancing.DescribeLoadBalancersOutput, error)
+	DeleteLoadBalancer(ctx context.Context, params *elasticloadbalancing.DeleteLoadBalancerInput, optFns ...func(*elasticloadbalancing.Options)) (*elasticloadbalancing.DeleteLoadBalancerOutput, error)
+}
+
 // LoadBalancers - represents all load balancers
 type LoadBalancers struct {
 	BaseAwsResource
-	Client elbiface.ELBAPI
+	Client LoadBalancersAPI
 	Region string
 	Names  []string
 }
 
-func (balancer *LoadBalancers) Init(session *session.Session) {
-	balancer.Client = elb.New(session)
+func (balancer *LoadBalancers) InitV2(cfg aws.Config) {
+	balancer.Client = elasticloadbalancing.NewFromConfig(cfg)
 }
 
+func (balancer *LoadBalancers) IsUsingV2() bool { return true }
+
 // ResourceName - the simple name of the aws resource
 func (balancer *LoadBalancers) ResourceName() string {
 	return "elb"
@@ -48,13 +53,13 @@ func (balancer *LoadBalancers) GetAndSetIdentifiers(c context.Context, configObj
 		return nil, err
 	}
 
-	balancer.Names = awsgo.StringValueSlice(identifiers)
+	balancer.Names = aws.ToStringSlice(identifiers)
 	return balancer.Names, nil
 }
 
 // Nuke - nuke 'em all!!!
 func (balancer *LoadBalancers) Nuke(identifiers []string) error {
-	if err := balancer.nukeAll(awsgo.StringSlice(identifiers)); err != nil {
+	if err := balancer.nukeAll(aws.StringSlice(identifiers)); err != nil {
 		return errors.WithStackTrace(err)
 	}
 
diff --git a/aws/resources/elbv2.go b/aws/resources/elbv2.go
index eb24a67..b4b3406 100644
--- a/aws/resources/elbv2.go
+++ b/aws/resources/elbv2.go
@@ -2,18 +2,19 @@ package resources
 
 import (
 	"context"
+	"time"
 
-	"github.com/aws/aws-sdk-go/aws"
-	"github.com/aws/aws-sdk-go/service/elbv2"
+	"github.com/aws/aws-sdk-go-v2/aws"
+	"github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2"
 	"github.com/gruntwork-io/cloud-nuke/config"
 	"github.com/gruntwork-io/cloud-nuke/logging"
 	"github.com/gruntwork-io/cloud-nuke/report"
 	"github.com/gruntwork-io/go-commons/errors"
 )
 
-// Returns a formatted string of ELBv2 Arns
+// Returns a formatted string of ELBv2 ARNs
 func (balancer *LoadBalancersV2) getAll(c context.Context, configObj config.Config) ([]*string, error) {
-	result, err := balancer.Client.DescribeLoadBalancersWithContext(balancer.Context, &elbv2.DescribeLoadBalancersInput{})
+	result, err := balancer.Client.DescribeLoadBalancers(balancer.Context, &elasticloadbalancingv2.DescribeLoadBalancersInput{})
 	if err != nil {
 		return nil, errors.WithStackTrace(err)
 	}
@@ -42,15 +43,15 @@ func (balancer *LoadBalancersV2) nukeAll(arns []*string) error {
 	var deletedArns []*string
 
 	for _, arn := range arns {
-		params := &elbv2.DeleteLoadBalancerInput{
+		params := &elasticloadbalancingv2.DeleteLoadBalancerInput{
 			LoadBalancerArn: arn,
 		}
 
-		_, err := balancer.Client.DeleteLoadBalancerWithContext(balancer.Context, params)
+		_, err := balancer.Client.DeleteLoadBalancer(balancer.Context, params)
 
 		// Record status of this resource
 		e := report.Entry{
-			Identifier:   aws.StringValue(arn),
+			Identifier:   aws.ToString(arn),
 			ResourceType: "Load Balancer (v2)",
 			Error:        err,
 		}
@@ -65,9 +66,10 @@ func (balancer *LoadBalancersV2) nukeAll(arns []*string) error {
 	}
 
 	if len(deletedArns) > 0 {
-		err := balancer.Client.WaitUntilLoadBalancersDeletedWithContext(balancer.Context, &elbv2.DescribeLoadBalancersInput{
-			LoadBalancerArns: deletedArns,
-		})
+		waiter := elasticloadbalancingv2.NewLoadBalancersDeletedWaiter(balancer.Client)
+		err := waiter.Wait(balancer.Context, &elasticloadbalancingv2.DescribeLoadBalancersInput{
+			LoadBalancerArns: aws.ToStringSlice(deletedArns),
+		}, 15*time.Minute)
 		if err != nil {
 			logging.Debugf("[Failed] %s", err)
 			return errors.WithStackTrace(err)
diff --git a/aws/resources/elbv2_types.go b/aws/resources/elbv2_types.go
index 55290fd..171a977 100644
--- a/aws/resources/elbv2_types.go
+++ b/aws/resources/elbv2_types.go
@@ -3,26 +3,31 @@ package resources
 import (
 	"context"
 
-	awsgo "github.com/aws/aws-sdk-go/aws"
-	"github.com/aws/aws-sdk-go/aws/session"
-	"github.com/aws/aws-sdk-go/service/elbv2"
-	"github.com/aws/aws-sdk-go/service/elbv2/elbv2iface"
+	"github.com/aws/aws-sdk-go-v2/aws"
+	"github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2"
 	"github.com/gruntwork-io/cloud-nuke/config"
 	"github.com/gruntwork-io/go-commons/errors"
 )
 
+type LoadBalancersV2API interface {
+	DescribeLoadBalancers(ctx context.Context, params *elasticloadbalancingv2.DescribeLoadBalancersInput, optFns ...func(*elasticloadbalancingv2.Options)) (*elasticloadbalancingv2.DescribeLoadBalancersOutput, error)
+	DeleteLoadBalancer(ctx context.Context, params *elasticloadbalancingv2.DeleteLoadBalancerInput, optFns ...func(*elasticloadbalancingv2.Options)) (*elasticloadbalancingv2.DeleteLoadBalancerOutput, error)
+}
+
 // LoadBalancersV2 - represents all load balancers
 type LoadBalancersV2 struct {
 	BaseAwsResource
-	Client elbv2iface.ELBV2API
+	Client LoadBalancersV2API
 	Region string
 	Arns   []string
 }
 
-func (balancer *LoadBalancersV2) Init(session *session.Session) {
-	balancer.Client = elbv2.New(session)
+func (balancer *LoadBalancersV2) InitV2(cfg aws.Config) {
+	balancer.Client = elasticloadbalancingv2.NewFromConfig(cfg)
 }
 
+func (balancer *LoadBalancersV2) IsUsingV2() bool { return true }
+
 // ResourceName - the simple name of the aws resource
 func (balancer *LoadBalancersV2) ResourceName() string {
 	return "elbv2"
@@ -48,13 +53,13 @@ func (balancer *LoadBalancersV2) GetAndSetIdentifiers(c context.Context, configO
 		return nil, err
 	}
 
-	balancer.Arns = awsgo.StringValueSlice(identifiers)
+	balancer.Arns = aws.ToStringSlice(identifiers)
 	return balancer.Arns, nil
 }
 
 // Nuke - nuke 'em all!!!
 func (balancer *LoadBalancersV2) Nuke(identifiers []string) error {
-	if err := balancer.nukeAll(awsgo.StringSlice(identifiers)); err != nil {
+	if err := balancer.nukeAll(aws.StringSlice(identifiers)); err != nil {
 		return errors.WithStackTrace(err)
 	}
 
diff --git a/aws/resources/guardduty.go b/aws/resources/guardduty.go
index 2b57b85..e131c39 100644
--- a/aws/resources/guardduty.go
+++ b/aws/resources/guardduty.go
@@ -3,8 +3,8 @@ package resources
 import (
 	"context"
 
-	"github.com/aws/aws-sdk-go/aws"
-	"github.com/aws/aws-sdk-go/service/guardduty"
+	"github.com/aws/aws-sdk-go-v2/aws"
+	"github.com/aws/aws-sdk-go-v2/service/guardduty"
 	"github.com/gruntwork-io/cloud-nuke/config"
 	"github.com/gruntwork-io/cloud-nuke/logging"
 	"github.com/gruntwork-io/cloud-nuke/report"
@@ -19,28 +19,27 @@ type DetectorOutputWithID struct {
 
 func (gd *GuardDuty) getAll(c context.Context, configObj config.Config) ([]*string, error) {
 	var detectorIdsToInclude []*string
-	var detectorIds []*string
-	err := gd.Client.ListDetectorsPagesWithContext(gd.Context, &guardduty.ListDetectorsInput{}, func(page *guardduty.ListDetectorsOutput, lastPage bool) bool {
-		detectorIds = append(detectorIds, page.DetectorIds...)
-		return !lastPage
-	})
-	if err != nil {
-		return nil, errors.WithStackTrace(err)
-	}
-
-	// Due to the ListDetectors method only returning the Ids of found detectors, we need to further enrich our data about
-	// each detector with a separate call to GetDetector for metadata including when it was created, which we need to make the
-	// determination about whether or not the given detector should be included
-	for _, detectorId := range detectorIds {
-		detector, err := gd.Client.GetDetectorWithContext(gd.Context, &guardduty.GetDetectorInput{
-			DetectorId: detectorId,
-		})
+	paginator := guardduty.NewListDetectorsPaginator(gd.Client, &guardduty.ListDetectorsInput{})
+	for paginator.HasMorePages() {
+		page, err := paginator.NextPage(c)
 		if err != nil {
 			return nil, errors.WithStackTrace(err)
 		}
 
-		if gd.shouldInclude(detector, detectorId, configObj) {
-			detectorIdsToInclude = append(detectorIdsToInclude, detectorId)
+		// Due to the ListDetectors method only returning the Ids of found detectors, we need to further enrich our data about
+		// each detector with a separate call to GetDetector for metadata including when it was created, which we need to make the
+		// determination about whether or not the given detector should be included
+		for _, detectorId := range page.DetectorIds {
+			detector, err := gd.Client.GetDetector(gd.Context, &guardduty.GetDetectorInput{
+				DetectorId: aws.String(detectorId),
+			})
+			if err != nil {
+				return nil, errors.WithStackTrace(err)
+			}
+
+			if gd.shouldInclude(detector, aws.String(detectorId), configObj) {
+				detectorIdsToInclude = append(detectorIdsToInclude, aws.String(detectorId))
+			}
 		}
 	}
 
@@ -65,14 +64,14 @@ func (gd *GuardDuty) nukeAll(detectorIds []string) error {
 
 	logging.Debugf("Deleting all GuardDuty detectors in region %s", gd.Region)
 
-	deletedIds := []string{}
+	var deletedIds []string
 
 	for _, detectorId := range detectorIds {
 		params := &guardduty.DeleteDetectorInput{
 			DetectorId: aws.String(detectorId),
 		}
 
-		_, err := gd.Client.DeleteDetectorWithContext(gd.Context, params)
+		_, err := gd.Client.DeleteDetector(gd.Context, params)
 
 		// Record status of this resource
 		e := report.Entry{
diff --git a/aws/resources/guardduty_types.go b/aws/resources/guardduty_types.go
index 9fe20b2..c3a41f9 100644
--- a/aws/resources/guardduty_types.go
+++ b/aws/resources/guardduty_types.go
@@ -3,24 +3,30 @@ package resources
 import (
 	"context"
 
-	awsgo "github.com/aws/aws-sdk-go/aws"
-	"github.com/aws/aws-sdk-go/aws/session"
-	"github.com/aws/aws-sdk-go/service/guardduty"
-	"github.com/aws/aws-sdk-go/service/guardduty/guarddutyiface"
+	"github.com/aws/aws-sdk-go-v2/aws"
+	"github.com/aws/aws-sdk-go-v2/service/guardduty"
 	"github.com/gruntwork-io/cloud-nuke/config"
 )
 
+type GuardDutyAPI interface {
+	GetDetector(ctx context.Context, params *guardduty.GetDetectorInput, optFns ...func(*guardduty.Options)) (*guardduty.GetDetectorOutput, error)
+	DeleteDetector(ctx context.Context, params *guardduty.DeleteDetectorInput, optFns ...func(*guardduty.Options)) (*guardduty.DeleteDetectorOutput, error)
+	ListDetectors(ctx context.Context, params *guardduty.ListDetectorsInput, optFns ...func(*guardduty.Options)) (*guardduty.ListDetectorsOutput, error)
+}
+
 type GuardDuty struct {
 	BaseAwsResource
-	Client      guarddutyiface.GuardDutyAPI
+	Client      GuardDutyAPI
 	Region      string
 	detectorIds []string
 }
 
-func (gd *GuardDuty) Init(session *session.Session) {
-	gd.Client = guardduty.New(session)
+func (gd *GuardDuty) InitV2(cfg aws.Config) {
+	gd.Client = guardduty.NewFromConfig(cfg)
 }
 
+func (gd *GuardDuty) IsUsingV2() bool { return true }
+
 func (gd *GuardDuty) ResourceName() string {
 	return "guardduty"
 }
@@ -43,7 +49,7 @@ func (gd *GuardDuty) GetAndSetIdentifiers(c context.Context, configObj config.Co
 		return nil, err
 	}
 
-	gd.detectorIds = awsgo.StringValueSlice(identifiers)
+	gd.detectorIds = aws.ToStringSlice(identifiers)
 	return gd.detectorIds, nil
 }
 
diff --git a/go.mod b/go.mod
index 870544a..98f3e04 100644
--- a/go.mod
+++ b/go.mod
@@ -5,16 +5,16 @@ go 1.21
 require (
 	github.com/aws/aws-sdk-go v1.49.13
 	github.com/aws/aws-sdk-go-v2 v1.32.3
-	github.com/aws/aws-sdk-go-v2/config v1.27.24
-	github.com/aws/aws-sdk-go-v2/credentials v1.17.24
+	github.com/aws/aws-sdk-go-v2/config v1.28.1
+	github.com/aws/aws-sdk-go-v2/credentials v1.17.42
 	github.com/aws/aws-sdk-go-v2/service/accessanalyzer v1.34.3
 	github.com/aws/aws-sdk-go-v2/service/acm v1.30.3
 	github.com/aws/aws-sdk-go-v2/service/acmpca v1.37.4
-	github.com/aws/aws-sdk-go-v2/service/amp v1.27.1
+	github.com/aws/aws-sdk-go-v2/service/amp v1.30.0
 	github.com/aws/aws-sdk-go-v2/service/apigateway v1.27.3
 	github.com/aws/aws-sdk-go-v2/service/apigatewayv2 v1.24.3
 	github.com/aws/aws-sdk-go-v2/service/apprunner v1.32.3
-	github.com/aws/aws-sdk-go-v2/service/autoscaling v1.23.16
+	github.com/aws/aws-sdk-go-v2/service/autoscaling v1.47.0
 	github.com/aws/aws-sdk-go-v2/service/backup v1.39.4
 	github.com/aws/aws-sdk-go-v2/service/cloudtrail v1.44.3
 	github.com/aws/aws-sdk-go-v2/service/cloudwatch v1.42.3
@@ -23,12 +23,22 @@ require (
 	github.com/aws/aws-sdk-go-v2/service/configservice v1.50.3
 	github.com/aws/aws-sdk-go-v2/service/datasync v1.43.0
 	github.com/aws/aws-sdk-go-v2/service/dynamodb v1.36.3
-	github.com/aws/aws-sdk-go-v2/service/ec2 v1.185.0
-	github.com/aws/aws-sdk-go-v2/service/eventbridge v1.33.7
-	github.com/aws/aws-sdk-go-v2/service/scheduler v1.10.7
-	github.com/aws/aws-sdk-go-v2/service/sns v1.32.3
-	github.com/aws/aws-sdk-go-v2/service/sqs v1.35.3
+	github.com/aws/aws-sdk-go-v2/service/ec2 v1.187.0
+	github.com/aws/aws-sdk-go-v2/service/ecr v1.36.3
+	github.com/aws/aws-sdk-go-v2/service/ecs v1.49.0
+	github.com/aws/aws-sdk-go-v2/service/efs v1.33.3
+	github.com/aws/aws-sdk-go-v2/service/eks v1.51.1
+	github.com/aws/aws-sdk-go-v2/service/elasticache v1.43.1
+	github.com/aws/aws-sdk-go-v2/service/elasticbeanstalk v1.28.3
+	github.com/aws/aws-sdk-go-v2/service/elasticloadbalancing v1.28.3
+	github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2 v1.41.0
+	github.com/aws/aws-sdk-go-v2/service/eventbridge v1.35.3
+	github.com/aws/aws-sdk-go-v2/service/guardduty v1.50.1
+	github.com/aws/aws-sdk-go-v2/service/scheduler v1.12.3
+	github.com/aws/aws-sdk-go-v2/service/sns v1.33.3
+	github.com/aws/aws-sdk-go-v2/service/sqs v1.36.3
 	github.com/aws/aws-sdk-go-v2/service/vpclattice v1.12.3
+	github.com/aws/smithy-go v1.22.0
 	github.com/charmbracelet/lipgloss v0.6.0
 	github.com/go-errors/errors v1.4.2
 	github.com/gruntwork-io/go-commons v0.17.0
@@ -45,18 +55,17 @@ require (
 	atomicgo.dev/cursor v0.1.1 // indirect
 	atomicgo.dev/keyboard v0.2.8 // indirect
 	github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.6 // indirect
-	github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.9 // indirect
+	github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.18 // indirect
 	github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.22 // indirect
 	github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.22 // indirect
-	github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 // indirect
-	github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.17 // indirect
+	github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 // indirect
+	github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.22 // indirect
 	github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.0 // indirect
 	github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.10.3 // indirect
-	github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.2 // indirect
-	github.com/aws/aws-sdk-go-v2/service/sso v1.22.1 // indirect
-	github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.2 // indirect
-	github.com/aws/aws-sdk-go-v2/service/sts v1.30.1 // indirect
-	github.com/aws/smithy-go v1.22.0 // indirect
+	github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.3 // indirect
+	github.com/aws/aws-sdk-go-v2/service/sso v1.24.3 // indirect
+	github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.3 // indirect
+	github.com/aws/aws-sdk-go-v2/service/sts v1.32.3 // indirect
 	github.com/containerd/console v1.0.3 // indirect
 	github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
 	github.com/davecgh/go-spew v1.1.1 // indirect
diff --git a/go.sum b/go.sum
index 38ea0dc..7e6777f 100644
--- a/go.sum
+++ b/go.sum
@@ -22,10 +22,16 @@ github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.6 h1:pT3hpW0cOHRJx8Y0
 github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.6/go.mod h1:j/I2++U0xX+cr44QjHay4Cvxj6FUbnxrgmqN3H1jTZA=
 github.com/aws/aws-sdk-go-v2/config v1.27.24 h1:NM9XicZ5o1CBU/MZaHwFtimRpWx9ohAUAqkG6AqSqPo=
 github.com/aws/aws-sdk-go-v2/config v1.27.24/go.mod h1:aXzi6QJTuQRVVusAO8/NxpdTeTyr/wRcybdDtfUwJSs=
+github.com/aws/aws-sdk-go-v2/config v1.28.1 h1:oxIvOUXy8x0U3fR//0eq+RdCKimWI900+SV+10xsCBw=
+github.com/aws/aws-sdk-go-v2/config v1.28.1/go.mod h1:bRQcttQJiARbd5JZxw6wG0yIK3eLeSCPdg6uqmmlIiI=
 github.com/aws/aws-sdk-go-v2/credentials v1.17.24 h1:YclAsrnb1/GTQNt2nzv+756Iw4mF8AOzcDfweWwwm/M=
 github.com/aws/aws-sdk-go-v2/credentials v1.17.24/go.mod h1:Hld7tmnAkoBQdTMNYZGzztzKRdA4fCdn9L83LOoigac=
+github.com/aws/aws-sdk-go-v2/credentials v1.17.42 h1:sBP0RPjBU4neGpIYyx8mkU2QqLPl5u9cmdTWVzIpHkM=
+github.com/aws/aws-sdk-go-v2/credentials v1.17.42/go.mod h1:FwZBfU530dJ26rv9saAbxa9Ej3eF/AK0OAY86k13n4M=
 github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.9 h1:Aznqksmd6Rfv2HQN9cpqIV/lQRMaIpJkLLaJ1ZI76no=
 github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.9/go.mod h1:WQr3MY7AxGNxaqAtsDWn+fBxmd4XvLkzeqQ8P1VM0/w=
+github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.18 h1:68jFVtt3NulEzojFesM/WVarlFpCaXLKaBxDpzkQ9OQ=
+github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.18/go.mod h1:Fjnn5jQVIo6VyedMc0/EhPpfNlPl7dHV916O6B+49aE=
 github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.23/go.mod h1:2DFxAQ9pfIRy0imBCJv+vZ2X6RKxves6fbnEuSry6b4=
 github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.22 h1:Jw50LwEkVjuVzE1NzkhNKkBf9cRN7MtE1F/b2cOKTUM=
 github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.22/go.mod h1:Y/SmAyPcOTmpeVaWSzSKiILfXTVJwrGmYZhcRbhWuEY=
@@ -34,8 +40,12 @@ github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.22 h1:981MHwBaRZM7+9QSR6
 github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.22/go.mod h1:1RA1+aBEfn+CAB/Mh0MB6LsdCYCnjZm7tKXtnk499ZQ=
 github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 h1:hT8rVHwugYE2lEfdFE0QWVo81lF7jMrYJVDWI+f+VxU=
 github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0/go.mod h1:8tu/lYfQfFe6IGnaOdrpVgEL2IrrDOf6/m9RQum4NkY=
+github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 h1:VaRN3TlFdd6KxX1x3ILT5ynH6HvKgqdiXoTxAF4HQcQ=
+github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1/go.mod h1:FbtygfRFze9usAadmnGJNc8KsP346kEe+y2/oyhGAGc=
 github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.17 h1:Roo69qTpfu8OlJ2Tb7pAYVuF0CpuUMB0IYWwYP/4DZM=
 github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.17/go.mod h1:NcWPxQzGM1USQggaTVwz6VpqMZPX1CvDJLDh6jnOCa4=
+github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.22 h1:yV+hCAHZZYJQcwAaszoBNwLbPItHvApxT0kVIw6jRgs=
+github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.22/go.mod h1:kbR1TL8llqB1eGnVbybcA4/wgScxdylOdyAd51yxPdw=
 github.com/aws/aws-sdk-go-v2/service/accessanalyzer v1.34.3 h1:ScJw+8v6RPTJbuWxowSiUw8xdPL0aQOAbakC6mF1uZU=
 github.com/aws/aws-sdk-go-v2/service/accessanalyzer v1.34.3/go.mod h1:PTv5/X1+6atCKR/vK3kbm9Ra/zzX/T/92Y/4MuL6ArU=
 github.com/aws/aws-sdk-go-v2/service/acm v1.30.3 h1:/7wq5haORYzJUkAbD9Hh4/SGiwupLhPdGqIzf+taLOA=
@@ -44,6 +54,8 @@ github.com/aws/aws-sdk-go-v2/service/acmpca v1.37.4 h1:uWqTNc//8pMepB0qUzu+r13Qy
 github.com/aws/aws-sdk-go-v2/service/acmpca v1.37.4/go.mod h1:WVF7A3ipjS/vpzOY09xJDeH8ja+rDbnl5u2mL26rt60=
 github.com/aws/aws-sdk-go-v2/service/amp v1.27.1 h1:va9j7MGA8jBlQs9KujMlkSdnC26TuEJXv7ywnFjmTZ8=
 github.com/aws/aws-sdk-go-v2/service/amp v1.27.1/go.mod h1:QhmX7qjomjuHJjCJbW+QRdaCBM42v1eAbWvBVFrT1Vw=
+github.com/aws/aws-sdk-go-v2/service/amp v1.30.0 h1:1AQM/Lo024FKGTW/iwIDQHV8+5j8/h0iabYm+4jB5Bo=
+github.com/aws/aws-sdk-go-v2/service/amp v1.30.0/go.mod h1:4OQEJHTg0Z2Q32qQUDWquPZKmLagi5/BVzTCYtcnpJo=
 github.com/aws/aws-sdk-go-v2/service/apigateway v1.27.3 h1:81BvgDQ0bYSim7mFZWSwsX0DRkMkxsYGCpgGfEagnks=
 github.com/aws/aws-sdk-go-v2/service/apigateway v1.27.3/go.mod h1:EN7f1IzcWoBfc2wwp8aftbof+ib5uk9b5OO1sQvPwB0=
 github.com/aws/aws-sdk-go-v2/service/apigatewayv2 v1.24.3 h1:LNnp0zMnX20sO+lUZ9e7tMRmIk311vgPgH3f6K1XbqU=
@@ -52,6 +64,8 @@ github.com/aws/aws-sdk-go-v2/service/apprunner v1.32.3 h1:wkQpocpYy3/SqFf8iUO1uB
 github.com/aws/aws-sdk-go-v2/service/apprunner v1.32.3/go.mod h1:lOQv8hfiAZCHdi+wNKBKdSqf1yCKzWiOEQNVKoK/Jko=
 github.com/aws/aws-sdk-go-v2/service/autoscaling v1.23.16 h1:cp30gVVAbZfeDod6UJGppMH2+p+/cRCG2AZ1TbT+LqA=
 github.com/aws/aws-sdk-go-v2/service/autoscaling v1.23.16/go.mod h1:hHTMeJt6CQwFdmS19RK1LsDscus8c25Ve8KiYRhsISg=
+github.com/aws/aws-sdk-go-v2/service/autoscaling v1.47.0 h1:3yvZKeDa/slOTk8Gym4ym9u7AKhYAvy0Y00oRE+HRvE=
+github.com/aws/aws-sdk-go-v2/service/autoscaling v1.47.0/go.mod h1:SDmFD5Xuoa8dHPOLakoiURaUXei4zcqrkZ0/myZch/A=
 github.com/aws/aws-sdk-go-v2/service/backup v1.39.4 h1:4JLXjQf1vEDFmGjr2Z+jLFkMvAEb3aHmq4ChiL+npdA=
 github.com/aws/aws-sdk-go-v2/service/backup v1.39.4/go.mod h1:bXVDvryQpYdWh2pqCk0L/RtKSAwucmAqiyByKLPF1W8=
 github.com/aws/aws-sdk-go-v2/service/cloudtrail v1.44.3 h1:wVATQoy9BnfUTPlcfliv8IVboUxfbFl36tIxjQ6LR3c=
@@ -70,26 +84,62 @@ github.com/aws/aws-sdk-go-v2/service/dynamodb v1.36.3 h1:pS5ka5Z026eG29K3cce+yxG
 github.com/aws/aws-sdk-go-v2/service/dynamodb v1.36.3/go.mod h1:MBT8rSGSZjJiV6X7rlrVGoIt+mCoaw0VbpdVtsrsJfk=
 github.com/aws/aws-sdk-go-v2/service/ec2 v1.185.0 h1:WPhQgVHZUEsIRGEFh5B7VmwFzTkYgk7CxjWxZOgjQco=
 github.com/aws/aws-sdk-go-v2/service/ec2 v1.185.0/go.mod h1:kYXaB4FzyhEJjvrJ84oPnMElLiEAjGxxUunVW2tBSng=
+github.com/aws/aws-sdk-go-v2/service/ec2 v1.187.0 h1:cA4hWo269CN5RY7Arqt8BfzXF0KIN8DSNo/KcqHKkWk=
+github.com/aws/aws-sdk-go-v2/service/ec2 v1.187.0/go.mod h1:ossaD9Z1ugYb6sq9QIqQLEOorCGcqUoxlhud9M9yE70=
+github.com/aws/aws-sdk-go-v2/service/ecr v1.36.3 h1:bqmoQEKpWFRDRxOv4lC5yZLc+N1cogZHPLeQACfVUJo=
+github.com/aws/aws-sdk-go-v2/service/ecr v1.36.3/go.mod h1:KwOqlt4MOBK9EpOGkj8RU9fqfTEae5AOUHi1pDEZ3OQ=
+github.com/aws/aws-sdk-go-v2/service/ecs v1.49.0 h1:xhCV6zY5ZFzfyAUOiBXK6wh0HVQTBkvNwA/eiz89ZWY=
+github.com/aws/aws-sdk-go-v2/service/ecs v1.49.0/go.mod h1:RXYd/Ts+sFnjDrVdAZsAfHVkYxQUxhC+l2zrSpSgCGc=
+github.com/aws/aws-sdk-go-v2/service/efs v1.33.3 h1:PvOnbQfS7gR6x9e3THv9k441t0Pyk2Se8TvVWedz6EM=
+github.com/aws/aws-sdk-go-v2/service/efs v1.33.3/go.mod h1:lgRqCGG4HGimYuAkEjtzekYr7xPjq8+BM51wGarbk1c=
+github.com/aws/aws-sdk-go-v2/service/eks v1.51.1 h1:OQjVHkANBbwE055NK49M/kelQbapsQOsSfUUWP1mi3w=
+github.com/aws/aws-sdk-go-v2/service/eks v1.51.1/go.mod h1:9wMtzHTjYbK5MLzYBWSznUPsys/n9LapMwb6UhKOVPQ=
+github.com/aws/aws-sdk-go-v2/service/elasticache v1.43.1 h1:mNdBr6JqVYp0DSjSiO7snzUo5xoczBBfhuUIHIqutgA=
+github.com/aws/aws-sdk-go-v2/service/elasticache v1.43.1/go.mod h1:rPN8bNqTMCKtKxkyVdPra/0J7ecOmRQlBv3BZTq9Fq0=
+github.com/aws/aws-sdk-go-v2/service/elasticbeanstalk v1.28.3 h1:cUhmI37/S8kYMfQrd5JB7zxfbLuXIAJcFJvo//cZLgs=
+github.com/aws/aws-sdk-go-v2/service/elasticbeanstalk v1.28.3/go.mod h1:ERGQhQc/0neux01Q60KOG4/3oRgdBNtOJ7/mYPUpjTY=
+github.com/aws/aws-sdk-go-v2/service/elasticloadbalancing v1.28.3 h1:cRDiIyPNUf71QjW6dFbHApMieS4svBvfTKBiEtzQZrs=
+github.com/aws/aws-sdk-go-v2/service/elasticloadbalancing v1.28.3/go.mod h1:G86bITIZX9wcacVyMHzLz9nEQaQLSBKDHym0spIEr+M=
+github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2 v1.41.0 h1:W+xNfPS8dQ8YoszdkHqTDYIgCrWJvyUU/ZgdJ0frCRE=
+github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2 v1.41.0/go.mod h1:6WuvTcPjB9gff93p/2LNBg09d8xK99jpVO6+fRSCKEU=
 github.com/aws/aws-sdk-go-v2/service/eventbridge v1.33.7 h1:q+xiPu+Dk5MFC20ZjdGGhbihD39Xsih98epvVjnOjyE=
 github.com/aws/aws-sdk-go-v2/service/eventbridge v1.33.7/go.mod h1:iQCsmx9LyBMyMEkLCBVqnIAz+rfo6/ss3oLcYn26+no=
+github.com/aws/aws-sdk-go-v2/service/eventbridge v1.35.3 h1:e/jGXEQi+lyTIhc3s+jbJrq2IWgLXsNbdYxDauWTyPU=
+github.com/aws/aws-sdk-go-v2/service/eventbridge v1.35.3/go.mod h1:607CryyDS58whuaVno9CCg3L/nnWOqorxiyAS2f9leY=
+github.com/aws/aws-sdk-go-v2/service/guardduty v1.50.1 h1:0A05jzCVA6W/UFqdtpKm8KXE8QhcEn/Fn01Zxsq2Owg=
+github.com/aws/aws-sdk-go-v2/service/guardduty v1.50.1/go.mod h1:tfpIzAIeMtSUucGN87ZUA2u5Lqnc04ManYSk3smJpGc=
 github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.0 h1:TToQNkvGguu209puTojY/ozlqy2d/SFNcoLIqTFi42g=
 github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.0/go.mod h1:0jp+ltwkf+SwG2fm/PKo8t4y8pJSgOCO4D8Lz3k0aHQ=
 github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.10.3 h1:wudRPcZMKytcywXERkR6PLqD8gPx754ZyIOo0iVg488=
 github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.10.3/go.mod h1:yRo5Kj5+m/ScVIZpQOquQvDtSrDM1JLRCnvglBcdNmw=
 github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.2 h1:s7NA1SOw8q/5c0wr8477yOPp0z+uBaXBnLE0XYb0POA=
 github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.2/go.mod h1:fnjjWyAW/Pj5HYOxl9LJqWtEwS7W2qgcRLWP+uWbss0=
+github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.3 h1:qcxX0JYlgWH3hpPUnd6U0ikcl6LLA9sLkXE2w1fpMvY=
+github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.3/go.mod h1:cLSNEmI45soc+Ef8K/L+8sEA3A3pYFEYf5B5UI+6bH4=
 github.com/aws/aws-sdk-go-v2/service/scheduler v1.10.7 h1:EcPyKUUo3neD2tDFKnq3TR3B9s2uZe9eWgxVQgixdzc=
 github.com/aws/aws-sdk-go-v2/service/scheduler v1.10.7/go.mod h1:MlNx35QVGG8TB2x1kOC0TKd9e93+RmFUE8HzYDLDLso=
+github.com/aws/aws-sdk-go-v2/service/scheduler v1.12.3 h1:VrfgbM8+DuUaTRx1Lllajic28bHaaUrYx9tN9JCGXVI=
+github.com/aws/aws-sdk-go-v2/service/scheduler v1.12.3/go.mod h1:0ujC4ruQHlBlToSoHj3s/OL9wr7dp7wPrcACMDc87ME=
 github.com/aws/aws-sdk-go-v2/service/sns v1.32.3 h1:LC5JBrEAdJ0SSRLfNcLzOLsfoc3xO/BAsHiUNcQfDI4=
 github.com/aws/aws-sdk-go-v2/service/sns v1.32.3/go.mod h1:ZO606Jfatw51c8q29gHVVCnufg2dq3MnmkNLlTZFrkE=
+github.com/aws/aws-sdk-go-v2/service/sns v1.33.3 h1:coZW/SqpINT0VWG8vRWWY9TWUof8TDdxublw2Xur0Zc=
+github.com/aws/aws-sdk-go-v2/service/sns v1.33.3/go.mod h1:J/G2xuhwNBlDvEi0WR/bnBbac4KSgpkERna/IXEF52w=
 github.com/aws/aws-sdk-go-v2/service/sqs v1.35.3 h1:Lcs658WFW235QuUfpAdxd8RCy8Va2VUA7/U9iIrcjcY=
 github.com/aws/aws-sdk-go-v2/service/sqs v1.35.3/go.mod h1:WuGxWQhu2LXoPGA2HBIbotpwhM6T4hAz0Ip/HjdxfJg=
+github.com/aws/aws-sdk-go-v2/service/sqs v1.36.3 h1:H1bCg79Q4PDtxQH8Fn5kASQlbVv2WGP5o5IEFEBNOAs=
+github.com/aws/aws-sdk-go-v2/service/sqs v1.36.3/go.mod h1:W6Uy6OWgxF9RZuHoikthB6f+A0oYXqnfWmFl5m7E2G4=
 github.com/aws/aws-sdk-go-v2/service/sso v1.22.1 h1:p1GahKIjyMDZtiKoIn0/jAj/TkMzfzndDv5+zi2Mhgc=
 github.com/aws/aws-sdk-go-v2/service/sso v1.22.1/go.mod h1:/vWdhoIoYA5hYoPZ6fm7Sv4d8701PiG5VKe8/pPJL60=
+github.com/aws/aws-sdk-go-v2/service/sso v1.24.3 h1:UTpsIf0loCIWEbrqdLb+0RxnTXfWh2vhw4nQmFi4nPc=
+github.com/aws/aws-sdk-go-v2/service/sso v1.24.3/go.mod h1:FZ9j3PFHHAR+w0BSEjK955w5YD2UwB/l/H0yAK3MJvI=
 github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.2 h1:ORnrOK0C4WmYV/uYt3koHEWBLYsRDwk2Np+eEoyV4Z0=
 github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.2/go.mod h1:xyFHA4zGxgYkdD73VeezHt3vSKEG9EmFnGwoKlP00u4=
+github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.3 h1:2YCmIXv3tmiItw0LlYf6v7gEHebLY45kBEnPezbUKyU=
+github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.3/go.mod h1:u19stRyNPxGhj6dRm+Cdgu6N75qnbW7+QN0q0dsAk58=
 github.com/aws/aws-sdk-go-v2/service/sts v1.30.1 h1:+woJ607dllHJQtsnJLi52ycuqHMwlW+Wqm2Ppsfp4nQ=
 github.com/aws/aws-sdk-go-v2/service/sts v1.30.1/go.mod h1:jiNR3JqT15Dm+QWq2SRgh0x0bCNSRP2L25+CqPNpJlQ=
+github.com/aws/aws-sdk-go-v2/service/sts v1.32.3 h1:wVnQ6tigGsRqSWDEEyH6lSAJ9OyFUsSnbaUWChuSGzs=
+github.com/aws/aws-sdk-go-v2/service/sts v1.32.3/go.mod h1:VZa9yTFyj4o10YGsmDO4gbQJUvvhY72fhumT8W4LqsE=
 github.com/aws/aws-sdk-go-v2/service/vpclattice v1.12.3 h1:YwFhhnQNn2bvnJ9HNy7DEhyIf5Ze/9Qn6ad6gtByLko=
 github.com/aws/aws-sdk-go-v2/service/vpclattice v1.12.3/go.mod h1:wjm69e87s+O7nq0zC54dEJ7M9gLHMfr9ZJ+j5u9IV0Q=
 github.com/aws/smithy-go v1.13.3/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA=
diff --git a/v2_migration_report/output.md b/v2_migration_report/output.md
index 76e7d6b..64fac78 100644
--- a/v2_migration_report/output.md
+++ b/v2_migration_report/output.md
@@ -25,7 +25,7 @@ run `go generate ./...` to refresh this report.
 | data-sync-location               | :white_check_mark: |
 | data-sync-task                   | :white_check_mark: |
 | dynamodb                         | :white_check_mark: |
-| ebs                              |                    |
+| ebs                              | :white_check_mark: |
 | ec2                              |                    |
 | ec2-dedicated-hosts              |                    |
 | ec2-endpoint                     |                    |
@@ -33,25 +33,25 @@ run `go generate ./...` to refresh this report.
 | ec2-placement-groups             |                    |
 | ec2-subnet                       |                    |
 | ec2_dhcp_option                  |                    |
-| ecr                              |                    |
-| ecscluster                       |                    |
-| ecsserv                          |                    |
-| efs                              |                    |
+| ecr                              | :white_check_mark: |
+| ecscluster                       | :white_check_mark: |
+| ecsserv                          | :white_check_mark: |
+| efs                              | :white_check_mark: |
 | egress-only-internet-gateway     |                    |
-| eip                              |                    |
-| ekscluster                       |                    |
-| elastic-beanstalk                |                    |
-| elasticache                      |                    |
-| elasticacheParameterGroups       |                    |
-| elasticacheSubnetGroups          |                    |
-| elb                              |                    |
-| elbv2                            |                    |
+| eip                              | :white_check_mark: |
+| ekscluster                       | :white_check_mark: |
+| elastic-beanstalk                | :white_check_mark: |
+| elasticache                      | :white_check_mark: |
+| elasticacheParameterGroups       | :white_check_mark: |
+| elasticacheSubnetGroups          | :white_check_mark: |
+| elb                              | :white_check_mark: |
+| elbv2                            | :white_check_mark: |
 | event-bridge                     | :white_check_mark: |
 | event-bridge-archive             | :white_check_mark: |
 | event-bridge-rule                | :white_check_mark: |
 | event-bridge-schedule            | :white_check_mark: |
 | event-bridge-schedule-group      | :white_check_mark: |
-| guardduty                        |                    |
+| guardduty                        | :white_check_mark: |
 | iam                              |                    |
 | iam-group                        |                    |
 | iam-policy                       |                    |
@@ -112,7 +112,7 @@ run `go generate ./...` to refresh this report.
 | snap                             |                    |
 | snstopic                         | :white_check_mark: |
 | sqs                              | :white_check_mark: |
-| transit-gateway                  |                    |
+| transit-gateway                  | :white_check_mark: |
 | transit-gateway-attachment       | :white_check_mark: |
 | transit-gateway-route-table      |                    |
 | vpc                              |                    |


Test patch:
diff --git a/aws/resources/ebs_test.go b/aws/resources/ebs_test.go
index e4defc6..6e8adf3 100644
--- a/aws/resources/ebs_test.go
+++ b/aws/resources/ebs_test.go
@@ -6,36 +6,28 @@ import (
 	"testing"
 	"time"
 
-	"github.com/aws/aws-sdk-go/aws/request"
-	"github.com/aws/aws-sdk-go/service/ec2/ec2iface"
-
-	"github.com/aws/aws-sdk-go/aws"
-	awsgo "github.com/aws/aws-sdk-go/aws"
-	"github.com/aws/aws-sdk-go/service/ec2"
+	"github.com/aws/aws-sdk-go-v2/aws"
+	"github.com/aws/aws-sdk-go-v2/service/ec2"
+	"github.com/aws/aws-sdk-go-v2/service/ec2/types"
 	"github.com/gruntwork-io/cloud-nuke/config"
 	"github.com/stretchr/testify/require"
 )
 
 type mockedEBS struct {
-	ec2iface.EC2API
-	DeleteVolumeOutput    ec2.DeleteVolumeOutput
+	EBSVolumesAPI
 	DescribeVolumesOutput ec2.DescribeVolumesOutput
+	DeleteVolumeOutput    ec2.DeleteVolumeOutput
 }
 
-func (m mockedEBS) DeleteVolumeWithContext(_ awsgo.Context, input *ec2.DeleteVolumeInput, _ ...request.Option) (*ec2.DeleteVolumeOutput, error) {
-	return &m.DeleteVolumeOutput, nil
-}
-
-func (m mockedEBS) DescribeVolumesWithContext(_ awsgo.Context, input *ec2.DescribeVolumesInput, _ ...request.Option) (*ec2.DescribeVolumesOutput, error) {
+func (m mockedEBS) DescribeVolumes(ctx context.Context, params *ec2.DescribeVolumesInput, optFns ...func(*ec2.Options)) (*ec2.DescribeVolumesOutput, error) {
 	return &m.DescribeVolumesOutput, nil
 }
 
-func (m mockedEBS) WaitUntilVolumeDeletedWithContext(_ awsgo.Context, input *ec2.DescribeVolumesInput, _ ...request.WaiterOption) error {
-	return nil
+func (m mockedEBS) DeleteVolume(ctx context.Context, params *ec2.DeleteVolumeInput, optFns ...func(*ec2.Options)) (*ec2.DeleteVolumeOutput, error) {
+	return &m.DeleteVolumeOutput, nil
 }
 
 func TestEBSVolume_GetAll(t *testing.T) {
-
 	t.Parallel()
 
 	testName1 := "test-name1"
@@ -46,21 +38,21 @@ func TestEBSVolume_GetAll(t *testing.T) {
 	ev := EBSVolumes{
 		Client: mockedEBS{
 			DescribeVolumesOutput: ec2.DescribeVolumesOutput{
-				Volumes: []*ec2.Volume{
+				Volumes: []types.Volume{
 					{
-						VolumeId:   awsgo.String(testVolume1),
-						CreateTime: awsgo.Time(now),
-						Tags: []*ec2.Tag{{
-							Key:   awsgo.String("Name"),
-							Value: awsgo.String(testName1),
+						VolumeId:   aws.String(testVolume1),
+						CreateTime: aws.Time(now),
+						Tags: []types.Tag{{
+							Key:   aws.String("Name"),
+							Value: aws.String(testName1),
 						}},
 					},
 					{
-						VolumeId:   awsgo.String(testVolume2),
-						CreateTime: awsgo.Time(now.Add(1)),
-						Tags: []*ec2.Tag{{
-							Key:   awsgo.String("Name"),
-							Value: awsgo.String(testName2),
+						VolumeId:   aws.String(testVolume2),
+						CreateTime: aws.Time(now.Add(1)),
+						Tags: []types.Tag{{
+							Key:   aws.String("Name"),
+							Value: aws.String(testName2),
 						}},
 					},
 				}}}}
@@ -97,13 +89,12 @@ func TestEBSVolume_GetAll(t *testing.T) {
 				EBSVolume: tc.configObj,
 			})
 			require.NoError(t, err)
-			require.Equal(t, tc.expected, aws.StringValueSlice(names))
+			require.Equal(t, tc.expected, aws.ToStringSlice(names))
 		})
 	}
 }
 
-func TestEBSVolumne_NukeAll(t *testing.T) {
-
+func TestEBSVolume_NukeAll(t *testing.T) {
 	t.Parallel()
 
 	ev := EBSVolumes{
@@ -114,5 +105,4 @@ func TestEBSVolumne_NukeAll(t *testing.T) {
 
 	err := ev.nukeAll([]*string{aws.String("test-volume")})
 	require.NoError(t, err)
-
 }
diff --git a/aws/resources/ecr_test.go b/aws/resources/ecr_test.go
index 0579892..96227a2 100644
--- a/aws/resources/ecr_test.go
+++ b/aws/resources/ecr_test.go
@@ -6,40 +6,36 @@ import (
 	"testing"
 	"time"
 
-	"github.com/aws/aws-sdk-go/aws"
-	"github.com/aws/aws-sdk-go/aws/request"
-	"github.com/aws/aws-sdk-go/service/ecr"
-	"github.com/aws/aws-sdk-go/service/ecr/ecriface"
+	"github.com/aws/aws-sdk-go-v2/aws"
+	"github.com/aws/aws-sdk-go-v2/service/ecr"
+	"github.com/aws/aws-sdk-go-v2/service/ecr/types"
 	"github.com/gruntwork-io/cloud-nuke/config"
 	"github.com/stretchr/testify/require"
 )
 
 type mockedECR struct {
-	ecriface.ECRAPI
-	DescribeRepositoriesPagesOutput ecr.DescribeRepositoriesOutput
-	DeleteRepositoryOutput          ecr.DeleteRepositoryOutput
+	ECRAPI
+	DescribeRepositoriesOutput ecr.DescribeRepositoriesOutput
+	DeleteRepositoryOutput     ecr.DeleteRepositoryOutput
 }
 
-func (m mockedECR) DescribeRepositoriesPagesWithContext(_ aws.Context, input *ecr.DescribeRepositoriesInput, callback func(*ecr.DescribeRepositoriesOutput, bool) bool, _ ...request.Option) error {
-	callback(&m.DescribeRepositoriesPagesOutput, true)
-	return nil
+func (m mockedECR) DescribeRepositories(ctx context.Context, params *ecr.DescribeRepositoriesInput, optFns ...func(*ecr.Options)) (*ecr.DescribeRepositoriesOutput, error) {
+	return &m.DescribeRepositoriesOutput, nil
 }
 
-func (m mockedECR) DeleteRepositoryWithContext(_ aws.Context, input *ecr.DeleteRepositoryInput, _ ...request.Option) (*ecr.DeleteRepositoryOutput, error) {
+func (m mockedECR) DeleteRepository(ctx context.Context, params *ecr.DeleteRepositoryInput, optFns ...func(*ecr.Options)) (*ecr.DeleteRepositoryOutput, error) {
 	return &m.DeleteRepositoryOutput, nil
 }
 
 func TestECR_GetAll(t *testing.T) {
-
 	t.Parallel()
-
 	testName1 := "test-repo1"
 	testName2 := "test-repo2"
 	now := time.Now()
 	er := ECR{
 		Client: &mockedECR{
-			DescribeRepositoriesPagesOutput: ecr.DescribeRepositoriesOutput{
-				Repositories: []*ecr.Repository{
+			DescribeRepositoriesOutput: ecr.DescribeRepositoriesOutput{
+				Repositories: []types.Repository{
 					{
 						RepositoryName: aws.String(testName1),
 						CreatedAt:      aws.Time(now),
@@ -84,16 +80,13 @@ func TestECR_GetAll(t *testing.T) {
 				ECRRepository: tc.configObj,
 			})
 			require.NoError(t, err)
-			require.Equal(t, tc.expected, aws.StringValueSlice(names))
+			require.Equal(t, tc.expected, aws.ToStringSlice(names))
 		})
 	}
 
 }
-
 func TestECR_NukeAll(t *testing.T) {
-
 	t.Parallel()
-
 	er := ECR{
 		Client: &mockedECR{
 			DeleteRepositoryOutput: ecr.DeleteRepositoryOutput{},
diff --git a/aws/resources/ecs_cluster_test.go b/aws/resources/ecs_cluster_test.go
index 0ebc19a..43a3084 100644
--- a/aws/resources/ecs_cluster_test.go
+++ b/aws/resources/ecs_cluster_test.go
@@ -6,57 +6,55 @@ import (
 	"testing"
 	"time"
 
-	"github.com/aws/aws-sdk-go/aws"
-	"github.com/aws/aws-sdk-go/aws/request"
-	"github.com/aws/aws-sdk-go/service/ecs"
-	"github.com/aws/aws-sdk-go/service/ecs/ecsiface"
+	"github.com/aws/aws-sdk-go-v2/aws"
+	"github.com/aws/aws-sdk-go-v2/service/ecs"
+	"github.com/aws/aws-sdk-go-v2/service/ecs/types"
 	"github.com/gruntwork-io/cloud-nuke/config"
 	"github.com/gruntwork-io/cloud-nuke/util"
 	"github.com/stretchr/testify/require"
 )
 
 type mockedEC2Cluster struct {
-	ecsiface.ECSAPI
-	ListClustersOutput        ecs.ListClustersOutput
+	ECSClustersAPI
 	DescribeClustersOutput    ecs.DescribeClustersOutput
-	TagResourceOutput         ecs.TagResourceOutput
-	ListTagsForResourceOutput ecs.ListTagsForResourceOutput
 	DeleteClusterOutput       ecs.DeleteClusterOutput
+	ListClustersOutput        ecs.ListClustersOutput
+	ListTagsForResourceOutput ecs.ListTagsForResourceOutput
 	ListTasksOutput           ecs.ListTasksOutput
 	StopTaskOutput            ecs.StopTaskOutput
+	TagResourceOutput         ecs.TagResourceOutput
 }
 
-func (m mockedEC2Cluster) ListClustersWithContext(_ aws.Context, _ *ecs.ListClustersInput, _ ...request.Option) (*ecs.ListClustersOutput, error) {
-	return &m.ListClustersOutput, nil
-}
-
-func (m mockedEC2Cluster) DescribeClustersWithContext(_ aws.Context, _ *ecs.DescribeClustersInput, _ ...request.Option) (*ecs.DescribeClustersOutput, error) {
+func (m mockedEC2Cluster) DescribeClusters(ctx context.Context, params *ecs.DescribeClustersInput, optFns ...func(*ecs.Options)) (*ecs.DescribeClustersOutput, error) {
 	return &m.DescribeClustersOutput, nil
 }
 
-func (m mockedEC2Cluster) TagResource(*ecs.TagResourceInput) (*ecs.TagResourceOutput, error) {
-	return &m.TagResourceOutput, nil
+func (m mockedEC2Cluster) DeleteCluster(ctx context.Context, params *ecs.DeleteClusterInput, optFns ...func(*ecs.Options)) (*ecs.DeleteClusterOutput, error) {
+	return &m.DeleteClusterOutput, nil
 }
 
-func (m mockedEC2Cluster) ListTagsForResource(*ecs.ListTagsForResourceInput) (*ecs.ListTagsForResourceOutput, error) {
-	return &m.ListTagsForResourceOutput, nil
+func (m mockedEC2Cluster) ListClusters(ctx context.Context, params *ecs.ListClustersInput, optFns ...func(*ecs.Options)) (*ecs.ListClustersOutput, error) {
+	return &m.ListClustersOutput, nil
 }
 
-func (m mockedEC2Cluster) DeleteClusterWithContext(_ aws.Context, _ *ecs.DeleteClusterInput, _ ...request.Option) (*ecs.DeleteClusterOutput, error) {
-	return &m.DeleteClusterOutput, nil
+func (m mockedEC2Cluster) ListTagsForResource(ctx context.Context, params *ecs.ListTagsForResourceInput, optFns ...func(*ecs.Options)) (*ecs.ListTagsForResourceOutput, error) {
+	return &m.ListTagsForResourceOutput, nil
 }
 
-func (m mockedEC2Cluster) ListTasksWithContext(_ aws.Context, _ *ecs.ListTasksInput, _ ...request.Option) (*ecs.ListTasksOutput, error) {
+func (m mockedEC2Cluster) ListTasks(ctx context.Context, params *ecs.ListTasksInput, optFns ...func(*ecs.Options)) (*ecs.ListTasksOutput, error) {
 	return &m.ListTasksOutput, nil
 }
-func (m mockedEC2Cluster) StopTaskWithContext(_ aws.Context, _ *ecs.StopTaskInput, _ ...request.Option) (*ecs.StopTaskOutput, error) {
+
+func (m mockedEC2Cluster) StopTask(ctx context.Context, params *ecs.StopTaskInput, optFns ...func(*ecs.Options)) (*ecs.StopTaskOutput, error) {
 	return &m.StopTaskOutput, nil
 }
 
-func TestEC2Cluster_GetAll(t *testing.T) {
+func (m mockedEC2Cluster) TagResource(ctx context.Context, params *ecs.TagResourceInput, optFns ...func(*ecs.Options)) (*ecs.TagResourceOutput, error) {
+	return &m.TagResourceOutput, nil
+}
 
+func TestEC2Cluster_GetAll(t *testing.T) {
 	t.Parallel()
-
 	// Set excludeFirstSeenTag to false for testing
 	ctx := context.WithValue(context.Background(), util.ExcludeFirstSeenTagKey, false)
 
@@ -68,14 +66,14 @@ func TestEC2Cluster_GetAll(t *testing.T) {
 	ec := ECSClusters{
 		Client: mockedEC2Cluster{
 			ListClustersOutput: ecs.ListClustersOutput{
-				ClusterArns: []*string{
-					aws.String(testArn1),
-					aws.String(testArn2),
+				ClusterArns: []string{
+					testArn1,
+					testArn2,
 				},
 			},
 
 			DescribeClustersOutput: ecs.DescribeClustersOutput{
-				Clusters: []*ecs.Cluster{
+				Clusters: []types.Cluster{
 					{
 						ClusterArn:  aws.String(testArn1),
 						Status:      aws.String("ACTIVE"),
@@ -90,7 +88,7 @@ func TestEC2Cluster_GetAll(t *testing.T) {
 			},
 
 			ListTagsForResourceOutput: ecs.ListTagsForResourceOutput{
-				Tags: []*ecs.Tag{
+				Tags: []types.Tag{
 					{
 						Key:   aws.String(util.FirstSeenTagKey),
 						Value: aws.String(util.FormatTimestamp(now)),
@@ -98,9 +96,9 @@ func TestEC2Cluster_GetAll(t *testing.T) {
 				},
 			},
 			ListTasksOutput: ecs.ListTasksOutput{
-				TaskArns: []*string{
-					aws.String("task-arn-001"),
-					aws.String("task-arn-002"),
+				TaskArns: []string{
+					"task-arn-001",
+					"task-arn-002",
 				},
 			},
 		},
@@ -141,16 +139,13 @@ func TestEC2Cluster_GetAll(t *testing.T) {
 				ECSCluster: tc.configObj,
 			})
 			require.NoError(t, err)
-			require.Equal(t, tc.expected, aws.StringValueSlice(names))
+			require.Equal(t, tc.expected, aws.ToStringSlice(names))
 		})
 	}
-
 }
 
 func TestEC2Cluster_NukeAll(t *testing.T) {
-
 	t.Parallel()
-
 	ec := ECSClusters{
 		Client: mockedEC2Cluster{
 			DeleteClusterOutput: ecs.DeleteClusterOutput{},
@@ -162,16 +157,14 @@ func TestEC2Cluster_NukeAll(t *testing.T) {
 }
 
 func TestEC2ClusterWithTasks_NukeAll(t *testing.T) {
-
 	t.Parallel()
-
 	ec := ECSClusters{
 		Client: mockedEC2Cluster{
 			DeleteClusterOutput: ecs.DeleteClusterOutput{},
 			ListTasksOutput: ecs.ListTasksOutput{
-				TaskArns: []*string{
-					aws.String("task-arn-001"),
-					aws.String("task-arn-002"),
+				TaskArns: []string{
+					"task-arn-001",
+					"task-arn-002",
 				},
 			},
 		},
diff --git a/aws/resources/ecs_service_test.go b/aws/resources/ecs_service_test.go
index 5b06f17..392ea94 100644
--- a/aws/resources/ecs_service_test.go
+++ b/aws/resources/ecs_service_test.go
@@ -6,55 +6,44 @@ import (
 	"testing"
 	"time"
 
-	"github.com/aws/aws-sdk-go/aws"
-	"github.com/aws/aws-sdk-go/aws/request"
-	"github.com/aws/aws-sdk-go/service/ecs"
-	"github.com/aws/aws-sdk-go/service/ecs/ecsiface"
+	"github.com/aws/aws-sdk-go-v2/aws"
+	"github.com/aws/aws-sdk-go-v2/service/ecs"
+	"github.com/aws/aws-sdk-go-v2/service/ecs/types"
 	"github.com/gruntwork-io/cloud-nuke/config"
 	"github.com/stretchr/testify/require"
 )
 
 type mockedEC2Service struct {
-	ecsiface.ECSAPI
+	ECSServicesAPI
 	ListClustersOutput     ecs.ListClustersOutput
-	DescribeServicesOutput ecs.DescribeServicesOutput
 	ListServicesOutput     ecs.ListServicesOutput
-	UpdateServiceOutput    ecs.UpdateServiceOutput
+	DescribeServicesOutput ecs.DescribeServicesOutput
 	DeleteServiceOutput    ecs.DeleteServiceOutput
+	UpdateServiceOutput    ecs.UpdateServiceOutput
 }
 
-func (m mockedEC2Service) ListClustersWithContext(_ aws.Context, _ *ecs.ListClustersInput, _ ...request.Option) (*ecs.ListClustersOutput, error) {
+func (m mockedEC2Service) ListClusters(ctx context.Context, params *ecs.ListClustersInput, optFns ...func(*ecs.Options)) (*ecs.ListClustersOutput, error) {
 	return &m.ListClustersOutput, nil
 }
 
-func (m mockedEC2Service) DescribeServicesWithContext(_ aws.Context, _ *ecs.DescribeServicesInput, _ ...request.Option) (*ecs.DescribeServicesOutput, error) {
-	return &m.DescribeServicesOutput, nil
-}
-
-func (m mockedEC2Service) ListServicesWithContext(_ aws.Context, _ *ecs.ListServicesInput, _ ...request.Option) (*ecs.ListServicesOutput, error) {
+func (m mockedEC2Service) ListServices(ctx context.Context, params *ecs.ListServicesInput, optFns ...func(*ecs.Options)) (*ecs.ListServicesOutput, error) {
 	return &m.ListServicesOutput, nil
 }
 
-func (m mockedEC2Service) UpdateServiceWithContext(_ aws.Context, _ *ecs.UpdateServiceInput, _ ...request.Option) (*ecs.UpdateServiceOutput, error) {
-	return &m.UpdateServiceOutput, nil
-}
-
-func (m mockedEC2Service) WaitUntilServicesStableWithContext(_ aws.Context, _ *ecs.DescribeServicesInput, _ ...request.WaiterOption) error {
-	return nil
+func (m mockedEC2Service) DescribeServices(ctx context.Context, params *ecs.DescribeServicesInput, optFns ...func(*ecs.Options)) (*ecs.DescribeServicesOutput, error) {
+	return &m.DescribeServicesOutput, nil
 }
 
-func (m mockedEC2Service) DeleteServiceWithContext(_ aws.Context, _ *ecs.DeleteServiceInput, _ ...request.Option) (*ecs.DeleteServiceOutput, error) {
+func (m mockedEC2Service) DeleteService(ctx context.Context, params *ecs.DeleteServiceInput, optFns ...func(*ecs.Options)) (*ecs.DeleteServiceOutput, error) {
 	return &m.DeleteServiceOutput, nil
 }
 
-func (m mockedEC2Service) WaitUntilServicesInactiveWithContext(_ aws.Context, _ *ecs.DescribeServicesInput, _ ...request.WaiterOption) error {
-	return nil
+func (m mockedEC2Service) UpdateService(ctx context.Context, params *ecs.UpdateServiceInput, optFns ...func(*ecs.Options)) (*ecs.UpdateServiceOutput, error) {
+	return &m.UpdateServiceOutput, nil
 }
 
 func TestEC2Service_GetAll(t *testing.T) {
-
 	t.Parallel()
-
 	testArn1 := "testArn1"
 	testArn2 := "testArn2"
 	testName1 := "testService1"
@@ -63,17 +52,17 @@ func TestEC2Service_GetAll(t *testing.T) {
 	es := ECSServices{
 		Client: mockedEC2Service{
 			ListClustersOutput: ecs.ListClustersOutput{
-				ClusterArns: []*string{
-					aws.String(testArn1),
+				ClusterArns: []string{
+					testArn1,
 				},
 			},
 			ListServicesOutput: ecs.ListServicesOutput{
-				ServiceArns: []*string{
-					aws.String(testArn1),
+				ServiceArns: []string{
+					testArn1,
 				},
 			},
 			DescribeServicesOutput: ecs.DescribeServicesOutput{
-				Services: []*ecs.Service{
+				Services: []types.Service{
 					{
 						ServiceArn:  aws.String(testArn1),
 						ServiceName: aws.String(testName1),
@@ -120,23 +109,25 @@ func TestEC2Service_GetAll(t *testing.T) {
 				ECSService: tc.configObj,
 			})
 			require.NoError(t, err)
-			require.Equal(t, tc.expected, aws.StringValueSlice(names))
+			require.Equal(t, tc.expected, aws.ToStringSlice(names))
 		})
 	}
 
 }
 
 func TestEC2Service_NukeAll(t *testing.T) {
-
 	t.Parallel()
-
 	es := ECSServices{
+		BaseAwsResource: BaseAwsResource{
+			Context: context.Background(),
+		},
 		Client: mockedEC2Service{
 			DescribeServicesOutput: ecs.DescribeServicesOutput{
-				Services: []*ecs.Service{
+				Services: []types.Service{
 					{
+						SchedulingStrategy: types.SchedulingStrategyDaemon,
 						ServiceArn:         aws.String("testArn1"),
-						SchedulingStrategy: aws.String(ecs.SchedulingStrategyDaemon),
+						Status:             aws.String("DRAINING"),
 					},
 				},
 			},
diff --git a/aws/resources/efs_test.go b/aws/resources/efs_test.go
index 72d9129..91f95ac 100644
--- a/aws/resources/efs_test.go
+++ b/aws/resources/efs_test.go
@@ -6,53 +6,48 @@ import (
 	"testing"
 	"time"
 
-	"github.com/aws/aws-sdk-go/aws"
-	"github.com/aws/aws-sdk-go/aws/request"
-	"github.com/aws/aws-sdk-go/service/efs"
-	"github.com/aws/aws-sdk-go/service/efs/efsiface"
+	"github.com/aws/aws-sdk-go-v2/aws"
+	"github.com/aws/aws-sdk-go-v2/service/efs"
+	"github.com/aws/aws-sdk-go-v2/service/efs/types"
 	"github.com/gruntwork-io/cloud-nuke/config"
 	"github.com/stretchr/testify/require"
 )
 
 type mockedElasticFileSystem struct {
-	efsiface.EFSAPI
-	DescribeFileSystemsPagesOutput efs.DescribeFileSystemsOutput
-	DescribeAccessPointsOutput     efs.DescribeAccessPointsOutput
-	DeleteAccessPointOutput        efs.DeleteAccessPointOutput
-	DescribeMountTargetsOutput     efs.DescribeMountTargetsOutput
-	DeleteMountTargetOutput        efs.DeleteMountTargetOutput
-	DeleteFileSystemOutput         efs.DeleteFileSystemOutput
+	DeleteAccessPointOutput    efs.DeleteAccessPointOutput
+	DeleteFileSystemOutput     efs.DeleteFileSystemOutput
+	DeleteMountTargetOutput    efs.DeleteMountTargetOutput
+	DescribeAccessPointsOutput efs.DescribeAccessPointsOutput
+	DescribeMountTargetsOutput efs.DescribeMountTargetsOutput
+	DescribeFileSystemsOutput  efs.DescribeFileSystemsOutput
 }
 
-func (m mockedElasticFileSystem) DescribeFileSystemsPagesWithContext(_ aws.Context, input *efs.DescribeFileSystemsInput, callback func(*efs.DescribeFileSystemsOutput, bool) bool, _ ...request.Option) error {
-	callback(&m.DescribeFileSystemsPagesOutput, true)
-	return nil
+func (m mockedElasticFileSystem) DeleteAccessPoint(ctx context.Context, params *efs.DeleteAccessPointInput, optFns ...func(*efs.Options)) (*efs.DeleteAccessPointOutput, error) {
+	return &m.DeleteAccessPointOutput, nil
 }
 
-func (m mockedElasticFileSystem) DescribeAccessPointsWithContext(_ aws.Context, input *efs.DescribeAccessPointsInput, _ ...request.Option) (*efs.DescribeAccessPointsOutput, error) {
-	return &m.DescribeAccessPointsOutput, nil
+func (m mockedElasticFileSystem) DeleteFileSystem(ctx context.Context, params *efs.DeleteFileSystemInput, optFns ...func(*efs.Options)) (*efs.DeleteFileSystemOutput, error) {
+	return &m.DeleteFileSystemOutput, nil
 }
 
-func (m mockedElasticFileSystem) DeleteAccessPointWithContext(_ aws.Context, input *efs.DeleteAccessPointInput, _ ...request.Option) (*efs.DeleteAccessPointOutput, error) {
-	return &m.DeleteAccessPointOutput, nil
+func (m mockedElasticFileSystem) DeleteMountTarget(ctx context.Context, params *efs.DeleteMountTargetInput, optFns ...func(*efs.Options)) (*efs.DeleteMountTargetOutput, error) {
+	return &m.DeleteMountTargetOutput, nil
 }
 
-func (m mockedElasticFileSystem) DescribeMountTargetsWithContext(_ aws.Context, input *efs.DescribeMountTargetsInput, _ ...request.Option) (*efs.DescribeMountTargetsOutput, error) {
-	return &m.DescribeMountTargetsOutput, nil
+func (m mockedElasticFileSystem) DescribeAccessPoints(ctx context.Context, params *efs.DescribeAccessPointsInput, optFns ...func(*efs.Options)) (*efs.DescribeAccessPointsOutput, error) {
+	return &m.DescribeAccessPointsOutput, nil
 }
 
-func (m mockedElasticFileSystem) DeleteMountTargetWithContext(_ aws.Context, input *efs.DeleteMountTargetInput, _ ...request.Option) (*efs.DeleteMountTargetOutput, error) {
-	return &m.DeleteMountTargetOutput, nil
+func (m mockedElasticFileSystem) DescribeMountTargets(ctx context.Context, params *efs.DescribeMountTargetsInput, optFns ...func(*efs.Options)) (*efs.DescribeMountTargetsOutput, error) {
+	return &m.DescribeMountTargetsOutput, nil
 }
 
-func (m mockedElasticFileSystem) DeleteFileSystemWithContext(_ aws.Context, input *efs.DeleteFileSystemInput, _ ...request.Option) (*efs.DeleteFileSystemOutput, error) {
-	return &m.DeleteFileSystemOutput, nil
+func (m mockedElasticFileSystem) DescribeFileSystems(ctx context.Context, params *efs.DescribeFileSystemsInput, optFns ...func(*efs.Options)) (*efs.DescribeFileSystemsOutput, error) {
+	return &m.DescribeFileSystemsOutput, nil
 }
 
 func TestEFS_GetAll(t *testing.T) {
-
 	t.Parallel()
-
 	testId1 := "testId1"
 	testName1 := "test-efs1"
 	testId2 := "testId2"
@@ -60,8 +55,8 @@ func TestEFS_GetAll(t *testing.T) {
 	now := time.Now()
 	ef := ElasticFileSystem{
 		Client: mockedElasticFileSystem{
-			DescribeFileSystemsPagesOutput: efs.DescribeFileSystemsOutput{
-				FileSystems: []*efs.FileSystemDescription{
+			DescribeFileSystemsOutput: efs.DescribeFileSystemsOutput{
+				FileSystems: []types.FileSystemDescription{
 					{
 						FileSystemId: aws.String(testId1),
 						Name:         aws.String(testName1),
@@ -108,28 +103,24 @@ func TestEFS_GetAll(t *testing.T) {
 				ElasticFileSystem: tc.configObj,
 			})
 			require.NoError(t, err)
-			require.Equal(t, tc.expected, aws.StringValueSlice(names))
+			require.Equal(t, tc.expected, aws.ToStringSlice(names))
 		})
 	}
-
 }
 
 func TestEFS_NukeAll(t *testing.T) {
-
 	t.Parallel()
-
 	ef := ElasticFileSystem{
 		Client: mockedElasticFileSystem{
-
 			DescribeAccessPointsOutput: efs.DescribeAccessPointsOutput{
-				AccessPoints: []*efs.AccessPointDescription{
+				AccessPoints: []types.AccessPointDescription{
 					{
 						AccessPointId: aws.String("fsap-1234567890abcdef0"),
 					},
 				},
 			},
 			DescribeMountTargetsOutput: efs.DescribeMountTargetsOutput{
-				MountTargets: []*efs.MountTargetDescription{
+				MountTargets: []types.MountTargetDescription{
 					{
 						MountTargetId: aws.String("fsmt-1234567890abcdef0"),
 					},
diff --git a/aws/resources/eip_test.go b/aws/resources/eip_test.go
index f7b5fad..f60eaf0 100644
--- a/aws/resources/eip_test.go
+++ b/aws/resources/eip_test.go
@@ -6,31 +6,29 @@ import (
 	"testing"
 	"time"
 
-	awsgo "github.com/aws/aws-sdk-go/aws"
-	"github.com/aws/aws-sdk-go/aws/request"
-	"github.com/aws/aws-sdk-go/service/ec2"
-	"github.com/aws/aws-sdk-go/service/ec2/ec2iface"
+	"github.com/aws/aws-sdk-go-v2/aws"
+	"github.com/aws/aws-sdk-go-v2/service/ec2"
+	"github.com/aws/aws-sdk-go-v2/service/ec2/types"
 	"github.com/gruntwork-io/cloud-nuke/config"
 	"github.com/gruntwork-io/cloud-nuke/util"
 	"github.com/stretchr/testify/require"
 )
 
 type mockedEIPAddresses struct {
-	ec2iface.EC2API
-	DescribeAddressesOutput ec2.DescribeAddressesOutput
+	EIPAddressesAPI
 	ReleaseAddressOutput    ec2.ReleaseAddressOutput
+	DescribeAddressesOutput ec2.DescribeAddressesOutput
 }
 
-func (m mockedEIPAddresses) DescribeAddressesWithContext(_ awsgo.Context, _ *ec2.DescribeAddressesInput, _ ...request.Option) (*ec2.DescribeAddressesOutput, error) {
-	return &m.DescribeAddressesOutput, nil
+func (m mockedEIPAddresses) ReleaseAddress(ctx context.Context, params *ec2.ReleaseAddressInput, optFns ...func(*ec2.Options)) (*ec2.ReleaseAddressOutput, error) {
+	return &m.ReleaseAddressOutput, nil
 }
 
-func (m mockedEIPAddresses) ReleaseAddressWithContext(_ awsgo.Context, _ *ec2.ReleaseAddressInput, _ ...request.Option) (*ec2.ReleaseAddressOutput, error) {
-	return &m.ReleaseAddressOutput, nil
+func (m mockedEIPAddresses) DescribeAddresses(ctx context.Context, params *ec2.DescribeAddressesInput, optFns ...func(*ec2.Options)) (*ec2.DescribeAddressesOutput, error) {
+	return &m.DescribeAddressesOutput, nil
 }
 
 func TestEIPAddress_GetAll(t *testing.T) {
-
 	t.Parallel()
 
 	// Set excludeFirstSeenTag to false for testing
@@ -44,30 +42,30 @@ func TestEIPAddress_GetAll(t *testing.T) {
 	ea := EIPAddresses{
 		Client: &mockedEIPAddresses{
 			DescribeAddressesOutput: ec2.DescribeAddressesOutput{
-				Addresses: []*ec2.Address{
+				Addresses: []types.Address{
 					{
-						AllocationId: awsgo.String(testAllocId1),
-						Tags: []*ec2.Tag{
+						AllocationId: aws.String(testAllocId1),
+						Tags: []types.Tag{
 							{
-								Key:   awsgo.String("Name"),
-								Value: awsgo.String(testName1),
+								Key:   aws.String("Name"),
+								Value: aws.String(testName1),
 							},
 							{
-								Key:   awsgo.String(util.FirstSeenTagKey),
-								Value: awsgo.String(util.FormatTimestamp(now)),
+								Key:   aws.String(util.FirstSeenTagKey),
+								Value: aws.String(util.FormatTimestamp(now)),
 							},
 						},
 					},
 					{
-						AllocationId: awsgo.String(testAllocId2),
-						Tags: []*ec2.Tag{
+						AllocationId: aws.String(testAllocId2),
+						Tags: []types.Tag{
 							{
-								Key:   awsgo.String("Name"),
-								Value: awsgo.String(testName2),
+								Key:   aws.String("Name"),
+								Value: aws.String(testName2),
 							},
 							{
-								Key:   awsgo.String(util.FirstSeenTagKey),
-								Value: awsgo.String(util.FormatTimestamp(now.Add(1))),
+								Key:   aws.String(util.FirstSeenTagKey),
+								Value: aws.String(util.FormatTimestamp(now.Add(1))),
 							},
 						},
 					},
@@ -100,7 +98,7 @@ func TestEIPAddress_GetAll(t *testing.T) {
 			ctx: ctx,
 			configObj: config.ResourceType{
 				ExcludeRule: config.FilterRule{
-					TimeAfter: awsgo.Time(now.Add(-1 * time.Hour)),
+					TimeAfter: aws.Time(now.Add(-1 * time.Hour)),
 				}},
 			expected: []string{},
 		},
@@ -111,22 +109,19 @@ func TestEIPAddress_GetAll(t *testing.T) {
 				ElasticIP: tc.configObj,
 			})
 			require.NoError(t, err)
-			require.Equal(t, tc.expected, awsgo.StringValueSlice(names))
+			require.Equal(t, tc.expected, aws.ToStringSlice(names))
 		})
 	}
-
 }
 
 func TestEIPAddress_NukeAll(t *testing.T) {
-
 	t.Parallel()
-
 	ea := EIPAddresses{
 		Client: &mockedEIPAddresses{
 			ReleaseAddressOutput: ec2.ReleaseAddressOutput{},
 		},
 	}
 
-	err := ea.nukeAll([]*string{awsgo.String("alloc1")})
+	err := ea.nukeAll([]*string{aws.String("alloc1")})
 	require.NoError(t, err)
 }
diff --git a/aws/resources/eks_test.go b/aws/resources/eks_test.go
index f19a757..9b0b5f5 100644
--- a/aws/resources/eks_test.go
+++ b/aws/resources/eks_test.go
@@ -5,86 +5,62 @@ import (
 	"testing"
 	"time"
 
-	awsgo "github.com/aws/aws-sdk-go/aws"
-	"github.com/aws/aws-sdk-go/aws/request"
-
-	"github.com/aws/aws-sdk-go/service/eks"
-	"github.com/aws/aws-sdk-go/service/eks/eksiface"
+	"github.com/aws/aws-sdk-go-v2/aws"
+	"github.com/aws/aws-sdk-go-v2/service/eks"
+	"github.com/aws/aws-sdk-go-v2/service/eks/types"
 	"github.com/gruntwork-io/cloud-nuke/config"
 	"github.com/stretchr/testify/require"
 )
 
 type mockedEKSCluster struct {
-	eksiface.EKSAPI
-
-	ListClustersOutput    eks.ListClustersOutput
-	DescribeClusterOutput eks.DescribeClusterOutput
-	DeleteClusterOutput   eks.DeleteClusterOutput
-
-	ListFargateProfilesOutput  eks.ListFargateProfilesOutput
-	DeleteFargateProfileOutput eks.DeleteFargateProfileOutput
-
-	DescribeNodegroupOutput eks.DescribeNodegroupOutput
-	ListNodegroupsOutput    eks.ListNodegroupsOutput
-	DeleteNodegroupOutput   eks.DeleteNodegroupOutput
+	EKSClustersAPI
+	DeleteClusterOutput          eks.DeleteClusterOutput
+	DeleteFargateProfileOutput   eks.DeleteFargateProfileOutput
+	DeleteNodegroupOutput        eks.DeleteNodegroupOutput
+	DescribeClusterOutput        eks.DescribeClusterOutput
+	DescribeFargateProfileOutput eks.DescribeFargateProfileOutput
+	DescribeNodegroupOutput      eks.DescribeNodegroupOutput
+	ListClustersOutput           eks.ListClustersOutput
+	ListFargateProfilesOutput    eks.ListFargateProfilesOutput
+	ListNodegroupsOutput         eks.ListNodegroupsOutput
 }
 
-func (m mockedEKSCluster) ListClustersWithContext(_ awsgo.Context, _ *eks.ListClustersInput, _ ...request.Option) (*eks.ListClustersOutput, error) {
-	// Only need to return mocked response output
-	return &m.ListClustersOutput, nil
-}
-
-func (m mockedEKSCluster) DescribeClusterWithContext(_ awsgo.Context, _ *eks.DescribeClusterInput, _ ...request.Option) (*eks.DescribeClusterOutput, error) {
-	// Only need to return mocked response output
-	return &m.DescribeClusterOutput, nil
+func (m mockedEKSCluster) DeleteCluster(ctx context.Context, params *eks.DeleteClusterInput, optFns ...func(*eks.Options)) (*eks.DeleteClusterOutput, error) {
+	return &m.DeleteClusterOutput, nil
 }
 
-func (m mockedEKSCluster) ListNodegroupsPagesWithContext(
-	_ awsgo.Context,
-	input *eks.ListNodegroupsInput, fn func(*eks.ListNodegroupsOutput, bool) bool,
-	_ ...request.Option) error {
-	// Only need to return mocked response output
-	fn(&m.ListNodegroupsOutput, true)
-	return nil
+func (m mockedEKSCluster) DeleteFargateProfile(ctx context.Context, params *eks.DeleteFargateProfileInput, optFns ...func(*eks.Options)) (*eks.DeleteFargateProfileOutput, error) {
+	return &m.DeleteFargateProfileOutput, nil
 }
 
-func (m mockedEKSCluster) DeleteNodegroupWithContext(_ awsgo.Context, _ *eks.DeleteNodegroupInput, _ ...request.Option) (*eks.DeleteNodegroupOutput, error) {
-	// Only need to return mocked response output
+func (m mockedEKSCluster) DeleteNodegroup(ctx context.Context, params *eks.DeleteNodegroupInput, optFns ...func(*eks.Options)) (*eks.DeleteNodegroupOutput, error) {
 	return &m.DeleteNodegroupOutput, nil
 }
 
-func (m mockedEKSCluster) WaitUntilNodegroupDeletedWithContext(_ awsgo.Context, input *eks.DescribeNodegroupInput, _ ...request.WaiterOption) error {
-	return nil
+func (m mockedEKSCluster) DescribeCluster(ctx context.Context, params *eks.DescribeClusterInput, optFns ...func(*eks.Options)) (*eks.DescribeClusterOutput, error) {
+	return &m.DescribeClusterOutput, nil
 }
 
-func (m mockedEKSCluster) ListFargateProfilesPagesWithContext(
-	_ awsgo.Context,
-	input *eks.ListFargateProfilesInput, fn func(*eks.ListFargateProfilesOutput, bool) bool,
-	_ ...request.Option) error {
-	// Only need to return mocked response output
-	fn(&m.ListFargateProfilesOutput, true)
-	return nil
+func (m mockedEKSCluster) DescribeFargateProfile(ctx context.Context, params *eks.DescribeFargateProfileInput, optFns ...func(*eks.Options)) (*eks.DescribeFargateProfileOutput, error) {
+	return &m.DescribeFargateProfileOutput, nil
 }
 
-func (m mockedEKSCluster) DeleteFargateProfileWithContext(_ awsgo.Context, input *eks.DeleteFargateProfileInput, _ ...request.Option) (*eks.DeleteFargateProfileOutput, error) {
-	// Only need to return mocked response output
-	return &m.DeleteFargateProfileOutput, nil
+func (m mockedEKSCluster) DescribeNodegroup(ctx context.Context, params *eks.DescribeNodegroupInput, optFns ...func(*eks.Options)) (*eks.DescribeNodegroupOutput, error) {
+	return &m.DescribeNodegroupOutput, nil
 }
 
-func (m mockedEKSCluster) WaitUntilFargateProfileDeletedWithContext(_ awsgo.Context, input *eks.DescribeFargateProfileInput, _ ...request.WaiterOption) error {
-	return nil
+func (m mockedEKSCluster) ListClusters(ctx context.Context, params *eks.ListClustersInput, optFns ...func(*eks.Options)) (*eks.ListClustersOutput, error) {
+	return &m.ListClustersOutput, nil
 }
 
-func (m mockedEKSCluster) WaitUntilClusterDeletedWithContext(_ awsgo.Context, input *eks.DescribeClusterInput, _ ...request.WaiterOption) error {
-	return nil
+func (m mockedEKSCluster) ListFargateProfiles(ctx context.Context, params *eks.ListFargateProfilesInput, optFns ...func(*eks.Options)) (*eks.ListFargateProfilesOutput, error) {
+	return &m.ListFargateProfilesOutput, nil
 }
 
-func (m mockedEKSCluster) DeleteClusterWithContext(_ awsgo.Context, input *eks.DeleteClusterInput, _ ...request.Option) (*eks.DeleteClusterOutput, error) {
-	return &m.DeleteClusterOutput, nil
+func (m mockedEKSCluster) ListNodegroups(ctx context.Context, params *eks.ListNodegroupsInput, optFns ...func(*eks.Options)) (*eks.ListNodegroupsOutput, error) {
+	return &m.ListNodegroupsOutput, nil
 }
-
 func TestEKSClusterGetAll(t *testing.T) {
-
 	t.Parallel()
 
 	testClusterName := "test_cluster1"
@@ -92,37 +68,34 @@ func TestEKSClusterGetAll(t *testing.T) {
 	eksCluster := EKSClusters{
 		Client: mockedEKSCluster{
 			ListClustersOutput: eks.ListClustersOutput{
-				Clusters: []*string{awsgo.String(testClusterName)},
+				Clusters: []string{testClusterName},
 			},
 			DescribeClusterOutput: eks.DescribeClusterOutput{
-				Cluster: &eks.Cluster{CreatedAt: &now},
+				Cluster: &types.Cluster{CreatedAt: &now},
 			},
 		},
 	}
 
 	clusters, err := eksCluster.getAll(context.Background(), config.Config{})
 	require.NoError(t, err)
-	require.Contains(t, awsgo.StringValueSlice(clusters), testClusterName)
+	require.Contains(t, aws.ToStringSlice(clusters), testClusterName)
 }
 
 func TestEKSClusterNukeAll(t *testing.T) {
-
 	t.Parallel()
-
 	testClusterName := "test_cluster1"
-	testFargateProfileName := "test_fargate_profile1"
-	testNodeGroupName := "test_nodegroup1"
 	eksCluster := EKSClusters{
+		BaseAwsResource: BaseAwsResource{
+			Context: context.Background(),
+		},
 		Client: mockedEKSCluster{
-			ListNodegroupsOutput: eks.ListNodegroupsOutput{
-				Nodegroups: []*string{&testNodeGroupName},
-			},
-			DescribeClusterOutput: eks.DescribeClusterOutput{},
-			ListFargateProfilesOutput: eks.ListFargateProfilesOutput{
-				FargateProfileNames: []*string{&testFargateProfileName},
-			},
-			DeleteFargateProfileOutput: eks.DeleteFargateProfileOutput{},
-			DeleteClusterOutput:        eks.DeleteClusterOutput{},
+			ListNodegroupsOutput:         eks.ListNodegroupsOutput{},
+			DescribeClusterOutput:        eks.DescribeClusterOutput{},
+			ListFargateProfilesOutput:    eks.ListFargateProfilesOutput{},
+			DescribeNodegroupOutput:      eks.DescribeNodegroupOutput{},
+			DeleteFargateProfileOutput:   eks.DeleteFargateProfileOutput{},
+			DeleteClusterOutput:          eks.DeleteClusterOutput{},
+			DescribeFargateProfileOutput: eks.DescribeFargateProfileOutput{},
 		},
 	}
 
diff --git a/aws/resources/elastic_beanstalk_test.go b/aws/resources/elastic_beanstalk_test.go
index 4d73395..1abaafa 100644
--- a/aws/resources/elastic_beanstalk_test.go
+++ b/aws/resources/elastic_beanstalk_test.go
@@ -6,25 +6,25 @@ import (
 	"testing"
 	"time"
 
-	"github.com/aws/aws-sdk-go/aws"
-	"github.com/aws/aws-sdk-go/aws/request"
-	"github.com/aws/aws-sdk-go/service/elasticbeanstalk"
-	"github.com/aws/aws-sdk-go/service/elasticbeanstalk/elasticbeanstalkiface"
+	"github.com/aws/aws-sdk-go-v2/aws"
+	"github.com/aws/aws-sdk-go-v2/service/elasticbeanstalk"
+	"github.com/aws/aws-sdk-go-v2/service/elasticbeanstalk/types"
 	"github.com/gruntwork-io/cloud-nuke/config"
 	"github.com/stretchr/testify/require"
 )
 
 type mockedEBApplication struct {
-	elasticbeanstalkiface.ElasticBeanstalkAPI
+	EBApplicationsAPI
 	DescribeApplicationsOutput elasticbeanstalk.DescribeApplicationsOutput
+	DeleteApplicationOutput    elasticbeanstalk.DeleteApplicationOutput
 }
 
-func (mock *mockedEBApplication) DescribeApplicationsWithContext(_ aws.Context, req *elasticbeanstalk.DescribeApplicationsInput, _ ...request.Option) (*elasticbeanstalk.DescribeApplicationsOutput, error) {
-	return &mock.DescribeApplicationsOutput, nil
+func (m *mockedEBApplication) DescribeApplications(ctx context.Context, params *elasticbeanstalk.DescribeApplicationsInput, optFns ...func(*elasticbeanstalk.Options)) (*elasticbeanstalk.DescribeApplicationsOutput, error) {
+	return &m.DescribeApplicationsOutput, nil
 }
 
-func (mock *mockedEBApplication) DeleteApplicationWithContext(_ aws.Context, _ *elasticbeanstalk.DeleteApplicationInput, _ ...request.Option) (*elasticbeanstalk.DeleteApplicationOutput, error) {
-	return nil, nil
+func (m *mockedEBApplication) DeleteApplication(ctx context.Context, params *elasticbeanstalk.DeleteApplicationInput, optFns ...func(*elasticbeanstalk.Options)) (*elasticbeanstalk.DeleteApplicationOutput, error) {
+	return &m.DeleteApplicationOutput, nil
 }
 
 func TestEBApplication_GetAll(t *testing.T) {
@@ -37,7 +37,7 @@ func TestEBApplication_GetAll(t *testing.T) {
 	eb := EBApplications{
 		Client: &mockedEBApplication{
 			DescribeApplicationsOutput: elasticbeanstalk.DescribeApplicationsOutput{
-				Applications: []*elasticbeanstalk.ApplicationDescription{
+				Applications: []types.ApplicationDescription{
 					{
 						ApplicationArn:  aws.String("app-arn-01"),
 						ApplicationName: &app1,
@@ -94,7 +94,7 @@ func TestEBApplication_GetAll(t *testing.T) {
 				ElasticBeanstalk: tc.configObj,
 			})
 			require.NoError(t, err)
-			require.Equal(t, tc.expected, aws.StringValueSlice(names))
+			require.Equal(t, tc.expected, aws.ToStringSlice(names))
 		})
 	}
 }
diff --git a/aws/resources/elasticache_test.go b/aws/resources/elasticache_test.go
index 59c04ee..9618972 100644
--- a/aws/resources/elasticache_test.go
+++ b/aws/resources/elasticache_test.go
@@ -6,39 +6,38 @@ import (
 	"testing"
 	"time"
 
-	"github.com/aws/aws-sdk-go/aws"
-	"github.com/aws/aws-sdk-go/aws/request"
-	"github.com/aws/aws-sdk-go/service/elasticache"
-	"github.com/aws/aws-sdk-go/service/elasticache/elasticacheiface"
+	"github.com/aws/aws-sdk-go-v2/aws"
+	"github.com/aws/aws-sdk-go-v2/service/elasticache"
+	"github.com/aws/aws-sdk-go-v2/service/elasticache/types"
 	"github.com/gruntwork-io/cloud-nuke/config"
 	"github.com/stretchr/testify/require"
 )
 
 type mockedElasticache struct {
-	elasticacheiface.ElastiCacheAPI
+	ElasticachesAPI
 	DescribeReplicationGroupsOutput elasticache.DescribeReplicationGroupsOutput
 	DescribeCacheClustersOutput     elasticache.DescribeCacheClustersOutput
+	DeleteCacheClusterOutput        elasticache.DeleteCacheClusterOutput
 	DeleteReplicationGroupOutput    elasticache.DeleteReplicationGroupOutput
 }
 
-func (m mockedElasticache) DescribeCacheClustersWithContext(_ aws.Context, input *elasticache.DescribeCacheClustersInput, _ ...request.Option) (*elasticache.DescribeCacheClustersOutput, error) {
-	return &m.DescribeCacheClustersOutput, nil
+func (m mockedElasticache) DescribeReplicationGroups(ctx context.Context, params *elasticache.DescribeReplicationGroupsInput, optFns ...func(*elasticache.Options)) (*elasticache.DescribeReplicationGroupsOutput, error) {
+	return &m.DescribeReplicationGroupsOutput, nil
 }
 
-func (m mockedElasticache) DescribeReplicationGroupsWithContext(_ aws.Context, input *elasticache.DescribeReplicationGroupsInput, _ ...request.Option) (*elasticache.DescribeReplicationGroupsOutput, error) {
-	return &m.DescribeReplicationGroupsOutput, nil
+func (m mockedElasticache) DescribeCacheClusters(ctx context.Context, params *elasticache.DescribeCacheClustersInput, optFns ...func(*elasticache.Options)) (*elasticache.DescribeCacheClustersOutput, error) {
+	return &m.DescribeCacheClustersOutput, nil
 }
 
-func (m mockedElasticache) DeleteReplicationGroupWithContext(_ aws.Context, input *elasticache.DeleteReplicationGroupInput, _ ...request.Option) (*elasticache.DeleteReplicationGroupOutput, error) {
-	return &m.DeleteReplicationGroupOutput, nil
+func (m mockedElasticache) DeleteCacheCluster(ctx context.Context, params *elasticache.DeleteCacheClusterInput, optFns ...func(*elasticache.Options)) (*elasticache.DeleteCacheClusterOutput, error) {
+	return &m.DeleteCacheClusterOutput, nil
 }
 
-func (m mockedElasticache) WaitUntilReplicationGroupDeletedWithContext(_ aws.Context, input *elasticache.DescribeReplicationGroupsInput, _ ...request.WaiterOption) error {
-	return nil
+func (m mockedElasticache) DeleteReplicationGroup(ctx context.Context, params *elasticache.DeleteReplicationGroupInput, optFns ...func(*elasticache.Options)) (*elasticache.DeleteReplicationGroupOutput, error) {
+	return &m.DeleteReplicationGroupOutput, nil
 }
 
 func TestElasticache_GetAll(t *testing.T) {
-
 	t.Parallel()
 
 	now := time.Now()
@@ -47,7 +46,7 @@ func TestElasticache_GetAll(t *testing.T) {
 	ec := Elasticaches{
 		Client: mockedElasticache{
 			DescribeReplicationGroupsOutput: elasticache.DescribeReplicationGroupsOutput{
-				ReplicationGroups: []*elasticache.ReplicationGroup{
+				ReplicationGroups: []types.ReplicationGroup{
 					{
 						ReplicationGroupId:         aws.String(testName1),
 						ReplicationGroupCreateTime: aws.Time(now),
@@ -59,7 +58,7 @@ func TestElasticache_GetAll(t *testing.T) {
 				},
 			},
 			DescribeCacheClustersOutput: elasticache.DescribeCacheClustersOutput{
-				CacheClusters: []*elasticache.CacheCluster{},
+				CacheClusters: []types.CacheCluster{},
 			},
 		},
 	}
@@ -95,23 +94,25 @@ func TestElasticache_GetAll(t *testing.T) {
 				Elasticache: tc.configObj,
 			})
 			require.NoError(t, err)
-			require.Equal(t, tc.expected, aws.StringValueSlice(names))
+			require.Equal(t, tc.expected, aws.ToStringSlice(names))
 		})
 	}
 }
 
 func TestElasticache_NukeAll(t *testing.T) {
-
 	t.Parallel()
 
-	now := time.Now()
 	ec := Elasticaches{
+		BaseAwsResource: BaseAwsResource{
+			Context: context.Background(),
+		},
 		Client: mockedElasticache{
 			DescribeReplicationGroupsOutput: elasticache.DescribeReplicationGroupsOutput{
-				ReplicationGroups: []*elasticache.ReplicationGroup{
+				ReplicationGroups: []types.ReplicationGroup{
 					{
 						ReplicationGroupId:         aws.String("test-name-1"),
-						ReplicationGroupCreateTime: aws.Time(now),
+						ReplicationGroupCreateTime: aws.Time(time.Now()),
+						Status:                     aws.String("deleted"),
 					},
 				},
 			},
diff --git a/aws/resources/elb_test.go b/aws/resources/elb_test.go
index b594b9a..b96757e 100644
--- a/aws/resources/elb_test.go
+++ b/aws/resources/elb_test.go
@@ -6,32 +6,28 @@ import (
 	"testing"
 	"time"
 
-	"github.com/aws/aws-sdk-go/aws"
-	"github.com/aws/aws-sdk-go/aws/awserr"
-	"github.com/aws/aws-sdk-go/aws/request"
-	"github.com/aws/aws-sdk-go/service/elb"
-	"github.com/aws/aws-sdk-go/service/elb/elbiface"
+	"github.com/aws/aws-sdk-go-v2/aws"
+	"github.com/aws/aws-sdk-go-v2/service/elasticloadbalancing"
+	"github.com/aws/aws-sdk-go-v2/service/elasticloadbalancing/types"
 	"github.com/gruntwork-io/cloud-nuke/config"
 	"github.com/stretchr/testify/require"
 )
 
 type mockedLoadBalancers struct {
-	elbiface.ELBAPI
-	DescribeLoadBalancersOutput elb.DescribeLoadBalancersOutput
-	DeleteLoadBalancerOutput    elb.DeleteLoadBalancerOutput
-	DescribeLoadBalancersError  error
+	LoadBalancersAPI
+	DescribeLoadBalancersOutput elasticloadbalancing.DescribeLoadBalancersOutput
+	DeleteLoadBalancerOutput    elasticloadbalancing.DeleteLoadBalancerOutput
 }
 
-func (m mockedLoadBalancers) DescribeLoadBalancersWithContext(_ aws.Context, input *elb.DescribeLoadBalancersInput, _ ...request.Option) (*elb.DescribeLoadBalancersOutput, error) {
+func (m mockedLoadBalancers) DescribeLoadBalancers(ctx context.Context, params *elasticloadbalancing.DescribeLoadBalancersInput, optFns ...func(*elasticloadbalancing.Options)) (*elasticloadbalancing.DescribeLoadBalancersOutput, error) {
 	return &m.DescribeLoadBalancersOutput, nil
 }
 
-func (m mockedLoadBalancers) DeleteLoadBalancerWithContext(_ aws.Context, input *elb.DeleteLoadBalancerInput, _ ...request.Option) (*elb.DeleteLoadBalancerOutput, error) {
-	return &m.DeleteLoadBalancerOutput, m.DescribeLoadBalancersError
+func (m mockedLoadBalancers) DeleteLoadBalancer(ctx context.Context, params *elasticloadbalancing.DeleteLoadBalancerInput, optFns ...func(*elasticloadbalancing.Options)) (*elasticloadbalancing.DeleteLoadBalancerOutput, error) {
+	return &m.DeleteLoadBalancerOutput, nil
 }
 
 func TestElb_GetAll(t *testing.T) {
-
 	t.Parallel()
 
 	testName1 := "test-name-1"
@@ -39,8 +35,8 @@ func TestElb_GetAll(t *testing.T) {
 	now := time.Now()
 	balancer := LoadBalancers{
 		Client: mockedLoadBalancers{
-			DescribeLoadBalancersOutput: elb.DescribeLoadBalancersOutput{
-				LoadBalancerDescriptions: []*elb.LoadBalancerDescription{
+			DescribeLoadBalancersOutput: elasticloadbalancing.DescribeLoadBalancersOutput{
+				LoadBalancerDescriptions: []types.LoadBalancerDescription{
 					{
 						LoadBalancerName: aws.String(testName1),
 						CreatedTime:      aws.Time(now),
@@ -85,19 +81,17 @@ func TestElb_GetAll(t *testing.T) {
 				ELBv1: tc.configObj,
 			})
 			require.NoError(t, err)
-			require.Equal(t, tc.expected, aws.StringValueSlice(names))
+			require.Equal(t, tc.expected, aws.ToStringSlice(names))
 		})
 	}
 }
 
 func TestElb_NukeAll(t *testing.T) {
-
 	t.Parallel()
 
 	balancer := LoadBalancers{
 		Client: mockedLoadBalancers{
-			DeleteLoadBalancerOutput:   elb.DeleteLoadBalancerOutput{},
-			DescribeLoadBalancersError: awserr.New("LoadBalancerNotFound", "", nil),
+			DeleteLoadBalancerOutput: elasticloadbalancing.DeleteLoadBalancerOutput{},
 		},
 	}
 
diff --git a/aws/resources/elbv2_test.go b/aws/resources/elbv2_test.go
index 34c0ae3..16d7dad 100644
--- a/aws/resources/elbv2_test.go
+++ b/aws/resources/elbv2_test.go
@@ -2,40 +2,36 @@ package resources
 
 import (
 	"context"
+	"fmt"
 	"regexp"
 	"testing"
 	"time"
 
-	"github.com/aws/aws-sdk-go/aws"
-	"github.com/aws/aws-sdk-go/aws/request"
-	"github.com/aws/aws-sdk-go/service/elbv2"
-	"github.com/aws/aws-sdk-go/service/elbv2/elbv2iface"
+	"github.com/aws/aws-sdk-go-v2/aws"
+	"github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2"
+	"github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2/types"
+	"github.com/aws/smithy-go"
 	"github.com/gruntwork-io/cloud-nuke/config"
 	"github.com/stretchr/testify/require"
 )
 
 type mockedElbV2 struct {
-	elbv2iface.ELBV2API
-	DescribeLoadBalancersOutput elbv2.DescribeLoadBalancersOutput
-	DeleteLoadBalancerOutput    elbv2.DeleteLoadBalancerOutput
+	LoadBalancersV2API
+	DescribeLoadBalancersOutput    elasticloadbalancingv2.DescribeLoadBalancersOutput
+	ErrDescribeLoadBalancersOutput error
+	DeleteLoadBalancerOutput       elasticloadbalancingv2.DeleteLoadBalancerOutput
 }
 
-func (m mockedElbV2) DescribeLoadBalancersWithContext(_ aws.Context, input *elbv2.DescribeLoadBalancersInput, _ ...request.Option) (*elbv2.DescribeLoadBalancersOutput, error) {
-	return &m.DescribeLoadBalancersOutput, nil
+func (m mockedElbV2) DescribeLoadBalancers(ctx context.Context, params *elasticloadbalancingv2.DescribeLoadBalancersInput, optFns ...func(*elasticloadbalancingv2.Options)) (*elasticloadbalancingv2.DescribeLoadBalancersOutput, error) {
+	return &m.DescribeLoadBalancersOutput, m.ErrDescribeLoadBalancersOutput
 }
 
-func (m mockedElbV2) DeleteLoadBalancerWithContext(_ aws.Context, input *elbv2.DeleteLoadBalancerInput, _ ...request.Option) (*elbv2.DeleteLoadBalancerOutput, error) {
+func (m mockedElbV2) DeleteLoadBalancer(ctx context.Context, params *elasticloadbalancingv2.DeleteLoadBalancerInput, optFns ...func(*elasticloadbalancingv2.Options)) (*elasticloadbalancingv2.DeleteLoadBalancerOutput, error) {
 	return &m.DeleteLoadBalancerOutput, nil
 }
 
-func (m mockedElbV2) WaitUntilLoadBalancersDeletedWithContext(_ aws.Context, input *elbv2.DescribeLoadBalancersInput, _ ...request.WaiterOption) error {
-	return nil
-}
-
 func TestElbV2_GetAll(t *testing.T) {
-
 	t.Parallel()
-
 	testName1 := "test-name-1"
 	testArn1 := "test-arn-1"
 	testName2 := "test-name-2"
@@ -43,8 +39,8 @@ func TestElbV2_GetAll(t *testing.T) {
 	now := time.Now()
 	balancer := LoadBalancersV2{
 		Client: mockedElbV2{
-			DescribeLoadBalancersOutput: elbv2.DescribeLoadBalancersOutput{
-				LoadBalancers: []*elbv2.LoadBalancer{
+			DescribeLoadBalancersOutput: elasticloadbalancingv2.DescribeLoadBalancersOutput{
+				LoadBalancers: []types.LoadBalancer{
 					{
 						LoadBalancerArn:  aws.String(testArn1),
 						LoadBalancerName: aws.String(testName1),
@@ -91,22 +87,43 @@ func TestElbV2_GetAll(t *testing.T) {
 				ELBv2: tc.configObj,
 			})
 			require.NoError(t, err)
-			require.Equal(t, tc.expected, aws.StringValueSlice(names))
+			require.Equal(t, tc.expected, aws.ToStringSlice(names))
 		})
 	}
+}
+
+type errMockLoadBalancerNotFound struct{}
 
+func (e errMockLoadBalancerNotFound) Error() string {
+	return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage())
 }
 
-func TestElbV2_NukeAll(t *testing.T) {
+func (e errMockLoadBalancerNotFound) ErrorCode() string {
+	return "LoadBalancerNotFound"
+}
 
-	t.Parallel()
+func (e errMockLoadBalancerNotFound) ErrorMessage() string {
+	return "The specified load balancer does not exist."
+}
+
+func (e errMockLoadBalancerNotFound) ErrorFault() smithy.ErrorFault {
+	return smithy.FaultServer
+}
 
+func TestElbV2_NukeAll(t *testing.T) {
+	t.Parallel()
+	var eLBNotFound errMockLoadBalancerNotFound
 	balancer := LoadBalancersV2{
+		BaseAwsResource: BaseAwsResource{
+			Context: context.Background(),
+		},
 		Client: mockedElbV2{
-			DeleteLoadBalancerOutput: elbv2.DeleteLoadBalancerOutput{},
+			DescribeLoadBalancersOutput:    elasticloadbalancingv2.DescribeLoadBalancersOutput{},
+			ErrDescribeLoadBalancersOutput: eLBNotFound,
+			DeleteLoadBalancerOutput:       elasticloadbalancingv2.DeleteLoadBalancerOutput{},
 		},
 	}
 
-	err := balancer.nukeAll([]*string{aws.String("test-arn-1"), aws.String("test-arn-2")})
+	err := balancer.nukeAll([]*string{aws.String("test-arn-1")})
 	require.NoError(t, err)
 }
diff --git a/aws/resources/guardduty_test.go b/aws/resources/guardduty_test.go
index 6aa6ec1..286d6cf 100644
--- a/aws/resources/guardduty_test.go
+++ b/aws/resources/guardduty_test.go
@@ -5,47 +5,42 @@ import (
 	"testing"
 	"time"
 
-	"github.com/aws/aws-sdk-go/aws"
-	"github.com/aws/aws-sdk-go/aws/request"
-	"github.com/aws/aws-sdk-go/service/guardduty"
-	"github.com/aws/aws-sdk-go/service/guardduty/guarddutyiface"
+	"github.com/aws/aws-sdk-go-v2/aws"
+	"github.com/aws/aws-sdk-go-v2/service/guardduty"
 	"github.com/gruntwork-io/cloud-nuke/config"
 	"github.com/stretchr/testify/require"
 )
 
 type mockedGuardDuty struct {
-	guarddutyiface.GuardDutyAPI
+	GuardDutyAPI
 	ListDetectorsPagesOutput guardduty.ListDetectorsOutput
 	GetDetectorOutput        guardduty.GetDetectorOutput
 	DeleteDetectorOutput     guardduty.DeleteDetectorOutput
 }
 
-func (m mockedGuardDuty) ListDetectorsPagesWithContext(_ aws.Context, input *guardduty.ListDetectorsInput, callback func(*guardduty.ListDetectorsOutput, bool) bool, _ ...request.Option) error {
-	callback(&m.ListDetectorsPagesOutput, true)
-	return nil
-}
-
-func (m mockedGuardDuty) GetDetectorWithContext(_ aws.Context, input *guardduty.GetDetectorInput, _ ...request.Option) (*guardduty.GetDetectorOutput, error) {
+func (m mockedGuardDuty) GetDetector(ctx context.Context, params *guardduty.GetDetectorInput, optFns ...func(*guardduty.Options)) (*guardduty.GetDetectorOutput, error) {
 	return &m.GetDetectorOutput, nil
 }
 
-func (m mockedGuardDuty) DeleteDetectorWithContext(_ aws.Context, input *guardduty.DeleteDetectorInput, _ ...request.Option) (*guardduty.DeleteDetectorOutput, error) {
+func (m mockedGuardDuty) DeleteDetector(ctx context.Context, params *guardduty.DeleteDetectorInput, optFns ...func(*guardduty.Options)) (*guardduty.DeleteDetectorOutput, error) {
 	return &m.DeleteDetectorOutput, nil
 }
 
-func TestGuardDuty_GetAll(t *testing.T) {
+func (m mockedGuardDuty) ListDetectors(ctx context.Context, params *guardduty.ListDetectorsInput, optFns ...func(*guardduty.Options)) (*guardduty.ListDetectorsOutput, error) {
+	return &m.ListDetectorsPagesOutput, nil
+}
 
+func TestGuardDuty_GetAll(t *testing.T) {
 	t.Parallel()
-
 	testId1 := "test-detector-id-1"
 	testId2 := "test-detector-id-2"
 	now := time.Now()
 	gd := GuardDuty{
 		Client: mockedGuardDuty{
 			ListDetectorsPagesOutput: guardduty.ListDetectorsOutput{
-				DetectorIds: []*string{
-					aws.String(testId1),
-					aws.String(testId2),
+				DetectorIds: []string{
+					testId1,
+					testId2,
 				},
 			},
 			GetDetectorOutput: guardduty.GetDetectorOutput{
@@ -76,15 +71,13 @@ func TestGuardDuty_GetAll(t *testing.T) {
 				GuardDuty: tc.configObj,
 			})
 			require.NoError(t, err)
-			require.Equal(t, tc.expected, aws.StringValueSlice(names))
+			require.Equal(t, tc.expected, aws.ToStringSlice(names))
 		})
 	}
 }
 
 func TestGuardDuty_NukeAll(t *testing.T) {
-
 	t.Parallel()
-
 	gd := GuardDuty{
 		Client: mockedGuardDuty{
 			DeleteDetectorOutput: guardduty.DeleteDetectorOutput{},
@@ -93,5 +86,4 @@ func TestGuardDuty_NukeAll(t *testing.T) {
 
 	err := gd.nukeAll([]string{"test"})
 	require.NoError(t, err)
-
 }