Repository: kubernetes-sigs/cluster-api-provider-aws
Pull request #3897 (2022-12-01 07:59:08)

test: save original aws resource quotas as returned by API
Signed-off-by: Richard Case <richard.case@outlook.com>

<!-- Thanks for this PR! If this is your first PR please read the [contributing guide](../CONTRIBUTING.md) -->
<!-- If this PR is still work-in-progress and is being open for visibility please prefix the title with `WIP:` -->

**What type of PR is this?**
/kind support

**What this PR does / why we need it**:

This adds saving of the original quotas from AWS.

**Which issue(s) this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close the issue(s) when PR gets merged)*:
Fixes #

**Special notes for your reviewer**:

**Checklist**:
<!-- Put an "X" character inside the brackets of each completed task. Some may be optional depending on the PR in which case these can be deleted -->

- [x] squashed commits
- [ ] includes documentation
- [ ] adds unit tests
- [x] adds or updates e2e tests



Patch:
diff --git a/api/v1beta2/tags.go b/api/v1beta2/tags.go
index b5e868c3a..1d620426c 100644
--- a/api/v1beta2/tags.go
+++ b/api/v1beta2/tags.go
@@ -155,7 +155,7 @@ const (
 	// NameAWSProviderPrefix is the tag prefix we use to differentiate
 	// cluster-api-provider-aws owned components from other tooling that
 	// uses NameKubernetesClusterPrefix.
-	NameAWSProviderPrefix = "sigs.k8s.io/cluster-api-provider-aws/"
+	NameAWSProviderPrefix = "sigs.k8s.io/cluster-api-provider-aws/v2/"
 
 	// NameAWSProviderOwned is the tag name we use to differentiate
 	// cluster-api-provider-aws owned components from other tooling that
diff --git a/docs/book/src/topics/accessing-ec2-instances.md b/docs/book/src/topics/accessing-ec2-instances.md
index 2babef987..c6ed21306 100644
--- a/docs/book/src/topics/accessing-ec2-instances.md
+++ b/docs/book/src/topics/accessing-ec2-instances.md
@@ -147,7 +147,7 @@ Similarly, to obtain the list of private IP addresses of the cluster nodes, use
 for type in control-plane node
 do
 	aws ec2 describe-instances \
-    --filter="Name=tag:sigs.k8s.io/cluster-api-provider-aws/role,\
+    --filter="Name=tag:sigs.k8s.io/cluster-api-provider-aws/v2/role,\
     Values=${type}" \
 		| jq '.Reservations[].Instances[].PrivateIpAddress' -r
 done
@@ -161,7 +161,7 @@ Finally, to obtain AWS instance IDs for cluster nodes, you can use this AWS CLI
 for type in control-plane node
 do
 	aws ec2 describe-instances \
-    --filter="Name=tag:sigs.k8s.io/cluster-api-provider-aws/role,\
+    --filter="Name=tag:sigs.k8s.io/cluster-api-provider-aws/v2/role,\
     Values=${type}" \
 		| jq '.Reservations[].Instances[].InstanceId' -r
 done
diff --git a/docs/book/src/topics/using-clusterawsadm-to-fulfill-prerequisites.md b/docs/book/src/topics/using-clusterawsadm-to-fulfill-prerequisites.md
index 7ffc3c903..8366fe2ad 100644
--- a/docs/book/src/topics/using-clusterawsadm-to-fulfill-prerequisites.md
+++ b/docs/book/src/topics/using-clusterawsadm-to-fulfill-prerequisites.md
@@ -146,7 +146,7 @@ If you want to save the private key directly into AWS Systems Manager Parameter
 Store with KMS encryption for security, you can use the following command:
 
 ```bash
-aws ssm put-parameter --name "/sigs.k8s.io/cluster-api-provider-aws/ssh-key" \
+aws ssm put-parameter --name "/sigs.k8s.io/cluster-api-provider-aws/v2/ssh-key" \
   --type SecureString \
   --value "$(aws ec2 create-key-pair --key-name default --output json | jq .KeyMaterial -r)"
 ```
diff --git a/exp/controllers/awsmachinepool_controller.go b/exp/controllers/awsmachinepool_controller.go
index 40879c904..338ff089c 100644
--- a/exp/controllers/awsmachinepool_controller.go
+++ b/exp/controllers/awsmachinepool_controller.go
@@ -267,7 +267,7 @@ func (r *AWSMachinePoolReconciler) reconcileNormal(ctx context.Context, machineP
 
 	if asg == nil {
 		// Create new ASG
-		if err := r.createPool(machinePoolScope, clusterScope); err != nil {
+		if _, err := r.createPool(machinePoolScope, clusterScope); err != nil {
 			conditions.MarkFalse(machinePoolScope.AWSMachinePool, expinfrav1.ASGReadyCondition, expinfrav1.ASGProvisionFailedReason, clusterv1.ConditionSeverityError, err.Error())
 			return ctrl.Result{}, err
 		}
@@ -404,7 +404,6 @@ func (r *AWSMachinePoolReconciler) updatePool(machinePoolScope *scope.MachinePoo
 
 	suspendedProcessesSlice := machinePoolScope.AWSMachinePool.Spec.SuspendProcesses.ConvertSetValuesToStringSlice()
 	if !cmp.Equal(existingASG.CurrentlySuspendProcesses, suspendedProcessesSlice) {
-		clusterScope.Info("reconciling processes", "suspend-processes", suspendedProcessesSlice)
 		var (
 			toBeSuspended []string
 			toBeResumed   []string
@@ -432,7 +431,7 @@ func (r *AWSMachinePoolReconciler) updatePool(machinePoolScope *scope.MachinePoo
 			delete(currentlySuspended, k)
 		}
 
-		// Convert them back into lists to pass them to resume/suspend.
+		// Convert them back into lists so
 		for k := range desiredSuspended {
 			toBeSuspended = append(toBeSuspended, k)
 		}
@@ -442,13 +441,11 @@ func (r *AWSMachinePoolReconciler) updatePool(machinePoolScope *scope.MachinePoo
 		}
 
 		if len(toBeSuspended) > 0 {
-			clusterScope.Info("suspending processes", "processes", toBeSuspended)
 			if err := asgSvc.SuspendProcesses(existingASG.Name, toBeSuspended); err != nil {
 				return errors.Wrapf(err, "failed to suspend processes while trying update pool")
 			}
 		}
 		if len(toBeResumed) > 0 {
-			clusterScope.Info("resuming processes", "processes", toBeResumed)
 			if err := asgSvc.ResumeProcesses(existingASG.Name, toBeResumed); err != nil {
 				return errors.Wrapf(err, "failed to resume processes while trying update pool")
 			}
@@ -457,17 +454,21 @@ func (r *AWSMachinePoolReconciler) updatePool(machinePoolScope *scope.MachinePoo
 	return nil
 }
 
-func (r *AWSMachinePoolReconciler) createPool(machinePoolScope *scope.MachinePoolScope, clusterScope cloud.ClusterScoper) error {
+func (r *AWSMachinePoolReconciler) createPool(machinePoolScope *scope.MachinePoolScope, clusterScope cloud.ClusterScoper) (*expinfrav1.AutoScalingGroup, error) {
 	clusterScope.Info("Initializing ASG client")
 
 	asgsvc := r.getASGService(clusterScope)
 
 	machinePoolScope.Info("Creating Autoscaling Group")
-	if _, err := asgsvc.CreateASG(machinePoolScope); err != nil {
-		return errors.Wrapf(err, "failed to create AWSMachinePool")
+	asg, err := asgsvc.CreateASG(machinePoolScope)
+	if err != nil {
+		return nil, errors.Wrapf(err, "failed to create AWSMachinePool")
 	}
-
-	return nil
+	suspendedProcessesSlice := machinePoolScope.AWSMachinePool.Spec.SuspendProcesses.ConvertSetValuesToStringSlice()
+	if err := asgsvc.SuspendProcesses(asg.Name, suspendedProcessesSlice); err != nil {
+		return nil, errors.Wrapf(err, "failed to suspend processes while trying to create Pool")
+	}
+	return asg, nil
 }
 
 func (r *AWSMachinePoolReconciler) findASG(machinePoolScope *scope.MachinePoolScope, asgsvc services.ASGInterface) (*expinfrav1.AutoScalingGroup, error) {


Test patch:
diff --git a/controllers/awscluster_controller_test.go b/controllers/awscluster_controller_test.go
index 3d6dc808b..fb77f66f4 100644
--- a/controllers/awscluster_controller_test.go
+++ b/controllers/awscluster_controller_test.go
@@ -320,12 +320,12 @@ func mockedDescribeInstanceCall(m *mocks.MockEC2APIMockRecorder) {
 	m.DescribeInstances(gomock.Eq(&ec2.DescribeInstancesInput{
 		Filters: []*ec2.Filter{
 			{
-				Name:   aws.String("tag:sigs.k8s.io/cluster-api-provider-aws/role"),
+				Name:   aws.String("tag:sigs.k8s.io/cluster-api-provider-aws/v2/role"),
 				Values: aws.StringSlice([]string{"bastion"}),
 			},
 			{
 				Name:   aws.String("tag-key"),
-				Values: aws.StringSlice([]string{"sigs.k8s.io/cluster-api-provider-aws/cluster/test-cluster"}),
+				Values: aws.StringSlice([]string{"sigs.k8s.io/cluster-api-provider-aws/v2/cluster/test-cluster"}),
 			},
 			{
 				Name:   aws.String("instance-state-name"),
@@ -425,11 +425,11 @@ func mockedCreateVPCCalls(m *mocks.MockEC2APIMockRecorder) {
 				Value: aws.String("1"),
 			},
 			{
-				Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/cluster/test-cluster"),
+				Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/cluster/test-cluster"),
 				Value: aws.String("owned"),
 			},
 			{
-				Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/role"),
+				Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/role"),
 				Value: aws.String("public"),
 			},
 		},
@@ -455,11 +455,11 @@ func mockedCreateVPCCalls(m *mocks.MockEC2APIMockRecorder) {
 						Value: aws.String("1"),
 					},
 					{
-						Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/cluster/test-cluster"),
+						Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/cluster/test-cluster"),
 						Value: aws.String("owned"),
 					},
 					{
-						Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/role"),
+						Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/role"),
 						Value: aws.String("public"),
 					},
 				},
@@ -474,11 +474,11 @@ func mockedCreateVPCCalls(m *mocks.MockEC2APIMockRecorder) {
 			MapPublicIpOnLaunch: aws.Bool(false),
 			Tags: []*ec2.Tag{
 				{
-					Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/cluster/test-cluster"),
+					Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/cluster/test-cluster"),
 					Value: aws.String("owned"),
 				},
 				{
-					Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/role"),
+					Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/role"),
 					Value: aws.String("public"),
 				},
 				{
@@ -519,11 +519,11 @@ func mockedCreateVPCCalls(m *mocks.MockEC2APIMockRecorder) {
 				MapPublicIpOnLaunch: aws.Bool(false),
 				Tags: []*ec2.Tag{
 					{
-						Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/cluster/test-cluster"),
+						Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/cluster/test-cluster"),
 						Value: aws.String("owned"),
 					},
 					{
-						Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/role"),
+						Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/role"),
 						Value: aws.String("public"),
 					},
 					{
@@ -585,7 +585,7 @@ func mockedCreateVPCCalls(m *mocks.MockEC2APIMockRecorder) {
 					CidrBlock: aws.String("10.0.0.0/8"),
 					Tags: []*ec2.Tag{
 						{
-							Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/role"),
+							Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/role"),
 							Value: aws.String("common"),
 						},
 						{
@@ -632,7 +632,7 @@ func mockedDeleteVPCCalls(m *mocks.MockEC2APIMockRecorder) {
 			},
 			{
 				Name:   aws.String("tag-key"),
-				Values: aws.StringSlice([]string{"sigs.k8s.io/cluster-api-provider-aws/cluster/test-cluster"}),
+				Values: aws.StringSlice([]string{"sigs.k8s.io/cluster-api-provider-aws/v2/cluster/test-cluster"}),
 			},
 		}})).Return(&ec2.DescribeRouteTablesOutput{
 		RouteTables: []*ec2.RouteTable{
@@ -686,7 +686,7 @@ func mockedDeleteVPCCalls(m *mocks.MockEC2APIMockRecorder) {
 		Filters: []*ec2.Filter{
 			{
 				Name:   aws.String("tag-key"),
-				Values: aws.StringSlice([]string{"sigs.k8s.io/cluster-api-provider-aws/cluster/test-cluster"}),
+				Values: aws.StringSlice([]string{"sigs.k8s.io/cluster-api-provider-aws/v2/cluster/test-cluster"}),
 			}},
 	})).Return(&ec2.DescribeAddressesOutput{
 		Addresses: []*ec2.Address{
@@ -722,7 +722,7 @@ func mockedDeleteVPCCalls(m *mocks.MockEC2APIMockRecorder) {
 					CidrBlock: aws.String("10.0.0.0/8"),
 					Tags: []*ec2.Tag{
 						{
-							Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/role"),
+							Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/role"),
 							Value: aws.String("common"),
 						},
 						{
@@ -730,7 +730,7 @@ func mockedDeleteVPCCalls(m *mocks.MockEC2APIMockRecorder) {
 							Value: aws.String("test-cluster"),
 						},
 						{
-							Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/cluster/test-cluster"),
+							Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/cluster/test-cluster"),
 							Value: aws.String("owned"),
 						},
 					},
@@ -754,7 +754,7 @@ func mockedCreateSGCalls(m *mocks.MockEC2APIMockRecorder) {
 			},
 			{
 				Name:   aws.String("tag-key"),
-				Values: aws.StringSlice([]string{"sigs.k8s.io/cluster-api-provider-aws/cluster/test-cluster"}),
+				Values: aws.StringSlice([]string{"sigs.k8s.io/cluster-api-provider-aws/v2/cluster/test-cluster"}),
 			},
 		},
 	})).Return(
@@ -779,11 +779,11 @@ func mockedCreateSGCalls(m *mocks.MockEC2APIMockRecorder) {
 						Value: aws.String("test-cluster-bastion"),
 					},
 					{
-						Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/cluster/test-cluster"),
+						Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/cluster/test-cluster"),
 						Value: aws.String("owned"),
 					},
 					{
-						Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/role"),
+						Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/role"),
 						Value: aws.String("bastion"),
 					},
 				},
@@ -804,11 +804,11 @@ func mockedCreateSGCalls(m *mocks.MockEC2APIMockRecorder) {
 						Value: aws.String("test-cluster-apiserver-lb"),
 					},
 					{
-						Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/cluster/test-cluster"),
+						Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/cluster/test-cluster"),
 						Value: aws.String("owned"),
 					},
 					{
-						Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/role"),
+						Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/role"),
 						Value: aws.String("apiserver-lb"),
 					},
 				},
@@ -833,11 +833,11 @@ func mockedCreateSGCalls(m *mocks.MockEC2APIMockRecorder) {
 						Value: aws.String("owned"),
 					},
 					{
-						Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/cluster/test-cluster"),
+						Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/cluster/test-cluster"),
 						Value: aws.String("owned"),
 					},
 					{
-						Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/role"),
+						Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/role"),
 						Value: aws.String("lb"),
 					},
 				},
@@ -858,11 +858,11 @@ func mockedCreateSGCalls(m *mocks.MockEC2APIMockRecorder) {
 						Value: aws.String("test-cluster-controlplane"),
 					},
 					{
-						Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/cluster/test-cluster"),
+						Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/cluster/test-cluster"),
 						Value: aws.String("owned"),
 					},
 					{
-						Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/role"),
+						Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/role"),
 						Value: aws.String("controlplane"),
 					},
 				},
@@ -883,11 +883,11 @@ func mockedCreateSGCalls(m *mocks.MockEC2APIMockRecorder) {
 						Value: aws.String("test-cluster-node"),
 					},
 					{
-						Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/cluster/test-cluster"),
+						Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/cluster/test-cluster"),
 						Value: aws.String("owned"),
 					},
 					{
-						Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/role"),
+						Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/role"),
 						Value: aws.String("node"),
 					},
 				},
diff --git a/controllers/awsmachine_controller_test.go b/controllers/awsmachine_controller_test.go
index a70cb2cd5..a5c36a81e 100644
--- a/controllers/awsmachine_controller_test.go
+++ b/controllers/awsmachine_controller_test.go
@@ -496,7 +496,7 @@ func mockedCreateInstanceCalls(m *mocks.MockEC2APIMockRecorder) {
 				Values: aws.StringSlice([]string{""}),
 			},
 			{
-				Name:   aws.String("tag:sigs.k8s.io/cluster-api-provider-aws/cluster/test-cluster"),
+				Name:   aws.String("tag:sigs.k8s.io/cluster-api-provider-aws/v2/cluster/test-cluster"),
 				Values: aws.StringSlice([]string{"owned"}),
 			},
 			{
diff --git a/controllers/helpers_test.go b/controllers/helpers_test.go
index c58634165..202fdcedc 100644
--- a/controllers/helpers_test.go
+++ b/controllers/helpers_test.go
@@ -66,11 +66,11 @@ var (
 			Value: lbName,
 		},
 		{
-			Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/cluster/test-cluster"),
+			Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/cluster/test-cluster"),
 			Value: aws.String("owned"),
 		},
 		{
-			Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/role"),
+			Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/role"),
 			Value: aws.String("apiserver"),
 		},
 	}
@@ -179,7 +179,7 @@ func mockedCreateLBCalls(t *testing.T, m *mocks.MockELBAPIMockRecorder) {
 		LoadBalancerNames: aws.StringSlice([]string{""}),
 		Tags: []*elb.TagKeyOnly{
 			{
-				Key: aws.String("sigs.k8s.io/cluster-api-provider-aws/cluster/test-cluster-apiserver"),
+				Key: aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/cluster/test-cluster-apiserver"),
 			},
 		},
 	})).MaxTimes(1)
diff --git a/exp/controllers/awsmachinepool_controller_test.go b/exp/controllers/awsmachinepool_controller_test.go
index bc6410d93..27d00e6ce 100644
--- a/exp/controllers/awsmachinepool_controller_test.go
+++ b/exp/controllers/awsmachinepool_controller_test.go
@@ -266,7 +266,7 @@ func TestAWSMachinePoolReconciler(t *testing.T) {
 					},
 				}
 			}
-			t.Run("it should not call suspend as we don't have an ASG yet", func(t *testing.T) {
+			t.Run("it should suspend these processes", func(t *testing.T) {
 				g := NewWithT(t)
 				setup(t, g)
 				defer teardown(t, g)
@@ -277,7 +277,7 @@ func TestAWSMachinePoolReconciler(t *testing.T) {
 				asgSvc.EXPECT().CreateASG(gomock.Any()).Return(&expinfrav1.AutoScalingGroup{
 					Name: "name",
 				}, nil)
-				asgSvc.EXPECT().SuspendProcesses("name", []string{"Launch", "Terminate"}).Return(nil).AnyTimes().Times(0)
+				asgSvc.EXPECT().SuspendProcesses("name", []string{"Launch", "Terminate"}).Return(nil).AnyTimes()
 
 				_, err := reconciler.reconcileNormal(context.Background(), ms, cs, cs)
 				g.Expect(err).To(Succeed())
@@ -290,29 +290,56 @@ func TestAWSMachinePoolReconciler(t *testing.T) {
 					All: true,
 				}
 			}
-			t.Run("processes should be suspended during an update call", func(t *testing.T) {
+			t.Run("it should result in all processes being included except the value all", func(t *testing.T) {
 				g := NewWithT(t)
 				setup(t, g)
 				defer teardown(t, g)
 				setSuspendedProcesses(t, g)
-				ms.AWSMachinePool.Spec.SuspendProcesses.All = true
+
 				ec2Svc.EXPECT().ReconcileLaunchTemplate(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil)
-				ec2Svc.EXPECT().ReconcileTags(gomock.Any(), gomock.Any()).Return(nil)
-				asgSvc.EXPECT().GetASGByName(gomock.Any()).Return(&expinfrav1.AutoScalingGroup{
+				asgSvc.EXPECT().GetASGByName(gomock.Any()).Return(nil, nil)
+				asgSvc.EXPECT().CreateASG(gomock.Any()).Return(&expinfrav1.AutoScalingGroup{
 					Name: "name",
 				}, nil)
-				asgSvc.EXPECT().UpdateASG(gomock.Any()).Return(nil).AnyTimes()
-				asgSvc.EXPECT().SuspendProcesses("name", gomock.InAnyOrder([]string{
-					"ScheduledActions",
+				asgSvc.EXPECT().SuspendProcesses("name", []string{
 					"Launch",
 					"Terminate",
 					"AddToLoadBalancer",
 					"AlarmNotification",
 					"AZRebalance",
+					"HealthCheck",
 					"InstanceRefresh",
+					"ReplaceUnhealthy",
+					"ScheduledActions",
+				}).Return(nil).AnyTimes()
+
+				_, err := reconciler.reconcileNormal(context.Background(), ms, cs, cs)
+				g.Expect(err).To(Succeed())
+			})
+			t.Run("and one or more processes are disabled, it should not list those", func(t *testing.T) {
+				g := NewWithT(t)
+				setup(t, g)
+				defer teardown(t, g)
+				setSuspendedProcesses(t, g)
+				ms.AWSMachinePool.Spec.SuspendProcesses.Processes = &expinfrav1.Processes{
+					Launch:      pointer.Bool(false),
+					AZRebalance: pointer.Bool(true), // this should still be included but not twice...
+				}
+				ec2Svc.EXPECT().ReconcileLaunchTemplate(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil)
+				asgSvc.EXPECT().GetASGByName(gomock.Any()).Return(nil, nil)
+				asgSvc.EXPECT().CreateASG(gomock.Any()).Return(&expinfrav1.AutoScalingGroup{
+					Name: "name",
+				}, nil)
+				asgSvc.EXPECT().SuspendProcesses("name", []string{
+					"Terminate",
+					"AddToLoadBalancer",
+					"AlarmNotification",
+					"AZRebalance",
 					"HealthCheck",
+					"InstanceRefresh",
 					"ReplaceUnhealthy",
-				})).Return(nil).AnyTimes().Times(1)
+					"ScheduledActions",
+				}).Return(nil).AnyTimes()
 
 				_, err := reconciler.reconcileNormal(context.Background(), ms, cs, cs)
 				g.Expect(err).To(Succeed())
@@ -342,8 +369,8 @@ func TestAWSMachinePoolReconciler(t *testing.T) {
 					CurrentlySuspendProcesses: []string{"Launch", "process3"},
 				}, nil)
 				asgSvc.EXPECT().UpdateASG(gomock.Any()).Return(nil).AnyTimes()
-				asgSvc.EXPECT().SuspendProcesses("name", []string{"Terminate"}).Return(nil).AnyTimes().Times(1)
-				asgSvc.EXPECT().ResumeProcesses("name", []string{"process3"}).Return(nil).AnyTimes().Times(1)
+				asgSvc.EXPECT().SuspendProcesses("name", []string{"Terminate"}).Return(nil).AnyTimes()
+				asgSvc.EXPECT().ResumeProcesses("name", []string{"process3"}).Return(nil).AnyTimes()
 
 				_, err := reconciler.reconcileNormal(context.Background(), ms, cs, cs)
 				g.Expect(err).To(Succeed())
diff --git a/pkg/cloud/services/autoscaling/autoscalinggroup_test.go b/pkg/cloud/services/autoscaling/autoscalinggroup_test.go
index 8b7dc95fa..30bc0ef80 100644
--- a/pkg/cloud/services/autoscaling/autoscalinggroup_test.go
+++ b/pkg/cloud/services/autoscaling/autoscalinggroup_test.go
@@ -460,14 +460,14 @@ func TestServiceCreateASG(t *testing.T) {
 							Value:             aws.String("owned"),
 						},
 						{
-							Key:               aws.String("sigs.k8s.io/cluster-api-provider-aws/cluster/test"),
+							Key:               aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/cluster/test"),
 							PropagateAtLaunch: aws.Bool(false),
 							ResourceId:        aws.String("create-asg-success"),
 							ResourceType:      aws.String("auto-scaling-group"),
 							Value:             aws.String("owned"),
 						},
 						{
-							Key:               aws.String("sigs.k8s.io/cluster-api-provider-aws/role"),
+							Key:               aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/role"),
 							PropagateAtLaunch: aws.Bool(false),
 							ResourceId:        aws.String("create-asg-success"),
 							ResourceType:      aws.String("auto-scaling-group"),
diff --git a/pkg/cloud/services/ec2/instances_test.go b/pkg/cloud/services/ec2/instances_test.go
index b3217aa81..9ebbd2d1a 100644
--- a/pkg/cloud/services/ec2/instances_test.go
+++ b/pkg/cloud/services/ec2/instances_test.go
@@ -2095,11 +2095,11 @@ func TestCreateInstance(t *testing.T) {
 										Value: aws.String("owned"),
 									},
 									{
-										Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/cluster/test1"),
+										Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/cluster/test1"),
 										Value: aws.String("owned"),
 									},
 									{
-										Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/role"),
+										Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/role"),
 										Value: aws.String("node"),
 									},
 								},
@@ -2232,11 +2232,11 @@ func TestCreateInstance(t *testing.T) {
 										Value: aws.String("owned"),
 									},
 									{
-										Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/cluster/test1"),
+										Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/cluster/test1"),
 										Value: aws.String("owned"),
 									},
 									{
-										Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/role"),
+										Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/role"),
 										Value: aws.String("node"),
 									},
 								},
diff --git a/pkg/cloud/services/network/egress_only_gateways_test.go b/pkg/cloud/services/network/egress_only_gateways_test.go
index 254039599..79abcb9d4 100644
--- a/pkg/cloud/services/network/egress_only_gateways_test.go
+++ b/pkg/cloud/services/network/egress_only_gateways_test.go
@@ -98,7 +98,7 @@ func TestReconcileEgressOnlyInternetGateways(t *testing.T) {
 									Value: aws.String("owned"),
 								},
 								{
-									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/role"),
+									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/role"),
 									Value: aws.String("common"),
 								},
 								{
diff --git a/pkg/cloud/services/network/gateways_test.go b/pkg/cloud/services/network/gateways_test.go
index b5ae3f895..07e83e027 100644
--- a/pkg/cloud/services/network/gateways_test.go
+++ b/pkg/cloud/services/network/gateways_test.go
@@ -96,7 +96,7 @@ func TestReconcileInternetGateways(t *testing.T) {
 									Value: aws.String("owned"),
 								},
 								{
-									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/role"),
+									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/role"),
 									Value: aws.String("common"),
 								},
 								{
diff --git a/pkg/cloud/services/network/natgateways_test.go b/pkg/cloud/services/network/natgateways_test.go
index cc223f185..9379b24fe 100644
--- a/pkg/cloud/services/network/natgateways_test.go
+++ b/pkg/cloud/services/network/natgateways_test.go
@@ -123,11 +123,11 @@ func TestReconcileNatGateways(t *testing.T) {
 									Value: aws.String("test-cluster-eip-apiserver"),
 								},
 								{
-									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/cluster/test-cluster"),
+									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/cluster/test-cluster"),
 									Value: aws.String("owned"),
 								},
 								{
-									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/role"),
+									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/role"),
 									Value: aws.String("apiserver"),
 								},
 							},
@@ -149,11 +149,11 @@ func TestReconcileNatGateways(t *testing.T) {
 									Value: aws.String("test-cluster-nat"),
 								},
 								{
-									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/cluster/test-cluster"),
+									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/cluster/test-cluster"),
 									Value: aws.String("owned"),
 								},
 								{
-									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/role"),
+									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/role"),
 									Value: aws.String("common"),
 								},
 							},
@@ -230,11 +230,11 @@ func TestReconcileNatGateways(t *testing.T) {
 									Value: aws.String("test-cluster-eip-apiserver"),
 								},
 								{
-									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/cluster/test-cluster"),
+									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/cluster/test-cluster"),
 									Value: aws.String("owned"),
 								},
 								{
-									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/role"),
+									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/role"),
 									Value: aws.String("apiserver"),
 								},
 							},
@@ -256,11 +256,11 @@ func TestReconcileNatGateways(t *testing.T) {
 									Value: aws.String("test-cluster-nat"),
 								},
 								{
-									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/cluster/test-cluster"),
+									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/cluster/test-cluster"),
 									Value: aws.String("owned"),
 								},
 								{
-									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/role"),
+									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/role"),
 									Value: aws.String("common"),
 								},
 							},
@@ -318,7 +318,7 @@ func TestReconcileNatGateways(t *testing.T) {
 						SubnetId:     aws.String("subnet-1"),
 						Tags: []*ec2.Tag{
 							{
-								Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/role"),
+								Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/role"),
 								Value: aws.String("common"),
 							},
 							{
@@ -326,7 +326,7 @@ func TestReconcileNatGateways(t *testing.T) {
 								Value: aws.String("test-cluster-nat"),
 							},
 							{
-								Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/cluster/test-cluster"),
+								Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/cluster/test-cluster"),
 								Value: aws.String("owned"),
 							},
 						},
diff --git a/pkg/cloud/services/network/routetables_test.go b/pkg/cloud/services/network/routetables_test.go
index 01ed5b3b3..95e4ab52b 100644
--- a/pkg/cloud/services/network/routetables_test.go
+++ b/pkg/cloud/services/network/routetables_test.go
@@ -360,7 +360,7 @@ func TestReconcileRouteTables(t *testing.T) {
 										Value: aws.String("owned"),
 									},
 									{
-										Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/role"),
+										Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/role"),
 										Value: aws.String("common"),
 									},
 									{
@@ -368,7 +368,7 @@ func TestReconcileRouteTables(t *testing.T) {
 										Value: aws.String("test-cluster-rt-private-us-east-1a"),
 									},
 									{
-										Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/cluster/test-cluster"),
+										Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/cluster/test-cluster"),
 										Value: aws.String("owned"),
 									},
 								},
@@ -392,7 +392,7 @@ func TestReconcileRouteTables(t *testing.T) {
 										Value: aws.String("owned"),
 									},
 									{
-										Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/role"),
+										Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/role"),
 										Value: aws.String("common"),
 									},
 									{
@@ -400,7 +400,7 @@ func TestReconcileRouteTables(t *testing.T) {
 										Value: aws.String("test-cluster-rt-public-us-east-1a"),
 									},
 									{
-										Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/cluster/test-cluster"),
+										Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/cluster/test-cluster"),
 										Value: aws.String("owned"),
 									},
 								},
@@ -469,7 +469,7 @@ func TestReconcileRouteTables(t *testing.T) {
 										Value: aws.String("owned"),
 									},
 									{
-										Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/role"),
+										Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/role"),
 										Value: aws.String("common"),
 									},
 									{
@@ -477,7 +477,7 @@ func TestReconcileRouteTables(t *testing.T) {
 										Value: aws.String("test-cluster-rt-private-us-east-1a"),
 									},
 									{
-										Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/cluster/test-cluster"),
+										Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/cluster/test-cluster"),
 										Value: aws.String("owned"),
 									},
 								},
@@ -501,7 +501,7 @@ func TestReconcileRouteTables(t *testing.T) {
 										Value: aws.String("owned"),
 									},
 									{
-										Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/role"),
+										Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/role"),
 										Value: aws.String("common"),
 									},
 									{
@@ -509,7 +509,7 @@ func TestReconcileRouteTables(t *testing.T) {
 										Value: aws.String("test-cluster-rt-public-us-east-1a"),
 									},
 									{
-										Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/cluster/test-cluster"),
+										Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/cluster/test-cluster"),
 										Value: aws.String("owned"),
 									},
 								},
@@ -599,7 +599,7 @@ func TestDeleteRouteTables(t *testing.T) {
 						Value: aws.String("owned"),
 					},
 					{
-						Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/role"),
+						Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/role"),
 						Value: aws.String("common"),
 					},
 					{
@@ -607,7 +607,7 @@ func TestDeleteRouteTables(t *testing.T) {
 						Value: aws.String("test-cluster-rt-public-us-east-1a"),
 					},
 					{
-						Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/cluster/test-cluster"),
+						Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/cluster/test-cluster"),
 						Value: aws.String("owned"),
 					},
 				},
diff --git a/pkg/cloud/services/network/subnets_test.go b/pkg/cloud/services/network/subnets_test.go
index d6b0c0d99..0d1a36b3e 100644
--- a/pkg/cloud/services/network/subnets_test.go
+++ b/pkg/cloud/services/network/subnets_test.go
@@ -784,11 +784,11 @@ func TestReconcileSubnets(t *testing.T) {
 									Value: aws.String("1"),
 								},
 								{
-									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/cluster/test-cluster"),
+									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/cluster/test-cluster"),
 									Value: aws.String("owned"),
 								},
 								{
-									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/role"),
+									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/role"),
 									Value: aws.String("private"),
 								},
 							},
@@ -830,11 +830,11 @@ func TestReconcileSubnets(t *testing.T) {
 									Value: aws.String("1"),
 								},
 								{
-									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/cluster/test-cluster"),
+									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/cluster/test-cluster"),
 									Value: aws.String("owned"),
 								},
 								{
-									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/role"),
+									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/role"),
 									Value: aws.String("public"),
 								},
 							},
@@ -992,11 +992,11 @@ func TestReconcileSubnets(t *testing.T) {
 									Value: aws.String("1"),
 								},
 								{
-									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/cluster/test-cluster"),
+									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/cluster/test-cluster"),
 									Value: aws.String("owned"),
 								},
 								{
-									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/role"),
+									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/role"),
 									Value: aws.String("public"),
 								},
 							},
@@ -1047,11 +1047,11 @@ func TestReconcileSubnets(t *testing.T) {
 									Value: aws.String("1"),
 								},
 								{
-									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/cluster/test-cluster"),
+									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/cluster/test-cluster"),
 									Value: aws.String("owned"),
 								},
 								{
-									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/role"),
+									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/role"),
 									Value: aws.String("private"),
 								},
 							},
@@ -1153,11 +1153,11 @@ func TestReconcileSubnets(t *testing.T) {
 									Value: aws.String("1"),
 								},
 								{
-									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/cluster/test-cluster"),
+									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/cluster/test-cluster"),
 									Value: aws.String("owned"),
 								},
 								{
-									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/role"),
+									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/role"),
 									Value: aws.String("public"),
 								},
 							},
@@ -1237,11 +1237,11 @@ func TestReconcileSubnets(t *testing.T) {
 									Value: aws.String("1"),
 								},
 								{
-									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/cluster/test-cluster"),
+									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/cluster/test-cluster"),
 									Value: aws.String("owned"),
 								},
 								{
-									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/role"),
+									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/role"),
 									Value: aws.String("private"),
 								},
 							},
@@ -1351,11 +1351,11 @@ func TestReconcileSubnets(t *testing.T) {
 									Value: aws.String("1"),
 								},
 								{
-									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/cluster/test-cluster"),
+									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/cluster/test-cluster"),
 									Value: aws.String("owned"),
 								},
 								{
-									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/role"),
+									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/role"),
 									Value: aws.String("public"),
 								},
 							},
@@ -1406,11 +1406,11 @@ func TestReconcileSubnets(t *testing.T) {
 									Value: aws.String("1"),
 								},
 								{
-									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/cluster/test-cluster"),
+									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/cluster/test-cluster"),
 									Value: aws.String("owned"),
 								},
 								{
-									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/role"),
+									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/role"),
 									Value: aws.String("private"),
 								},
 							},
@@ -1454,11 +1454,11 @@ func TestReconcileSubnets(t *testing.T) {
 									Value: aws.String("1"),
 								},
 								{
-									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/cluster/test-cluster"),
+									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/cluster/test-cluster"),
 									Value: aws.String("owned"),
 								},
 								{
-									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/role"),
+									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/role"),
 									Value: aws.String("public"),
 								},
 							},
@@ -1509,11 +1509,11 @@ func TestReconcileSubnets(t *testing.T) {
 									Value: aws.String("1"),
 								},
 								{
-									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/cluster/test-cluster"),
+									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/cluster/test-cluster"),
 									Value: aws.String("owned"),
 								},
 								{
-									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/role"),
+									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/role"),
 									Value: aws.String("private"),
 								},
 							},
@@ -1615,11 +1615,11 @@ func TestReconcileSubnets(t *testing.T) {
 									Value: aws.String("1"),
 								},
 								{
-									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/cluster/test-cluster"),
+									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/cluster/test-cluster"),
 									Value: aws.String("owned"),
 								},
 								{
-									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/role"),
+									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/role"),
 									Value: aws.String("public"),
 								},
 							},
@@ -1670,11 +1670,11 @@ func TestReconcileSubnets(t *testing.T) {
 									Value: aws.String("1"),
 								},
 								{
-									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/cluster/test-cluster"),
+									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/cluster/test-cluster"),
 									Value: aws.String("owned"),
 								},
 								{
-									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/role"),
+									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/role"),
 									Value: aws.String("private"),
 								},
 							},
@@ -1741,11 +1741,11 @@ func TestReconcileSubnets(t *testing.T) {
 								CidrBlock:        aws.String("10.0.0.0/17"),
 								Tags: []*ec2.Tag{
 									{
-										Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/cluster/test-cluster"),
+										Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/cluster/test-cluster"),
 										Value: aws.String("owned"),
 									},
 									{
-										Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/role"),
+										Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/role"),
 										Value: aws.String("public"),
 									},
 									{
@@ -1800,11 +1800,11 @@ func TestReconcileSubnets(t *testing.T) {
 									Value: aws.String("1"),
 								},
 								{
-									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/cluster/test-cluster"),
+									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/cluster/test-cluster"),
 									Value: aws.String("owned"),
 								},
 								{
-									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/role"),
+									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/role"),
 									Value: aws.String("private"),
 								},
 							},
@@ -1907,11 +1907,11 @@ func TestReconcileSubnets(t *testing.T) {
 									Value: aws.String("1"),
 								},
 								{
-									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/cluster/test-cluster"),
+									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/cluster/test-cluster"),
 									Value: aws.String("owned"),
 								},
 								{
-									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/role"),
+									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/role"),
 									Value: aws.String("public"),
 								},
 							},
@@ -1962,11 +1962,11 @@ func TestReconcileSubnets(t *testing.T) {
 									Value: aws.String("1"),
 								},
 								{
-									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/cluster/test-cluster"),
+									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/cluster/test-cluster"),
 									Value: aws.String("owned"),
 								},
 								{
-									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/role"),
+									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/role"),
 									Value: aws.String("private"),
 								},
 							},
@@ -2010,11 +2010,11 @@ func TestReconcileSubnets(t *testing.T) {
 									Value: aws.String("1"),
 								},
 								{
-									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/cluster/test-cluster"),
+									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/cluster/test-cluster"),
 									Value: aws.String("owned"),
 								},
 								{
-									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/role"),
+									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/role"),
 									Value: aws.String("public"),
 								},
 							},
@@ -2065,11 +2065,11 @@ func TestReconcileSubnets(t *testing.T) {
 									Value: aws.String("1"),
 								},
 								{
-									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/cluster/test-cluster"),
+									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/cluster/test-cluster"),
 									Value: aws.String("owned"),
 								},
 								{
-									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/role"),
+									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/role"),
 									Value: aws.String("private"),
 								},
 							},
diff --git a/pkg/cloud/services/network/vpc_test.go b/pkg/cloud/services/network/vpc_test.go
index a9b1a5735..f753363cc 100644
--- a/pkg/cloud/services/network/vpc_test.go
+++ b/pkg/cloud/services/network/vpc_test.go
@@ -71,7 +71,7 @@ func TestReconcileVPC(t *testing.T) {
 	selection := infrav1.AZSelectionSchemeOrdered
 	tags := []*ec2.Tag{
 		{
-			Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/role"),
+			Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/role"),
 			Value: aws.String("common"),
 		},
 		{
@@ -79,7 +79,7 @@ func TestReconcileVPC(t *testing.T) {
 			Value: aws.String("test-cluster-vpc"),
 		},
 		{
-			Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/cluster/test-cluster"),
+			Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/cluster/test-cluster"),
 			Value: aws.String("owned"),
 		},
 	}
@@ -98,9 +98,9 @@ func TestReconcileVPC(t *testing.T) {
 				ID:        "vpc-exists",
 				CidrBlock: "10.0.0.0/8",
 				Tags: map[string]string{
-					"sigs.k8s.io/cluster-api-provider-aws/role": "common",
+					"sigs.k8s.io/cluster-api-provider-aws/v2/role": "common",
 					"Name": "test-cluster-vpc",
-					"sigs.k8s.io/cluster-api-provider-aws/cluster/test-cluster": "owned",
+					"sigs.k8s.io/cluster-api-provider-aws/v2/cluster/test-cluster": "owned",
 				},
 				AvailabilityZoneUsageLimit: &usageLimit,
 				AvailabilityZoneSelection:  &selection,
@@ -140,9 +140,9 @@ func TestReconcileVPC(t *testing.T) {
 				ID:        "vpc-new",
 				CidrBlock: "10.1.0.0/16",
 				Tags: map[string]string{
-					"sigs.k8s.io/cluster-api-provider-aws/role": "common",
+					"sigs.k8s.io/cluster-api-provider-aws/v2/role": "common",
 					"Name": "test-cluster-vpc",
-					"sigs.k8s.io/cluster-api-provider-aws/cluster/test-cluster": "owned",
+					"sigs.k8s.io/cluster-api-provider-aws/v2/cluster/test-cluster": "owned",
 				},
 				AvailabilityZoneUsageLimit: &usageLimit,
 				AvailabilityZoneSelection:  &selection,
@@ -179,9 +179,9 @@ func TestReconcileVPC(t *testing.T) {
 					PoolID:    "amazon",
 				},
 				Tags: map[string]string{
-					"sigs.k8s.io/cluster-api-provider-aws/role": "common",
+					"sigs.k8s.io/cluster-api-provider-aws/v2/role": "common",
 					"Name": "test-cluster-vpc",
-					"sigs.k8s.io/cluster-api-provider-aws/cluster/test-cluster": "owned",
+					"sigs.k8s.io/cluster-api-provider-aws/v2/cluster/test-cluster": "owned",
 				},
 				AvailabilityZoneUsageLimit: &usageLimit,
 				AvailabilityZoneSelection:  &selection,
@@ -245,9 +245,9 @@ func TestReconcileVPC(t *testing.T) {
 					PoolID:    "my-pool",
 				},
 				Tags: map[string]string{
-					"sigs.k8s.io/cluster-api-provider-aws/role": "common",
+					"sigs.k8s.io/cluster-api-provider-aws/v2/role": "common",
 					"Name": "test-cluster-vpc",
-					"sigs.k8s.io/cluster-api-provider-aws/cluster/test-cluster": "owned",
+					"sigs.k8s.io/cluster-api-provider-aws/v2/cluster/test-cluster": "owned",
 				},
 				AvailabilityZoneUsageLimit: &usageLimit,
 				AvailabilityZoneSelection:  &selection,
@@ -357,7 +357,7 @@ func TestReconcileVPC(t *testing.T) {
 				ID:        "unmanaged-vpc-exists",
 				CidrBlock: "10.0.0.0/8",
 				Tags: map[string]string{
-					"sigs.k8s.io/cluster-api-provider-aws/role": "common",
+					"sigs.k8s.io/cluster-api-provider-aws/v2/role": "common",
 					"Name": "test-cluster-vpc",
 				},
 				IPv6: &infrav1.IPv6{
@@ -386,7 +386,7 @@ func TestReconcileVPC(t *testing.T) {
 							},
 							Tags: []*ec2.Tag{
 								{
-									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/role"),
+									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/role"),
 									Value: aws.String("common"),
 								},
 								{
@@ -424,7 +424,7 @@ func TestReconcileVPC(t *testing.T) {
 				ID:        "unmanaged-vpc-exists",
 				CidrBlock: "10.0.0.0/8",
 				Tags: map[string]string{
-					"sigs.k8s.io/cluster-api-provider-aws/role": "common",
+					"sigs.k8s.io/cluster-api-provider-aws/v2/role": "common",
 					"Name": "test-cluster-vpc",
 				},
 				AvailabilityZoneUsageLimit: &usageLimit,
@@ -439,7 +439,7 @@ func TestReconcileVPC(t *testing.T) {
 							CidrBlock: aws.String("10.0.0.0/8"),
 							Tags: []*ec2.Tag{
 								{
-									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/role"),
+									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/role"),
 									Value: aws.String("common"),
 								},
 								{
@@ -459,9 +459,9 @@ func TestReconcileVPC(t *testing.T) {
 				ID:        "managed-vpc-exists",
 				CidrBlock: "10.0.0.0/8",
 				Tags: map[string]string{
-					"sigs.k8s.io/cluster-api-provider-aws/role": "common",
+					"sigs.k8s.io/cluster-api-provider-aws/v2/role": "common",
 					"Name": "test-cluster-vpc",
-					"sigs.k8s.io/cluster-api-provider-aws/cluster/test-cluster": "owned",
+					"sigs.k8s.io/cluster-api-provider-aws/v2/cluster/test-cluster": "owned",
 				},
 				AvailabilityZoneUsageLimit: &usageLimit,
 				AvailabilityZoneSelection:  &selection,
@@ -588,7 +588,7 @@ func TestDeleteVPC(t *testing.T) {
 	defer mockCtrl.Finish()
 
 	tags := map[string]string{
-		"sigs.k8s.io/cluster-api-provider-aws/cluster/test-cluster": "owned",
+		"sigs.k8s.io/cluster-api-provider-aws/v2/cluster/test-cluster": "owned",
 	}
 
 	testCases := []struct {
diff --git a/pkg/cloud/services/secretsmanager/secret_test.go b/pkg/cloud/services/secretsmanager/secret_test.go
index 14e346b63..b5defa57a 100644
--- a/pkg/cloud/services/secretsmanager/secret_test.go
+++ b/pkg/cloud/services/secretsmanager/secret_test.go
@@ -64,11 +64,11 @@ func TestServiceCreate(t *testing.T) {
 			Value: aws.String("owned"),
 		},
 		{
-			Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/cluster/test"),
+			Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/cluster/test"),
 			Value: aws.String("owned"),
 		},
 		{
-			Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/role"),
+			Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/role"),
 			Value: aws.String("node"),
 		},
 	}
diff --git a/pkg/cloud/services/securitygroup/securitygroups_test.go b/pkg/cloud/services/securitygroup/securitygroups_test.go
index 9e89afdd2..fbd00c570 100644
--- a/pkg/cloud/services/securitygroup/securitygroups_test.go
+++ b/pkg/cloud/services/securitygroup/securitygroups_test.go
@@ -100,11 +100,11 @@ func TestReconcileSecurityGroups(t *testing.T) {
 									Value: aws.String("test-cluster-bastion"),
 								},
 								{
-									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/cluster/test-cluster"),
+									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/cluster/test-cluster"),
 									Value: aws.String("owned"),
 								},
 								{
-									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/role"),
+									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/role"),
 									Value: aws.String("bastion"),
 								},
 							},
@@ -132,11 +132,11 @@ func TestReconcileSecurityGroups(t *testing.T) {
 									Value: aws.String("test-cluster-apiserver-lb"),
 								},
 								{
-									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/cluster/test-cluster"),
+									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/cluster/test-cluster"),
 									Value: aws.String("owned"),
 								},
 								{
-									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/role"),
+									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/role"),
 									Value: aws.String("apiserver-lb"),
 								},
 							},
@@ -168,11 +168,11 @@ func TestReconcileSecurityGroups(t *testing.T) {
 									Value: aws.String("owned"),
 								},
 								{
-									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/cluster/test-cluster"),
+									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/cluster/test-cluster"),
 									Value: aws.String("owned"),
 								},
 								{
-									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/role"),
+									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/role"),
 									Value: aws.String("lb"),
 								},
 							},
@@ -194,11 +194,11 @@ func TestReconcileSecurityGroups(t *testing.T) {
 									Value: aws.String("test-cluster-controlplane"),
 								},
 								{
-									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/cluster/test-cluster"),
+									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/cluster/test-cluster"),
 									Value: aws.String("owned"),
 								},
 								{
-									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/role"),
+									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/role"),
 									Value: aws.String("controlplane"),
 								},
 							},
@@ -226,11 +226,11 @@ func TestReconcileSecurityGroups(t *testing.T) {
 									Value: aws.String("test-cluster-node"),
 								},
 								{
-									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/cluster/test-cluster"),
+									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/cluster/test-cluster"),
 									Value: aws.String("owned"),
 								},
 								{
-									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/role"),
+									Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/role"),
 									Value: aws.String("node"),
 								},
 							},
diff --git a/pkg/cloud/services/ssm/secret_test.go b/pkg/cloud/services/ssm/secret_test.go
index 16d81d176..ab1c94661 100644
--- a/pkg/cloud/services/ssm/secret_test.go
+++ b/pkg/cloud/services/ssm/secret_test.go
@@ -77,11 +77,11 @@ func TestServiceCreate(t *testing.T) {
 			Value: aws.String("owned"),
 		},
 		{
-			Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/cluster/test"),
+			Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/cluster/test"),
 			Value: aws.String("owned"),
 		},
 		{
-			Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/role"),
+			Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/role"),
 			Value: aws.String("node"),
 		},
 	}
diff --git a/pkg/cloud/tags/tags_test.go b/pkg/cloud/tags/tags_test.go
index 8d0e70c24..024995988 100644
--- a/pkg/cloud/tags/tags_test.go
+++ b/pkg/cloud/tags/tags_test.go
@@ -50,11 +50,11 @@ var (
 			Value: aws.String("v1"),
 		},
 		{
-			Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/cluster/testcluster"),
+			Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/cluster/testcluster"),
 			Value: aws.String("owned"),
 		},
 		{
-			Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/role"),
+			Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/v2/role"),
 			Value: aws.String("testrole"),
 		},
 	}
@@ -202,7 +202,7 @@ func TestTagsEnsureWithEKS(t *testing.T) {
 			expect: func(m *mock_eksiface.MockEKSAPIMockRecorder) {
 				m.TagResource(gomock.Eq(&eks.TagResourceInput{
 					ResourceArn: aws.String(""),
-					Tags:        map[string]*string{"Name": aws.String("test"), "k1": aws.String("v1"), "sigs.k8s.io/cluster-api-provider-aws/cluster/testcluster": aws.String("owned"), "sigs.k8s.io/cluster-api-provider-aws/role": aws.String("testrole")},
+					Tags:        map[string]*string{"Name": aws.String("test"), "k1": aws.String("v1"), "sigs.k8s.io/cluster-api-provider-aws/v2/cluster/testcluster": aws.String("owned"), "sigs.k8s.io/cluster-api-provider-aws/v2/role": aws.String("testrole")},
 				})).Return(nil, errors.New("failed to tag resource"))
 			},
 		},
@@ -212,7 +212,7 @@ func TestTagsEnsureWithEKS(t *testing.T) {
 			expect: func(m *mock_eksiface.MockEKSAPIMockRecorder) {
 				m.TagResource(gomock.Eq(&eks.TagResourceInput{
 					ResourceArn: aws.String(""),
-					Tags:        map[string]*string{"Name": aws.String("test"), "k1": aws.String("v1"), "sigs.k8s.io/cluster-api-provider-aws/cluster/testcluster": aws.String("owned"), "sigs.k8s.io/cluster-api-provider-aws/role": aws.String("testrole")},
+					Tags:        map[string]*string{"Name": aws.String("test"), "k1": aws.String("v1"), "sigs.k8s.io/cluster-api-provider-aws/v2/cluster/testcluster": aws.String("owned"), "sigs.k8s.io/cluster-api-provider-aws/v2/role": aws.String("testrole")},
 				})).Return(nil, nil)
 			},
 		},
diff --git a/test/e2e/shared/aws.go b/test/e2e/shared/aws.go
index c311b117f..d02f592fc 100644
--- a/test/e2e/shared/aws.go
+++ b/test/e2e/shared/aws.go
@@ -165,19 +165,28 @@ func (i *AWSInfrastructure) AllocateAddress() AWSInfrastructure {
 		return *i
 	}
 
-	var addr *ec2.Address
-	Eventually(func(gomega Gomega) {
+	t := 0
+	addr, _ := GetAddress(i.Context, *aa.AllocationId)
+	for addr == nil && t < 180 {
+		time.Sleep(1 * time.Second)
 		addr, _ = GetAddress(i.Context, *aa.AllocationId)
-	}, 2*time.Minute, 5*time.Second).Should(Succeed())
+		t++
+	}
 	i.ElasticIP = addr
 	return *i
 }
 
 func (i *AWSInfrastructure) CreateNatGateway(ct string) AWSInfrastructure {
-	var s *ec2.Subnet
-	Eventually(func(gomega Gomega) {
+	t := 0
+	s, serr := GetSubnetByName(i.Context, i.Spec.ClusterName+"-subnet-"+ct)
+	if serr != nil {
+		return *i
+	}
+	for s == nil && t < 180 {
+		time.Sleep(1 * time.Second)
 		s, _ = GetSubnetByName(i.Context, i.Spec.ClusterName+"-subnet-"+ct)
-	}, 2*time.Minute, 5*time.Second).Should(Succeed())
+		t++
+	}
 	if s == nil {
 		return *i
 	}
@@ -185,7 +194,7 @@ func (i *AWSInfrastructure) CreateNatGateway(ct string) AWSInfrastructure {
 	if ngwce != nil {
 		return *i
 	}
-	if WaitForNatGatewayState(i.Context, *ngwC.NatGatewayId, "available") {
+	if WaitForNatGatewayState(i.Context, *ngwC.NatGatewayId, 180, "available") {
 		ngw, _ := GetNatGateway(i.Context, *ngwC.NatGatewayId)
 		i.NatGateway = ngw
 		i.State.NatGatewayState = ngw.State
@@ -229,10 +238,6 @@ func (i *AWSInfrastructure) GetRouteTable(rtID string) AWSInfrastructure {
 // routes to their respective gateway.
 func (i *AWSInfrastructure) CreateInfrastructure() AWSInfrastructure {
 	i.CreateVPC()
-	Eventually(func(gomega Gomega) bool {
-		return *i.RefreshVPCState().State.VpcState == "available"
-	}, 2*time.Minute, 5*time.Second).Should(BeTrue())
-
 	Byf("Created VPC - %s", *i.VPC.VpcId)
 	if i.VPC != nil {
 		i.CreatePublicSubnet()
@@ -243,6 +248,12 @@ func (i *AWSInfrastructure) CreateInfrastructure() AWSInfrastructure {
 		if i.State.PrivateSubnetID != nil {
 			Byf("Created Private Subnet - %s", *i.State.PrivateSubnetID)
 		}
+		for t := 0; t < 30; t++ {
+			if *i.RefreshVPCState().State.VpcState == "available" {
+				break
+			}
+			time.Sleep(1 * time.Second)
+		}
 		i.CreateInternetGateway()
 		if i.InternetGateway != nil {
 			Byf("Created Internet Gateway - %s", *i.InternetGateway.InternetGatewayId)
@@ -253,7 +264,7 @@ func (i *AWSInfrastructure) CreateInfrastructure() AWSInfrastructure {
 		Byf("Created Elastic IP - %s", *i.ElasticIP.AllocationId)
 		i.CreateNatGateway("public")
 		if i.NatGateway != nil && i.NatGateway.NatGatewayId != nil {
-			WaitForNatGatewayState(i.Context, *i.NatGateway.NatGatewayId, "available")
+			WaitForNatGatewayState(i.Context, *i.NatGateway.NatGatewayId, 180, "available")
 			Byf("Created NAT Gateway - %s", *i.NatGateway.NatGatewayId)
 		}
 	}
@@ -293,7 +304,7 @@ func (i *AWSInfrastructure) DeleteInfrastructure() {
 			Byf("Deleting orphaned instance: %s - %v", *instance.InstanceId, TerminateInstance(i.Context, *instance.InstanceId))
 		}
 	}
-	WaitForInstanceState(i.Context, i.Spec.ClusterName, "terminated")
+	WaitForInstanceState(i.Context, i.Spec.ClusterName, 300, "terminated")
 
 	loadbalancers, _ := ListLoadBalancers(i.Context, i.Spec.ClusterName)
 	for _, lb := range loadbalancers {
@@ -309,7 +320,7 @@ func (i *AWSInfrastructure) DeleteInfrastructure() {
 
 	if i.NatGateway != nil {
 		Byf("Deleting NAT Gateway - %s - %v", *i.NatGateway.NatGatewayId, DeleteNatGateway(i.Context, *i.NatGateway.NatGatewayId))
-		WaitForNatGatewayState(i.Context, *i.NatGateway.NatGatewayId, "deleted")
+		WaitForNatGatewayState(i.Context, *i.NatGateway.NatGatewayId, 180, "deleted")
 	}
 
 	if i.ElasticIP != nil {
@@ -787,16 +798,19 @@ type ServiceQuota struct {
 	RequestStatus       string
 }
 
-func EnsureServiceQuotas(sess client.ConfigProvider) map[string]*ServiceQuota {
+func EnsureServiceQuotas(sess client.ConfigProvider) (map[string]*ServiceQuota, map[string]*servicequotas.ServiceQuota) {
 	limitedResources := getLimitedResources()
 	serviceQuotasClient := servicequotas.New(sess)
 
+	originalQuotas := map[string]*servicequotas.ServiceQuota{}
+
 	for k, v := range limitedResources {
 		out, err := serviceQuotasClient.GetServiceQuota(&servicequotas.GetServiceQuotaInput{
 			QuotaCode:   aws.String(v.QuotaCode),
 			ServiceCode: aws.String(v.ServiceCode),
 		})
 		Expect(err).NotTo(HaveOccurred())
+		originalQuotas[k] = out.Quota
 		v.Value = int(aws.Float64Value(out.Quota.Value))
 		limitedResources[k] = v
 		if v.Value < v.DesiredMinimumValue {
@@ -804,7 +818,7 @@ func EnsureServiceQuotas(sess client.ConfigProvider) map[string]*ServiceQuota {
 		}
 	}
 
-	return limitedResources
+	return limitedResources, originalQuotas
 }
 
 func (s *ServiceQuota) attemptRaiseServiceQuotaRequest(serviceQuotasClient *servicequotas.ServiceQuotas) {
@@ -979,7 +993,7 @@ func ListClusterEC2Instances(e2eCtx *E2EContext, clusterName string) ([]*ec2.Ins
 	ec2Svc := ec2.New(e2eCtx.AWSSession)
 	filter := &ec2.Filter{
 		Name:   aws.String("tag-key"),
-		Values: aws.StringSlice([]string{"sigs.k8s.io/cluster-api-provider-aws/cluster/" + clusterName}),
+		Values: aws.StringSlice([]string{"sigs.k8s.io/cluster-api-provider-aws/v2/cluster/" + clusterName}),
 	}
 	input := &ec2.DescribeInstancesInput{
 		Filters: []*ec2.Filter{
@@ -998,8 +1012,9 @@ func ListClusterEC2Instances(e2eCtx *E2EContext, clusterName string) ([]*ec2.Ins
 	return instances, nil
 }
 
-func WaitForInstanceState(e2eCtx *E2EContext, clusterName string, state string) bool {
-	Eventually(func(gomega Gomega) bool {
+func WaitForInstanceState(e2eCtx *E2EContext, clusterName string, timeout int, state string) bool {
+	t := 0
+	for t < timeout {
 		st := map[string]int{
 			"pending":       0,
 			"running":       0,
@@ -1014,9 +1029,9 @@ func WaitForInstanceState(e2eCtx *E2EContext, clusterName string, state string)
 		if st[state] == len(instances) || len(instances) == 0 {
 			return true
 		}
-		return false
-	}, 5*time.Minute, 5*time.Second).Should(BeTrue())
-
+		time.Sleep(1 * time.Second)
+		t++
+	}
 	return false
 }
 
@@ -1404,12 +1419,17 @@ func DeleteNatGateway(e2eCtx *E2EContext, gatewayID string) bool {
 	return true
 }
 
-func WaitForNatGatewayState(e2eCtx *E2EContext, gatewayID string, state string) bool {
-	Eventually(func(gomega Gomega) bool {
+func WaitForNatGatewayState(e2eCtx *E2EContext, gatewayID string, timeout int, state string) bool {
+	t := 0
+	for t < timeout {
 		gw, _ := GetNatGateway(e2eCtx, gatewayID)
 		gwState := *gw.State
-		return gwState == state
-	}, 3*time.Minute, 5*time.Second).Should(BeTrue())
+		if gwState == state {
+			return true
+		}
+		time.Sleep(1 * time.Second)
+		t++
+	}
 	return false
 }
 
diff --git a/test/e2e/shared/resource.go b/test/e2e/shared/resource.go
index ff8796609..3477d4e98 100644
--- a/test/e2e/shared/resource.go
+++ b/test/e2e/shared/resource.go
@@ -27,6 +27,7 @@ import (
 	"path/filepath"
 	"time"
 
+	"github.com/aws/aws-sdk-go/service/servicequotas"
 	"github.com/gofrs/flock"
 	. "github.com/onsi/gomega"
 	"sigs.k8s.io/yaml"
@@ -66,6 +67,19 @@ func WriteResourceQuotesToFile(logPath string, serviceQuotas map[string]*Service
 	Expect(err).NotTo(HaveOccurred())
 }
 
+func WriteAWSResourceQuotesToFile(logPath string, serviceQuotas map[string]*servicequotas.ServiceQuota) {
+	if _, err := os.Stat(logPath); err == nil {
+		// If resource-quotas file exists, remove it. Should not fail on error, another ginkgo node might have already deleted it.
+		os.Remove(logPath)
+	}
+
+	data, err := yaml.Marshal(serviceQuotas)
+	Expect(err).NotTo(HaveOccurred())
+
+	err = os.WriteFile(logPath, data, 0644) //nolint:gosec
+	Expect(err).NotTo(HaveOccurred())
+}
+
 func (r *TestResource) String() string {
 	return fmt.Sprintf("{ec2-normal:%v, vpc:%v, eip:%v, ngw:%v, igw:%v, classiclb:%v, ec2-GPU:%v, volume-gp2:%v}", r.EC2Normal, r.VPC, r.EIP, r.NGW, r.IGW, r.ClassicLB, r.EC2GPU, r.VolumeGP2)
 }
diff --git a/test/e2e/shared/suite.go b/test/e2e/shared/suite.go
index 01be727be..6dbebe550 100644
--- a/test/e2e/shared/suite.go
+++ b/test/e2e/shared/suite.go
@@ -158,9 +158,10 @@ func Node1BeforeSuite(e2eCtx *E2EContext) []byte {
 
 	if !e2eCtx.Settings.SkipQuotas {
 		By("Writing AWS service quotas to a file for parallel tests")
-		quotas := EnsureServiceQuotas(e2eCtx.BootstrapUserAWSSession)
+		quotas, originalQuotas := EnsureServiceQuotas(e2eCtx.BootstrapUserAWSSession)
 		WriteResourceQuotesToFile(ResourceQuotaFilePath, quotas)
 		WriteResourceQuotesToFile(path.Join(e2eCtx.Settings.ArtifactFolder, "initial-resource-quotas.yaml"), quotas)
+		WriteAWSResourceQuotesToFile(path.Join(e2eCtx.Settings.ArtifactFolder, "initial-aws-resource-quotas.yaml"), originalQuotas)
 	}
 
 	e2eCtx.Settings.InstanceVCPU, err = strconv.Atoi(e2eCtx.E2EConfig.GetVariable(InstanceVcpu))