Repository: gruntwork-io/cloud-nuke
Pull request #778 (2024-11-03 10:42:28)

change port iam, iam-group, iam-policy, iam-role, iam-service-linked-role to awsSDKv2
## Description
change port resources to aws SDK v2
- iam
- iam-group
- iam-policy
- iam-role
- iam-service-linked-role

## 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)

- [x] Updated iam, iam-group, iam-policy, iam-role, iam-service-linked-role resources to awsSDKv2 

### Migration Guide
n/a


james03160927: Hi @wakeful, can you just rebase your change and resolve conflict? I ran the tests and looking good other than that. 
wakeful: hey, @james03160927 

rebase done.

Patch:
diff --git a/aws/resources/iam.go b/aws/resources/iam.go
index cd6e0cf..12f069a 100644
--- a/aws/resources/iam.go
+++ b/aws/resources/iam.go
@@ -2,30 +2,36 @@ package resources
 
 import (
 	"context"
+	goerr "errors"
 	"fmt"
 	"time"
 
+	"github.com/aws/aws-sdk-go-v2/service/iam/types"
+	"github.com/gruntwork-io/cloud-nuke/report"
 	"github.com/gruntwork-io/cloud-nuke/util"
+	"github.com/hashicorp/go-multierror"
 
-	"github.com/aws/aws-sdk-go/aws"
-	"github.com/aws/aws-sdk-go/aws/awserr"
-	"github.com/aws/aws-sdk-go/service/iam"
+	"github.com/aws/aws-sdk-go-v2/aws"
+	"github.com/aws/aws-sdk-go-v2/service/iam"
 	"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"
 	"github.com/gruntwork-io/go-commons/retry"
-	"github.com/hashicorp/go-multierror"
 )
 
 // List all IAM users in the AWS account and returns a slice of the UserNames
 func (iu *IAMUsers) getAll(c context.Context, configObj config.Config) ([]*string, error) {
+	var userNames []*string
+
 	input := &iam.ListUsersInput{}
+	paginator := iam.NewListUsersPaginator(iu.Client, input)
+	for paginator.HasMorePages() {
+		page, err := paginator.NextPage(c)
+		if err != nil {
+			return nil, errors.WithStackTrace(err)
+		}
 
-	var userNames []*string
-	err := iu.Client.ListUsersPagesWithContext(iu.Context, input, func(page *iam.ListUsersOutput, lastPage bool) bool {
 		for _, user := range page.Users {
-
 			// Note :
 			// IAM resource-listing operations return a subset of the available attributes for the resource.
 			// This operation does not return the following attributes, even though they are an attribute of the returned object:
@@ -33,13 +39,19 @@ func (iu *IAMUsers) getAll(c context.Context, configObj config.Config) ([]*strin
 			//    Tags
 			// Referene : https://docs.aws.amazon.com/cli/latest/reference/iam/list-users.html
 
-			var tags []*iam.Tag
-			iu.Client.ListUserTagsPagesWithContext(iu.Context, &iam.ListUserTagsInput{
+			var tags []types.Tag
+
+			tagsPaginator := iam.NewListUserTagsPaginator(iu.Client, &iam.ListUserTagsInput{
 				UserName: user.UserName,
-			}, func(page *iam.ListUserTagsOutput, lastPage bool) bool {
-				tags = append(tags, page.Tags...)
-				return !lastPage
 			})
+			for tagsPaginator.HasMorePages() {
+				tagsPage, errListTags := tagsPaginator.NextPage(c)
+				if errListTags != nil {
+					return nil, errors.WithStackTrace(errListTags)
+				}
+
+				tags = append(tags, tagsPage.Tags...)
+			}
 
 			if configObj.IAMUsers.ShouldInclude(config.ResourceValue{
 				Name: user.UserName,
@@ -49,15 +61,13 @@ func (iu *IAMUsers) getAll(c context.Context, configObj config.Config) ([]*strin
 				userNames = append(userNames, user.UserName)
 			}
 		}
+	}
 
-		return !lastPage
-	})
-
-	return userNames, errors.WithStackTrace(err)
+	return userNames, nil
 }
 
 func (iu *IAMUsers) detachUserPolicies(userName *string) error {
-	policiesOutput, err := iu.Client.ListAttachedUserPoliciesWithContext(iu.Context, &iam.ListAttachedUserPoliciesInput{
+	policiesOutput, err := iu.Client.ListAttachedUserPolicies(iu.Context, &iam.ListAttachedUserPoliciesInput{
 		UserName: userName,
 	})
 	if err != nil {
@@ -66,7 +76,7 @@ func (iu *IAMUsers) detachUserPolicies(userName *string) error {
 
 	for _, attachedPolicy := range policiesOutput.AttachedPolicies {
 		arn := attachedPolicy.PolicyArn
-		_, err = iu.Client.DetachUserPolicyWithContext(iu.Context, &iam.DetachUserPolicyInput{
+		_, err = iu.Client.DetachUserPolicy(iu.Context, &iam.DetachUserPolicyInput{
 			PolicyArn: arn,
 			UserName:  userName,
 		})
@@ -74,14 +84,14 @@ func (iu *IAMUsers) detachUserPolicies(userName *string) error {
 			logging.Errorf("[Failed] %s", err)
 			return errors.WithStackTrace(err)
 		}
-		logging.Debugf("Detached Policy %s from User %s", aws.StringValue(arn), aws.StringValue(userName))
+		logging.Debugf("Detached Policy %s from User %s", aws.ToString(arn), aws.ToString(userName))
 	}
 
 	return nil
 }
 
 func (iu *IAMUsers) deleteInlineUserPolicies(userName *string) error {
-	policyOutput, err := iu.Client.ListUserPoliciesWithContext(iu.Context, &iam.ListUserPoliciesInput{
+	policyOutput, err := iu.Client.ListUserPolicies(iu.Context, &iam.ListUserPoliciesInput{
 		UserName: userName,
 	})
 	if err != nil {
@@ -90,22 +100,22 @@ func (iu *IAMUsers) deleteInlineUserPolicies(userName *string) error {
 	}
 
 	for _, policyName := range policyOutput.PolicyNames {
-		_, err := iu.Client.DeleteUserPolicyWithContext(iu.Context, &iam.DeleteUserPolicyInput{
-			PolicyName: policyName,
+		_, err := iu.Client.DeleteUserPolicy(iu.Context, &iam.DeleteUserPolicyInput{
+			PolicyName: aws.String(policyName),
 			UserName:   userName,
 		})
 		if err != nil {
 			logging.Errorf("[Failed] %s", err)
 			return errors.WithStackTrace(err)
 		}
-		logging.Debugf("Deleted Inline Policy %s from User %s", aws.StringValue(policyName), aws.StringValue(userName))
+		logging.Debugf("Deleted Inline Policy %s from User %s", policyName, aws.ToString(userName))
 	}
 
 	return nil
 }
 
 func (iu *IAMUsers) removeUserFromGroups(userName *string) error {
-	groupsOutput, err := iu.Client.ListGroupsForUserWithContext(iu.Context, &iam.ListGroupsForUserInput{
+	groupsOutput, err := iu.Client.ListGroupsForUser(iu.Context, &iam.ListGroupsForUserInput{
 		UserName: userName,
 	})
 	if err != nil {
@@ -113,7 +123,7 @@ func (iu *IAMUsers) removeUserFromGroups(userName *string) error {
 	}
 
 	for _, group := range groupsOutput.Groups {
-		_, err := iu.Client.RemoveUserFromGroupWithContext(iu.Context, &iam.RemoveUserFromGroupInput{
+		_, err := iu.Client.RemoveUserFromGroup(iu.Context, &iam.RemoveUserFromGroupInput{
 			GroupName: group.GroupName,
 			UserName:  userName,
 		})
@@ -121,7 +131,7 @@ func (iu *IAMUsers) removeUserFromGroups(userName *string) error {
 			logging.Errorf("[Failed] %s", err)
 			return errors.WithStackTrace(err)
 		}
-		logging.Debugf("Removed user %s from group %s", aws.StringValue(userName), aws.StringValue(group.GroupName))
+		logging.Debugf("Removed user %s from group %s", aws.ToString(userName), aws.ToString(group.GroupName))
 	}
 
 	return nil
@@ -135,34 +145,36 @@ func (iu *IAMUsers) deleteLoginProfile(userName *string) error {
 		2*time.Second,
 		func() error {
 			// Delete Login Profile attached to the user
-			_, err := iu.Client.DeleteLoginProfileWithContext(iu.Context, &iam.DeleteLoginProfileInput{
+			_, err := iu.Client.DeleteLoginProfile(iu.Context, &iam.DeleteLoginProfileInput{
 				UserName: userName,
 			})
 			if err != nil {
-				if aerr, ok := err.(awserr.Error); ok {
-					switch aerr.Code() {
-					case iam.ErrCodeNoSuchEntityException:
-						// This is expected if the user doesn't have a Login Profile
-						// (automated users created via API calls withouth further
-						// configuration)
-						return nil
-					case iam.ErrCodeEntityTemporarilyUnmodifiableException:
-						// The request was rejected because it referenced an entity that is
-						// temporarily unmodifiable. We have to try again.
-						return fmt.Errorf("Login Profile for user %s cannot be deleted now", aws.StringValue(userName))
-					default:
-						return retry.FatalError{Underlying: err}
-					}
+				var (
+					errNoSuchEntityException                  *types.NoSuchEntityException
+					errEntityTemporarilyUnmodifiableException *types.EntityTemporarilyUnmodifiableException
+				)
+				switch {
+				case goerr.As(err, &errNoSuchEntityException):
+					// This is expected if the user doesn't have a Login Profile
+					// (automated users created via API calls withouth further
+					// configuration)
+					return nil
+				case goerr.As(err, &errEntityTemporarilyUnmodifiableException):
+					// The request was rejected because it referenced an entity that is
+					// temporarily unmodifiable. We have to try again.
+					return fmt.Errorf("Login Profile for user %s cannot be deleted now", aws.ToString(userName))
+				default:
+					return retry.FatalError{Underlying: err}
 				}
 			}
 
-			logging.Debugf("Deleted Login Profile from user %s", aws.StringValue(userName))
+			logging.Debugf("Deleted Login Profile from user %s", aws.ToString(userName))
 			return nil
 		})
 }
 
 func (iu *IAMUsers) deleteAccessKeys(userName *string) error {
-	output, err := iu.Client.ListAccessKeysWithContext(iu.Context, &iam.ListAccessKeysInput{
+	output, err := iu.Client.ListAccessKeys(iu.Context, &iam.ListAccessKeysInput{
 		UserName: userName,
 	})
 	if err != nil {
@@ -172,7 +184,7 @@ func (iu *IAMUsers) deleteAccessKeys(userName *string) error {
 
 	for _, md := range output.AccessKeyMetadata {
 		accessKeyId := md.AccessKeyId
-		_, err := iu.Client.DeleteAccessKeyWithContext(iu.Context, &iam.DeleteAccessKeyInput{
+		_, err := iu.Client.DeleteAccessKey(iu.Context, &iam.DeleteAccessKeyInput{
 			AccessKeyId: accessKeyId,
 			UserName:    userName,
 		})
@@ -181,14 +193,14 @@ func (iu *IAMUsers) deleteAccessKeys(userName *string) error {
 			return errors.WithStackTrace(err)
 		}
 
-		logging.Debugf("Deleted Access Key %s from user %s", aws.StringValue(accessKeyId), aws.StringValue(userName))
+		logging.Debugf("Deleted Access Key %s from user %s", aws.ToString(accessKeyId), aws.ToString(userName))
 	}
 
 	return nil
 }
 
 func (iu *IAMUsers) deleteSigningCertificate(userName *string) error {
-	output, err := iu.Client.ListSigningCertificatesWithContext(iu.Context, &iam.ListSigningCertificatesInput{
+	output, err := iu.Client.ListSigningCertificates(iu.Context, &iam.ListSigningCertificatesInput{
 		UserName: userName,
 	})
 	if err != nil {
@@ -198,7 +210,7 @@ func (iu *IAMUsers) deleteSigningCertificate(userName *string) error {
 
 	for _, cert := range output.Certificates {
 		certificateId := cert.CertificateId
-		_, err := iu.Client.DeleteSigningCertificateWithContext(iu.Context, &iam.DeleteSigningCertificateInput{
+		_, err := iu.Client.DeleteSigningCertificate(iu.Context, &iam.DeleteSigningCertificateInput{
 			CertificateId: certificateId,
 			UserName:      userName,
 		})
@@ -207,14 +219,14 @@ func (iu *IAMUsers) deleteSigningCertificate(userName *string) error {
 			return errors.WithStackTrace(err)
 		}
 
-		logging.Debugf("Deleted Signing Certificate ID %s from user %s", aws.StringValue(certificateId), aws.StringValue(userName))
+		logging.Debugf("Deleted Signing Certificate ID %s from user %s", aws.ToString(certificateId), aws.ToString(userName))
 	}
 
 	return nil
 }
 
 func (iu *IAMUsers) deleteSSHPublicKeys(userName *string) error {
-	output, err := iu.Client.ListSSHPublicKeysWithContext(iu.Context, &iam.ListSSHPublicKeysInput{
+	output, err := iu.Client.ListSSHPublicKeys(iu.Context, &iam.ListSSHPublicKeysInput{
 		UserName: userName,
 	})
 	if err != nil {
@@ -224,7 +236,7 @@ func (iu *IAMUsers) deleteSSHPublicKeys(userName *string) error {
 
 	for _, key := range output.SSHPublicKeys {
 		keyId := key.SSHPublicKeyId
-		_, err := iu.Client.DeleteSSHPublicKeyWithContext(iu.Context, &iam.DeleteSSHPublicKeyInput{
+		_, err := iu.Client.DeleteSSHPublicKey(iu.Context, &iam.DeleteSSHPublicKeyInput{
 			SSHPublicKeyId: keyId,
 			UserName:       userName,
 		})
@@ -233,7 +245,7 @@ func (iu *IAMUsers) deleteSSHPublicKeys(userName *string) error {
 			return errors.WithStackTrace(err)
 		}
 
-		logging.Debugf("Deleted SSH Public Key with ID %s from user %s", aws.StringValue(keyId), aws.StringValue(userName))
+		logging.Debugf("Deleted SSH Public Key with ID %s from user %s", aws.ToString(keyId), aws.ToString(userName))
 	}
 
 	return nil
@@ -245,7 +257,7 @@ func (iu *IAMUsers) deleteServiceSpecificCredentials(userName *string) error {
 		"codecommit.amazonaws.com",
 	}
 	for _, service := range services {
-		output, err := iu.Client.ListServiceSpecificCredentialsWithContext(iu.Context, &iam.ListServiceSpecificCredentialsInput{
+		output, err := iu.Client.ListServiceSpecificCredentials(iu.Context, &iam.ListServiceSpecificCredentialsInput{
 			ServiceName: aws.String(service),
 			UserName:    userName,
 		})
@@ -257,7 +269,7 @@ func (iu *IAMUsers) deleteServiceSpecificCredentials(userName *string) error {
 		for _, metadata := range output.ServiceSpecificCredentials {
 			serviceSpecificCredentialId := metadata.ServiceSpecificCredentialId
 
-			_, err := iu.Client.DeleteServiceSpecificCredentialWithContext(iu.Context, &iam.DeleteServiceSpecificCredentialInput{
+			_, err := iu.Client.DeleteServiceSpecificCredential(iu.Context, &iam.DeleteServiceSpecificCredentialInput{
 				ServiceSpecificCredentialId: serviceSpecificCredentialId,
 				UserName:                    userName,
 			})
@@ -266,7 +278,7 @@ func (iu *IAMUsers) deleteServiceSpecificCredentials(userName *string) error {
 				return errors.WithStackTrace(err)
 			}
 
-			logging.Debugf("Deleted Service Specific Credential with ID %s of service %s from user %s", aws.StringValue(serviceSpecificCredentialId), service, aws.StringValue(userName))
+			logging.Debugf("Deleted Service Specific Credential with ID %s of service %s from user %s", aws.ToString(serviceSpecificCredentialId), service, aws.ToString(userName))
 		}
 	}
 
@@ -274,7 +286,7 @@ func (iu *IAMUsers) deleteServiceSpecificCredentials(userName *string) error {
 }
 
 func (iu *IAMUsers) deleteMFADevices(userName *string) error {
-	output, err := iu.Client.ListMFADevicesWithContext(iu.Context, &iam.ListMFADevicesInput{
+	output, err := iu.Client.ListMFADevices(iu.Context, &iam.ListMFADevicesInput{
 		UserName: userName,
 	})
 	if err != nil {
@@ -286,7 +298,7 @@ func (iu *IAMUsers) deleteMFADevices(userName *string) error {
 	for _, device := range output.MFADevices {
 		serialNumber := device.SerialNumber
 
-		_, err := iu.Client.DeactivateMFADeviceWithContext(iu.Context, &iam.DeactivateMFADeviceInput{
+		_, err := iu.Client.DeactivateMFADevice(iu.Context, &iam.DeactivateMFADeviceInput{
 			SerialNumber: serialNumber,
 			UserName:     userName,
 		})
@@ -295,14 +307,14 @@ func (iu *IAMUsers) deleteMFADevices(userName *string) error {
 			return errors.WithStackTrace(err)
 		}
 
-		logging.Debugf("Deactivated Virtual MFA Device with ID %s from user %s", aws.StringValue(serialNumber), aws.StringValue(userName))
+		logging.Debugf("Deactivated Virtual MFA Device with ID %s from user %s", aws.ToString(serialNumber), aws.ToString(userName))
 	}
 
 	// After their deactivation we can delete them
 	for _, device := range output.MFADevices {
 		serialNumber := device.SerialNumber
 
-		_, err := iu.Client.DeleteVirtualMFADeviceWithContext(iu.Context, &iam.DeleteVirtualMFADeviceInput{
+		_, err := iu.Client.DeleteVirtualMFADevice(iu.Context, &iam.DeleteVirtualMFADeviceInput{
 			SerialNumber: serialNumber,
 		})
 		if err != nil {
@@ -310,14 +322,14 @@ func (iu *IAMUsers) deleteMFADevices(userName *string) error {
 			return errors.WithStackTrace(err)
 		}
 
-		logging.Debugf("Deleted Virtual MFA Device with ID %s from user %s", aws.StringValue(serialNumber), aws.StringValue(userName))
+		logging.Debugf("Deleted Virtual MFA Device with ID %s from user %s", aws.ToString(serialNumber), aws.ToString(userName))
 	}
 
 	return nil
 }
 
 func (iu *IAMUsers) deleteUser(userName *string) error {
-	_, err := iu.Client.DeleteUserWithContext(iu.Context, &iam.DeleteUserInput{
+	_, err := iu.Client.DeleteUser(iu.Context, &iam.DeleteUserInput{
 		UserName: userName,
 	})
 	if err != nil {
@@ -371,7 +383,7 @@ func (iu *IAMUsers) nukeAll(userNames []*string) error {
 		err := iu.nukeUser(userName)
 		// Record status of this resource
 		e := report.Entry{
-			Identifier:   aws.StringValue(userName),
+			Identifier:   aws.ToString(userName),
 			ResourceType: "IAM User",
 			Error:        err,
 		}
diff --git a/aws/resources/iam_group.go b/aws/resources/iam_group.go
index 96caa37..345a7e4 100644
--- a/aws/resources/iam_group.go
+++ b/aws/resources/iam_group.go
@@ -4,8 +4,8 @@ import (
 	"context"
 	"sync"
 
-	"github.com/aws/aws-sdk-go/aws"
-	"github.com/aws/aws-sdk-go/service/iam"
+	"github.com/aws/aws-sdk-go-v2/aws"
+	"github.com/aws/aws-sdk-go-v2/service/iam"
 	"github.com/gruntwork-io/cloud-nuke/config"
 	"github.com/gruntwork-io/cloud-nuke/logging"
 	"github.com/gruntwork-io/cloud-nuke/report"
@@ -15,23 +15,21 @@ import (
 
 func (ig *IAMGroups) getAll(c context.Context, configObj config.Config) ([]*string, error) {
 	var allIamGroups []*string
-	err := ig.Client.ListGroupsPagesWithContext(
-		ig.Context,
-		&iam.ListGroupsInput{},
-		func(page *iam.ListGroupsOutput, lastPage bool) bool {
-			for _, iamGroup := range page.Groups {
-				if configObj.IAMGroups.ShouldInclude(config.ResourceValue{
-					Time: iamGroup.CreateDate,
-					Name: iamGroup.GroupName,
-				}) {
-					allIamGroups = append(allIamGroups, iamGroup.GroupName)
-				}
+	paginator := iam.NewListGroupsPaginator(ig.Client, &iam.ListGroupsInput{})
+	for paginator.HasMorePages() {
+		page, err := paginator.NextPage(c)
+		if err != nil {
+			return nil, errors.WithStackTrace(err)
+		}
+
+		for _, iamGroup := range page.Groups {
+			if configObj.IAMGroups.ShouldInclude(config.ResourceValue{
+				Time: iamGroup.CreateDate,
+				Name: iamGroup.GroupName,
+			}) {
+				allIamGroups = append(allIamGroups, iamGroup.GroupName)
 			}
-			return !lastPage
-		},
-	)
-	if err != nil {
-		return nil, errors.WithStackTrace(err)
+		}
 	}
 
 	return allIamGroups, nil
@@ -44,13 +42,13 @@ func (ig *IAMGroups) nukeAll(groupNames []*string) error {
 		return nil
 	}
 
-	//Probably not required since pagination is handled by the caller
+	// Probably not required since pagination is handled by the caller
 	if len(groupNames) > 100 {
 		logging.Errorf("Nuking too many IAM Groups at once (100): Halting to avoid rate limits")
 		return TooManyIamGroupErr{}
 	}
 
-	//No bulk delete exists, do it with goroutines
+	// No bulk delete exists, do it with goroutines
 	logging.Debug("Deleting all IAM Groups")
 	wg := new(sync.WaitGroup)
 	wg.Add(len(groupNames))
@@ -61,7 +59,7 @@ func (ig *IAMGroups) nukeAll(groupNames []*string) error {
 	}
 	wg.Wait()
 
-	//Collapse the errors down to one
+	// Collapse the errors down to one
 	var allErrs *multierror.Error
 	for _, errChan := range errChans {
 		if err := <-errChan; err != nil {
@@ -82,71 +80,80 @@ func (ig *IAMGroups) deleteAsync(wg *sync.WaitGroup, errChan chan error, groupNa
 	defer wg.Done()
 	var multierr *multierror.Error
 
-	//Remove any users from the group
+	// Remove any users from the group
 	getGroupInput := &iam.GetGroupInput{
 		GroupName: groupName,
 	}
-	grp, err := ig.Client.GetGroupWithContext(ig.Context, getGroupInput)
+	grp, err := ig.Client.GetGroup(ig.Context, getGroupInput)
 	for _, user := range grp.Users {
 		unlinkUserInput := &iam.RemoveUserFromGroupInput{
 			UserName:  user.UserName,
 			GroupName: groupName,
 		}
-		_, err := ig.Client.RemoveUserFromGroupWithContext(ig.Context, unlinkUserInput)
+		_, err := ig.Client.RemoveUserFromGroup(ig.Context, unlinkUserInput)
 		if err != nil {
 			multierr = multierror.Append(multierr, err)
 		}
 	}
 
-	//Detach any policies on the group
-	allPolicies := []*string{}
-	err = ig.Client.ListAttachedGroupPoliciesPagesWithContext(ig.Context, &iam.ListAttachedGroupPoliciesInput{GroupName: groupName},
-		func(page *iam.ListAttachedGroupPoliciesOutput, lastPage bool) bool {
-			for _, iamPolicy := range page.AttachedPolicies {
-				allPolicies = append(allPolicies, iamPolicy.PolicyArn)
-			}
-			return !lastPage
-		},
-	)
+	// Detach any policies on the group
+	var allPolicies []*string
+	paginator := iam.NewListAttachedGroupPoliciesPaginator(ig.Client, &iam.ListAttachedGroupPoliciesInput{GroupName: groupName})
+	for paginator.HasMorePages() {
+		page, err := paginator.NextPage(ig.Context)
+		if err != nil {
+			multierr = multierror.Append(multierr, err)
+			break
+		}
+
+		for _, iamPolicy := range page.AttachedPolicies {
+			allPolicies = append(allPolicies, iamPolicy.PolicyArn)
+		}
+	}
 
 	for _, policy := range allPolicies {
 		unlinkPolicyInput := &iam.DetachGroupPolicyInput{
 			GroupName: groupName,
 			PolicyArn: policy,
 		}
-		_, err = ig.Client.DetachGroupPolicyWithContext(ig.Context, unlinkPolicyInput)
+		_, err = ig.Client.DetachGroupPolicy(ig.Context, unlinkPolicyInput)
 	}
 
 	// Detach any inline policies on the group
-	allInlinePolicyNames := []*string{}
-	err = ig.Client.ListGroupPoliciesPagesWithContext(ig.Context, &iam.ListGroupPoliciesInput{GroupName: groupName},
-		func(page *iam.ListGroupPoliciesOutput, lastPage bool) bool {
-			for _, policyName := range page.PolicyNames {
-				allInlinePolicyNames = append(allInlinePolicyNames, policyName)
-			}
-			return !lastPage
-		},
-	)
+	var allInlinePolicyNames []*string
+
+	policiesPaginator := iam.NewListGroupPoliciesPaginator(ig.Client, &iam.ListGroupPoliciesInput{GroupName: groupName})
+	for policiesPaginator.HasMorePages() {
+		page, err := policiesPaginator.NextPage(ig.Context)
+		if err != nil {
+			multierr = multierror.Append(multierr, err)
+			break
+		}
+
+		for _, policyName := range page.PolicyNames {
+			allInlinePolicyNames = append(allInlinePolicyNames, aws.String(policyName))
+		}
+	}
 
 	for _, policyName := range allInlinePolicyNames {
-		_, err = ig.Client.DeleteGroupPolicyWithContext(ig.Context, &iam.DeleteGroupPolicyInput{
+		_, err = ig.Client.DeleteGroupPolicy(ig.Context, &iam.DeleteGroupPolicyInput{
 			GroupName:  groupName,
 			PolicyName: policyName,
 		})
 	}
 
-	//Delete the group
-	_, err = ig.Client.DeleteGroupWithContext(ig.Context, &iam.DeleteGroupInput{
+	// Delete the group
+	_, err = ig.Client.DeleteGroup(ig.Context, &iam.DeleteGroupInput{
 		GroupName: groupName,
 	})
 	if err != nil {
 		multierr = multierror.Append(multierr, err)
 	} else {
-		logging.Debugf("[OK] IAM Group %s was deleted in global", aws.StringValue(groupName))
+		logging.Debugf("[OK] IAM Group %s was deleted in global", aws.ToString(groupName))
 	}
 
 	e := report.Entry{
-		Identifier:   aws.StringValue(groupName),
+		Identifier:   aws.ToString(groupName),
 		ResourceType: "IAM Group",
 		Error:        multierr.ErrorOrNil(),
 	}
diff --git a/aws/resources/iam_group_types.go b/aws/resources/iam_group_types.go
index bb0eaa9..7d5a9ed 100644
--- a/aws/resources/iam_group_types.go
+++ b/aws/resources/iam_group_types.go
@@ -3,25 +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/iam"
-	"github.com/aws/aws-sdk-go/service/iam/iamiface"
+	"github.com/aws/aws-sdk-go-v2/aws"
+	"github.com/aws/aws-sdk-go-v2/service/iam"
 	"github.com/gruntwork-io/cloud-nuke/config"
 	"github.com/gruntwork-io/go-commons/errors"
 )
 
+type IAMGroupsAPI interface {
+	DetachGroupPolicy(ctx context.Context, params *iam.DetachGroupPolicyInput, optFns ...func(*iam.Options)) (*iam.DetachGroupPolicyOutput, error)
+	DeleteGroupPolicy(ctx context.Context, params *iam.DeleteGroupPolicyInput, optFns ...func(*iam.Options)) (*iam.DeleteGroupPolicyOutput, error)
+	DeleteGroup(ctx context.Context, params *iam.DeleteGroupInput, optFns ...func(*iam.Options)) (*iam.DeleteGroupOutput, error)
+	GetGroup(ctx context.Context, params *iam.GetGroupInput, optFns ...func(*iam.Options)) (*iam.GetGroupOutput, error)
+	ListAttachedGroupPolicies(ctx context.Context, params *iam.ListAttachedGroupPoliciesInput, optFns ...func(*iam.Options)) (*iam.ListAttachedGroupPoliciesOutput, error)
+	ListGroups(ctx context.Context, params *iam.ListGroupsInput, optFns ...func(*iam.Options)) (*iam.ListGroupsOutput, error)
+	ListGroupPolicies(ctx context.Context, params *iam.ListGroupPoliciesInput, optFns ...func(*iam.Options)) (*iam.ListGroupPoliciesOutput, error)
+	RemoveUserFromGroup(ctx context.Context, params *iam.RemoveUserFromGroupInput, optFns ...func(*iam.Options)) (*iam.RemoveUserFromGroupOutput, error)
+}
+
 // IAMGroups - represents all IAMGroups on the AWS Account
 type IAMGroups struct {
 	BaseAwsResource
-	Client     iamiface.IAMAPI
+	Client     IAMGroupsAPI
 	GroupNames []string
 }
 
-func (ig *IAMGroups) Init(session *session.Session) {
-	ig.Client = iam.New(session)
+func (ig *IAMGroups) InitV2(cfg aws.Config) {
+	ig.Client = iam.NewFromConfig(cfg)
 }
 
+func (ig *IAMGroups) IsUsingV2() bool { return true }
+
 // ResourceName - the simple name of the AWS resource
 func (ig *IAMGroups) ResourceName() string {
 	return "iam-group"
@@ -48,13 +59,13 @@ func (ig *IAMGroups) GetAndSetIdentifiers(c context.Context, configObj config.Co
 		return nil, err
 	}
 
-	ig.GroupNames = awsgo.StringValueSlice(identifiers)
+	ig.GroupNames = aws.ToStringSlice(identifiers)
 	return ig.GroupNames, nil
 }
 
 // Nuke - Destroy every group in this collection
 func (ig *IAMGroups) Nuke(identifiers []string) error {
-	if err := ig.nukeAll(awsgo.StringSlice(identifiers)); err != nil {
+	if err := ig.nukeAll(aws.StringSlice(identifiers)); err != nil {
 		return errors.WithStackTrace(err)
 	}
 
diff --git a/aws/resources/iam_policy.go b/aws/resources/iam_policy.go
index 02574a3..461514d 100644
--- a/aws/resources/iam_policy.go
+++ b/aws/resources/iam_policy.go
@@ -4,8 +4,9 @@ import (
 	"context"
 	"sync"
 
-	"github.com/aws/aws-sdk-go/aws"
-	"github.com/aws/aws-sdk-go/service/iam"
+	"github.com/aws/aws-sdk-go-v2/aws"
+	"github.com/aws/aws-sdk-go-v2/service/iam"
+	"github.com/aws/aws-sdk-go-v2/service/iam/types"
 	"github.com/gruntwork-io/cloud-nuke/config"
 	"github.com/gruntwork-io/cloud-nuke/logging"
 	"github.com/gruntwork-io/cloud-nuke/report"
@@ -16,25 +17,21 @@ import (
 // Returns the ARN of all customer managed policies
 func (ip *IAMPolicies) getAll(c context.Context, configObj config.Config) ([]*string, error) {
 	var allIamPolicies []*string
+	paginator := iam.NewListPoliciesPaginator(ip.Client, &iam.ListPoliciesInput{Scope: types.PolicyScopeTypeLocal})
+	for paginator.HasMorePages() {
+		page, err := paginator.NextPage(c)
+		if err != nil {
+			return nil, errors.WithStackTrace(err)
+		}
 
-	err := ip.Client.ListPoliciesPagesWithContext(
-		ip.Context,
-		&iam.ListPoliciesInput{Scope: aws.String(iam.PolicyScopeTypeLocal)},
-		func(page *iam.ListPoliciesOutput, lastPage bool) bool {
-			for _, policy := range page.Policies {
-				if configObj.IAMPolicies.ShouldInclude(config.ResourceValue{
-					Name: policy.PolicyName,
-					Time: policy.CreateDate,
-				}) {
-					allIamPolicies = append(allIamPolicies, policy.Arn)
-				}
+		for _, policy := range page.Policies {
+			if configObj.IAMPolicies.ShouldInclude(config.ResourceValue{
+				Name: policy.PolicyName,
+				Time: policy.CreateDate,
+			}) {
+				allIamPolicies = append(allIamPolicies, policy.Arn)
 			}
-
-			return !lastPage
-		},
-	)
-	if err != nil {
-		return nil, errors.WithStackTrace(err)
+		}
 	}
 
 	return allIamPolicies, nil
@@ -46,13 +43,13 @@ func (ip *IAMPolicies) nukeAll(policyArns []*string) error {
 		logging.Debug("No IAM Policies to nuke")
 	}
 
-	//Probably not required since pagination is handled by the caller
+	// Probably not required since pagination is handled by the caller
 	if len(policyArns) > 100 {
 		logging.Errorf("Nuking too many IAM Policies at once (100): Halting to avoid rate limits")
 		return TooManyIamPolicyErr{}
 	}
 
-	//No Bulk Delete exists, do it with goroutines
+	// No Bulk Delete exists, do it with goroutines
 	logging.Debug("Deleting all IAM Policies")
 	wg := new(sync.WaitGroup)
 	wg.Add(len(policyArns))
@@ -63,7 +60,7 @@ func (ip *IAMPolicies) nukeAll(policyArns []*string) error {
 	}
 	wg.Wait()
 
-	//Collapse the errors down to one
+	// Collapse the errors down to one
 	var allErrs *multierror.Error
 	for _, errChan := range errChans {
 		if err := <-errChan; err != nil {
@@ -84,44 +81,46 @@ func (ip *IAMPolicies) deleteIamPolicyAsync(wg *sync.WaitGroup, errChan chan err
 	defer wg.Done()
 	var multierr *multierror.Error
 
-	//Detach any entities the policy is attached to
+	// Detach any entities the policy is attached to
 	err := ip.detachPolicyEntities(policyArn)
 	if err != nil {
 		multierr = multierror.Append(multierr, err)
 	}
 
-	//Get Old Policy Versions
+	// Get Old Policy Versions
 	var versionsToRemove []*string
-	err = ip.Client.ListPolicyVersionsPagesWithContext(ip.Context, &iam.ListPolicyVersionsInput{PolicyArn: policyArn},
-		func(page *iam.ListPolicyVersionsOutput, lastPage bool) bool {
-			for _, policyVersion := range page.Versions {
-				if !*policyVersion.IsDefaultVersion {
-					versionsToRemove = append(versionsToRemove, policyVersion.VersionId)
-				}
+	paginator := iam.NewListPolicyVersionsPaginator(ip.Client, &iam.ListPolicyVersionsInput{PolicyArn: policyArn})
+	for paginator.HasMorePages() {
+		page, err := paginator.NextPage(context.Background())
+		if err != nil {
+			multierr = multierror.Append(multierr, err)
+			break
+		}
+
+		for _, policyVersion := range page.Versions {
+			if !policyVersion.IsDefaultVersion {
+				versionsToRemove = append(versionsToRemove, policyVersion.VersionId)
 			}
-			return !lastPage
-		})
-	if err != nil {
-		multierr = multierror.Append(multierr, err)
+		}
 	}
 
-	//Delete old policy versions
+	// Delete old policy versions
 	for _, versionId := range versionsToRemove {
-		_, err = ip.Client.DeletePolicyVersionWithContext(ip.Context, &iam.DeletePolicyVersionInput{VersionId: versionId, PolicyArn: policyArn})
+		_, err = ip.Client.DeletePolicyVersion(ip.Context, &iam.DeletePolicyVersionInput{VersionId: versionId, PolicyArn: policyArn})
 		if err != nil {
 			multierr = multierror.Append(multierr, err)
 		}
 	}
-	//Delete the policy
-	_, err = ip.Client.DeletePolicyWithContext(ip.Context, &iam.DeletePolicyInput{PolicyArn: policyArn})
+	// Delete the policy
+	_, err = ip.Client.DeletePolicy(ip.Context, &iam.DeletePolicyInput{PolicyArn: policyArn})
 	if err != nil {
 		multierr = multierror.Append(multierr, err)
 	} else {
-		logging.Debugf("[OK] IAM Policy %s was deleted in global", aws.StringValue(policyArn))
+		logging.Debugf("[OK] IAM Policy %s was deleted in global", aws.ToString(policyArn))
 	}
 
 	e := report.Entry{
-		Identifier:   aws.StringValue(policyArn),
+		Identifier:   aws.ToString(policyArn),
 		ResourceType: "IAM Policy",
 		Error:        multierr.ErrorOrNil(),
 	}
@@ -134,57 +133,60 @@ func (ip *IAMPolicies) detachPolicyEntities(policyArn *string) error {
 	var allPolicyGroups []*string
 	var allPolicyRoles []*string
 	var allPolicyUsers []*string
-	err := ip.Client.ListEntitiesForPolicyPagesWithContext(ip.Context, &iam.ListEntitiesForPolicyInput{PolicyArn: policyArn},
-		func(page *iam.ListEntitiesForPolicyOutput, lastPage bool) bool {
-			for _, group := range page.PolicyGroups {
-				allPolicyGroups = append(allPolicyGroups, group.GroupName)
-			}
-			for _, role := range page.PolicyRoles {
-				allPolicyRoles = append(allPolicyRoles, role.RoleName)
-			}
-			for _, user := range page.PolicyUsers {
-				allPolicyUsers = append(allPolicyUsers, user.UserName)
-			}
-			return !lastPage
-		},
-	)
-	if err != nil {
-		return err
+
+	paginator := iam.NewListEntitiesForPolicyPaginator(ip.Client, &iam.ListEntitiesForPolicyInput{PolicyArn: policyArn})
+	for paginator.HasMorePages() {
+		page, err := paginator.NextPage(ip.Context)
+		if err != nil {
+			return errors.WithStackTrace(err)
+		}
+
+		for _, group := range page.PolicyGroups {
+			allPolicyGroups = append(allPolicyGroups, group.GroupName)
+		}
+		for _, role := range page.PolicyRoles {
+			allPolicyRoles = append(allPolicyRoles, role.RoleName)
+		}
+		for _, user := range page.PolicyUsers {
+			allPolicyUsers = append(allPolicyUsers, user.UserName)
+		}
 	}
-	//Detach policy from any users
+
+	// Detach policy from any users
 	for _, userName := range allPolicyUsers {
 		detachUserInput := &iam.DetachUserPolicyInput{
 			UserName:  userName,
 			PolicyArn: policyArn,
 		}
-		_, err = ip.Client.DetachUserPolicyWithContext(ip.Context, detachUserInput)
+		_, err := ip.Client.DetachUserPolicy(ip.Context, detachUserInput)
 		if err != nil {
-			return err
+			return errors.WithStackTrace(err)
 		}
 	}
-	//Detach policy from any groups
+	// Detach policy from any groups
 	for _, groupName := range allPolicyGroups {
 		detachGroupInput := &iam.DetachGroupPolicyInput{
 			GroupName: groupName,
 			PolicyArn: policyArn,
 		}
-		_, err = ip.Client.DetachGroupPolicyWithContext(ip.Context, detachGroupInput)
+		_, err := ip.Client.DetachGroupPolicy(ip.Context, detachGroupInput)
 		if err != nil {
-			return err
+			return errors.WithStackTrace(err)
 		}
 	}
-	//Detach policy from any roles
+	// Detach policy from any roles
 	for _, roleName := range allPolicyRoles {
 		detachRoleInput := &iam.DetachRolePolicyInput{
 			RoleName:  roleName,
 			PolicyArn: policyArn,
 		}
-		_, err = ip.Client.DetachRolePolicyWithContext(ip.Context, detachRoleInput)
+		_, err := ip.Client.DetachRolePolicy(ip.Context, detachRoleInput)
 		if err != nil {
-			return err
+			return errors.WithStackTrace(err)
 		}
 	}
-	return err
+
+	return nil
 }
 
 // TooManyIamPolicyErr Custom Errors
diff --git a/aws/resources/iam_policy_types.go b/aws/resources/iam_policy_types.go
index 7152f72..e302e85 100644
--- a/aws/resources/iam_policy_types.go
+++ b/aws/resources/iam_policy_types.go
@@ -3,25 +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/iam"
-	"github.com/aws/aws-sdk-go/service/iam/iamiface"
+	"github.com/aws/aws-sdk-go-v2/aws"
+	"github.com/aws/aws-sdk-go-v2/service/iam"
 	"github.com/gruntwork-io/cloud-nuke/config"
 	"github.com/gruntwork-io/go-commons/errors"
 )
 
+type IAMPoliciesAPI interface {
+	ListEntitiesForPolicy(ctx context.Context, params *iam.ListEntitiesForPolicyInput, optFns ...func(*iam.Options)) (*iam.ListEntitiesForPolicyOutput, error)
+	ListPolicies(ctx context.Context, params *iam.ListPoliciesInput, optFns ...func(*iam.Options)) (*iam.ListPoliciesOutput, error)
+	ListPolicyVersions(ctx context.Context, params *iam.ListPolicyVersionsInput, optFns ...func(*iam.Options)) (*iam.ListPolicyVersionsOutput, error)
+	DeletePolicy(ctx context.Context, params *iam.DeletePolicyInput, optFns ...func(*iam.Options)) (*iam.DeletePolicyOutput, error)
+	DeletePolicyVersion(ctx context.Context, params *iam.DeletePolicyVersionInput, optFns ...func(*iam.Options)) (*iam.DeletePolicyVersionOutput, error)
+	DetachGroupPolicy(ctx context.Context, params *iam.DetachGroupPolicyInput, optFns ...func(*iam.Options)) (*iam.DetachGroupPolicyOutput, error)
+	DetachUserPolicy(ctx context.Context, params *iam.DetachUserPolicyInput, optFns ...func(*iam.Options)) (*iam.DetachUserPolicyOutput, error)
+	DetachRolePolicy(ctx context.Context, params *iam.DetachRolePolicyInput, optFns ...func(*iam.Options)) (*iam.DetachRolePolicyOutput, error)
+}
+
 // IAMPolicies - represents all IAM Policies on the AWS account
 type IAMPolicies struct {
 	BaseAwsResource
-	Client     iamiface.IAMAPI
+	Client     IAMPoliciesAPI
 	PolicyArns []string
 }
 
-func (ip *IAMPolicies) Init(session *session.Session) {
-	ip.Client = iam.New(session)
+func (ip *IAMPolicies) InitV2(cfg aws.Config) {
+	ip.Client = iam.NewFromConfig(cfg)
 }
 
+func (ip *IAMPolicies) IsUsingV2() bool { return true }
+
 // ResourceName - the simple name of the AWS resource
 func (ip *IAMPolicies) ResourceName() string {
 	return "iam-policy"
@@ -47,13 +58,13 @@ func (ip *IAMPolicies) GetAndSetIdentifiers(c context.Context, configObj config.
 		return nil, err
 	}
 
-	ip.PolicyArns = awsgo.StringValueSlice(identifiers)
+	ip.PolicyArns = aws.ToStringSlice(identifiers)
 	return ip.PolicyArns, nil
 }
 
 // Nuke - Destroy every group in this collection
 func (ip *IAMPolicies) Nuke(identifiers []string) error {
-	if err := ip.nukeAll(awsgo.StringSlice(identifiers)); err != nil {
+	if err := ip.nukeAll(aws.StringSlice(identifiers)); err != nil {
 		return errors.WithStackTrace(err)
 	}
 
diff --git a/aws/resources/iam_role.go b/aws/resources/iam_role.go
index 61605e6..8568a45 100644
--- a/aws/resources/iam_role.go
+++ b/aws/resources/iam_role.go
@@ -5,8 +5,9 @@ import (
 	"strings"
 	"sync"
 
-	"github.com/aws/aws-sdk-go/aws"
-	"github.com/aws/aws-sdk-go/service/iam"
+	"github.com/aws/aws-sdk-go-v2/aws"
+	"github.com/aws/aws-sdk-go-v2/service/iam"
+	"github.com/aws/aws-sdk-go-v2/service/iam/types"
 	"github.com/gruntwork-io/cloud-nuke/config"
 	"github.com/gruntwork-io/cloud-nuke/logging"
 	"github.com/gruntwork-io/cloud-nuke/report"
@@ -16,28 +17,26 @@ import (
 
 // List all IAM Roles in the AWS account
 func (ir *IAMRoles) getAll(c context.Context, configObj config.Config) ([]*string, error) {
-	allIAMRoles := []*string{}
-	err := ir.Client.ListRolesPagesWithContext(
-		ir.Context,
-		&iam.ListRolesInput{},
-		func(page *iam.ListRolesOutput, lastPage bool) bool {
-			for _, iamRole := range page.Roles {
-				if ir.shouldInclude(iamRole, configObj) {
-					allIAMRoles = append(allIAMRoles, iamRole.RoleName)
-				}
-			}
+	var allIAMRoles []*string
+	paginator := iam.NewListRolesPaginator(ir.Client, &iam.ListRolesInput{})
+	for paginator.HasMorePages() {
+		page, err := paginator.NextPage(c)
+		if err != nil {
+			return nil, errors.WithStackTrace(err)
+		}
 
-			return !lastPage
-		},
-	)
-	if err != nil {
-		return nil, errors.WithStackTrace(err)
+		for _, iamRole := range page.Roles {
+			if ir.shouldInclude(&iamRole, configObj) {
+				allIAMRoles = append(allIAMRoles, iamRole.RoleName)
+			}
+		}
 	}
+
 	return allIAMRoles, nil
 }
 
 func (ir *IAMRoles) deleteManagedRolePolicies(roleName *string) error {
-	policiesOutput, err := ir.Client.ListAttachedRolePoliciesWithContext(ir.Context, &iam.ListAttachedRolePoliciesInput{
+	policiesOutput, err := ir.Client.ListAttachedRolePolicies(ir.Context, &iam.ListAttachedRolePoliciesInput{
 		RoleName: roleName,
 	})
 	if err != nil {
@@ -46,7 +45,7 @@ func (ir *IAMRoles) deleteManagedRolePolicies(roleName *string) error {
 
 	for _, attachedPolicy := range policiesOutput.AttachedPolicies {
 		arn := attachedPolicy.PolicyArn
-		_, err = ir.Client.DetachRolePolicyWithContext(ir.Context, &iam.DetachRolePolicyInput{
+		_, err = ir.Client.DetachRolePolicy(ir.Context, &iam.DetachRolePolicyInput{
 			PolicyArn: arn,
 			RoleName:  roleName,
 		})
@@ -54,14 +53,14 @@ func (ir *IAMRoles) deleteManagedRolePolicies(roleName *string) error {
 			logging.Errorf("[Failed] %s", err)
 			return errors.WithStackTrace(err)
 		}
-		logging.Debugf("Detached Policy %s from Role %s", aws.StringValue(arn), aws.StringValue(roleName))
+		logging.Debugf("Detached Policy %s from Role %s", aws.ToString(arn), aws.ToString(roleName))
 	}
 
 	return nil
 }
 
 func (ir *IAMRoles) deleteInlineRolePolicies(roleName *string) error {
-	policyOutput, err := ir.Client.ListRolePoliciesWithContext(ir.Context, &iam.ListRolePoliciesInput{
+	policyOutput, err := ir.Client.ListRolePolicies(ir.Context, &iam.ListRolePoliciesInput{
 		RoleName: roleName,
 	})
 	if err != nil {
@@ -70,22 +69,22 @@ func (ir *IAMRoles) deleteInlineRolePolicies(roleName *string) error {
 	}
 
 	for _, policyName := range policyOutput.PolicyNames {
-		_, err := ir.Client.DeleteRolePolicyWithContext(ir.Context, &iam.DeleteRolePolicyInput{
-			PolicyName: policyName,
+		_, err := ir.Client.DeleteRolePolicy(ir.Context, &iam.DeleteRolePolicyInput{
+			PolicyName: aws.String(policyName),
 			RoleName:   roleName,
 		})
 		if err != nil {
 			logging.Debugf("[Failed] %s", err)
 			return errors.WithStackTrace(err)
 		}
-		logging.Debugf("Deleted Inline Policy %s from Role %s", aws.StringValue(policyName), aws.StringValue(roleName))
+		logging.Debugf("Deleted Inline Policy %s from Role %s", policyName, aws.ToString(roleName))
 	}
 
 	return nil
 }
 
 func (ir *IAMRoles) deleteInstanceProfilesFromRole(roleName *string) error {
-	profilesOutput, err := ir.Client.ListInstanceProfilesForRoleWithContext(ir.Context, &iam.ListInstanceProfilesForRoleInput{
+	profilesOutput, err := ir.Client.ListInstanceProfilesForRole(ir.Context, &iam.ListInstanceProfilesForRoleInput{
 		RoleName: roleName,
 	})
 	if err != nil {
@@ -95,7 +94,7 @@ func (ir *IAMRoles) deleteInstanceProfilesFromRole(roleName *string) error {
 	for _, profile := range profilesOutput.InstanceProfiles {
 
 		// Role needs to be removed from instance profile before it can be deleted
-		_, err := ir.Client.RemoveRoleFromInstanceProfileWithContext(ir.Context, &iam.RemoveRoleFromInstanceProfileInput{
+		_, err := ir.Client.RemoveRoleFromInstanceProfile(ir.Context, &iam.RemoveRoleFromInstanceProfileInput{
 			InstanceProfileName: profile.InstanceProfileName,
 			RoleName:            roleName,
 		})
@@ -103,7 +102,7 @@ func (ir *IAMRoles) deleteInstanceProfilesFromRole(roleName *string) error {
 			logging.Debugf("[Failed] %s", err)
 			return errors.WithStackTrace(err)
 		} else {
-			_, err := ir.Client.DeleteInstanceProfileWithContext(ir.Context, &iam.DeleteInstanceProfileInput{
+			_, err := ir.Client.DeleteInstanceProfile(ir.Context, &iam.DeleteInstanceProfileInput{
 				InstanceProfileName: profile.InstanceProfileName,
 			})
 			if err != nil {
@@ -111,13 +110,13 @@ func (ir *IAMRoles) deleteInstanceProfilesFromRole(roleName *string) error {
 				return errors.WithStackTrace(err)
 			}
 		}
-		logging.Debugf("Detached and Deleted InstanceProfile %s from Role %s", aws.StringValue(profile.InstanceProfileName), aws.StringValue(roleName))
+		logging.Debugf("Detached and Deleted InstanceProfile %s from Role %s", aws.ToString(profile.InstanceProfileName), aws.ToString(roleName))
 	}
 	return nil
 }
 
 func (ir *IAMRoles) deleteIamRole(roleName *string) error {
-	_, err := ir.Client.DeleteRoleWithContext(ir.Context, &iam.DeleteRoleInput{
+	_, err := ir.Client.DeleteRole(ir.Context, &iam.DeleteRoleInput{
 		RoleName: roleName,
 	})
 	if err != nil {
@@ -168,12 +167,12 @@ func (ir *IAMRoles) nukeAll(roleNames []*string) error {
 	}
 
 	for _, roleName := range roleNames {
-		logging.Debugf("[OK] IAM Role %s was deleted", aws.StringValue(roleName))
+		logging.Debugf("[OK] IAM Role %s was deleted", aws.ToString(roleName))
 	}
 	return nil
 }
 
-func (ir *IAMRoles) shouldInclude(iamRole *iam.Role, configObj config.Config) bool {
+func (ir *IAMRoles) shouldInclude(iamRole *types.Role, configObj config.Config) bool {
 	if iamRole == nil {
 		return false
 	}
@@ -181,13 +180,13 @@ func (ir *IAMRoles) shouldInclude(iamRole *iam.Role, configObj config.Config) bo
 	// The OrganizationAccountAccessRole is a special role that is created by AWS Organizations, and is used to allow
 	// users to access the AWS account. We should not delete this role, so we can filter it out of the Roles found and
 	// managed by cloud-nuke.
-	if strings.Contains(aws.StringValue(iamRole.RoleName), "OrganizationAccountAccessRole") {
+	if strings.Contains(aws.ToString(iamRole.RoleName), "OrganizationAccountAccessRole") {
 		return false
 	}
 
 	// The ARNs of AWS-reserved IAM roles, which can only be modified or deleted by AWS, contain "aws-reserved", so we can filter them out
 	// of the Roles found and managed by cloud-nuke
-	if strings.Contains(aws.StringValue(iamRole.Arn), "aws-reserved") {
+	if strings.Contains(aws.ToString(iamRole.Arn), "aws-reserved") {
 		return false
 	}
 
@@ -221,7 +220,7 @@ func (ir *IAMRoles) deleteIamRoleAsync(wg *sync.WaitGroup, errChan chan error, r
 
 	// Record status of this resource
 	e := report.Entry{
-		Identifier:   aws.StringValue(roleName),
+		Identifier:   aws.ToString(roleName),
 		ResourceType: "IAM Role",
 		Error:        result.ErrorOrNil(),
 	}
diff --git a/aws/resources/iam_role_types.go b/aws/resources/iam_role_types.go
index 177cf28..091c5ce 100644
--- a/aws/resources/iam_role_types.go
+++ b/aws/resources/iam_role_types.go
@@ -3,25 +3,37 @@ 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/iam"
-	"github.com/aws/aws-sdk-go/service/iam/iamiface"
+	"github.com/aws/aws-sdk-go-v2/aws"
+	"github.com/aws/aws-sdk-go-v2/service/iam"
 	"github.com/gruntwork-io/cloud-nuke/config"
 	"github.com/gruntwork-io/go-commons/errors"
 )
 
+type IAMRolesAPI interface {
+	ListAttachedRolePolicies(ctx context.Context, params *iam.ListAttachedRolePoliciesInput, optFns ...func(*iam.Options)) (*iam.ListAttachedRolePoliciesOutput, error)
+	ListInstanceProfilesForRole(ctx context.Context, params *iam.ListInstanceProfilesForRoleInput, optFns ...func(*iam.Options)) (*iam.ListInstanceProfilesForRoleOutput, error)
+	ListRolePolicies(ctx context.Context, params *iam.ListRolePoliciesInput, optFns ...func(*iam.Options)) (*iam.ListRolePoliciesOutput, error)
+	ListRoles(ctx context.Context, params *iam.ListRolesInput, optFns ...func(*iam.Options)) (*iam.ListRolesOutput, error)
+	DeleteInstanceProfile(ctx context.Context, params *iam.DeleteInstanceProfileInput, optFns ...func(*iam.Options)) (*iam.DeleteInstanceProfileOutput, error)
+	DetachRolePolicy(ctx context.Context, params *iam.DetachRolePolicyInput, optFns ...func(*iam.Options)) (*iam.DetachRolePolicyOutput, error)
+	DeleteRolePolicy(ctx context.Context, params *iam.DeleteRolePolicyInput, optFns ...func(*iam.Options)) (*iam.DeleteRolePolicyOutput, error)
+	DeleteRole(ctx context.Context, params *iam.DeleteRoleInput, optFns ...func(*iam.Options)) (*iam.DeleteRoleOutput, error)
+	RemoveRoleFromInstanceProfile(ctx context.Context, params *iam.RemoveRoleFromInstanceProfileInput, optFns ...func(*iam.Options)) (*iam.RemoveRoleFromInstanceProfileOutput, error)
+}
+
 // IAMRoles - represents all IAMRoles on the AWS Account
 type IAMRoles struct {
 	BaseAwsResource
-	Client    iamiface.IAMAPI
+	Client    IAMRolesAPI
 	RoleNames []string
 }
 
-func (ir *IAMRoles) Init(session *session.Session) {
-	ir.Client = iam.New(session)
+func (ir *IAMRoles) InitV2(cfg aws.Config) {
+	ir.Client = iam.NewFromConfig(cfg)
 }
 
+func (ir *IAMRoles) IsUsingV2() bool { return true }
+
 // ResourceName - the simple name of the aws resource
 func (ir *IAMRoles) ResourceName() string {
 	return "iam-role"
@@ -47,13 +59,13 @@ func (ir *IAMRoles) GetAndSetIdentifiers(c context.Context, configObj config.Con
 		return nil, err
 	}
 
-	ir.RoleNames = awsgo.StringValueSlice(identifiers)
+	ir.RoleNames = aws.ToStringSlice(identifiers)
 	return ir.RoleNames, nil
 }
 
 // Nuke - nuke 'em all!!!
 func (ir *IAMRoles) Nuke(identifiers []string) error {
-	if err := ir.nukeAll(awsgo.StringSlice(identifiers)); err != nil {
+	if err := ir.nukeAll(aws.StringSlice(identifiers)); err != nil {
 		return errors.WithStackTrace(err)
 	}
 
diff --git a/aws/resources/iam_service_linked_role.go b/aws/resources/iam_service_linked_role.go
index 6752166..fe11a2b 100644
--- a/aws/resources/iam_service_linked_role.go
+++ b/aws/resources/iam_service_linked_role.go
@@ -8,8 +8,9 @@ import (
 	"sync"
 	"time"
 
-	"github.com/aws/aws-sdk-go/aws"
-	"github.com/aws/aws-sdk-go/service/iam"
+	"github.com/aws/aws-sdk-go-v2/aws"
+	"github.com/aws/aws-sdk-go-v2/service/iam"
+	"github.com/aws/aws-sdk-go-v2/service/iam/types"
 	"github.com/gruntwork-io/cloud-nuke/config"
 	"github.com/gruntwork-io/cloud-nuke/logging"
 	"github.com/gruntwork-io/cloud-nuke/report"
@@ -19,31 +20,30 @@ import (
 
 // List all IAM Roles in the AWS account
 func (islr *IAMServiceLinkedRoles) getAll(c context.Context, configObj config.Config) ([]*string, error) {
-	allIAMServiceLinkedRoles := []*string{}
-	err := islr.Client.ListRolesPagesWithContext(
-		islr.Context,
-		&iam.ListRolesInput{},
-		func(page *iam.ListRolesOutput, lastPage bool) bool {
-			for _, iamServiceLinkedRole := range page.Roles {
-				if islr.shouldInclude(iamServiceLinkedRole, configObj) {
-					allIAMServiceLinkedRoles = append(allIAMServiceLinkedRoles, iamServiceLinkedRole.RoleName)
-				}
+	var allIAMServiceLinkedRoles []*string
+	paginator := iam.NewListRolesPaginator(islr.Client, &iam.ListRolesInput{})
+	for paginator.HasMorePages() {
+		page, err := paginator.NextPage(c)
+		if err != nil {
+			return nil, gruntworkerrors.WithStackTrace(err)
+		}
+
+		for _, iamServiceLinkedRole := range page.Roles {
+			if islr.shouldInclude(&iamServiceLinkedRole, configObj) {
+				allIAMServiceLinkedRoles = append(allIAMServiceLinkedRoles, iamServiceLinkedRole.RoleName)
 			}
-			return !lastPage
-		},
-	)
-	if err != nil {
-		return nil, gruntworkerrors.WithStackTrace(err)
+		}
 	}
+
 	return allIAMServiceLinkedRoles, nil
 }
 
 func (islr *IAMServiceLinkedRoles) deleteIamServiceLinkedRole(roleName *string) error {
 	// Deletion ID looks like this: "
-	//{
+	// {
 	//	DeletionTaskId: "task/aws-service-role/autoscaling.amazonaws.com/AWSServiceRoleForAutoScaling_2/d3c4c9fc-7fd3-4a36-974a-afb0eb78f102"
-	//}
-	deletionData, err := islr.Client.DeleteServiceLinkedRoleWithContext(islr.Context, &iam.DeleteServiceLinkedRoleInput{
+	// }
+	deletionData, err := islr.Client.DeleteServiceLinkedRole(islr.Context, &iam.DeleteServiceLinkedRoleInput{
 		RoleName: roleName,
 	})
 	if err != nil {
@@ -59,22 +59,22 @@ func (islr *IAMServiceLinkedRoles) deleteIamServiceLinkedRole(roleName *string)
 	for !done {
 		done = true
 		// Check if the deletion is complete
-		deletionStatus, err = islr.Client.GetServiceLinkedRoleDeletionStatusWithContext(islr.Context, &iam.GetServiceLinkedRoleDeletionStatusInput{
+		deletionStatus, err = islr.Client.GetServiceLinkedRoleDeletionStatus(islr.Context, &iam.GetServiceLinkedRoleDeletionStatusInput{
 			DeletionTaskId: deletionData.DeletionTaskId,
 		})
 		if err != nil {
 			return gruntworkerrors.WithStackTrace(err)
 		}
-		if aws.StringValue(deletionStatus.Status) == "IN_PROGRESS" {
-			logging.Debugf("Deletion of IAM ServiceLinked Role %s is still in progress", aws.StringValue(roleName))
+		if deletionStatus.Status == types.DeletionTaskStatusTypeInProgress {
+			logging.Debugf("Deletion of IAM ServiceLinked Role %s is still in progress", aws.ToString(roleName))
 			done = false
 			time.Sleep(3 * time.Second)
 		}
 
 	}
 
-	if aws.StringValue(deletionStatus.Status) != "SUCCEEDED" {
-		err := fmt.Sprintf("Deletion of IAM ServiceLinked Role %s failed with status %s", aws.StringValue(roleName), aws.StringValue(deletionStatus.Status))
+	if deletionStatus.Status != types.DeletionTaskStatusTypeSucceeded {
+		err := fmt.Sprintf("Deletion of IAM ServiceLinked Role %s failed with status %s", aws.ToString(roleName), string(deletionStatus.Status))
 		return gruntworkerrors.WithStackTrace(errors.New(err))
 	}
 
@@ -122,13 +122,13 @@ func (islr *IAMServiceLinkedRoles) nukeAll(roleNames []*string) error {
 	}
 
 	for _, roleName := range roleNames {
-		logging.Debugf("[OK] IAM Service Linked Role %s was deleted.", aws.StringValue(roleName))
+		logging.Debugf("[OK] IAM Service Linked Role %s was deleted.", aws.ToString(roleName))
 	}
 	return nil
 }
 
-func (islr *IAMServiceLinkedRoles) shouldInclude(iamServiceLinkedRole *iam.Role, configObj config.Config) bool {
-	if !strings.Contains(aws.StringValue(iamServiceLinkedRole.Arn), "aws-service-role") {
+func (islr *IAMServiceLinkedRoles) shouldInclude(iamServiceLinkedRole *types.Role, configObj config.Config) bool {
+	if !strings.Contains(aws.ToString(iamServiceLinkedRole.Arn), "aws-service-role") {
 		return false
 	}
 
@@ -159,7 +159,7 @@ func (islr *IAMServiceLinkedRoles) deleteIamServiceLinkedRoleAsync(wg *sync.Wait
 
 	// Record status of this resource
 	e := report.Entry{
-		Identifier:   aws.StringValue(roleName),
+		Identifier:   aws.ToString(roleName),
 		ResourceType: "IAM Service Linked Role",
 		Error:        result.ErrorOrNil(),
 	}
diff --git a/aws/resources/iam_service_linked_role_types.go b/aws/resources/iam_service_linked_role_types.go
index a87c63c..9d6983f 100644
--- a/aws/resources/iam_service_linked_role_types.go
+++ b/aws/resources/iam_service_linked_role_types.go
@@ -3,25 +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/iam"
-	"github.com/aws/aws-sdk-go/service/iam/iamiface"
+	"github.com/aws/aws-sdk-go-v2/aws"
+	"github.com/aws/aws-sdk-go-v2/service/iam"
 	"github.com/gruntwork-io/cloud-nuke/config"
 	"github.com/gruntwork-io/go-commons/errors"
 )
 
+type IAMServiceLinkedRolesAPI interface {
+	ListRoles(ctx context.Context, params *iam.ListRolesInput, optFns ...func(*iam.Options)) (*iam.ListRolesOutput, error)
+	DeleteServiceLinkedRole(ctx context.Context, params *iam.DeleteServiceLinkedRoleInput, optFns ...func(*iam.Options)) (*iam.DeleteServiceLinkedRoleOutput, error)
+	GetServiceLinkedRoleDeletionStatus(ctx context.Context, params *iam.GetServiceLinkedRoleDeletionStatusInput, optFns ...func(*iam.Options)) (*iam.GetServiceLinkedRoleDeletionStatusOutput, error)
+}
+
 // IAMServiceLinkedRoles - represents all IAMServiceLinkedRoles on the AWS Account
 type IAMServiceLinkedRoles struct {
 	BaseAwsResource
-	Client    iamiface.IAMAPI
+	Client    IAMServiceLinkedRolesAPI
 	RoleNames []string
 }
 
-func (islr *IAMServiceLinkedRoles) Init(session *session.Session) {
-	islr.Client = iam.New(session)
+func (islr *IAMServiceLinkedRoles) InitV2(cfg aws.Config) {
+	islr.Client = iam.NewFromConfig(cfg)
 }
 
+func (islr *IAMServiceLinkedRoles) IsUsingV2() bool { return true }
+
 // ResourceName - the simple name of the aws resource
 func (islr *IAMServiceLinkedRoles) ResourceName() string {
 	return "iam-service-linked-role"
@@ -32,7 +38,7 @@ func (islr *IAMServiceLinkedRoles) ResourceIdentifiers() []string {
 	return islr.RoleNames
 }
 
-// Tentative batch size to ensure AWS doesn't throttle
+// MaxBatchSize Tentative batch size to ensure AWS doesn't throttle
 func (islr *IAMServiceLinkedRoles) MaxBatchSize() int {
 	return 49
 }
@@ -47,13 +53,13 @@ func (islr *IAMServiceLinkedRoles) GetAndSetIdentifiers(c context.Context, confi
 		return nil, err
 	}
 
-	islr.RoleNames = awsgo.StringValueSlice(identifiers)
+	islr.RoleNames = aws.ToStringSlice(identifiers)
 	return islr.RoleNames, nil
 }
 
 // Nuke - nuke 'em all!!!
 func (islr *IAMServiceLinkedRoles) Nuke(identifiers []string) error {
-	if err := islr.nukeAll(awsgo.StringSlice(identifiers)); err != nil {
+	if err := islr.nukeAll(aws.StringSlice(identifiers)); err != nil {
 		return errors.WithStackTrace(err)
 	}
 
diff --git a/aws/resources/iam_types.go b/aws/resources/iam_types.go
index d2dadb3..b83b46a 100644
--- a/aws/resources/iam_types.go
+++ b/aws/resources/iam_types.go
@@ -3,25 +3,49 @@ 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/iam"
-	"github.com/aws/aws-sdk-go/service/iam/iamiface"
+	"github.com/aws/aws-sdk-go-v2/aws"
+	"github.com/aws/aws-sdk-go-v2/service/iam"
 	"github.com/gruntwork-io/cloud-nuke/config"
 	"github.com/gruntwork-io/go-commons/errors"
 )
 
+type IAMUsersAPI interface {
+	ListAccessKeys(ctx context.Context, params *iam.ListAccessKeysInput, optFns ...func(*iam.Options)) (*iam.ListAccessKeysOutput, error)
+	ListGroupsForUser(ctx context.Context, params *iam.ListGroupsForUserInput, optFns ...func(*iam.Options)) (*iam.ListGroupsForUserOutput, error)
+	ListUserPolicies(ctx context.Context, params *iam.ListUserPoliciesInput, optFns ...func(*iam.Options)) (*iam.ListUserPoliciesOutput, error)
+	ListUserTags(ctx context.Context, params *iam.ListUserTagsInput, optFns ...func(*iam.Options)) (*iam.ListUserTagsOutput, error)
+	ListMFADevices(ctx context.Context, params *iam.ListMFADevicesInput, optFns ...func(*iam.Options)) (*iam.ListMFADevicesOutput, error)
+	ListSSHPublicKeys(ctx context.Context, params *iam.ListSSHPublicKeysInput, optFns ...func(*iam.Options)) (*iam.ListSSHPublicKeysOutput, error)
+	ListServiceSpecificCredentials(ctx context.Context, params *iam.ListServiceSpecificCredentialsInput, optFns ...func(*iam.Options)) (*iam.ListServiceSpecificCredentialsOutput, error)
+	ListSigningCertificates(ctx context.Context, params *iam.ListSigningCertificatesInput, optFns ...func(*iam.Options)) (*iam.ListSigningCertificatesOutput, error)
+	ListUsers(ctx context.Context, params *iam.ListUsersInput, optFns ...func(*iam.Options)) (*iam.ListUsersOutput, error)
+	ListAttachedUserPolicies(ctx context.Context, params *iam.ListAttachedUserPoliciesInput, optFns ...func(*iam.Options)) (*iam.ListAttachedUserPoliciesOutput, error)
+	DetachUserPolicy(ctx context.Context, params *iam.DetachUserPolicyInput, optFns ...func(*iam.Options)) (*iam.DetachUserPolicyOutput, error)
+	DeleteLoginProfile(ctx context.Context, params *iam.DeleteLoginProfileInput, optFns ...func(*iam.Options)) (*iam.DeleteLoginProfileOutput, error)
+	DeleteUserPolicy(ctx context.Context, params *iam.DeleteUserPolicyInput, optFns ...func(*iam.Options)) (*iam.DeleteUserPolicyOutput, error)
+	DeleteAccessKey(ctx context.Context, params *iam.DeleteAccessKeyInput, optFns ...func(*iam.Options)) (*iam.DeleteAccessKeyOutput, error)
+	DeleteSigningCertificate(ctx context.Context, params *iam.DeleteSigningCertificateInput, optFns ...func(*iam.Options)) (*iam.DeleteSigningCertificateOutput, error)
+	DeleteSSHPublicKey(ctx context.Context, params *iam.DeleteSSHPublicKeyInput, optFns ...func(*iam.Options)) (*iam.DeleteSSHPublicKeyOutput, error)
+	DeleteServiceSpecificCredential(ctx context.Context, params *iam.DeleteServiceSpecificCredentialInput, optFns ...func(*iam.Options)) (*iam.DeleteServiceSpecificCredentialOutput, error)
+	DeactivateMFADevice(ctx context.Context, params *iam.DeactivateMFADeviceInput, optFns ...func(*iam.Options)) (*iam.DeactivateMFADeviceOutput, error)
+	DeleteVirtualMFADevice(ctx context.Context, params *iam.DeleteVirtualMFADeviceInput, optFns ...func(*iam.Options)) (*iam.DeleteVirtualMFADeviceOutput, error)
+	DeleteUser(ctx context.Context, params *iam.DeleteUserInput, optFns ...func(*iam.Options)) (*iam.DeleteUserOutput, error)
+	RemoveUserFromGroup(ctx context.Context, params *iam.RemoveUserFromGroupInput, optFns ...func(*iam.Options)) (*iam.RemoveUserFromGroupOutput, error)
+}
+
 // IAMUsers - represents all IAMUsers on the AWS Account
 type IAMUsers struct {
 	BaseAwsResource
-	Client    iamiface.IAMAPI
+	Client    IAMUsersAPI
 	UserNames []string
 }
 
-func (iu *IAMUsers) Init(session *session.Session) {
-	iu.Client = iam.New(session)
+func (iu *IAMUsers) InitV2(cfg aws.Config) {
+	iu.Client = iam.NewFromConfig(cfg)
 }
 
+func (iu *IAMUsers) IsUsingV2() bool { return true }
+
 // ResourceName - the simple name of the aws resource
 func (iu *IAMUsers) ResourceName() string {
 	return "iam"
@@ -47,13 +71,13 @@ func (iu *IAMUsers) GetAndSetIdentifiers(c context.Context, configObj config.Con
 		return nil, err
 	}
 
-	iu.UserNames = awsgo.StringValueSlice(identifiers)
+	iu.UserNames = aws.ToStringSlice(identifiers)
 	return iu.UserNames, nil
 }
 
 // Nuke - nuke 'em all!!!
 func (iu *IAMUsers) Nuke(users []string) error {
-	if err := iu.nukeAll(awsgo.StringSlice(users)); err != nil {
+	if err := iu.nukeAll(aws.StringSlice(users)); err != nil {
 		return errors.WithStackTrace(err)
 	}
 
diff --git a/go.mod b/go.mod
index c4adbbf..7127d3e 100644
--- a/go.mod
+++ b/go.mod
@@ -34,6 +34,7 @@ require (
 	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/iam v1.37.3
 	github.com/aws/aws-sdk-go-v2/service/scheduler v1.12.3
 	github.com/aws/aws-sdk-go-v2/service/securityhub v1.54.4
 	github.com/aws/aws-sdk-go-v2/service/ses v1.28.3
diff --git a/go.sum b/go.sum
index af2f819..13825b4 100644
--- a/go.sum
+++ b/go.sum
@@ -87,6 +87,8 @@ github.com/aws/aws-sdk-go-v2/service/eventbridge v1.35.3 h1:e/jGXEQi+lyTIhc3s+jb
 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/iam v1.37.3 h1:uuoXyOwX2ReYgHJW0W84cKDUrvQNQA2l9KhkXUgT+R4=
+github.com/aws/aws-sdk-go-v2/service/iam v1.37.3/go.mod h1:RCrjvkN/ZpVAzW3ZmIlyflv7MUM45YlWx3v+6MaVX2w=
 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=
diff --git a/util/tag.go b/util/tag.go
index 5a9e659..6dc1d0f 100644
--- a/util/tag.go
+++ b/util/tag.go
@@ -3,8 +3,8 @@ package util
 import (
 	autoscaling "github.com/aws/aws-sdk-go-v2/service/autoscaling/types"
 	"github.com/aws/aws-sdk-go-v2/service/ec2/types"
+	iam "github.com/aws/aws-sdk-go-v2/service/iam/types"
 	"github.com/aws/aws-sdk-go/service/ec2"
-	"github.com/aws/aws-sdk-go/service/iam"
 	"github.com/aws/aws-sdk-go/service/networkfirewall"
 	"github.com/aws/aws-sdk-go/service/rds"
 	"github.com/aws/aws-sdk-go/service/s3"
@@ -55,7 +55,7 @@ func ConvertStringPtrTagsToMap(tags map[string]*string) map[string]string {
 	return tagMap
 }
 
-func ConvertIAMTagsToMap(tags []*iam.Tag) map[string]string {
+func ConvertIAMTagsToMap(tags []iam.Tag) map[string]string {
 	tagMap := make(map[string]string)
 	for _, tag := range tags {
 		tagMap[*tag.Key] = *tag.Value
diff --git a/v2_migration_report/output.md b/v2_migration_report/output.md
index 73cec9c..ee3701c 100644
--- a/v2_migration_report/output.md
+++ b/v2_migration_report/output.md
@@ -52,11 +52,11 @@ run `go generate ./...` to refresh this report.
 | event-bridge-schedule            | :white_check_mark: |
 | event-bridge-schedule-group      | :white_check_mark: |
 | guardduty                        | :white_check_mark: |
-| iam                              |                    |
-| iam-group                        |                    |
-| iam-policy                       |                    |
-| iam-role                         |                    |
-| iam-service-linked-role          |                    |
+| iam                              | :white_check_mark: |
+| iam-group                        | :white_check_mark: |
+| iam-policy                       | :white_check_mark: |
+| iam-role                         | :white_check_mark: |
+| iam-service-linked-role          | :white_check_mark: |
 | internet-gateway                 |                    |
 | ipam                             |                    |
 | ipam-byoasn                      |                    |


Test patch:
diff --git a/aws/resources/iam_group_test.go b/aws/resources/iam_group_test.go
index 4f03f7d..7dae9f3 100644
--- a/aws/resources/iam_group_test.go
+++ b/aws/resources/iam_group_test.go
@@ -6,84 +6,73 @@ 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/iam/iamiface"
-
-	awsgo "github.com/aws/aws-sdk-go/aws"
-	"github.com/aws/aws-sdk-go/service/iam"
+	"github.com/aws/aws-sdk-go-v2/aws"
+	"github.com/aws/aws-sdk-go-v2/service/iam"
+	"github.com/aws/aws-sdk-go-v2/service/iam/types"
 	"github.com/gruntwork-io/cloud-nuke/config"
 	"github.com/stretchr/testify/require"
 )
 
 type mockedIAMGroups struct {
-	iamiface.IAMAPI
-	ListGroupsPagesOutput                iam.ListGroupsOutput
-	GetGroupOutput                       iam.GetGroupOutput
-	RemoveUserFromGroupOutput            iam.RemoveUserFromGroupOutput
-	DeleteGroupOutput                    iam.DeleteGroupOutput
-	ListAttachedGroupPoliciesPagesOutput iam.ListAttachedGroupPoliciesOutput
-	DetachGroupPolicyOutput              iam.DetachGroupPolicyOutput
-	ListGroupPoliciesOutput              iam.ListGroupPoliciesOutput
-	DeleteGroupPolicyOutput              iam.DeleteGroupPolicyOutput
+	IAMGroupsAPI
+	DetachGroupPolicyOutput         iam.DetachGroupPolicyOutput
+	DeleteGroupPolicyOutput         iam.DeleteGroupPolicyOutput
+	DeleteGroupOutput               iam.DeleteGroupOutput
+	GetGroupOutput                  iam.GetGroupOutput
+	ListAttachedGroupPoliciesOutput iam.ListAttachedGroupPoliciesOutput
+	ListGroupsOutput                iam.ListGroupsOutput
+	ListGroupPoliciesOutput         iam.ListGroupPoliciesOutput
+	RemoveUserFromGroupOutput       iam.RemoveUserFromGroupOutput
 }
 
-func (m mockedIAMGroups) ListGroupsPagesWithContext(
-	_ aws.Context, input *iam.ListGroupsInput, fn func(*iam.ListGroupsOutput, bool) bool, _ ...request.Option) error {
-	fn(&m.ListGroupsPagesOutput, true)
-	return nil
+func (m mockedIAMGroups) DetachGroupPolicy(ctx context.Context, params *iam.DetachGroupPolicyInput, optFns ...func(*iam.Options)) (*iam.DetachGroupPolicyOutput, error) {
+	return &m.DetachGroupPolicyOutput, nil
 }
 
-func (m mockedIAMGroups) DeleteGroupWithContext(_ aws.Context, input *iam.DeleteGroupInput, _ ...request.Option) (*iam.DeleteGroupOutput, error) {
-	return &m.DeleteGroupOutput, nil
+func (m mockedIAMGroups) DeleteGroupPolicy(ctx context.Context, params *iam.DeleteGroupPolicyInput, optFns ...func(*iam.Options)) (*iam.DeleteGroupPolicyOutput, error) {
+	return &m.DeleteGroupPolicyOutput, nil
 }
 
-func (m mockedIAMGroups) ListAttachedGroupPoliciesPagesWithContext(
-	_ aws.Context, input *iam.ListAttachedGroupPoliciesInput, fn func(*iam.ListAttachedGroupPoliciesOutput, bool) bool, _ ...request.Option) error {
-	fn(&m.ListAttachedGroupPoliciesPagesOutput, true)
-	return nil
+func (m mockedIAMGroups) DeleteGroup(ctx context.Context, params *iam.DeleteGroupInput, optFns ...func(*iam.Options)) (*iam.DeleteGroupOutput, error) {
+	return &m.DeleteGroupOutput, nil
 }
 
-func (m mockedIAMGroups) ListGroupPoliciesPagesWithContext(
-	_ aws.Context, input *iam.ListGroupPoliciesInput, fn func(*iam.ListGroupPoliciesOutput, bool) bool, _ ...request.Option) error {
-	fn(&m.ListGroupPoliciesOutput, true)
-	return nil
+func (m mockedIAMGroups) GetGroup(ctx context.Context, params *iam.GetGroupInput, optFns ...func(*iam.Options)) (*iam.GetGroupOutput, error) {
+	return &m.GetGroupOutput, nil
 }
 
-func (m mockedIAMGroups) DetachGroupPolicyWithContext(_ aws.Context, input *iam.DetachGroupPolicyInput, _ ...request.Option) (*iam.DetachGroupPolicyOutput, error) {
-	return &m.DetachGroupPolicyOutput, nil
+func (m mockedIAMGroups) ListAttachedGroupPolicies(ctx context.Context, params *iam.ListAttachedGroupPoliciesInput, optFns ...func(*iam.Options)) (*iam.ListAttachedGroupPoliciesOutput, error) {
+	return &m.ListAttachedGroupPoliciesOutput, nil
 }
 
-func (m mockedIAMGroups) DeleteGroupPolicyWithContext(_ aws.Context, input *iam.DeleteGroupPolicyInput, _ ...request.Option) (*iam.DeleteGroupPolicyOutput, error) {
-	return &m.DeleteGroupPolicyOutput, nil
+func (m mockedIAMGroups) ListGroups(ctx context.Context, params *iam.ListGroupsInput, optFns ...func(*iam.Options)) (*iam.ListGroupsOutput, error) {
+	return &m.ListGroupsOutput, nil
 }
 
-func (m mockedIAMGroups) GetGroupWithContext(_ aws.Context, input *iam.GetGroupInput, _ ...request.Option) (*iam.GetGroupOutput, error) {
-	return &m.GetGroupOutput, nil
+func (m mockedIAMGroups) ListGroupPolicies(ctx context.Context, params *iam.ListGroupPoliciesInput, optFns ...func(*iam.Options)) (*iam.ListGroupPoliciesOutput, error) {
+	return &m.ListGroupPoliciesOutput, nil
 }
 
-func (m mockedIAMGroups) RemoveUserFromGroupWithContext(_ aws.Context, input *iam.RemoveUserFromGroupInput, _ ...request.Option) (*iam.RemoveUserFromGroupOutput, error) {
+func (m mockedIAMGroups) RemoveUserFromGroup(ctx context.Context, params *iam.RemoveUserFromGroupInput, optFns ...func(*iam.Options)) (*iam.RemoveUserFromGroupOutput, error) {
 	return &m.RemoveUserFromGroupOutput, nil
 }
 
 func TestIamGroups_GetAll(t *testing.T) {
-
 	t.Parallel()
-
 	testName1 := "group1"
 	testName2 := "group2"
 	now := time.Now()
 	ig := IAMGroups{
 		Client: mockedIAMGroups{
-			ListGroupsPagesOutput: iam.ListGroupsOutput{
-				Groups: []*iam.Group{
+			ListGroupsOutput: iam.ListGroupsOutput{
+				Groups: []types.Group{
 					{
-						GroupName:  awsgo.String(testName1),
-						CreateDate: awsgo.Time(now),
+						GroupName:  aws.String(testName1),
+						CreateDate: aws.Time(now),
 					},
 					{
-						GroupName:  awsgo.String(testName2),
-						CreateDate: awsgo.Time(now.Add(1)),
+						GroupName:  aws.String(testName2),
+						CreateDate: aws.Time(now.Add(1)),
 					},
 				},
 			},
@@ -110,7 +99,7 @@ func TestIamGroups_GetAll(t *testing.T) {
 		"timeAfterExclusionFilter": {
 			configObj: config.ResourceType{
 				ExcludeRule: config.FilterRule{
-					TimeAfter: awsgo.Time(now),
+					TimeAfter: aws.Time(now),
 				}},
 			expected: []string{testName1},
 		},
@@ -121,36 +110,34 @@ func TestIamGroups_GetAll(t *testing.T) {
 				IAMGroups: tc.configObj,
 			})
 			require.NoError(t, err)
-			require.Equal(t, tc.expected, awsgo.StringValueSlice(names))
+			require.Equal(t, tc.expected, aws.ToStringSlice(names))
 		})
 	}
 }
 
 func TestIamGroups_NukeAll(t *testing.T) {
-
 	t.Parallel()
-
 	ig := IAMGroups{
 		Client: mockedIAMGroups{
 			GetGroupOutput: iam.GetGroupOutput{
-				Users: []*iam.User{
+				Users: []types.User{
 					{
-						UserName: awsgo.String("user1"),
+						UserName: aws.String("user1"),
 					},
 				},
 			},
 			RemoveUserFromGroupOutput: iam.RemoveUserFromGroupOutput{},
-			ListAttachedGroupPoliciesPagesOutput: iam.ListAttachedGroupPoliciesOutput{
-				AttachedPolicies: []*iam.AttachedPolicy{
+			ListAttachedGroupPoliciesOutput: iam.ListAttachedGroupPoliciesOutput{
+				AttachedPolicies: []types.AttachedPolicy{
 					{
-						PolicyName: awsgo.String("policy1"),
+						PolicyName: aws.String("policy1"),
 					},
 				},
 			},
 			DetachGroupPolicyOutput: iam.DetachGroupPolicyOutput{},
 			ListGroupPoliciesOutput: iam.ListGroupPoliciesOutput{
-				PolicyNames: []*string{
-					awsgo.String("policy2"),
+				PolicyNames: []string{
+					"policy2",
 				},
 			},
 			DeleteGroupPolicyOutput: iam.DeleteGroupPolicyOutput{},
@@ -158,6 +145,6 @@ func TestIamGroups_NukeAll(t *testing.T) {
 		},
 	}
 
-	err := ig.nukeAll([]*string{awsgo.String("group1")})
+	err := ig.nukeAll([]*string{aws.String("group1")})
 	require.NoError(t, err)
 }
diff --git a/aws/resources/iam_policy_test.go b/aws/resources/iam_policy_test.go
index 5ab07b7..a4ba17a 100644
--- a/aws/resources/iam_policy_test.go
+++ b/aws/resources/iam_policy_test.go
@@ -6,69 +6,59 @@ import (
 	"testing"
 	"time"
 
+	"github.com/aws/aws-sdk-go-v2/service/iam"
+	"github.com/aws/aws-sdk-go-v2/service/iam/types"
 	"github.com/aws/aws-sdk-go/aws"
-	"github.com/aws/aws-sdk-go/aws/request"
-	"github.com/aws/aws-sdk-go/service/iam"
-	"github.com/aws/aws-sdk-go/service/iam/iamiface"
 	"github.com/gruntwork-io/cloud-nuke/config"
 	"github.com/stretchr/testify/require"
 )
 
 type mockedIAMPolicies struct {
-	iamiface.IAMAPI
-	ListPoliciesPagesOutput iam.ListPoliciesOutput
-
-	ListEntitiesForPolicyPagesOutput iam.ListEntitiesForPolicyOutput
-	DetachUserPolicyOutput           iam.DetachUserPolicyOutput
-	DetachGroupPolicyOutput          iam.DetachGroupPolicyOutput
-	DetachRolePolicyOutput           iam.DetachRolePolicyOutput
-	ListPolicyVersionsPagesOutput    iam.ListPolicyVersionsOutput
-	DeletePolicyVersionOutput        iam.DeletePolicyVersionOutput
-	DeletePolicyOutput               iam.DeletePolicyOutput
+	IAMPoliciesAPI
+	ListEntitiesForPolicyOutput iam.ListEntitiesForPolicyOutput
+	ListPoliciesOutput          iam.ListPoliciesOutput
+	ListPolicyVersionsOutput    iam.ListPolicyVersionsOutput
+	DeletePolicyOutput          iam.DeletePolicyOutput
+	DeletePolicyVersionOutput   iam.DeletePolicyVersionOutput
+	DetachGroupPolicyOutput     iam.DetachGroupPolicyOutput
+	DetachUserPolicyOutput      iam.DetachUserPolicyOutput
+	DetachRolePolicyOutput      iam.DetachRolePolicyOutput
 }
 
-func (m mockedIAMPolicies) ListPoliciesPagesWithContext(
-	_ aws.Context, input *iam.ListPoliciesInput, fn func(*iam.ListPoliciesOutput, bool) bool, _ ...request.Option) error {
-	fn(&m.ListPoliciesPagesOutput, true)
-	return nil
+func (m mockedIAMPolicies) ListEntitiesForPolicy(ctx context.Context, params *iam.ListEntitiesForPolicyInput, optFns ...func(*iam.Options)) (*iam.ListEntitiesForPolicyOutput, error) {
+	return &m.ListEntitiesForPolicyOutput, nil
 }
 
-func (m mockedIAMPolicies) ListEntitiesForPolicyPagesWithContext(
-	_ aws.Context, input *iam.ListEntitiesForPolicyInput, fn func(*iam.ListEntitiesForPolicyOutput, bool) bool, _ ...request.Option) error {
-	fn(&m.ListEntitiesForPolicyPagesOutput, true)
-	return nil
+func (m mockedIAMPolicies) ListPolicies(ctx context.Context, params *iam.ListPoliciesInput, optFns ...func(*iam.Options)) (*iam.ListPoliciesOutput, error) {
+	return &m.ListPoliciesOutput, nil
 }
 
-func (m mockedIAMPolicies) DetachUserPolicyWithContext(_ aws.Context, input *iam.DetachUserPolicyInput, _ ...request.Option) (*iam.DetachUserPolicyOutput, error) {
-	return &m.DetachUserPolicyOutput, nil
+func (m mockedIAMPolicies) ListPolicyVersions(ctx context.Context, params *iam.ListPolicyVersionsInput, optFns ...func(*iam.Options)) (*iam.ListPolicyVersionsOutput, error) {
+	return &m.ListPolicyVersionsOutput, nil
 }
 
-func (m mockedIAMPolicies) DetachGroupPolicyWithContext(_ aws.Context, input *iam.DetachGroupPolicyInput, _ ...request.Option) (*iam.DetachGroupPolicyOutput, error) {
-	return &m.DetachGroupPolicyOutput, nil
+func (m mockedIAMPolicies) DeletePolicy(ctx context.Context, params *iam.DeletePolicyInput, optFns ...func(*iam.Options)) (*iam.DeletePolicyOutput, error) {
+	return &m.DeletePolicyOutput, nil
 }
 
-func (m mockedIAMPolicies) DetachRolePolicyWithContext(_ aws.Context, input *iam.DetachRolePolicyInput, _ ...request.Option) (*iam.DetachRolePolicyOutput, error) {
-	return &m.DetachRolePolicyOutput, nil
+func (m mockedIAMPolicies) DeletePolicyVersion(ctx context.Context, params *iam.DeletePolicyVersionInput, optFns ...func(*iam.Options)) (*iam.DeletePolicyVersionOutput, error) {
+	return &m.DeletePolicyVersionOutput, nil
 }
 
-func (m mockedIAMPolicies) ListPolicyVersionsPagesWithContext(
-	_ aws.Context, input *iam.ListPolicyVersionsInput, fn func(*iam.ListPolicyVersionsOutput, bool) bool, _ ...request.Option) error {
-	fn(&m.ListPolicyVersionsPagesOutput, true)
-	return nil
+func (m mockedIAMPolicies) DetachGroupPolicy(ctx context.Context, params *iam.DetachGroupPolicyInput, optFns ...func(*iam.Options)) (*iam.DetachGroupPolicyOutput, error) {
+	return &m.DetachGroupPolicyOutput, nil
 }
 
-func (m mockedIAMPolicies) DeletePolicyVersionWithContext(_ aws.Context, input *iam.DeletePolicyVersionInput, _ ...request.Option) (*iam.DeletePolicyVersionOutput, error) {
-	return &m.DeletePolicyVersionOutput, nil
+func (m mockedIAMPolicies) DetachUserPolicy(ctx context.Context, params *iam.DetachUserPolicyInput, optFns ...func(*iam.Options)) (*iam.DetachUserPolicyOutput, error) {
+	return &m.DetachUserPolicyOutput, nil
 }
 
-func (m mockedIAMPolicies) DeletePolicyWithContext(_ aws.Context, input *iam.DeletePolicyInput, _ ...request.Option) (*iam.DeletePolicyOutput, error) {
-	return &m.DeletePolicyOutput, nil
+func (m mockedIAMPolicies) DetachRolePolicy(ctx context.Context, params *iam.DetachRolePolicyInput, optFns ...func(*iam.Options)) (*iam.DetachRolePolicyOutput, error) {
+	return &m.DetachRolePolicyOutput, nil
 }
 
 func TestIAMPolicy_GetAll(t *testing.T) {
-
 	t.Parallel()
-
 	testName1 := "MyPolicy1"
 	testName2 := "MyPolicy2"
 	testArn1 := "arn:aws:iam::123456789012:policy/MyPolicy1"
@@ -76,8 +66,8 @@ func TestIAMPolicy_GetAll(t *testing.T) {
 	now := time.Now()
 	ip := IAMPolicies{
 		Client: mockedIAMPolicies{
-			ListPoliciesPagesOutput: iam.ListPoliciesOutput{
-				Policies: []*iam.Policy{
+			ListPoliciesOutput: iam.ListPoliciesOutput{
+				Policies: []types.Policy{
 					{
 						Arn:        aws.String(testArn1),
 						PolicyName: aws.String(testName1),
@@ -130,30 +120,29 @@ func TestIAMPolicy_GetAll(t *testing.T) {
 }
 
 func TestIAMPolicy_NukeAll(t *testing.T) {
-
 	t.Parallel()
 
 	ip := IAMPolicies{
 		Client: mockedIAMPolicies{
-			ListEntitiesForPolicyPagesOutput: iam.ListEntitiesForPolicyOutput{
-				PolicyGroups: []*iam.PolicyGroup{
+			ListEntitiesForPolicyOutput: iam.ListEntitiesForPolicyOutput{
+				PolicyGroups: []types.PolicyGroup{
 					{GroupName: aws.String("group1")},
 				},
-				PolicyUsers: []*iam.PolicyUser{
+				PolicyUsers: []types.PolicyUser{
 					{UserName: aws.String("user1")},
 				},
-				PolicyRoles: []*iam.PolicyRole{
+				PolicyRoles: []types.PolicyRole{
 					{RoleName: aws.String("role1")},
 				},
 			},
 			DetachUserPolicyOutput:  iam.DetachUserPolicyOutput{},
 			DetachGroupPolicyOutput: iam.DetachGroupPolicyOutput{},
 			DetachRolePolicyOutput:  iam.DetachRolePolicyOutput{},
-			ListPolicyVersionsPagesOutput: iam.ListPolicyVersionsOutput{
-				Versions: []*iam.PolicyVersion{
+			ListPolicyVersionsOutput: iam.ListPolicyVersionsOutput{
+				Versions: []types.PolicyVersion{
 					{
 						VersionId:        aws.String("v1"),
-						IsDefaultVersion: aws.Bool(false),
+						IsDefaultVersion: false,
 					},
 				},
 			},
diff --git a/aws/resources/iam_role_test.go b/aws/resources/iam_role_test.go
index c48ca18..5d94cd0 100644
--- a/aws/resources/iam_role_test.go
+++ b/aws/resources/iam_role_test.go
@@ -6,75 +6,71 @@ 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/iam"
-	"github.com/aws/aws-sdk-go/service/iam/iamiface"
+	"github.com/aws/aws-sdk-go-v2/aws"
+	"github.com/aws/aws-sdk-go-v2/service/iam"
+	"github.com/aws/aws-sdk-go-v2/service/iam/types"
 	"github.com/gruntwork-io/cloud-nuke/config"
 	"github.com/stretchr/testify/require"
 )
 
 type mockedIAMRoles struct {
-	iamiface.IAMAPI
-	ListRolesPagesOutput                iam.ListRolesOutput
+	IAMRolesAPI
+	ListAttachedRolePoliciesOutput      iam.ListAttachedRolePoliciesOutput
 	ListInstanceProfilesForRoleOutput   iam.ListInstanceProfilesForRoleOutput
-	RemoveRoleFromInstanceProfileOutput iam.RemoveRoleFromInstanceProfileOutput
-	DeleteInstanceProfileOutput         iam.DeleteInstanceProfileOutput
 	ListRolePoliciesOutput              iam.ListRolePoliciesOutput
-	DeleteRolePolicyOutput              iam.DeleteRolePolicyOutput
-	ListAttachedRolePoliciesOutput      iam.ListAttachedRolePoliciesOutput
+	ListRolesOutput                     iam.ListRolesOutput
+	DeleteInstanceProfileOutput         iam.DeleteInstanceProfileOutput
 	DetachRolePolicyOutput              iam.DetachRolePolicyOutput
+	DeleteRolePolicyOutput              iam.DeleteRolePolicyOutput
 	DeleteRoleOutput                    iam.DeleteRoleOutput
+	RemoveRoleFromInstanceProfileOutput iam.RemoveRoleFromInstanceProfileOutput
 }
 
-func (m mockedIAMRoles) ListRolesPagesWithContext(_ aws.Context, input *iam.ListRolesInput, f func(*iam.ListRolesOutput, bool) bool, _ ...request.Option) error {
-	f(&m.ListRolesPagesOutput, true)
-	return nil
+func (m mockedIAMRoles) ListAttachedRolePolicies(ctx context.Context, params *iam.ListAttachedRolePoliciesInput, optFns ...func(*iam.Options)) (*iam.ListAttachedRolePoliciesOutput, error) {
+	return &m.ListAttachedRolePoliciesOutput, nil
 }
 
-func (m mockedIAMRoles) ListInstanceProfilesForRoleWithContext(_ aws.Context, input *iam.ListInstanceProfilesForRoleInput, _ ...request.Option) (*iam.ListInstanceProfilesForRoleOutput, error) {
+func (m mockedIAMRoles) ListInstanceProfilesForRole(ctx context.Context, params *iam.ListInstanceProfilesForRoleInput, optFns ...func(*iam.Options)) (*iam.ListInstanceProfilesForRoleOutput, error) {
 	return &m.ListInstanceProfilesForRoleOutput, nil
 }
 
-func (m mockedIAMRoles) RemoveRoleFromInstanceProfileWithContext(_ aws.Context, input *iam.RemoveRoleFromInstanceProfileInput, _ ...request.Option) (*iam.RemoveRoleFromInstanceProfileOutput, error) {
-	return &m.RemoveRoleFromInstanceProfileOutput, nil
+func (m mockedIAMRoles) ListRolePolicies(ctx context.Context, params *iam.ListRolePoliciesInput, optFns ...func(*iam.Options)) (*iam.ListRolePoliciesOutput, error) {
+	return &m.ListRolePoliciesOutput, nil
 }
 
-func (m mockedIAMRoles) DeleteInstanceProfileWithContext(_ aws.Context, input *iam.DeleteInstanceProfileInput, _ ...request.Option) (*iam.DeleteInstanceProfileOutput, error) {
-	return &m.DeleteInstanceProfileOutput, nil
+func (m mockedIAMRoles) ListRoles(ctx context.Context, params *iam.ListRolesInput, optFns ...func(*iam.Options)) (*iam.ListRolesOutput, error) {
+	return &m.ListRolesOutput, nil
 }
 
-func (m mockedIAMRoles) ListRolePoliciesWithContext(_ aws.Context, input *iam.ListRolePoliciesInput, _ ...request.Option) (*iam.ListRolePoliciesOutput, error) {
-	return &m.ListRolePoliciesOutput, nil
+func (m mockedIAMRoles) DeleteInstanceProfile(ctx context.Context, params *iam.DeleteInstanceProfileInput, optFns ...func(*iam.Options)) (*iam.DeleteInstanceProfileOutput, error) {
+	return &m.DeleteInstanceProfileOutput, nil
 }
 
-func (m mockedIAMRoles) DeleteRolePolicyWithContext(_ aws.Context, input *iam.DeleteRolePolicyInput, _ ...request.Option) (*iam.DeleteRolePolicyOutput, error) {
-	return &m.DeleteRolePolicyOutput, nil
+func (m mockedIAMRoles) DetachRolePolicy(ctx context.Context, params *iam.DetachRolePolicyInput, optFns ...func(*iam.Options)) (*iam.DetachRolePolicyOutput, error) {
+	return &m.DetachRolePolicyOutput, nil
 }
 
-func (m mockedIAMRoles) ListAttachedRolePoliciesWithContext(_ aws.Context, input *iam.ListAttachedRolePoliciesInput, _ ...request.Option) (*iam.ListAttachedRolePoliciesOutput, error) {
-	return &m.ListAttachedRolePoliciesOutput, nil
+func (m mockedIAMRoles) DeleteRolePolicy(ctx context.Context, params *iam.DeleteRolePolicyInput, optFns ...func(*iam.Options)) (*iam.DeleteRolePolicyOutput, error) {
+	return &m.DeleteRolePolicyOutput, nil
 }
 
-func (m mockedIAMRoles) DetachRolePolicyWithContext(_ aws.Context, input *iam.DetachRolePolicyInput, _ ...request.Option) (*iam.DetachRolePolicyOutput, error) {
-	return &m.DetachRolePolicyOutput, nil
+func (m mockedIAMRoles) DeleteRole(ctx context.Context, params *iam.DeleteRoleInput, optFns ...func(*iam.Options)) (*iam.DeleteRoleOutput, error) {
+	return &m.DeleteRoleOutput, nil
 }
 
-func (m mockedIAMRoles) DeleteRoleWithContext(_ aws.Context, input *iam.DeleteRoleInput, _ ...request.Option) (*iam.DeleteRoleOutput, error) {
-	return &m.DeleteRoleOutput, nil
+func (m mockedIAMRoles) RemoveRoleFromInstanceProfile(ctx context.Context, params *iam.RemoveRoleFromInstanceProfileInput, optFns ...func(*iam.Options)) (*iam.RemoveRoleFromInstanceProfileOutput, error) {
+	return &m.RemoveRoleFromInstanceProfileOutput, nil
 }
 
 func TestIAMRoles_GetAll(t *testing.T) {
-
 	t.Parallel()
-
 	testName1 := "test-role1"
 	testName2 := "test-role2"
 	now := time.Now()
 	ir := IAMRoles{
 		Client: mockedIAMRoles{
-			ListRolesPagesOutput: iam.ListRolesOutput{
-				Roles: []*iam.Role{
+			ListRolesOutput: iam.ListRolesOutput{
+				Roles: []types.Role{
 					{
 						RoleName:   aws.String(testName1),
 						CreateDate: aws.Time(now),
@@ -119,20 +115,18 @@ func TestIAMRoles_GetAll(t *testing.T) {
 				IAMRoles: tc.configObj,
 			})
 			require.NoError(t, err)
-			require.Equal(t, tc.expected, aws.StringValueSlice(names))
+			require.Equal(t, tc.expected, aws.ToStringSlice(names))
 		})
 	}
 
 }
 
 func TestIAMRoles_NukeAll(t *testing.T) {
-
 	t.Parallel()
-
 	ir := IAMRoles{
 		Client: mockedIAMRoles{
 			ListInstanceProfilesForRoleOutput: iam.ListInstanceProfilesForRoleOutput{
-				InstanceProfiles: []*iam.InstanceProfile{
+				InstanceProfiles: []types.InstanceProfile{
 					{
 						InstanceProfileName: aws.String("test-instance-profile"),
 					},
@@ -141,13 +135,13 @@ func TestIAMRoles_NukeAll(t *testing.T) {
 			RemoveRoleFromInstanceProfileOutput: iam.RemoveRoleFromInstanceProfileOutput{},
 			DeleteInstanceProfileOutput:         iam.DeleteInstanceProfileOutput{},
 			ListRolePoliciesOutput: iam.ListRolePoliciesOutput{
-				PolicyNames: []*string{
-					aws.String("test-policy"),
+				PolicyNames: []string{
+					"test-policy",
 				},
 			},
 			DeleteRolePolicyOutput: iam.DeleteRolePolicyOutput{},
 			ListAttachedRolePoliciesOutput: iam.ListAttachedRolePoliciesOutput{
-				AttachedPolicies: []*iam.AttachedPolicy{
+				AttachedPolicies: []types.AttachedPolicy{
 					{
 						PolicyArn: aws.String("test-policy-arn"),
 					},
diff --git a/aws/resources/iam_service_linked_role_test.go b/aws/resources/iam_service_linked_role_test.go
index 3393c06..9ae5187 100644
--- a/aws/resources/iam_service_linked_role_test.go
+++ b/aws/resources/iam_service_linked_role_test.go
@@ -6,45 +6,41 @@ 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/iam"
-	"github.com/aws/aws-sdk-go/service/iam/iamiface"
+	"github.com/aws/aws-sdk-go-v2/aws"
+	"github.com/aws/aws-sdk-go-v2/service/iam"
+	"github.com/aws/aws-sdk-go-v2/service/iam/types"
 	"github.com/gruntwork-io/cloud-nuke/config"
 	"github.com/stretchr/testify/require"
 )
 
 type mockedIAMServiceLinkedRoles struct {
-	iamiface.IAMAPI
-	ListRolesPagesOutput                     iam.ListRolesOutput
+	IAMServiceLinkedRolesAPI
+	ListRolesOutput                          iam.ListRolesOutput
 	DeleteServiceLinkedRoleOutput            iam.DeleteServiceLinkedRoleOutput
 	GetServiceLinkedRoleDeletionStatusOutput iam.GetServiceLinkedRoleDeletionStatusOutput
 }
 
-func (m mockedIAMServiceLinkedRoles) ListRolesPagesWithContext(_ aws.Context, input *iam.ListRolesInput, fn func(*iam.ListRolesOutput, bool) bool, _ ...request.Option) error {
-	fn(&m.ListRolesPagesOutput, true)
-	return nil
+func (m mockedIAMServiceLinkedRoles) ListRoles(ctx context.Context, params *iam.ListRolesInput, optFns ...func(*iam.Options)) (*iam.ListRolesOutput, error) {
+	return &m.ListRolesOutput, nil
 }
 
-func (m mockedIAMServiceLinkedRoles) DeleteServiceLinkedRoleWithContext(_ aws.Context, input *iam.DeleteServiceLinkedRoleInput, _ ...request.Option) (*iam.DeleteServiceLinkedRoleOutput, error) {
+func (m mockedIAMServiceLinkedRoles) DeleteServiceLinkedRole(ctx context.Context, params *iam.DeleteServiceLinkedRoleInput, optFns ...func(*iam.Options)) (*iam.DeleteServiceLinkedRoleOutput, error) {
 	return &m.DeleteServiceLinkedRoleOutput, nil
 }
 
-func (m mockedIAMServiceLinkedRoles) GetServiceLinkedRoleDeletionStatusWithContext(_ aws.Context, input *iam.GetServiceLinkedRoleDeletionStatusInput, _ ...request.Option) (*iam.GetServiceLinkedRoleDeletionStatusOutput, error) {
+func (m mockedIAMServiceLinkedRoles) GetServiceLinkedRoleDeletionStatus(ctx context.Context, params *iam.GetServiceLinkedRoleDeletionStatusInput, optFns ...func(*iam.Options)) (*iam.GetServiceLinkedRoleDeletionStatusOutput, error) {
 	return &m.GetServiceLinkedRoleDeletionStatusOutput, nil
 }
 
 func TestIAMServiceLinkedRoles_GetAll(t *testing.T) {
-
 	t.Parallel()
-
 	now := time.Now()
 	testName1 := "test-role1"
 	testName2 := "test-role2"
 	islr := IAMServiceLinkedRoles{
 		Client: &mockedIAMServiceLinkedRoles{
-			ListRolesPagesOutput: iam.ListRolesOutput{
-				Roles: []*iam.Role{
+			ListRolesOutput: iam.ListRolesOutput{
+				Roles: []types.Role{
 					{
 						RoleName:   aws.String(testName1),
 						CreateDate: aws.Time(now),
@@ -91,22 +87,19 @@ func TestIAMServiceLinkedRoles_GetAll(t *testing.T) {
 				IAMServiceLinkedRoles: tc.configObj,
 			})
 			require.NoError(t, err)
-			require.Equal(t, tc.expected, aws.StringValueSlice(names))
+			require.Equal(t, tc.expected, aws.ToStringSlice(names))
 		})
 	}
 
 }
 
 func TestIAMServiceLinkedRoles_NukeAll(t *testing.T) {
-
 	t.Parallel()
-
 	islr := IAMServiceLinkedRoles{
-
 		Client: &mockedIAMServiceLinkedRoles{
 			DeleteServiceLinkedRoleOutput: iam.DeleteServiceLinkedRoleOutput{},
 			GetServiceLinkedRoleDeletionStatusOutput: iam.GetServiceLinkedRoleDeletionStatusOutput{
-				Status: aws.String("SUCCEEDED"),
+				Status: types.DeletionTaskStatusTypeSucceeded,
 			},
 		},
 	}
diff --git a/aws/resources/iam_test.go b/aws/resources/iam_test.go
index 0e503fd..bfb74c5 100644
--- a/aws/resources/iam_test.go
+++ b/aws/resources/iam_test.go
@@ -6,143 +6,138 @@ import (
 	"testing"
 	"time"
 
-	"github.com/aws/aws-sdk-go/aws"
-	awsgo "github.com/aws/aws-sdk-go/aws"
-	"github.com/aws/aws-sdk-go/aws/request"
-	"github.com/aws/aws-sdk-go/service/iam"
-	"github.com/aws/aws-sdk-go/service/iam/iamiface"
+	"github.com/aws/aws-sdk-go-v2/aws"
+	"github.com/aws/aws-sdk-go-v2/service/iam"
+	"github.com/aws/aws-sdk-go-v2/service/iam/types"
 	"github.com/gruntwork-io/cloud-nuke/config"
 	"github.com/stretchr/testify/require"
 )
 
 type mockedIAMUsers struct {
-	iamiface.IAMAPI
-	ListUsersPagesOutput                  iam.ListUsersOutput
+	IAMUsersAPI
+	ListAccessKeysOutput                  iam.ListAccessKeysOutput
+	ListGroupsForUserOutput               iam.ListGroupsForUserOutput
+	ListUserPoliciesOutput                iam.ListUserPoliciesOutput
+	ListUserTagsOutput                    iam.ListUserTagsOutput
+	ListMFADevicesOutput                  iam.ListMFADevicesOutput
+	ListSSHPublicKeysOutput               iam.ListSSHPublicKeysOutput
+	ListServiceSpecificCredentialsOutput  iam.ListServiceSpecificCredentialsOutput
+	ListSigningCertificatesOutput         iam.ListSigningCertificatesOutput
+	ListUsersOutput                       iam.ListUsersOutput
 	ListAttachedUserPoliciesOutput        iam.ListAttachedUserPoliciesOutput
 	DetachUserPolicyOutput                iam.DetachUserPolicyOutput
-	ListUserPoliciesOutput                iam.ListUserPoliciesOutput
-	DeleteUserPolicyOutput                iam.DeleteUserPolicyOutput
-	ListGroupsForUserOutput               iam.ListGroupsForUserOutput
-	RemoveUserFromGroupOutput             iam.RemoveUserFromGroupOutput
 	DeleteLoginProfileOutput              iam.DeleteLoginProfileOutput
-	ListAccessKeysOutput                  iam.ListAccessKeysOutput
+	DeleteUserPolicyOutput                iam.DeleteUserPolicyOutput
 	DeleteAccessKeyOutput                 iam.DeleteAccessKeyOutput
-	ListSigningCertificatesOutput         iam.ListSigningCertificatesOutput
 	DeleteSigningCertificateOutput        iam.DeleteSigningCertificateOutput
-	ListSSHPublicKeysOutput               iam.ListSSHPublicKeysOutput
 	DeleteSSHPublicKeyOutput              iam.DeleteSSHPublicKeyOutput
-	ListServiceSpecificCredentialsOutput  iam.ListServiceSpecificCredentialsOutput
 	DeleteServiceSpecificCredentialOutput iam.DeleteServiceSpecificCredentialOutput
-	ListMFADevicesOutput                  iam.ListMFADevicesOutput
 	DeactivateMFADeviceOutput             iam.DeactivateMFADeviceOutput
 	DeleteVirtualMFADeviceOutput          iam.DeleteVirtualMFADeviceOutput
 	DeleteUserOutput                      iam.DeleteUserOutput
-	ListUserTagsOutput                    iam.ListUserTagsOutput
+	RemoveUserFromGroupOutput             iam.RemoveUserFromGroupOutput
 }
 
-func (m mockedIAMUsers) ListUsersPagesWithContext(_ aws.Context, input *iam.ListUsersInput, callback func(*iam.ListUsersOutput, bool) bool, _ ...request.Option) error {
-	callback(&m.ListUsersPagesOutput, true)
-	return nil
+func (m mockedIAMUsers) ListAccessKeys(ctx context.Context, params *iam.ListAccessKeysInput, optFns ...func(*iam.Options)) (*iam.ListAccessKeysOutput, error) {
+	return &m.ListAccessKeysOutput, nil
 }
 
-func (m mockedIAMUsers) ListAttachedUserPoliciesWithContext(_ aws.Context, input *iam.ListAttachedUserPoliciesInput, _ ...request.Option) (*iam.ListAttachedUserPoliciesOutput, error) {
-	return &m.ListAttachedUserPoliciesOutput, nil
+func (m mockedIAMUsers) ListGroupsForUser(ctx context.Context, params *iam.ListGroupsForUserInput, optFns ...func(*iam.Options)) (*iam.ListGroupsForUserOutput, error) {
+	return &m.ListGroupsForUserOutput, nil
 }
 
-func (m mockedIAMUsers) DetachUserPolicyWithContext(_ aws.Context, input *iam.DetachUserPolicyInput, _ ...request.Option) (*iam.DetachUserPolicyOutput, error) {
-	return &m.DetachUserPolicyOutput, nil
+func (m mockedIAMUsers) ListUserPolicies(ctx context.Context, params *iam.ListUserPoliciesInput, optFns ...func(*iam.Options)) (*iam.ListUserPoliciesOutput, error) {
+	return &m.ListUserPoliciesOutput, nil
 }
 
-func (m mockedIAMUsers) ListUserPoliciesWithContext(_ aws.Context, input *iam.ListUserPoliciesInput, _ ...request.Option) (*iam.ListUserPoliciesOutput, error) {
-	return &m.ListUserPoliciesOutput, nil
+func (m mockedIAMUsers) ListUserTags(ctx context.Context, params *iam.ListUserTagsInput, optFns ...func(*iam.Options)) (*iam.ListUserTagsOutput, error) {
+	return &m.ListUserTagsOutput, nil
 }
 
-func (m mockedIAMUsers) DeleteUserPolicyWithContext(_ aws.Context, input *iam.DeleteUserPolicyInput, _ ...request.Option) (*iam.DeleteUserPolicyOutput, error) {
-	return &m.DeleteUserPolicyOutput, nil
+func (m mockedIAMUsers) ListMFADevices(ctx context.Context, params *iam.ListMFADevicesInput, optFns ...func(*iam.Options)) (*iam.ListMFADevicesOutput, error) {
+	return &m.ListMFADevicesOutput, nil
 }
 
-func (m mockedIAMUsers) ListGroupsForUserWithContext(_ aws.Context, input *iam.ListGroupsForUserInput, _ ...request.Option) (*iam.ListGroupsForUserOutput, error) {
-	return &m.ListGroupsForUserOutput, nil
+func (m mockedIAMUsers) ListSSHPublicKeys(ctx context.Context, params *iam.ListSSHPublicKeysInput, optFns ...func(*iam.Options)) (*iam.ListSSHPublicKeysOutput, error) {
+	return &m.ListSSHPublicKeysOutput, nil
 }
 
-func (m mockedIAMUsers) RemoveUserFromGroupWithContext(_ aws.Context, input *iam.RemoveUserFromGroupInput, _ ...request.Option) (*iam.RemoveUserFromGroupOutput, error) {
-	return &m.RemoveUserFromGroupOutput, nil
+func (m mockedIAMUsers) ListServiceSpecificCredentials(ctx context.Context, params *iam.ListServiceSpecificCredentialsInput, optFns ...func(*iam.Options)) (*iam.ListServiceSpecificCredentialsOutput, error) {
+	return &m.ListServiceSpecificCredentialsOutput, nil
 }
 
-func (m mockedIAMUsers) DeleteLoginProfileWithContext(_ aws.Context, input *iam.DeleteLoginProfileInput, _ ...request.Option) (*iam.DeleteLoginProfileOutput, error) {
-	return &m.DeleteLoginProfileOutput, nil
+func (m mockedIAMUsers) ListSigningCertificates(ctx context.Context, params *iam.ListSigningCertificatesInput, optFns ...func(*iam.Options)) (*iam.ListSigningCertificatesOutput, error) {
+	return &m.ListSigningCertificatesOutput, nil
 }
 
-func (m mockedIAMUsers) ListAccessKeysWithContext(_ aws.Context, input *iam.ListAccessKeysInput, _ ...request.Option) (*iam.ListAccessKeysOutput, error) {
-	return &m.ListAccessKeysOutput, nil
+func (m mockedIAMUsers) ListUsers(ctx context.Context, params *iam.ListUsersInput, optFns ...func(*iam.Options)) (*iam.ListUsersOutput, error) {
+	return &m.ListUsersOutput, nil
 }
 
-func (m mockedIAMUsers) DeleteAccessKeyWithContext(_ aws.Context, input *iam.DeleteAccessKeyInput, _ ...request.Option) (*iam.DeleteAccessKeyOutput, error) {
-	return &m.DeleteAccessKeyOutput, nil
+func (m mockedIAMUsers) ListAttachedUserPolicies(ctx context.Context, params *iam.ListAttachedUserPoliciesInput, optFns ...func(*iam.Options)) (*iam.ListAttachedUserPoliciesOutput, error) {
+	return &m.ListAttachedUserPoliciesOutput, nil
 }
 
-func (m mockedIAMUsers) ListSigningCertificatesWithContext(_ aws.Context, input *iam.ListSigningCertificatesInput, _ ...request.Option) (*iam.ListSigningCertificatesOutput, error) {
-	return &m.ListSigningCertificatesOutput, nil
+func (m mockedIAMUsers) DetachUserPolicy(ctx context.Context, params *iam.DetachUserPolicyInput, optFns ...func(*iam.Options)) (*iam.DetachUserPolicyOutput, error) {
+	return &m.DetachUserPolicyOutput, nil
 }
 
-func (m mockedIAMUsers) DeleteSigningCertificateWithContext(_ aws.Context, input *iam.DeleteSigningCertificateInput, _ ...request.Option) (*iam.DeleteSigningCertificateOutput, error) {
-	return &m.DeleteSigningCertificateOutput, nil
+func (m mockedIAMUsers) DeleteLoginProfile(ctx context.Context, params *iam.DeleteLoginProfileInput, optFns ...func(*iam.Options)) (*iam.DeleteLoginProfileOutput, error) {
+	return &m.DeleteLoginProfileOutput, nil
 }
 
-func (m mockedIAMUsers) ListSSHPublicKeysWithContext(_ aws.Context, input *iam.ListSSHPublicKeysInput, _ ...request.Option) (*iam.ListSSHPublicKeysOutput, error) {
-	return &m.ListSSHPublicKeysOutput, nil
+func (m mockedIAMUsers) DeleteUserPolicy(ctx context.Context, params *iam.DeleteUserPolicyInput, optFns ...func(*iam.Options)) (*iam.DeleteUserPolicyOutput, error) {
+	return &m.DeleteUserPolicyOutput, nil
 }
 
-func (m mockedIAMUsers) DeleteSSHPublicKeyWithContext(_ aws.Context, input *iam.DeleteSSHPublicKeyInput, _ ...request.Option) (*iam.DeleteSSHPublicKeyOutput, error) {
-	return &m.DeleteSSHPublicKeyOutput, nil
+func (m mockedIAMUsers) DeleteAccessKey(ctx context.Context, params *iam.DeleteAccessKeyInput, optFns ...func(*iam.Options)) (*iam.DeleteAccessKeyOutput, error) {
+	return &m.DeleteAccessKeyOutput, nil
 }
 
-func (m mockedIAMUsers) ListServiceSpecificCredentialsWithContext(_ aws.Context, input *iam.ListServiceSpecificCredentialsInput, _ ...request.Option) (*iam.ListServiceSpecificCredentialsOutput, error) {
-	return &m.ListServiceSpecificCredentialsOutput, nil
+func (m mockedIAMUsers) DeleteSigningCertificate(ctx context.Context, params *iam.DeleteSigningCertificateInput, optFns ...func(*iam.Options)) (*iam.DeleteSigningCertificateOutput, error) {
+	return &m.DeleteSigningCertificateOutput, nil
 }
 
-func (m mockedIAMUsers) DeleteServiceSpecificCredentialWithContext(_ aws.Context, input *iam.DeleteServiceSpecificCredentialInput, _ ...request.Option) (*iam.DeleteServiceSpecificCredentialOutput, error) {
-	return &m.DeleteServiceSpecificCredentialOutput, nil
+func (m mockedIAMUsers) DeleteSSHPublicKey(ctx context.Context, params *iam.DeleteSSHPublicKeyInput, optFns ...func(*iam.Options)) (*iam.DeleteSSHPublicKeyOutput, error) {
+	return &m.DeleteSSHPublicKeyOutput, nil
 }
 
-func (m mockedIAMUsers) ListMFADevicesWithContext(_ aws.Context, input *iam.ListMFADevicesInput, _ ...request.Option) (*iam.ListMFADevicesOutput, error) {
-	return &m.ListMFADevicesOutput, nil
+func (m mockedIAMUsers) DeleteServiceSpecificCredential(ctx context.Context, params *iam.DeleteServiceSpecificCredentialInput, optFns ...func(*iam.Options)) (*iam.DeleteServiceSpecificCredentialOutput, error) {
+	return &m.DeleteServiceSpecificCredentialOutput, nil
 }
 
-func (m mockedIAMUsers) DeactivateMFADeviceWithContext(_ aws.Context, input *iam.DeactivateMFADeviceInput, _ ...request.Option) (*iam.DeactivateMFADeviceOutput, error) {
+func (m mockedIAMUsers) DeactivateMFADevice(ctx context.Context, params *iam.DeactivateMFADeviceInput, optFns ...func(*iam.Options)) (*iam.DeactivateMFADeviceOutput, error) {
 	return &m.DeactivateMFADeviceOutput, nil
 }
 
-func (m mockedIAMUsers) DeleteVirtualMFADeviceWithContext(_ aws.Context, input *iam.DeleteVirtualMFADeviceInput, _ ...request.Option) (*iam.DeleteVirtualMFADeviceOutput, error) {
+func (m mockedIAMUsers) DeleteVirtualMFADevice(ctx context.Context, params *iam.DeleteVirtualMFADeviceInput, optFns ...func(*iam.Options)) (*iam.DeleteVirtualMFADeviceOutput, error) {
 	return &m.DeleteVirtualMFADeviceOutput, nil
 }
 
-func (m mockedIAMUsers) DeleteUserWithContext(_ aws.Context, input *iam.DeleteUserInput, _ ...request.Option) (*iam.DeleteUserOutput, error) {
+func (m mockedIAMUsers) DeleteUser(ctx context.Context, params *iam.DeleteUserInput, optFns ...func(*iam.Options)) (*iam.DeleteUserOutput, error) {
 	return &m.DeleteUserOutput, nil
 }
-func (m mockedIAMUsers) ListUserTagsPagesWithContext(_ aws.Context, input *iam.ListUserTagsInput, callback func(*iam.ListUserTagsOutput, bool) bool, _ ...request.Option) error {
-	callback(&m.ListUserTagsOutput, true)
-	return nil
+
+func (m mockedIAMUsers) RemoveUserFromGroup(ctx context.Context, params *iam.RemoveUserFromGroupInput, optFns ...func(*iam.Options)) (*iam.RemoveUserFromGroupOutput, error) {
+	return &m.RemoveUserFromGroupOutput, nil
 }
 
 func TestIAMUsers_GetAll(t *testing.T) {
-
 	t.Parallel()
-
 	now := time.Now()
 	testName1 := "test-user1"
 	testName2 := "test-user2"
 	iu := IAMUsers{
 		Client: mockedIAMUsers{
-			ListUsersPagesOutput: iam.ListUsersOutput{
-				Users: []*iam.User{
+			ListUsersOutput: iam.ListUsersOutput{
+				Users: []types.User{
 					{
-						UserName:   awsgo.String(testName1),
-						CreateDate: awsgo.Time(now),
+						UserName:   aws.String(testName1),
+						CreateDate: aws.Time(now),
 					},
 					{
-						UserName:   awsgo.String(testName2),
-						CreateDate: awsgo.Time(now.Add(1)),
+						UserName:   aws.String(testName2),
+						CreateDate: aws.Time(now.Add(1)),
 					},
 				},
 			},
@@ -180,77 +175,75 @@ func TestIAMUsers_GetAll(t *testing.T) {
 				IAMUsers: tc.configObj,
 			})
 			require.NoError(t, err)
-			require.Equal(t, tc.expected, awsgo.StringValueSlice(names))
+			require.Equal(t, tc.expected, aws.ToStringSlice(names))
 		})
 	}
 
 }
 
 func TestIAMUsers_NukeAll(t *testing.T) {
-
 	t.Parallel()
-
 	iu := IAMUsers{
 		Client: mockedIAMUsers{
 			ListAttachedUserPoliciesOutput: iam.ListAttachedUserPoliciesOutput{
-				AttachedPolicies: []*iam.AttachedPolicy{
+				AttachedPolicies: []types.AttachedPolicy{
 					{
-						PolicyName: awsgo.String("test-policy"),
+						PolicyName: aws.String("test-policy"),
 					},
 				},
 			},
 			DetachUserPolicyOutput: iam.DetachUserPolicyOutput{},
 			ListUserPoliciesOutput: iam.ListUserPoliciesOutput{
-				PolicyNames: []*string{
-					awsgo.String("test-policy"),
+				PolicyNames: []string{
+					"test-policy",
 				},
 			},
 			DeleteUserPolicyOutput: iam.DeleteUserPolicyOutput{},
 			ListGroupsForUserOutput: iam.ListGroupsForUserOutput{
-				Groups: []*iam.Group{
+				Groups: []types.Group{
 					{
-						GroupName: awsgo.String("test-group"),
+						GroupName: aws.String("test-group"),
 					},
 				},
 			},
 			RemoveUserFromGroupOutput: iam.RemoveUserFromGroupOutput{},
 			DeleteLoginProfileOutput:  iam.DeleteLoginProfileOutput{},
 			ListAccessKeysOutput: iam.ListAccessKeysOutput{
-				AccessKeyMetadata: []*iam.AccessKeyMetadata{
+				AccessKeyMetadata: []types.AccessKeyMetadata{
 					{
-						AccessKeyId: awsgo.String("test-key"),
+						AccessKeyId: aws.String("test-key"),
 					},
 				},
 			},
 			DeleteAccessKeyOutput: iam.DeleteAccessKeyOutput{},
 			ListSigningCertificatesOutput: iam.ListSigningCertificatesOutput{
-				Certificates: []*iam.SigningCertificate{
+				Certificates: []types.SigningCertificate{
 					{
-						CertificateId: awsgo.String("test-certificate"),
+						CertificateId: aws.String("test-certificate"),
 					},
 				},
 			},
 			DeleteSigningCertificateOutput: iam.DeleteSigningCertificateOutput{},
 			ListSSHPublicKeysOutput: iam.ListSSHPublicKeysOutput{
-				SSHPublicKeys: []*iam.SSHPublicKeyMetadata{
+				SSHPublicKeys: []types.SSHPublicKeyMetadata{
 					{
-						SSHPublicKeyId: awsgo.String("test-ssh-key"),
+						SSHPublicKeyId: aws.String("test-ssh-key"),
 					},
 				},
 			},
 			DeleteSSHPublicKeyOutput: iam.DeleteSSHPublicKeyOutput{},
 			ListServiceSpecificCredentialsOutput: iam.ListServiceSpecificCredentialsOutput{
-				ServiceSpecificCredentials: []*iam.ServiceSpecificCredentialMetadata{
+				ServiceSpecificCredentials: []types.ServiceSpecificCredentialMetadata{
 					{
-						ServiceSpecificCredentialId: awsgo.String("test-service-credential"),
+						ServiceSpecificCredentialId: aws.String("test-service-credential"),
 					},
 				},
 			},
 			DeleteServiceSpecificCredentialOutput: iam.DeleteServiceSpecificCredentialOutput{},
 			ListMFADevicesOutput: iam.ListMFADevicesOutput{
-				MFADevices: []*iam.MFADevice{
+				MFADevices: []types.MFADevice{
 					{
-						SerialNumber: awsgo.String("test-mfa-device"),
+						SerialNumber: aws.String("test-mfa-device"),
 					},
 				},
 			},
@@ -260,6 +253,6 @@ func TestIAMUsers_NukeAll(t *testing.T) {
 		},
 	}
 
-	err := iu.nukeAll([]*string{awsgo.String("test-user")})
+	err := iu.nukeAll([]*string{aws.String("test-user")})
 	require.NoError(t, err)
 }