Repository: kubernetes-sigs/cluster-api-provider-aws
Pull request #4800 (2024-02-20 15:45:38)

✨ Filter CNI subnets when creating EKS NodeGroup
<!-- 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 feature

**What this PR does / why we need it**:

<!-- Enter a description of the change and why this change is needed -->

Not sure if this is a bug or a feature. I don't think it's intended for nodes to land on the subnets intended for CNI, but if it is then I can also change this PR to add another `AZSubnetType`.

**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
- [x] includes [emojis](https://github.com/kubernetes-sigs/kubebuilder-release-tools?tab=readme-ov-file#kubebuilder-project-versioning)
- [x] adds unit tests - _I've updated the unit test_
- [ ] adds or updates e2e tests

**Release note**:
<!--  Write your release note:
1. Enter your extended release note in the below block. If the PR requires additional action from users switching to the new release, include the string "action required".
2. If no release note is required, just write "NONE".
-->
```release-note
Exclude CNI subnets when creating EKS NodeGroup with private availability zone subnet type.
```


k8s-ci-robot: Hi @mnitchev. Thanks for your PR.

I'm waiting for a [kubernetes-sigs](https://github.com/orgs/kubernetes-sigs/people) member to verify that this patch is reasonable to test. If it is, they should reply with `/ok-to-test` on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work. Regular contributors should [join the org](https://git.k8s.io/community/community-membership.md#member) to skip this step.

Once the patch is verified, the new status will be reflected by the `ok-to-test` label.

I understand the commands that are listed [here](https://go.k8s.io/bot-commands?repo=kubernetes-sigs%2Fcluster-api-provider-aws).

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository.
</details>

k8s-ci-robot: [APPROVALNOTIFIER] This PR is **NOT APPROVED**

This pull-request has been approved by:
**Once this PR has been reviewed and has the lgtm label**, please assign [richardcase](https://github.com/richardcase) for approval. For more information see [the Kubernetes Code Review Process](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process).

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=kubernetes-sigs%2Fcluster-api-provider-aws).

<details open>
Needs approval from an approver in each of these files:

- **[OWNERS](https://github.com/kubernetes-sigs/cluster-api-provider-aws/blob/main/OWNERS)**

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":["richardcase"]} -->
nrb: /ok-to-test
Ankitasw: /test pull-cluster-api-provider-aws-e2e
k8s-ci-robot: @mnitchev: The following test **failed**, say `/retest` to rerun all failed tests or `/retest-required` to rerun all mandatory failed tests:

Test name | Commit | Details | Required | Rerun command
--- | --- | --- | --- | ---
pull-cluster-api-provider-aws-build-docker | e4222690d5919491a715af7d6bec164e1d606213 | [link](https://prow.k8s.io/view/gs/kubernetes-jenkins/pr-logs/pull/kubernetes-sigs_cluster-api-provider-aws/4800/pull-cluster-api-provider-aws-build-docker/1763177531495682048) | true | `/test pull-cluster-api-provider-aws-build-docker`

[Full PR test history](https://prow.k8s.io/pr-history?org=kubernetes-sigs&repo=cluster-api-provider-aws&pr=4800). [Your PR dashboard](https://prow.k8s.io/pr?query=is%3Apr%20state%3Aopen%20author%3Amnitchev). Please help us cut down on flakes by [linking to](https://git.k8s.io/community/contributors/devel/sig-testing/flaky-tests.md#filing-issues-for-flaky-tests) an [open issue](https://github.com/kubernetes-sigs/cluster-api-provider-aws/issues?q=is:issue+is:open) when you hit one in your PR.

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
mnitchev: /retest
k8s-ci-robot: PR needs rebase.

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository.
</details>
k8s-ci-robot: Adding label `do-not-merge/contains-merge-commits` because PR contains merge commits, which are not allowed in this repository.
Use `git rebase` to reapply your commits on top of the target branch. Detailed instructions for doing so can be found [here](https://git.k8s.io/community/contributors/guide/github-workflow.md#4-keep-your-branch-in-sync).

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository.
</details>
mnitchev: @cnmcavoy @dlipovetsky Can you please review? CI is green
Ankitasw: /test pull-cluster-api-provider-aws-e2e

Patch:
diff --git a/api/v1beta1/awscluster_conversion.go b/api/v1beta1/awscluster_conversion.go
index 37dafa53e..a3763d22c 100644
--- a/api/v1beta1/awscluster_conversion.go
+++ b/api/v1beta1/awscluster_conversion.go
@@ -56,9 +56,7 @@ func (src *AWSCluster) ConvertTo(dstRaw conversion.Hub) error {
 	if restored.Status.Bastion != nil {
 		dst.Status.Bastion.InstanceMetadataOptions = restored.Status.Bastion.InstanceMetadataOptions
 		dst.Status.Bastion.PlacementGroupName = restored.Status.Bastion.PlacementGroupName
-		dst.Status.Bastion.PlacementGroupPartition = restored.Status.Bastion.PlacementGroupPartition
 		dst.Status.Bastion.PrivateDNSName = restored.Status.Bastion.PrivateDNSName
-		dst.Status.Bastion.PublicIPOnLaunch = restored.Status.Bastion.PublicIPOnLaunch
 	}
 	dst.Spec.Partition = restored.Spec.Partition
 
diff --git a/api/v1beta1/awsmachine_conversion.go b/api/v1beta1/awsmachine_conversion.go
index 3cd84b20a..55856591a 100644
--- a/api/v1beta1/awsmachine_conversion.go
+++ b/api/v1beta1/awsmachine_conversion.go
@@ -38,7 +38,6 @@ func (src *AWSMachine) ConvertTo(dstRaw conversion.Hub) error {
 	dst.Spec.Ignition = restored.Spec.Ignition
 	dst.Spec.InstanceMetadataOptions = restored.Spec.InstanceMetadataOptions
 	dst.Spec.PlacementGroupName = restored.Spec.PlacementGroupName
-	dst.Spec.PlacementGroupPartition = restored.Spec.PlacementGroupPartition
 	dst.Spec.PrivateDNSName = restored.Spec.PrivateDNSName
 	dst.Spec.SecurityGroupOverrides = restored.Spec.SecurityGroupOverrides
 
@@ -88,7 +87,6 @@ func (r *AWSMachineTemplate) ConvertTo(dstRaw conversion.Hub) error {
 	dst.Spec.Template.Spec.Ignition = restored.Spec.Template.Spec.Ignition
 	dst.Spec.Template.Spec.InstanceMetadataOptions = restored.Spec.Template.Spec.InstanceMetadataOptions
 	dst.Spec.Template.Spec.PlacementGroupName = restored.Spec.Template.Spec.PlacementGroupName
-	dst.Spec.Template.Spec.PlacementGroupPartition = restored.Spec.Template.Spec.PlacementGroupPartition
 	dst.Spec.Template.Spec.PrivateDNSName = restored.Spec.Template.Spec.PrivateDNSName
 	dst.Spec.Template.Spec.SecurityGroupOverrides = restored.Spec.Template.Spec.SecurityGroupOverrides
 
diff --git a/api/v1beta1/zz_generated.conversion.go b/api/v1beta1/zz_generated.conversion.go
index eb1f4ad8d..30c710277 100644
--- a/api/v1beta1/zz_generated.conversion.go
+++ b/api/v1beta1/zz_generated.conversion.go
@@ -1428,7 +1428,6 @@ func autoConvert_v1beta2_AWSMachineSpec_To_v1beta1_AWSMachineSpec(in *v1beta2.AW
 	}
 	out.SpotMarketOptions = (*SpotMarketOptions)(unsafe.Pointer(in.SpotMarketOptions))
 	// WARNING: in.PlacementGroupName requires manual conversion: does not exist in peer-type
-	// WARNING: in.PlacementGroupPartition requires manual conversion: does not exist in peer-type
 	out.Tenancy = in.Tenancy
 	// WARNING: in.PrivateDNSName requires manual conversion: does not exist in peer-type
 	return nil
@@ -2025,12 +2024,10 @@ func autoConvert_v1beta2_Instance_To_v1beta1_Instance(in *v1beta2.Instance, out
 	out.AvailabilityZone = in.AvailabilityZone
 	out.SpotMarketOptions = (*SpotMarketOptions)(unsafe.Pointer(in.SpotMarketOptions))
 	// WARNING: in.PlacementGroupName requires manual conversion: does not exist in peer-type
-	// WARNING: in.PlacementGroupPartition requires manual conversion: does not exist in peer-type
 	out.Tenancy = in.Tenancy
 	out.VolumeIDs = *(*[]string)(unsafe.Pointer(&in.VolumeIDs))
 	// WARNING: in.InstanceMetadataOptions requires manual conversion: does not exist in peer-type
 	// WARNING: in.PrivateDNSName requires manual conversion: does not exist in peer-type
-	// WARNING: in.PublicIPOnLaunch requires manual conversion: does not exist in peer-type
 	return nil
 }
 
diff --git a/api/v1beta2/awsmachine_types.go b/api/v1beta2/awsmachine_types.go
index 26e733b9c..c4fd5530a 100644
--- a/api/v1beta2/awsmachine_types.go
+++ b/api/v1beta2/awsmachine_types.go
@@ -172,14 +172,6 @@ type AWSMachineSpec struct {
 	// +optional
 	PlacementGroupName string `json:"placementGroupName,omitempty"`
 
-	// PlacementGroupPartition is the partition number within the placement group in which to launch the instance.
-	// This value is only valid if the placement group, referred in `PlacementGroupName`, was created with
-	// strategy set to partition.
-	// +kubebuilder:validation:Minimum:=1
-	// +kubebuilder:validation:Maximum:=7
-	// +optional
-	PlacementGroupPartition int64 `json:"placementGroupPartition,omitempty"`
-
 	// Tenancy indicates if instance should run on shared or single-tenant hardware.
 	// +optional
 	// +kubebuilder:validation:Enum:=default;dedicated;host
diff --git a/api/v1beta2/network_types.go b/api/v1beta2/network_types.go
index ea5d627a6..ed4b947c7 100644
--- a/api/v1beta2/network_types.go
+++ b/api/v1beta2/network_types.go
@@ -510,6 +510,17 @@ func (s Subnets) FilterPrivate() (res Subnets) {
 	return
 }
 
+// FilterNonCni returns the subnets that are NOT intended for usage with the CNI pod network
+// (i.e. do NOT have the `sigs.k8s.io/cluster-api-provider-aws/association=secondary` tag).
+func (s Subnets) FilterNonCni() (res Subnets) {
+	for _, x := range s {
+		if x.Tags[NameAWSSubnetAssociation] != SecondarySubnetTagValue {
+			res = append(res, x)
+		}
+	}
+	return
+}
+
 // FilterPublic returns a slice containing all subnets marked as public.
 func (s Subnets) FilterPublic() (res Subnets) {
 	for _, x := range s {
diff --git a/api/v1beta2/types.go b/api/v1beta2/types.go
index abf92ae4e..55ce2f9cc 100644
--- a/api/v1beta2/types.go
+++ b/api/v1beta2/types.go
@@ -222,14 +222,6 @@ type Instance struct {
 	// +optional
 	PlacementGroupName string `json:"placementGroupName,omitempty"`
 
-	// PlacementGroupPartition is the partition number within the placement group in which to launch the instance.
-	// This value is only valid if the placement group, referred in `PlacementGroupName`, was created with
-	// strategy set to partition.
-	// +kubebuilder:validation:Minimum:=1
-	// +kubebuilder:validation:Maximum:=7
-	// +optional
-	PlacementGroupPartition int64 `json:"placementGroupPartition,omitempty"`
-
 	// Tenancy indicates if instance should run on shared or single-tenant hardware.
 	// +optional
 	Tenancy string `json:"tenancy,omitempty"`
@@ -245,10 +237,6 @@ type Instance struct {
 	// PrivateDNSName is the options for the instance hostname.
 	// +optional
 	PrivateDNSName *PrivateDNSName `json:"privateDnsName,omitempty"`
-
-	// PublicIPOnLaunch is the option to associate a public IP on instance launch
-	// +optional
-	PublicIPOnLaunch *bool `json:"publicIPOnLaunch,omitempty"`
 }
 
 // InstanceMetadataState describes the state of InstanceMetadataOptions.HttpEndpoint and InstanceMetadataOptions.InstanceMetadataTags
diff --git a/api/v1beta2/zz_generated.deepcopy.go b/api/v1beta2/zz_generated.deepcopy.go
index a41c5393f..ee0dc510c 100644
--- a/api/v1beta2/zz_generated.deepcopy.go
+++ b/api/v1beta2/zz_generated.deepcopy.go
@@ -1547,11 +1547,6 @@ func (in *Instance) DeepCopyInto(out *Instance) {
 		*out = new(PrivateDNSName)
 		(*in).DeepCopyInto(*out)
 	}
-	if in.PublicIPOnLaunch != nil {
-		in, out := &in.PublicIPOnLaunch, &out.PublicIPOnLaunch
-		*out = new(bool)
-		**out = **in
-	}
 }
 
 // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Instance.
diff --git a/cmd/clusterawsadm/cloudformation/bootstrap/cluster_api_controller.go b/cmd/clusterawsadm/cloudformation/bootstrap/cluster_api_controller.go
index 95ccdc723..c91939295 100644
--- a/cmd/clusterawsadm/cloudformation/bootstrap/cluster_api_controller.go
+++ b/cmd/clusterawsadm/cloudformation/bootstrap/cluster_api_controller.go
@@ -131,7 +131,6 @@ func (t Template) ControllersPolicy() *iamv1.PolicyDocument {
 				"ec2:DescribeSecurityGroups",
 				"ec2:DescribeSubnets",
 				"ec2:DescribeVpcs",
-				"ec2:DescribeDhcpOptions",
 				"ec2:DescribeVpcAttribute",
 				"ec2:DescribeVpcEndpoints",
 				"ec2:DescribeVolumes",
diff --git a/cmd/clusterawsadm/cloudformation/bootstrap/fixtures/customsuffix.yaml b/cmd/clusterawsadm/cloudformation/bootstrap/fixtures/customsuffix.yaml
index 901858498..d5b550500 100644
--- a/cmd/clusterawsadm/cloudformation/bootstrap/fixtures/customsuffix.yaml
+++ b/cmd/clusterawsadm/cloudformation/bootstrap/fixtures/customsuffix.yaml
@@ -190,7 +190,6 @@ Resources:
           - ec2:DescribeSecurityGroups
           - ec2:DescribeSubnets
           - ec2:DescribeVpcs
-          - ec2:DescribeDhcpOptions
           - ec2:DescribeVpcAttribute
           - ec2:DescribeVpcEndpoints
           - ec2:DescribeVolumes
diff --git a/cmd/clusterawsadm/cloudformation/bootstrap/fixtures/default.yaml b/cmd/clusterawsadm/cloudformation/bootstrap/fixtures/default.yaml
index 7e9442998..a2c06a7e2 100644
--- a/cmd/clusterawsadm/cloudformation/bootstrap/fixtures/default.yaml
+++ b/cmd/clusterawsadm/cloudformation/bootstrap/fixtures/default.yaml
@@ -190,7 +190,6 @@ Resources:
           - ec2:DescribeSecurityGroups
           - ec2:DescribeSubnets
           - ec2:DescribeVpcs
-          - ec2:DescribeDhcpOptions
           - ec2:DescribeVpcAttribute
           - ec2:DescribeVpcEndpoints
           - ec2:DescribeVolumes
diff --git a/cmd/clusterawsadm/cloudformation/bootstrap/fixtures/with_all_secret_backends.yaml b/cmd/clusterawsadm/cloudformation/bootstrap/fixtures/with_all_secret_backends.yaml
index 0fbe28169..e965556dc 100644
--- a/cmd/clusterawsadm/cloudformation/bootstrap/fixtures/with_all_secret_backends.yaml
+++ b/cmd/clusterawsadm/cloudformation/bootstrap/fixtures/with_all_secret_backends.yaml
@@ -196,7 +196,6 @@ Resources:
           - ec2:DescribeSecurityGroups
           - ec2:DescribeSubnets
           - ec2:DescribeVpcs
-          - ec2:DescribeDhcpOptions
           - ec2:DescribeVpcAttribute
           - ec2:DescribeVpcEndpoints
           - ec2:DescribeVolumes
diff --git a/cmd/clusterawsadm/cloudformation/bootstrap/fixtures/with_allow_assume_role.yaml b/cmd/clusterawsadm/cloudformation/bootstrap/fixtures/with_allow_assume_role.yaml
index f8a2bae71..46b412150 100644
--- a/cmd/clusterawsadm/cloudformation/bootstrap/fixtures/with_allow_assume_role.yaml
+++ b/cmd/clusterawsadm/cloudformation/bootstrap/fixtures/with_allow_assume_role.yaml
@@ -190,7 +190,6 @@ Resources:
           - ec2:DescribeSecurityGroups
           - ec2:DescribeSubnets
           - ec2:DescribeVpcs
-          - ec2:DescribeDhcpOptions
           - ec2:DescribeVpcAttribute
           - ec2:DescribeVpcEndpoints
           - ec2:DescribeVolumes
diff --git a/cmd/clusterawsadm/cloudformation/bootstrap/fixtures/with_bootstrap_user.yaml b/cmd/clusterawsadm/cloudformation/bootstrap/fixtures/with_bootstrap_user.yaml
index 489bfd4ba..6fc278b78 100644
--- a/cmd/clusterawsadm/cloudformation/bootstrap/fixtures/with_bootstrap_user.yaml
+++ b/cmd/clusterawsadm/cloudformation/bootstrap/fixtures/with_bootstrap_user.yaml
@@ -196,7 +196,6 @@ Resources:
           - ec2:DescribeSecurityGroups
           - ec2:DescribeSubnets
           - ec2:DescribeVpcs
-          - ec2:DescribeDhcpOptions
           - ec2:DescribeVpcAttribute
           - ec2:DescribeVpcEndpoints
           - ec2:DescribeVolumes
diff --git a/cmd/clusterawsadm/cloudformation/bootstrap/fixtures/with_custom_bootstrap_user.yaml b/cmd/clusterawsadm/cloudformation/bootstrap/fixtures/with_custom_bootstrap_user.yaml
index 7992953ec..4cb1a565c 100644
--- a/cmd/clusterawsadm/cloudformation/bootstrap/fixtures/with_custom_bootstrap_user.yaml
+++ b/cmd/clusterawsadm/cloudformation/bootstrap/fixtures/with_custom_bootstrap_user.yaml
@@ -196,7 +196,6 @@ Resources:
           - ec2:DescribeSecurityGroups
           - ec2:DescribeSubnets
           - ec2:DescribeVpcs
-          - ec2:DescribeDhcpOptions
           - ec2:DescribeVpcAttribute
           - ec2:DescribeVpcEndpoints
           - ec2:DescribeVolumes
diff --git a/cmd/clusterawsadm/cloudformation/bootstrap/fixtures/with_different_instance_profiles.yaml b/cmd/clusterawsadm/cloudformation/bootstrap/fixtures/with_different_instance_profiles.yaml
index 63d9a5d55..1dd528076 100644
--- a/cmd/clusterawsadm/cloudformation/bootstrap/fixtures/with_different_instance_profiles.yaml
+++ b/cmd/clusterawsadm/cloudformation/bootstrap/fixtures/with_different_instance_profiles.yaml
@@ -190,7 +190,6 @@ Resources:
           - ec2:DescribeSecurityGroups
           - ec2:DescribeSubnets
           - ec2:DescribeVpcs
-          - ec2:DescribeDhcpOptions
           - ec2:DescribeVpcAttribute
           - ec2:DescribeVpcEndpoints
           - ec2:DescribeVolumes
diff --git a/cmd/clusterawsadm/cloudformation/bootstrap/fixtures/with_eks_console.yaml b/cmd/clusterawsadm/cloudformation/bootstrap/fixtures/with_eks_console.yaml
index 6f56f0736..80f96c8d6 100644
--- a/cmd/clusterawsadm/cloudformation/bootstrap/fixtures/with_eks_console.yaml
+++ b/cmd/clusterawsadm/cloudformation/bootstrap/fixtures/with_eks_console.yaml
@@ -190,7 +190,6 @@ Resources:
           - ec2:DescribeSecurityGroups
           - ec2:DescribeSubnets
           - ec2:DescribeVpcs
-          - ec2:DescribeDhcpOptions
           - ec2:DescribeVpcAttribute
           - ec2:DescribeVpcEndpoints
           - ec2:DescribeVolumes
diff --git a/cmd/clusterawsadm/cloudformation/bootstrap/fixtures/with_eks_default_roles.yaml b/cmd/clusterawsadm/cloudformation/bootstrap/fixtures/with_eks_default_roles.yaml
index 28977affa..9ce26aff2 100644
--- a/cmd/clusterawsadm/cloudformation/bootstrap/fixtures/with_eks_default_roles.yaml
+++ b/cmd/clusterawsadm/cloudformation/bootstrap/fixtures/with_eks_default_roles.yaml
@@ -190,7 +190,6 @@ Resources:
           - ec2:DescribeSecurityGroups
           - ec2:DescribeSubnets
           - ec2:DescribeVpcs
-          - ec2:DescribeDhcpOptions
           - ec2:DescribeVpcAttribute
           - ec2:DescribeVpcEndpoints
           - ec2:DescribeVolumes
diff --git a/cmd/clusterawsadm/cloudformation/bootstrap/fixtures/with_eks_disable.yaml b/cmd/clusterawsadm/cloudformation/bootstrap/fixtures/with_eks_disable.yaml
index 794ab27ec..76af2c7ae 100644
--- a/cmd/clusterawsadm/cloudformation/bootstrap/fixtures/with_eks_disable.yaml
+++ b/cmd/clusterawsadm/cloudformation/bootstrap/fixtures/with_eks_disable.yaml
@@ -190,7 +190,6 @@ Resources:
           - ec2:DescribeSecurityGroups
           - ec2:DescribeSubnets
           - ec2:DescribeVpcs
-          - ec2:DescribeDhcpOptions
           - ec2:DescribeVpcAttribute
           - ec2:DescribeVpcEndpoints
           - ec2:DescribeVolumes
diff --git a/cmd/clusterawsadm/cloudformation/bootstrap/fixtures/with_eks_kms_prefix.yaml b/cmd/clusterawsadm/cloudformation/bootstrap/fixtures/with_eks_kms_prefix.yaml
index 74aa22f79..67e78b950 100644
--- a/cmd/clusterawsadm/cloudformation/bootstrap/fixtures/with_eks_kms_prefix.yaml
+++ b/cmd/clusterawsadm/cloudformation/bootstrap/fixtures/with_eks_kms_prefix.yaml
@@ -190,7 +190,6 @@ Resources:
           - ec2:DescribeSecurityGroups
           - ec2:DescribeSubnets
           - ec2:DescribeVpcs
-          - ec2:DescribeDhcpOptions
           - ec2:DescribeVpcAttribute
           - ec2:DescribeVpcEndpoints
           - ec2:DescribeVolumes
diff --git a/cmd/clusterawsadm/cloudformation/bootstrap/fixtures/with_extra_statements.yaml b/cmd/clusterawsadm/cloudformation/bootstrap/fixtures/with_extra_statements.yaml
index a239b9e89..ef5fd5998 100644
--- a/cmd/clusterawsadm/cloudformation/bootstrap/fixtures/with_extra_statements.yaml
+++ b/cmd/clusterawsadm/cloudformation/bootstrap/fixtures/with_extra_statements.yaml
@@ -196,7 +196,6 @@ Resources:
           - ec2:DescribeSecurityGroups
           - ec2:DescribeSubnets
           - ec2:DescribeVpcs
-          - ec2:DescribeDhcpOptions
           - ec2:DescribeVpcAttribute
           - ec2:DescribeVpcEndpoints
           - ec2:DescribeVolumes
diff --git a/cmd/clusterawsadm/cloudformation/bootstrap/fixtures/with_s3_bucket.yaml b/cmd/clusterawsadm/cloudformation/bootstrap/fixtures/with_s3_bucket.yaml
index 28126ce41..39bd20ef2 100644
--- a/cmd/clusterawsadm/cloudformation/bootstrap/fixtures/with_s3_bucket.yaml
+++ b/cmd/clusterawsadm/cloudformation/bootstrap/fixtures/with_s3_bucket.yaml
@@ -190,7 +190,6 @@ Resources:
           - ec2:DescribeSecurityGroups
           - ec2:DescribeSubnets
           - ec2:DescribeVpcs
-          - ec2:DescribeDhcpOptions
           - ec2:DescribeVpcAttribute
           - ec2:DescribeVpcEndpoints
           - ec2:DescribeVolumes
diff --git a/cmd/clusterawsadm/cloudformation/bootstrap/fixtures/with_ssm_secret_backend.yaml b/cmd/clusterawsadm/cloudformation/bootstrap/fixtures/with_ssm_secret_backend.yaml
index 1b6cfe4f5..472fdaacf 100644
--- a/cmd/clusterawsadm/cloudformation/bootstrap/fixtures/with_ssm_secret_backend.yaml
+++ b/cmd/clusterawsadm/cloudformation/bootstrap/fixtures/with_ssm_secret_backend.yaml
@@ -190,7 +190,6 @@ Resources:
           - ec2:DescribeSecurityGroups
           - ec2:DescribeSubnets
           - ec2:DescribeVpcs
-          - ec2:DescribeDhcpOptions
           - ec2:DescribeVpcAttribute
           - ec2:DescribeVpcEndpoints
           - ec2:DescribeVolumes
diff --git a/config/crd/bases/controlplane.cluster.x-k8s.io_awsmanagedcontrolplanes.yaml b/config/crd/bases/controlplane.cluster.x-k8s.io_awsmanagedcontrolplanes.yaml
index f2ed7ef9d..3227df4d8 100644
--- a/config/crd/bases/controlplane.cluster.x-k8s.io_awsmanagedcontrolplanes.yaml
+++ b/config/crd/bases/controlplane.cluster.x-k8s.io_awsmanagedcontrolplanes.yaml
@@ -1109,15 +1109,6 @@ spec:
                     description: PlacementGroupName specifies the name of the placement
                       group in which to launch the instance.
                     type: string
-                  placementGroupPartition:
-                    description: PlacementGroupPartition is the partition number within
-                      the placement group in which to launch the instance. This value
-                      is only valid if the placement group, referred in `PlacementGroupName`,
-                      was created with strategy set to partition.
-                    format: int64
-                    maximum: 7
-                    minimum: 1
-                    type: integer
                   privateDnsName:
                     description: PrivateDNSName is the options for the instance hostname.
                     properties:
@@ -1141,10 +1132,6 @@ spec:
                   privateIp:
                     description: The private IPv4 address assigned to the instance.
                     type: string
-                  publicIPOnLaunch:
-                    description: PublicIPOnLaunch is the option to associate a public
-                      IP on instance launch
-                    type: boolean
                   publicIp:
                     description: The public IPv4 address assigned to the instance,
                       if applicable.
@@ -2974,15 +2961,6 @@ spec:
                     description: PlacementGroupName specifies the name of the placement
                       group in which to launch the instance.
                     type: string
-                  placementGroupPartition:
-                    description: PlacementGroupPartition is the partition number within
-                      the placement group in which to launch the instance. This value
-                      is only valid if the placement group, referred in `PlacementGroupName`,
-                      was created with strategy set to partition.
-                    format: int64
-                    maximum: 7
-                    minimum: 1
-                    type: integer
                   privateDnsName:
                     description: PrivateDNSName is the options for the instance hostname.
                     properties:
@@ -3006,10 +2984,6 @@ spec:
                   privateIp:
                     description: The private IPv4 address assigned to the instance.
                     type: string
-                  publicIPOnLaunch:
-                    description: PublicIPOnLaunch is the option to associate a public
-                      IP on instance launch
-                    type: boolean
                   publicIp:
                     description: The public IPv4 address assigned to the instance,
                       if applicable.
diff --git a/config/crd/bases/controlplane.cluster.x-k8s.io_rosacontrolplanes.yaml b/config/crd/bases/controlplane.cluster.x-k8s.io_rosacontrolplanes.yaml
index 76577fefa..38cc06b8f 100644
--- a/config/crd/bases/controlplane.cluster.x-k8s.io_rosacontrolplanes.yaml
+++ b/config/crd/bases/controlplane.cluster.x-k8s.io_rosacontrolplanes.yaml
@@ -116,8 +116,7 @@ spec:
                 properties:
                   autoscaling:
                     description: Autoscaling specifies auto scaling behaviour for
-                      the default MachinePool. Autoscaling min/max value must be equal
-                      or multiple of the availability zones count.
+                      this MachinePool.
                     properties:
                       maxReplicas:
                         minimum: 1
diff --git a/config/crd/bases/infrastructure.cluster.x-k8s.io_awsclusters.yaml b/config/crd/bases/infrastructure.cluster.x-k8s.io_awsclusters.yaml
index 523153831..a74b9c7e8 100644
--- a/config/crd/bases/infrastructure.cluster.x-k8s.io_awsclusters.yaml
+++ b/config/crd/bases/infrastructure.cluster.x-k8s.io_awsclusters.yaml
@@ -1884,15 +1884,6 @@ spec:
                     description: PlacementGroupName specifies the name of the placement
                       group in which to launch the instance.
                     type: string
-                  placementGroupPartition:
-                    description: PlacementGroupPartition is the partition number within
-                      the placement group in which to launch the instance. This value
-                      is only valid if the placement group, referred in `PlacementGroupName`,
-                      was created with strategy set to partition.
-                    format: int64
-                    maximum: 7
-                    minimum: 1
-                    type: integer
                   privateDnsName:
                     description: PrivateDNSName is the options for the instance hostname.
                     properties:
@@ -1916,10 +1907,6 @@ spec:
                   privateIp:
                     description: The private IPv4 address assigned to the instance.
                     type: string
-                  publicIPOnLaunch:
-                    description: PublicIPOnLaunch is the option to associate a public
-                      IP on instance launch
-                    type: boolean
                   publicIp:
                     description: The public IPv4 address assigned to the instance,
                       if applicable.
diff --git a/config/crd/bases/infrastructure.cluster.x-k8s.io_awsmachines.yaml b/config/crd/bases/infrastructure.cluster.x-k8s.io_awsmachines.yaml
index 2f4a15b26..2ad97a52d 100644
--- a/config/crd/bases/infrastructure.cluster.x-k8s.io_awsmachines.yaml
+++ b/config/crd/bases/infrastructure.cluster.x-k8s.io_awsmachines.yaml
@@ -854,15 +854,6 @@ spec:
                 description: PlacementGroupName specifies the name of the placement
                   group in which to launch the instance.
                 type: string
-              placementGroupPartition:
-                description: PlacementGroupPartition is the partition number within
-                  the placement group in which to launch the instance. This value
-                  is only valid if the placement group, referred in `PlacementGroupName`,
-                  was created with strategy set to partition.
-                format: int64
-                maximum: 7
-                minimum: 1
-                type: integer
               privateDnsName:
                 description: PrivateDNSName is the options for the instance hostname.
                 properties:
diff --git a/config/crd/bases/infrastructure.cluster.x-k8s.io_awsmachinetemplates.yaml b/config/crd/bases/infrastructure.cluster.x-k8s.io_awsmachinetemplates.yaml
index 343fb0587..dec081752 100644
--- a/config/crd/bases/infrastructure.cluster.x-k8s.io_awsmachinetemplates.yaml
+++ b/config/crd/bases/infrastructure.cluster.x-k8s.io_awsmachinetemplates.yaml
@@ -813,16 +813,6 @@ spec:
                         description: PlacementGroupName specifies the name of the
                           placement group in which to launch the instance.
                         type: string
-                      placementGroupPartition:
-                        description: PlacementGroupPartition is the partition number
-                          within the placement group in which to launch the instance.
-                          This value is only valid if the placement group, referred
-                          in `PlacementGroupName`, was created with strategy set to
-                          partition.
-                        format: int64
-                        maximum: 7
-                        minimum: 1
-                        type: integer
                       privateDnsName:
                         description: PrivateDNSName is the options for the instance
                           hostname.
diff --git a/controlplane/rosa/api/v1beta2/rosacontrolplane_types.go b/controlplane/rosa/api/v1beta2/rosacontrolplane_types.go
index 787e8060a..b35e7f6be 100644
--- a/controlplane/rosa/api/v1beta2/rosacontrolplane_types.go
+++ b/controlplane/rosa/api/v1beta2/rosacontrolplane_types.go
@@ -198,8 +198,7 @@ type DefaultMachinePoolSpec struct {
 	// +optional
 	InstanceType string `json:"instanceType,omitempty"`
 
-	// Autoscaling specifies auto scaling behaviour for the default MachinePool. Autoscaling min/max value
-	// must be equal or multiple of the availability zones count.
+	// Autoscaling specifies auto scaling behaviour for this MachinePool.
 	// +optional
 	Autoscaling *expinfrav1.RosaMachinePoolAutoScaling `json:"autoscaling,omitempty"`
 }
diff --git a/controlplane/rosa/controllers/rosacontrolplane_controller.go b/controlplane/rosa/controllers/rosacontrolplane_controller.go
index 84c9bcf1d..e54023c20 100644
--- a/controlplane/rosa/controllers/rosacontrolplane_controller.go
+++ b/controlplane/rosa/controllers/rosacontrolplane_controller.go
@@ -611,13 +611,9 @@ func buildOCMClusterSpec(controPlaneSpec rosacontrolplanev1.RosaControlPlaneSpec
 	}
 
 	// Set cluster compute autoscaling replicas
-	// In case autoscaling is not defined and multiple zones defined, set the compute nodes equal to the zones count.
 	if computeAutoscaling := controPlaneSpec.DefaultMachinePoolSpec.Autoscaling; computeAutoscaling != nil {
-		ocmClusterSpec.Autoscaling = true
 		ocmClusterSpec.MaxReplicas = computeAutoscaling.MaxReplicas
 		ocmClusterSpec.MinReplicas = computeAutoscaling.MinReplicas
-	} else if computeAutoscaling == nil && len(controPlaneSpec.AvailabilityZones) > 1 {
-		ocmClusterSpec.ComputeNodes = len(controPlaneSpec.AvailabilityZones)
 	}
 
 	if controPlaneSpec.ProvisionShardID != "" {
diff --git a/go.mod b/go.mod
index c91485fc9..54d3a6882 100644
--- a/go.mod
+++ b/go.mod
@@ -90,7 +90,7 @@ require (
 	github.com/daviddengcn/go-colortext v1.0.0 // indirect
 	github.com/distribution/reference v0.5.0 // indirect
 	github.com/docker/distribution v2.8.3+incompatible // indirect
-	github.com/docker/docker v24.0.9+incompatible // indirect
+	github.com/docker/docker v24.0.7+incompatible // indirect
 	github.com/docker/go-connections v0.4.0 // indirect
 	github.com/docker/go-units v0.5.0 // indirect
 	github.com/drone/envsubst/v2 v2.0.0-20210730161058-179042472c46 // indirect
@@ -216,7 +216,7 @@ require (
 	google.golang.org/genproto/googleapis/api v0.0.0-20230913181813-007df8e322eb // indirect
 	google.golang.org/genproto/googleapis/rpc v0.0.0-20230920204549-e6e6cdab5c13 // indirect
 	google.golang.org/grpc v1.59.0 // indirect
-	google.golang.org/protobuf v1.33.0 // indirect
+	google.golang.org/protobuf v1.32.0 // indirect
 	gopkg.in/inf.v0 v0.9.1 // indirect
 	gopkg.in/ini.v1 v1.67.0 // indirect
 	gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
diff --git a/go.sum b/go.sum
index 2b88f1e4f..3cbb352ea 100644
--- a/go.sum
+++ b/go.sum
@@ -157,8 +157,8 @@ github.com/distribution/reference v0.5.0 h1:/FUIFXtfc/x2gpa5/VGfiGLuOIdYa1t65IKK
 github.com/distribution/reference v0.5.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
 github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk=
 github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
-github.com/docker/docker v24.0.9+incompatible h1:HPGzNmwfLZWdxHqK9/II92pyi1EpYKsAqcl4G0Of9v0=
-github.com/docker/docker v24.0.9+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
+github.com/docker/docker v24.0.7+incompatible h1:Wo6l37AuwP3JaMnZa226lzVXGA3F9Ig1seQen0cKYlM=
+github.com/docker/docker v24.0.7+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
 github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
 github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
 github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
@@ -1007,8 +1007,8 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj
 google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
 google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
 google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
-google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
-google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
+google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I=
+google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
diff --git a/hack/tools/go.mod b/hack/tools/go.mod
index 09b2df9fa..e2c803f1c 100644
--- a/hack/tools/go.mod
+++ b/hack/tools/go.mod
@@ -112,7 +112,7 @@ require (
 	github.com/dimchansky/utfbom v1.1.1 // indirect
 	github.com/docker/cli v24.0.7+incompatible // indirect
 	github.com/docker/distribution v2.8.3+incompatible // indirect
-	github.com/docker/docker v24.0.9+incompatible // indirect
+	github.com/docker/docker v24.0.7+incompatible // indirect
 	github.com/docker/docker-credential-helpers v0.8.0 // indirect
 	github.com/elliotchance/orderedmap v1.5.1 // indirect
 	github.com/emicklei/go-restful/v3 v3.11.0 // indirect
@@ -129,7 +129,7 @@ require (
 	github.com/go-git/go-billy/v5 v5.5.0 // indirect
 	github.com/go-git/go-git/v5 v5.11.0 // indirect
 	github.com/go-ini/ini v1.67.0 // indirect
-	github.com/go-jose/go-jose/v3 v3.0.3 // indirect
+	github.com/go-jose/go-jose/v3 v3.0.1 // indirect
 	github.com/go-logr/logr v1.4.1 // indirect
 	github.com/go-logr/stdr v1.2.2 // indirect
 	github.com/go-logr/zapr v1.2.0 // indirect
@@ -296,8 +296,8 @@ require (
 	google.golang.org/genproto/googleapis/api v0.0.0-20240125205218-1f4bbc51befe // indirect
 	google.golang.org/genproto/googleapis/rpc v0.0.0-20240116215550-a9fa1716bcac // indirect
 	google.golang.org/grpc v1.61.0 // indirect
-	google.golang.org/protobuf v1.33.0 // indirect
-	gopkg.in/go-jose/go-jose.v2 v2.6.3 // indirect
+	google.golang.org/protobuf v1.32.0 // indirect
+	gopkg.in/go-jose/go-jose.v2 v2.6.1 // indirect
 	gopkg.in/inf.v0 v0.9.1 // indirect
 	gopkg.in/ini.v1 v1.67.0 // indirect
 	gopkg.in/op/go-logging.v1 v1.0.0-20160211212156-b2cb9fa56473 // indirect
diff --git a/hack/tools/go.sum b/hack/tools/go.sum
index 7ae5541cb..7e1517b86 100644
--- a/hack/tools/go.sum
+++ b/hack/tools/go.sum
@@ -316,8 +316,8 @@ github.com/docker/cli v24.0.7+incompatible h1:wa/nIwYFW7BVTGa7SWPVyyXU9lgORqUb1x
 github.com/docker/cli v24.0.7+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
 github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk=
 github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
-github.com/docker/docker v24.0.9+incompatible h1:HPGzNmwfLZWdxHqK9/II92pyi1EpYKsAqcl4G0Of9v0=
-github.com/docker/docker v24.0.9+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
+github.com/docker/docker v24.0.7+incompatible h1:Wo6l37AuwP3JaMnZa226lzVXGA3F9Ig1seQen0cKYlM=
+github.com/docker/docker v24.0.7+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
 github.com/docker/docker-credential-helpers v0.8.0 h1:YQFtbBQb4VrpoPxhFuzEBPQ9E16qz5SpHLS+uswaCp8=
 github.com/docker/docker-credential-helpers v0.8.0/go.mod h1:UGFXcuoQ5TxPiB54nHOZ32AWRqQdECoh/Mg0AlEYb40=
 github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
@@ -387,8 +387,8 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2
 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
 github.com/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A=
 github.com/go-ini/ini v1.67.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
-github.com/go-jose/go-jose/v3 v3.0.3 h1:fFKWeig/irsp7XD2zBxvnmA/XaRWp5V3CBsZXJF7G7k=
-github.com/go-jose/go-jose/v3 v3.0.3/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ=
+github.com/go-jose/go-jose/v3 v3.0.1 h1:pWmKFVtt+Jl0vBZTIpz/eAKwsm6LkIxDVVbFHKkchhA=
+github.com/go-jose/go-jose/v3 v3.0.1/go.mod h1:RNkWWRld676jZEYoV3+XK8L2ZnNSvIsxFMht0mSX+u8=
 github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
 github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
 github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
@@ -1022,6 +1022,7 @@ golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8U
 golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/crypto v0.0.0-20191219195013-becbf705a915/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
@@ -1428,8 +1429,8 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba
 google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
 google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
 google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
-google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
-google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
+google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I=
+google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
@@ -1439,8 +1440,8 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntN
 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
 gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
 gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
-gopkg.in/go-jose/go-jose.v2 v2.6.3 h1:nt80fvSDlhKWQgSWyHyy5CfmlQr+asih51R8PTWNKKs=
-gopkg.in/go-jose/go-jose.v2 v2.6.3/go.mod h1:zzZDPkNNw/c9IE7Z9jr11mBZQhKQTMzoEEIoEdZlFBI=
+gopkg.in/go-jose/go-jose.v2 v2.6.1 h1:qEzJlIDmG9q5VO0M/o8tGS65QMHMS1w01TQJB1VPJ4U=
+gopkg.in/go-jose/go-jose.v2 v2.6.1/go.mod h1:zzZDPkNNw/c9IE7Z9jr11mBZQhKQTMzoEEIoEdZlFBI=
 gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
 gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
 gopkg.in/ini.v1 v1.56.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
diff --git a/main.go b/main.go
index fad2ec396..35d324dcc 100644
--- a/main.go
+++ b/main.go
@@ -92,23 +92,20 @@ func init() {
 }
 
 var (
-	enableLeaderElection        bool
-	leaderElectionLeaseDuration time.Duration
-	leaderElectionRenewDeadline time.Duration
-	leaderElectionRetryPeriod   time.Duration
-	leaderElectionNamespace     string
-	watchNamespace              string
-	watchFilterValue            string
-	profilerAddress             string
-	awsClusterConcurrency       int
-	instanceStateConcurrency    int
-	awsMachineConcurrency       int
-	waitInfraPeriod             time.Duration
-	syncPeriod                  time.Duration
-	webhookPort                 int
-	webhookCertDir              string
-	healthAddr                  string
-	serviceEndpoints            string
+	enableLeaderElection     bool
+	leaderElectionNamespace  string
+	watchNamespace           string
+	watchFilterValue         string
+	profilerAddress          string
+	awsClusterConcurrency    int
+	instanceStateConcurrency int
+	awsMachineConcurrency    int
+	waitInfraPeriod          time.Duration
+	syncPeriod               time.Duration
+	webhookPort              int
+	webhookCertDir           string
+	healthAddr               string
+	serviceEndpoints         string
 
 	// maxEKSSyncPeriod is the maximum allowed duration for the sync-period flag when using EKS. It is set to 10 minutes
 	// because during resync it will create a new AWS auth token which can a maximum life of 15 minutes and this ensures
@@ -174,9 +171,6 @@ func main() {
 		Scheme:                     scheme,
 		Metrics:                    diagnosticsOpts,
 		LeaderElection:             enableLeaderElection,
-		LeaseDuration:              &leaderElectionLeaseDuration,
-		RenewDeadline:              &leaderElectionRenewDeadline,
-		RetryPeriod:                &leaderElectionRetryPeriod,
 		LeaderElectionResourceLock: resourcelock.LeasesResourceLock,
 		LeaderElectionID:           "controller-leader-elect-capa",
 		LeaderElectionNamespace:    leaderElectionNamespace,
@@ -501,27 +495,6 @@ func initFlags(fs *pflag.FlagSet) {
 		"Enable leader election for controller manager. Enabling this will ensure there is only one active controller manager.",
 	)
 
-	fs.DurationVar(
-		&leaderElectionLeaseDuration,
-		"leader-elect-lease-duration",
-		15*time.Second,
-		"Interval at which non-leader candidates will wait to force acquire leadership (duration string)",
-	)
-
-	fs.DurationVar(
-		&leaderElectionRenewDeadline,
-		"leader-elect-renew-deadline",
-		10*time.Second,
-		"Duration that the leading controller manager will retry refreshing leadership before giving up (duration string)",
-	)
-
-	fs.DurationVar(
-		&leaderElectionRetryPeriod,
-		"leader-elect-retry-period",
-		2*time.Second,
-		"Duration the LeaderElector clients should wait between tries of actions (duration string)",
-	)
-
 	fs.StringVar(
 		&watchNamespace,
 		"namespace",
diff --git a/pkg/cloud/scope/managedcontrolplane.go b/pkg/cloud/scope/managedcontrolplane.go
index 018cbc778..bc93cd49b 100644
--- a/pkg/cloud/scope/managedcontrolplane.go
+++ b/pkg/cloud/scope/managedcontrolplane.go
@@ -430,11 +430,6 @@ func (s *ManagedControlPlaneScope) ControlPlaneLoadBalancer() *infrav1.AWSLoadBa
 	return nil
 }
 
-// ControlPlaneLoadBalancers returns the AWSLoadBalancerSpecs.
-func (s *ManagedControlPlaneScope) ControlPlaneLoadBalancers() []*infrav1.AWSLoadBalancerSpec {
-	return nil
-}
-
 // Partition returns the cluster partition.
 func (s *ManagedControlPlaneScope) Partition() string {
 	if s.ControlPlane.Spec.Partition == "" {
diff --git a/pkg/cloud/scope/sg.go b/pkg/cloud/scope/sg.go
index 5db8282c8..793ff8066 100644
--- a/pkg/cloud/scope/sg.go
+++ b/pkg/cloud/scope/sg.go
@@ -44,7 +44,6 @@ type SGScope interface {
 	Bastion() *infrav1.Bastion
 
 	// ControlPlaneLoadBalancer returns the load balancer settings that are requested.
-	// Deprecated: Use ControlPlaneLoadBalancers()
 	ControlPlaneLoadBalancer() *infrav1.AWSLoadBalancerSpec
 
 	// SetNatGatewaysIPs sets the Nat Gateways Public IPs.
@@ -55,8 +54,4 @@ type SGScope interface {
 
 	// AdditionalControlPlaneIngressRules returns the additional ingress rules for the control plane security group.
 	AdditionalControlPlaneIngressRules() []infrav1.IngressRule
-
-	// ControlPlaneLoadBalancers returns both the ControlPlaneLoadBalancer and SecondaryControlPlaneLoadBalancer AWSLoadBalancerSpecs.
-	// The control plane load balancers should always be returned in the above order.
-	ControlPlaneLoadBalancers() []*infrav1.AWSLoadBalancerSpec
 }
diff --git a/pkg/cloud/scope/shared.go b/pkg/cloud/scope/shared.go
index 865ebfaf5..ce7ed2fa0 100644
--- a/pkg/cloud/scope/shared.go
+++ b/pkg/cloud/scope/shared.go
@@ -122,6 +122,7 @@ func (p *defaultSubnetPlacementStrategy) getSubnetsForAZs(azs []string, controlP
 				subnets = subnets.FilterPublic()
 			case expinfrav1.AZSubnetTypePrivate:
 				subnets = subnets.FilterPrivate()
+				subnets = subnets.FilterNonCni()
 			}
 		}
 		if len(subnets) == 0 {
diff --git a/pkg/cloud/services/ec2/instances.go b/pkg/cloud/services/ec2/instances.go
index b943a493b..dde96bd8a 100644
--- a/pkg/cloud/services/ec2/instances.go
+++ b/pkg/cloud/services/ec2/instances.go
@@ -25,7 +25,6 @@ import (
 
 	"github.com/aws/aws-sdk-go/aws"
 	"github.com/aws/aws-sdk-go/service/ec2"
-	"github.com/aws/aws-sdk-go/service/ec2/ec2iface"
 	"github.com/pkg/errors"
 	"k8s.io/utils/ptr"
 
@@ -182,21 +181,6 @@ func (s *Service) CreateInstance(scope *scope.MachineScope, userData []byte, use
 	}
 	input.SubnetID = subnetID
 
-	if ptr.Deref(scope.AWSMachine.Spec.PublicIP, false) {
-		subnets, err := s.getFilteredSubnets(&ec2.Filter{
-			Name:   aws.String("subnet-id"),
-			Values: aws.StringSlice([]string{subnetID}),
-		})
-		if err != nil {
-			return nil, fmt.Errorf("could not query if subnet has MapPublicIpOnLaunch set: %w", err)
-		}
-		if len(subnets) == 0 {
-			return nil, fmt.Errorf("expected to find subnet %q", subnetID)
-		}
-		// If the subnet does not assign public IPs, set that option in the instance's network interface
-		input.PublicIPOnLaunch = ptr.To(!aws.BoolValue(subnets[0].MapPublicIpOnLaunch))
-	}
-
 	if !scope.IsControlPlaneExternallyManaged() && !scope.IsExternallyManaged() && !scope.IsEKSManaged() && s.scope.Network().APIServerELB.DNSName == "" {
 		record.Eventf(s.scope.InfraCluster(), "FailedCreateInstance", "Failed to run controlplane, APIServer ELB not available")
 		return nil, awserrors.NewFailedDependency("failed to run controlplane, APIServer ELB not available")
@@ -252,8 +236,6 @@ func (s *Service) CreateInstance(scope *scope.MachineScope, userData []byte, use
 
 	input.PlacementGroupName = scope.AWSMachine.Spec.PlacementGroupName
 
-	input.PlacementGroupPartition = scope.AWSMachine.Spec.PlacementGroupPartition
-
 	input.PrivateDNSName = scope.AWSMachine.Spec.PrivateDNSName
 
 	s.scope.Debug("Running instance", "machine-role", scope.Role())
@@ -352,7 +334,7 @@ func (s *Service) findSubnet(scope *scope.MachineScope) (string, error) {
 					*subnet.SubnetId, *subnet.AvailabilityZone, *failureDomain)
 				continue
 			}
-			if scope.AWSMachine.Spec.PublicIP != nil && *scope.AWSMachine.Spec.PublicIP && !s.scope.Subnets().FindByID(*subnet.SubnetId).IsPublic {
+			if scope.AWSMachine.Spec.PublicIP != nil && *scope.AWSMachine.Spec.PublicIP && !*subnet.MapPublicIpOnLaunch {
 				errMessage += fmt.Sprintf(" subnet %q is a private subnet.", *subnet.SubnetId)
 				continue
 			}
@@ -556,25 +538,13 @@ func (s *Service) runInstance(role string, i *infrav1.Instance) (*infrav1.Instan
 				DeviceIndex:        aws.Int64(int64(index)),
 			})
 		}
-		netInterfaces[0].AssociatePublicIpAddress = i.PublicIPOnLaunch
 
 		input.NetworkInterfaces = netInterfaces
 	} else {
-		if ptr.Deref(i.PublicIPOnLaunch, false) {
-			input.NetworkInterfaces = []*ec2.InstanceNetworkInterfaceSpecification{
-				{
-					DeviceIndex:              aws.Int64(0),
-					SubnetId:                 aws.String(i.SubnetID),
-					Groups:                   aws.StringSlice(i.SecurityGroupIDs),
-					AssociatePublicIpAddress: i.PublicIPOnLaunch,
-				},
-			}
-		} else {
-			input.SubnetId = aws.String(i.SubnetID)
+		input.SubnetId = aws.String(i.SubnetID)
 
-			if len(i.SecurityGroupIDs) > 0 {
-				input.SecurityGroupIds = aws.StringSlice(i.SecurityGroupIDs)
-			}
+		if len(i.SecurityGroupIDs) > 0 {
+			input.SecurityGroupIds = aws.StringSlice(i.SecurityGroupIDs)
 		}
 	}
 
@@ -640,18 +610,11 @@ func (s *Service) runInstance(role string, i *infrav1.Instance) (*infrav1.Instan
 		}
 	}
 
-	if i.PlacementGroupName == "" && i.PlacementGroupPartition != 0 {
-		return nil, errors.Errorf("placementGroupPartition is set but placementGroupName is empty")
-	}
-
 	if i.PlacementGroupName != "" {
 		if input.Placement == nil {
 			input.Placement = &ec2.Placement{}
 		}
 		input.Placement.GroupName = &i.PlacementGroupName
-		if i.PlacementGroupPartition != 0 {
-			input.Placement.PartitionNumber = &i.PlacementGroupPartition
-		}
 	}
 
 	out, err := s.EC2Client.RunInstancesWithContext(context.TODO(), input)
@@ -923,8 +886,6 @@ func (s *Service) SDKToInstance(v *ec2.Instance) (*infrav1.Instance, error) {
 
 func (s *Service) getInstanceAddresses(instance *ec2.Instance) []clusterv1.MachineAddress {
 	addresses := []clusterv1.MachineAddress{}
-	// Check if the DHCP Option Set has domain name set
-	domainName := s.GetDHCPOptionSetDomainName(s.EC2Client, instance.VpcId)
 	for _, eni := range instance.NetworkInterfaces {
 		privateDNSAddress := clusterv1.MachineAddress{
 			Type:    clusterv1.MachineInternalDNS,
@@ -934,18 +895,8 @@ func (s *Service) getInstanceAddresses(instance *ec2.Instance) []clusterv1.Machi
 			Type:    clusterv1.MachineInternalIP,
 			Address: aws.StringValue(eni.PrivateIpAddress),
 		}
-
 		addresses = append(addresses, privateDNSAddress, privateIPAddress)
 
-		if domainName != nil {
-			// Add secondary private DNS Name with domain name set in DHCP Option Set
-			additionalPrivateDNSAddress := clusterv1.MachineAddress{
-				Type:    clusterv1.MachineInternalDNS,
-				Address: fmt.Sprintf("%s.%s", strings.Split(privateDNSAddress.Address, ".")[0], *domainName),
-			}
-			addresses = append(addresses, additionalPrivateDNSAddress)
-		}
-
 		// An elastic IP is attached if association is non nil pointer
 		if eni.Association != nil {
 			publicDNSAddress := clusterv1.MachineAddress{
@@ -959,7 +910,6 @@ func (s *Service) getInstanceAddresses(instance *ec2.Instance) []clusterv1.Machi
 			addresses = append(addresses, publicDNSAddress, publicIPAddress)
 		}
 	}
-
 	return addresses
 }
 
@@ -1058,54 +1008,6 @@ func (s *Service) ModifyInstanceMetadataOptions(instanceID string, options *infr
 	return nil
 }
 
-// GetDHCPOptionSetDomainName returns the domain DNS name for the VPC from the DHCP Options.
-func (s *Service) GetDHCPOptionSetDomainName(ec2client ec2iface.EC2API, vpcID *string) *string {
-	log := s.scope.GetLogger()
-
-	if vpcID == nil {
-		log.Info("vpcID is nil, skipping DHCP Option Set discovery")
-		return nil
-	}
-
-	vpcInput := &ec2.DescribeVpcsInput{
-		VpcIds: []*string{vpcID},
-	}
-
-	vpcResult, err := ec2client.DescribeVpcs(vpcInput)
-	if err != nil {
-		log.Info("failed to describe VPC, skipping DHCP Option Set discovery", "vpcID", *vpcID, "Error", err.Error())
-		return nil
-	}
-
-	dhcpInput := &ec2.DescribeDhcpOptionsInput{
-		DhcpOptionsIds: []*string{vpcResult.Vpcs[0].DhcpOptionsId},
-	}
-
-	dhcpResult, err := ec2client.DescribeDhcpOptions(dhcpInput)
-	if err != nil {
-		log.Error(err, "failed to describe DHCP Options Set", "DhcpOptionsSet", *dhcpResult)
-		return nil
-	}
-
-	for _, dhcpConfig := range dhcpResult.DhcpOptions[0].DhcpConfigurations {
-		if *dhcpConfig.Key == "domain-name" {
-			if len(dhcpConfig.Values) == 0 {
-				return nil
-			}
-			domainName := dhcpConfig.Values[0].Value
-			// default domainName is 'ec2.internal' in us-east-1 and 'region.compute.internal' in the other regions.
-			if (s.scope.Region() == "us-east-1" && *domainName == "ec2.internal") ||
-				(s.scope.Region() != "us-east-1" && *domainName == fmt.Sprintf("%s.compute.internal", s.scope.Region())) {
-				return nil
-			}
-
-			return domainName
-		}
-	}
-
-	return nil
-}
-
 // filterGroups filters a list for a string.
 func filterGroups(list []string, strToFilter string) (newList []string) {
 	for _, item := range list {
diff --git a/pkg/cloud/services/network/routetables.go b/pkg/cloud/services/network/routetables.go
index 638a87faf..777c12fd6 100644
--- a/pkg/cloud/services/network/routetables.go
+++ b/pkg/cloud/services/network/routetables.go
@@ -214,32 +214,6 @@ func (s *Service) describeVpcRouteTablesBySubnet() (map[string]*ec2.RouteTable,
 	return res, nil
 }
 
-func (s *Service) deleteRouteTable(rt *ec2.RouteTable) error {
-	for _, as := range rt.Associations {
-		if as.SubnetId == nil {
-			continue
-		}
-
-		if _, err := s.EC2Client.DisassociateRouteTableWithContext(context.TODO(), &ec2.DisassociateRouteTableInput{AssociationId: as.RouteTableAssociationId}); err != nil {
-			record.Warnf(s.scope.InfraCluster(), "FailedDisassociateRouteTable", "Failed to disassociate managed RouteTable %q from Subnet %q: %v", *rt.RouteTableId, *as.SubnetId, err)
-			return errors.Wrapf(err, "failed to disassociate route table %q from subnet %q", *rt.RouteTableId, *as.SubnetId)
-		}
-
-		record.Eventf(s.scope.InfraCluster(), "SuccessfulDisassociateRouteTable", "Disassociated managed RouteTable %q from subnet %q", *rt.RouteTableId, *as.SubnetId)
-		s.scope.Debug("Deleted association between route table and subnet", "route-table-id", *rt.RouteTableId, "subnet-id", *as.SubnetId)
-	}
-
-	if _, err := s.EC2Client.DeleteRouteTableWithContext(context.TODO(), &ec2.DeleteRouteTableInput{RouteTableId: rt.RouteTableId}); err != nil {
-		record.Warnf(s.scope.InfraCluster(), "FailedDeleteRouteTable", "Failed to delete managed RouteTable %q: %v", *rt.RouteTableId, err)
-		return errors.Wrapf(err, "failed to delete route table %q", *rt.RouteTableId)
-	}
-
-	record.Eventf(s.scope.InfraCluster(), "SuccessfulDeleteRouteTable", "Deleted managed RouteTable %q", *rt.RouteTableId)
-	s.scope.Info("Deleted route table", "route-table-id", *rt.RouteTableId)
-
-	return nil
-}
-
 func (s *Service) deleteRouteTables() error {
 	if s.scope.VPC().IsUnmanaged(s.scope.Name()) {
 		s.scope.Trace("Skipping routing tables deletion in unmanaged mode")
@@ -252,10 +226,27 @@ func (s *Service) deleteRouteTables() error {
 	}
 
 	for _, rt := range rts {
-		err := s.deleteRouteTable(rt)
-		if err != nil {
-			return err
+		for _, as := range rt.Associations {
+			if as.SubnetId == nil {
+				continue
+			}
+
+			if _, err := s.EC2Client.DisassociateRouteTableWithContext(context.TODO(), &ec2.DisassociateRouteTableInput{AssociationId: as.RouteTableAssociationId}); err != nil {
+				record.Warnf(s.scope.InfraCluster(), "FailedDisassociateRouteTable", "Failed to disassociate managed RouteTable %q from Subnet %q: %v", *rt.RouteTableId, *as.SubnetId, err)
+				return errors.Wrapf(err, "failed to disassociate route table %q from subnet %q", *rt.RouteTableId, *as.SubnetId)
+			}
+
+			record.Eventf(s.scope.InfraCluster(), "SuccessfulDisassociateRouteTable", "Disassociated managed RouteTable %q from subnet %q", *rt.RouteTableId, *as.SubnetId)
+			s.scope.Debug("Deleted association between route table and subnet", "route-table-id", *rt.RouteTableId, "subnet-id", *as.SubnetId)
+		}
+
+		if _, err := s.EC2Client.DeleteRouteTableWithContext(context.TODO(), &ec2.DeleteRouteTableInput{RouteTableId: rt.RouteTableId}); err != nil {
+			record.Warnf(s.scope.InfraCluster(), "FailedDeleteRouteTable", "Failed to delete managed RouteTable %q: %v", *rt.RouteTableId, err)
+			return errors.Wrapf(err, "failed to delete route table %q", *rt.RouteTableId)
 		}
+
+		record.Eventf(s.scope.InfraCluster(), "SuccessfulDeleteRouteTable", "Deleted managed RouteTable %q", *rt.RouteTableId)
+		s.scope.Info("Deleted route table", "route-table-id", *rt.RouteTableId)
 	}
 	return nil
 }
@@ -311,11 +302,8 @@ func (s *Service) createRouteTableWithRoutes(routes []*ec2.Route, isPublic bool,
 			}
 			return true, nil
 		}, awserrors.RouteTableNotFound, awserrors.NATGatewayNotFound, awserrors.GatewayNotFound); err != nil {
+			// TODO(vincepri): cleanup the route table if this fails.
 			record.Warnf(s.scope.InfraCluster(), "FailedCreateRoute", "Failed to create route %s for RouteTable %q: %v", route.GoString(), *out.RouteTable.RouteTableId, err)
-			errDel := s.deleteRouteTable(out.RouteTable)
-			if errDel != nil {
-				record.Warnf(s.scope.InfraCluster(), "FailedDeleteRouteTable", "Failed to delete managed RouteTable %q: %v", *out.RouteTable.RouteTableId, errDel)
-			}
 			return nil, errors.Wrapf(err, "failed to create route in route table %q: %s", *out.RouteTable.RouteTableId, route.GoString())
 		}
 		record.Eventf(s.scope.InfraCluster(), "SuccessfulCreateRoute", "Created route %s for RouteTable %q", route.GoString(), *out.RouteTable.RouteTableId)
diff --git a/pkg/cloud/services/s3/s3.go b/pkg/cloud/services/s3/s3.go
index 7cccebc0f..b6695fd00 100644
--- a/pkg/cloud/services/s3/s3.go
+++ b/pkg/cloud/services/s3/s3.go
@@ -204,9 +204,6 @@ func (s *Service) Delete(m *scope.MachineScope) error {
 
 				s.scope.Debug("Delete object call succeeded despite missing GetObject permission", "bucket", bucket, "key", key)
 
-				return nil
-			case "NotFound":
-				s.scope.Debug("Either bucket or object does not exist", "bucket", bucket, "key", key)
 				return nil
 			case s3.ErrCodeNoSuchKey:
 				s.scope.Debug("Object already deleted", "bucket", bucket, "key", key)
@@ -214,9 +211,10 @@ func (s *Service) Delete(m *scope.MachineScope) error {
 			case s3.ErrCodeNoSuchBucket:
 				s.scope.Debug("Bucket does not exist", "bucket", bucket)
 				return nil
+			default:
+				return errors.Wrap(aerr, "deleting S3 object")
 			}
 		}
-		return errors.Wrap(err, "deleting S3 object")
 	}
 
 	s.scope.Info("Deleting S3 object", "bucket", bucket, "key", key)
diff --git a/pkg/cloud/services/secretsmanager/secret_fetch_script.go b/pkg/cloud/services/secretsmanager/secret_fetch_script.go
index 4e3f09e8f..d7d4accbe 100644
--- a/pkg/cloud/services/secretsmanager/secret_fetch_script.go
+++ b/pkg/cloud/services/secretsmanager/secret_fetch_script.go
@@ -48,8 +48,6 @@ SECRET_PREFIX="{{.SecretPrefix}}"
 CHUNKS="{{.Chunks}}"
 FILE="/etc/secret-userdata.txt"
 FINAL_INDEX=$((CHUNKS - 1))
-MAX_RETRIES=10
-RETRY_DELAY=10 # in seconds
 
 # Log an error and exit.
 # Args:
@@ -117,7 +115,6 @@ check_aws_command() {
     ;;
   esac
 }
-
 delete_secret_value() {
   local id="${SECRET_PREFIX}-${1}"
   local out
@@ -129,27 +126,19 @@ delete_secret_value() {
     aws secretsmanager ${ENDPOINT} --region ${REGION} delete-secret --force-delete-without-recovery --secret-id "${id}" 2>&1
   )
   local delete_return=$?
+  set -o errexit
+  set -o nounset
+  set -o pipefail
   check_aws_command "SecretsManager::DeleteSecret" "${delete_return}" "${out}"
   if [ ${delete_return} -ne 0 ]; then
-    log::error "Could not delete secret value"
-    return 1
+    log::error_exit "Could not delete secret value" 2
   fi
 }
 
-retry_delete_secret_value() {
-  local retries=0
-  while [ ${retries} -lt ${MAX_RETRIES} ]; do
-    delete_secret_value "$1"
-    local return_code=$?
-    if [ ${return_code} -eq 0 ]; then
-      return 0
-    else
-      ((retries++))
-      log::info "Retrying in ${RETRY_DELAY} seconds..."
-      sleep ${RETRY_DELAY}
-    fi
+delete_secrets() {
+  for i in $(seq 0 ${FINAL_INDEX}); do
+    delete_secret_value "$i"
   done
-  return 1
 }
 
 get_secret_value() {
@@ -170,33 +159,18 @@ get_secret_value() {
   )
   local get_return=$?
   check_aws_command "SecretsManager::GetSecretValue" "${get_return}" "${data}"
-  if [ ${get_return} -ne 0 ]; then
-    log::error "could not get secret value"
-    return 1
-  fi
   set -o errexit
   set -o nounset
   set -o pipefail
+  if [ ${get_return} -ne 0 ]; then
+    log::error "could not get secret value, deleting secret"
+    delete_secrets
+    log::error_exit "could not get secret value, but secret was deleted" 1
+  fi
   log::info "appending data to temporary file ${FILE}.gz"
   echo "${data}" | base64 -d >>${FILE}.gz
 }
 
-retry_get_secret_value() {
-  local retries=0
-  while [ ${retries} -lt ${MAX_RETRIES} ]; do
-    get_secret_value "$1"
-    local return_code=$?
-    if [ ${return_code} -eq 0 ]; then
-      return 0
-    else
-      ((retries++))
-      log::info "Retrying in ${RETRY_DELAY} seconds..."
-      sleep ${RETRY_DELAY}
-    fi
-  done
-  return 1
-}
-
 log::info "aws.cluster.x-k8s.io encrypted cloud-init script $0 started"
 log::info "secret prefix: ${SECRET_PREFIX}"
 log::info "secret count: ${CHUNKS}"
@@ -207,21 +181,10 @@ if test -f "${FILE}"; then
 fi
 
 for i in $(seq 0 "${FINAL_INDEX}"); do
-  retry_get_secret_value "$i"
-  return_code=$?
-  if [ ${return_code} -ne 0 ]; then
-    log::error "Failed to get secret value after ${MAX_RETRIES} attempts"
-  fi
+  get_secret_value "$i"
 done
 
-for i in $(seq 0 ${FINAL_INDEX}); do
-  retry_delete_secret_value "$i"
-  return_code=$?
-  if [ ${return_code} -ne 0 ]; then
-    log::error "Failed to delete secret value after ${MAX_RETRIES} attempts"
-    log::error_exit "couldn't delete the secret value, exiting" 1
-  fi
-done
+delete_secrets
 
 log::info "decompressing userdata to ${FILE}"
 gunzip "${FILE}.gz"
diff --git a/pkg/cloud/services/securitygroup/securitygroups.go b/pkg/cloud/services/securitygroup/securitygroups.go
index bce3a50ed..b6e9bcabc 100644
--- a/pkg/cloud/services/securitygroup/securitygroups.go
+++ b/pkg/cloud/services/securitygroup/securitygroups.go
@@ -660,15 +660,10 @@ func (s *Service) getSecurityGroupIngressRules(role infrav1.SecurityGroupRole) (
 		rulesToApply := customIngressRules.Difference(kubeletRules)
 		return append(kubeletRules, rulesToApply...), nil
 	case infrav1.SecurityGroupLB:
-		rules := infrav1.IngressRules{}
-		allowedNLBTraffic := false
 		// We hand this group off to the in-cluster cloud provider, so these rules aren't used
 		// Except if the load balancer type is NLB, and we have an AWS Cluster in which case we
 		// need to open port 6443 to the NLB traffic and health check inside the VPC.
-		for _, lb := range s.scope.ControlPlaneLoadBalancers() {
-			if lb == nil || lb.LoadBalancerType != infrav1.LoadBalancerTypeNLB {
-				continue
-			}
+		if s.scope.ControlPlaneLoadBalancer() != nil && s.scope.ControlPlaneLoadBalancer().LoadBalancerType == infrav1.LoadBalancerTypeNLB {
 			var (
 				ipv4CidrBlocks []string
 				ipv6CidrBlocks []string
@@ -678,26 +673,25 @@ func (s *Service) getSecurityGroupIngressRules(role infrav1.SecurityGroupRole) (
 			if s.scope.VPC().IsIPv6Enabled() {
 				ipv6CidrBlocks = []string{s.scope.VPC().IPv6.CidrBlock}
 			}
-			if lb.PreserveClientIP {
+			if s.scope.ControlPlaneLoadBalancer().PreserveClientIP {
 				ipv4CidrBlocks = []string{services.AnyIPv4CidrBlock}
 				if s.scope.VPC().IsIPv6Enabled() {
 					ipv6CidrBlocks = []string{services.AnyIPv6CidrBlock}
 				}
 			}
 
-			if !allowedNLBTraffic {
-				rules = append(rules, infrav1.IngressRule{
+			rules := infrav1.IngressRules{
+				{
 					Description:    "Allow NLB traffic to the control plane instances.",
 					Protocol:       infrav1.SecurityGroupProtocolTCP,
 					FromPort:       int64(s.scope.APIServerPort()),
 					ToPort:         int64(s.scope.APIServerPort()),
 					CidrBlocks:     ipv4CidrBlocks,
 					IPv6CidrBlocks: ipv6CidrBlocks,
-				})
-				allowedNLBTraffic = true
+				},
 			}
 
-			for _, ln := range lb.AdditionalListeners {
+			for _, ln := range s.scope.ControlPlaneLoadBalancer().AdditionalListeners {
 				rules = append(rules, infrav1.IngressRule{
 					Description:    fmt.Sprintf("Allow NLB traffic to the control plane instances on port %d.", ln.Port),
 					Protocol:       infrav1.SecurityGroupProtocolTCP,
@@ -707,8 +701,10 @@ func (s *Service) getSecurityGroupIngressRules(role infrav1.SecurityGroupRole) (
 					IPv6CidrBlocks: ipv6CidrBlocks,
 				})
 			}
+
+			return rules, nil
 		}
-		return rules, nil
+		return infrav1.IngressRules{}, nil
 	}
 
 	return nil, errors.Errorf("Cannot determine ingress rules for unknown security group role %q", role)
@@ -919,14 +915,8 @@ func (s *Service) getIngressRulesToAllowKubeletToAccessTheControlPlaneLB() infra
 // getControlPlaneLBIngressRules returns the ingress rules for the control plane LB.
 // We allow all traffic when no other rules are defined.
 func (s *Service) getControlPlaneLBIngressRules() infrav1.IngressRules {
-	ingressRules := infrav1.IngressRules{}
-	for _, lb := range s.scope.ControlPlaneLoadBalancers() {
-		if lb != nil && len(lb.IngressRules) > 0 {
-			ingressRules = append(ingressRules, lb.IngressRules...)
-		}
-	}
-	if len(ingressRules) > 0 {
-		return ingressRules
+	if s.scope.ControlPlaneLoadBalancer() != nil && len(s.scope.ControlPlaneLoadBalancer().IngressRules) > 0 {
+		return s.scope.ControlPlaneLoadBalancer().IngressRules
 	}
 
 	// If no custom ingress rules have been defined we allow all traffic so that the MC can access the WC API


Test patch:
diff --git a/controllers/awsmachine_controller_test.go b/controllers/awsmachine_controller_test.go
index 52f4025d5..01122cad0 100644
--- a/controllers/awsmachine_controller_test.go
+++ b/controllers/awsmachine_controller_test.go
@@ -114,10 +114,6 @@ func TestAWSMachineReconcilerIntegrationTests(t *testing.T) {
 		}}})
 		g.Expect(err).To(BeNil())
 		cs.Cluster = &clusterv1.Cluster{ObjectMeta: metav1.ObjectMeta{Name: "test-cluster"}}
-		cs.AWSCluster.Spec.NetworkSpec.VPC = infrav1.VPCSpec{
-			ID:        "vpc-exists",
-			CidrBlock: "10.0.0.0/16",
-		}
 		cs.AWSCluster.Status.Network.APIServerELB.DNSName = DNSName
 		cs.AWSCluster.Spec.ControlPlaneLoadBalancer = &infrav1.AWSLoadBalancerSpec{
 			LoadBalancerType: infrav1.LoadBalancerTypeClassic,
@@ -287,10 +283,6 @@ func TestAWSMachineReconcilerIntegrationTests(t *testing.T) {
 		g.Expect(err).To(BeNil())
 		cs.Cluster = &clusterv1.Cluster{ObjectMeta: metav1.ObjectMeta{Name: "test-cluster"}}
 		cs.AWSCluster.Status.Network.APIServerELB.DNSName = DNSName
-		cs.AWSCluster.Spec.NetworkSpec.VPC = infrav1.VPCSpec{
-			ID:        "vpc-exists",
-			CidrBlock: "10.0.0.0/16",
-		}
 		cs.AWSCluster.Spec.ControlPlaneLoadBalancer = &infrav1.AWSLoadBalancerSpec{
 			LoadBalancerType: infrav1.LoadBalancerTypeClassic,
 		}
diff --git a/pkg/cloud/scope/shared_test.go b/pkg/cloud/scope/shared_test.go
index 34d124abf..8afc051c6 100644
--- a/pkg/cloud/scope/shared_test.go
+++ b/pkg/cloud/scope/shared_test.go
@@ -182,6 +182,14 @@ func TestSubnetPlacement(t *testing.T) {
 					AvailabilityZone: "eu-west-1c",
 					IsPublic:         false,
 				},
+				infrav1.SubnetSpec{
+					ID:               "subnet-az6",
+					AvailabilityZone: "eu-west-1c",
+					IsPublic:         false,
+					Tags: infrav1.Tags{
+						infrav1.NameAWSSubnetAssociation: infrav1.SecondarySubnetTagValue,
+					},
+				},
 			},
 			logger:            logger.NewLogger(klog.Background()),
 			expectedSubnetIDs: []string{"subnet-az3"},
diff --git a/pkg/cloud/services/ec2/instances_test.go b/pkg/cloud/services/ec2/instances_test.go
index e87ac6c9c..f68e4a5f5 100644
--- a/pkg/cloud/services/ec2/instances_test.go
+++ b/pkg/cloud/services/ec2/instances_test.go
@@ -28,7 +28,6 @@ import (
 	"github.com/aws/aws-sdk-go/service/ec2"
 	"github.com/golang/mock/gomock"
 	"github.com/google/go-cmp/cmp"
-	. "github.com/onsi/gomega"
 	"github.com/pkg/errors"
 	corev1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -336,9 +335,6 @@ func TestCreateInstance(t *testing.T) {
 								IsPublic: false,
 							},
 						},
-						VPC: infrav1.VPCSpec{
-							ID: "vpc-test",
-						},
 					},
 				},
 				Status: infrav1.AWSClusterStatus{
@@ -466,9 +462,6 @@ func TestCreateInstance(t *testing.T) {
 								IsPublic:         true,
 							},
 						},
-						VPC: infrav1.VPCSpec{
-							ID: "vpc-test",
-						},
 					},
 				},
 				Status: infrav1.AWSClusterStatus{
@@ -980,9 +973,6 @@ func TestCreateInstance(t *testing.T) {
 								IsPublic: false,
 							},
 						},
-						VPC: infrav1.VPCSpec{
-							ID: "vpc-test",
-						},
 					},
 				},
 				Status: infrav1.AWSClusterStatus{
@@ -1132,9 +1122,6 @@ func TestCreateInstance(t *testing.T) {
 								IsPublic: false,
 							},
 						},
-						VPC: infrav1.VPCSpec{
-							ID: "vpc-test",
-						},
 					},
 					ImageLookupOrg: "cluster-level-image-lookup-org",
 				},
@@ -1286,9 +1273,6 @@ func TestCreateInstance(t *testing.T) {
 								IsPublic: false,
 							},
 						},
-						VPC: infrav1.VPCSpec{
-							ID: "vpc-test",
-						},
 					},
 					ImageLookupOrg: "cluster-level-image-lookup-org",
 				},
@@ -2129,161 +2113,6 @@ func TestCreateInstance(t *testing.T) {
 							MapPublicIpOnLaunch: aws.Bool(true),
 						}},
 					}, nil)
-				m.
-					DescribeSubnetsWithContext(context.TODO(), &ec2.DescribeSubnetsInput{
-						Filters: []*ec2.Filter{
-							{Name: aws.String("subnet-id"), Values: aws.StringSlice([]string{"public-subnet-1"})},
-						},
-					}).
-					Return(&ec2.DescribeSubnetsOutput{
-						Subnets: []*ec2.Subnet{{
-							SubnetId:            aws.String("public-subnet-1"),
-							AvailabilityZone:    aws.String("us-east-1b"),
-							MapPublicIpOnLaunch: aws.Bool(true),
-						}},
-					}, nil)
-				m.
-					DescribeInstanceTypesWithContext(context.TODO(), gomock.Eq(&ec2.DescribeInstanceTypesInput{
-						InstanceTypes: []*string{
-							aws.String("m5.large"),
-						},
-					})).
-					Return(&ec2.DescribeInstanceTypesOutput{
-						InstanceTypes: []*ec2.InstanceTypeInfo{
-							{
-								ProcessorInfo: &ec2.ProcessorInfo{
-									SupportedArchitectures: []*string{
-										aws.String("x86_64"),
-									},
-								},
-							},
-						},
-					}, nil)
-				m.
-					RunInstancesWithContext(context.TODO(), gomock.Any()).
-					Return(&ec2.Reservation{
-						Instances: []*ec2.Instance{
-							{
-								State: &ec2.InstanceState{
-									Name: aws.String(ec2.InstanceStateNamePending),
-								},
-								IamInstanceProfile: &ec2.IamInstanceProfile{
-									Arn: aws.String("arn:aws:iam::123456789012:instance-profile/foo"),
-								},
-								InstanceId:     aws.String("two"),
-								InstanceType:   aws.String("m5.large"),
-								SubnetId:       aws.String("public-subnet-1"),
-								ImageId:        aws.String("ami-1"),
-								RootDeviceName: aws.String("device-1"),
-								BlockDeviceMappings: []*ec2.InstanceBlockDeviceMapping{
-									{
-										DeviceName: aws.String("device-1"),
-										Ebs: &ec2.EbsInstanceBlockDevice{
-											VolumeId: aws.String("volume-1"),
-										},
-									},
-								},
-								Placement: &ec2.Placement{
-									AvailabilityZone: &az,
-								},
-							},
-						},
-					}, nil)
-				m.
-					DescribeNetworkInterfacesWithContext(context.TODO(), gomock.Any()).
-					Return(&ec2.DescribeNetworkInterfacesOutput{
-						NetworkInterfaces: []*ec2.NetworkInterface{},
-						NextToken:         nil,
-					}, nil)
-			},
-			check: func(instance *infrav1.Instance, err error) {
-				if err != nil {
-					t.Fatalf("did not expect error: %v", err)
-				}
-			},
-		},
-		{
-			name: "public IP true, public subnet ID given and MapPublicIpOnLaunch is false",
-			machine: &clusterv1.Machine{
-				ObjectMeta: metav1.ObjectMeta{
-					Labels: map[string]string{"set": "node"},
-				},
-				Spec: clusterv1.MachineSpec{
-					Bootstrap: clusterv1.Bootstrap{
-						DataSecretName: ptr.To[string]("bootstrap-data"),
-					},
-				},
-			},
-			machineConfig: &infrav1.AWSMachineSpec{
-				AMI: infrav1.AMIReference{
-					ID: aws.String("abc"),
-				},
-				InstanceType: "m5.large",
-				Subnet: &infrav1.AWSResourceReference{
-					ID: aws.String("public-subnet-1"),
-				},
-				PublicIP: aws.Bool(true),
-			},
-			awsCluster: &infrav1.AWSCluster{
-				ObjectMeta: metav1.ObjectMeta{Name: "test"},
-				Spec: infrav1.AWSClusterSpec{
-					NetworkSpec: infrav1.NetworkSpec{
-						VPC: infrav1.VPCSpec{
-							ID: "vpc-id",
-						},
-						Subnets: infrav1.Subnets{{
-							ID:       "public-subnet-1",
-							IsPublic: true,
-						}},
-					},
-				},
-				Status: infrav1.AWSClusterStatus{
-					Network: infrav1.NetworkStatus{
-						SecurityGroups: map[infrav1.SecurityGroupRole]infrav1.SecurityGroup{
-							infrav1.SecurityGroupControlPlane: {
-								ID: "1",
-							},
-							infrav1.SecurityGroupNode: {
-								ID: "2",
-							},
-							infrav1.SecurityGroupLB: {
-								ID: "3",
-							},
-						},
-						APIServerELB: infrav1.LoadBalancer{
-							DNSName: "test-apiserver.us-east-1.aws",
-						},
-					},
-				},
-			},
-			expect: func(m *mocks.MockEC2APIMockRecorder) {
-				m.
-					DescribeSubnetsWithContext(context.TODO(), &ec2.DescribeSubnetsInput{
-						Filters: []*ec2.Filter{
-							filter.EC2.SubnetStates(ec2.SubnetStatePending, ec2.SubnetStateAvailable),
-							{Name: aws.String("subnet-id"), Values: aws.StringSlice([]string{"public-subnet-1"})},
-						},
-					}).
-					Return(&ec2.DescribeSubnetsOutput{
-						Subnets: []*ec2.Subnet{{
-							SubnetId:            aws.String("public-subnet-1"),
-							AvailabilityZone:    aws.String("us-east-1b"),
-							MapPublicIpOnLaunch: aws.Bool(false),
-						}},
-					}, nil)
-				m.
-					DescribeSubnetsWithContext(context.TODO(), &ec2.DescribeSubnetsInput{
-						Filters: []*ec2.Filter{
-							{Name: aws.String("subnet-id"), Values: aws.StringSlice([]string{"public-subnet-1"})},
-						},
-					}).
-					Return(&ec2.DescribeSubnetsOutput{
-						Subnets: []*ec2.Subnet{{
-							SubnetId:            aws.String("public-subnet-1"),
-							AvailabilityZone:    aws.String("us-east-1b"),
-							MapPublicIpOnLaunch: aws.Bool(false),
-						}},
-					}, nil)
 				m.
 					DescribeInstanceTypesWithContext(context.TODO(), gomock.Eq(&ec2.DescribeInstanceTypesInput{
 						InstanceTypes: []*string{
@@ -2303,20 +2132,6 @@ func TestCreateInstance(t *testing.T) {
 					}, nil)
 				m.
 					RunInstancesWithContext(context.TODO(), gomock.Any()).
-					Do(func(_ context.Context, in *ec2.RunInstancesInput, _ ...request.Option) {
-						if len(in.NetworkInterfaces) == 0 {
-							t.Fatalf("expected a NetworkInterface to be defined")
-						}
-						if !aws.BoolValue(in.NetworkInterfaces[0].AssociatePublicIpAddress) {
-							t.Fatalf("expected AssociatePublicIpAddress to be set and true")
-						}
-						if subnet := aws.StringValue(in.NetworkInterfaces[0].SubnetId); subnet != "public-subnet-1" {
-							t.Fatalf("expected subnet ID to be \"public-subnet-1\", got %q", subnet)
-						}
-						if in.NetworkInterfaces[0].Groups == nil {
-							t.Fatalf("expected security groups to be set")
-						}
-					}).
 					Return(&ec2.Reservation{
 						Instances: []*ec2.Instance{
 							{
@@ -2546,19 +2361,7 @@ func TestCreateInstance(t *testing.T) {
 					}).
 					Return(&ec2.DescribeSubnetsOutput{
 						Subnets: []*ec2.Subnet{{
-							SubnetId:            aws.String("public-subnet-1"),
-							MapPublicIpOnLaunch: aws.Bool(true),
-						}},
-					}, nil)
-				m.
-					DescribeSubnetsWithContext(context.TODO(), &ec2.DescribeSubnetsInput{
-						Filters: []*ec2.Filter{
-							{Name: aws.String("subnet-id"), Values: aws.StringSlice([]string{"public-subnet-1"})},
-						},
-					}).
-					Return(&ec2.DescribeSubnetsOutput{
-						Subnets: []*ec2.Subnet{{
-							SubnetId:            aws.String("public-subnet-1"),
+							SubnetId:            aws.String("filtered-subnet-1"),
 							MapPublicIpOnLaunch: aws.Bool(true),
 						}},
 					}, nil)
@@ -2606,7 +2409,7 @@ func TestCreateInstance(t *testing.T) {
 			},
 		},
 		{
-			name: "both public IP, subnet filter defined and MapPublicIpOnLaunch is false",
+			name: "public IP true and public subnet exists",
 			machine: &clusterv1.Machine{
 				ObjectMeta: metav1.ObjectMeta{
 					Labels: map[string]string{"set": "node"},
@@ -2622,13 +2425,7 @@ func TestCreateInstance(t *testing.T) {
 					ID: aws.String("abc"),
 				},
 				InstanceType: "m5.large",
-				Subnet: &infrav1.AWSResourceReference{
-					Filters: []infrav1.Filter{{
-						Name:   "tag:some-tag",
-						Values: []string{"some-value"},
-					}},
-				},
-				PublicIP: aws.Bool(true),
+				PublicIP:     aws.Bool(true),
 			},
 			awsCluster: &infrav1.AWSCluster{
 				ObjectMeta: metav1.ObjectMeta{Name: "test"},
@@ -2686,47 +2483,8 @@ func TestCreateInstance(t *testing.T) {
 							},
 						},
 					}, nil)
-				m.
-					DescribeSubnetsWithContext(context.TODO(), &ec2.DescribeSubnetsInput{
-						Filters: []*ec2.Filter{
-							filter.EC2.SubnetStates(ec2.SubnetStatePending, ec2.SubnetStateAvailable),
-							{Name: aws.String("tag:some-tag"), Values: aws.StringSlice([]string{"some-value"})},
-						},
-					}).
-					Return(&ec2.DescribeSubnetsOutput{
-						Subnets: []*ec2.Subnet{{
-							SubnetId:            aws.String("public-subnet-1"),
-							MapPublicIpOnLaunch: aws.Bool(false),
-						}},
-					}, nil)
-				m.
-					DescribeSubnetsWithContext(context.TODO(), &ec2.DescribeSubnetsInput{
-						Filters: []*ec2.Filter{
-							{Name: aws.String("subnet-id"), Values: aws.StringSlice([]string{"public-subnet-1"})},
-						},
-					}).
-					Return(&ec2.DescribeSubnetsOutput{
-						Subnets: []*ec2.Subnet{{
-							SubnetId:            aws.String("public-subnet-1"),
-							MapPublicIpOnLaunch: aws.Bool(false),
-						}},
-					}, nil)
 				m.
 					RunInstancesWithContext(context.TODO(), gomock.Any()).
-					Do(func(_ context.Context, in *ec2.RunInstancesInput, _ ...request.Option) {
-						if len(in.NetworkInterfaces) == 0 {
-							t.Fatalf("expected a NetworkInterface to be defined")
-						}
-						if !aws.BoolValue(in.NetworkInterfaces[0].AssociatePublicIpAddress) {
-							t.Fatalf("expected AssociatePublicIpAddress to be set and true")
-						}
-						if subnet := aws.StringValue(in.NetworkInterfaces[0].SubnetId); subnet != "public-subnet-1" {
-							t.Fatalf("expected subnet ID to be \"public-subnet-1\", got %q", subnet)
-						}
-						if in.NetworkInterfaces[0].Groups == nil {
-							t.Fatalf("expected security groups to be set")
-						}
-					}).
 					Return(&ec2.Reservation{
 						Instances: []*ec2.Instance{
 							{
@@ -2769,281 +2527,7 @@ func TestCreateInstance(t *testing.T) {
 			},
 		},
 		{
-			name: "public IP true and public subnet exists",
-			machine: &clusterv1.Machine{
-				ObjectMeta: metav1.ObjectMeta{
-					Labels: map[string]string{"set": "node"},
-				},
-				Spec: clusterv1.MachineSpec{
-					Bootstrap: clusterv1.Bootstrap{
-						DataSecretName: ptr.To[string]("bootstrap-data"),
-					},
-				},
-			},
-			machineConfig: &infrav1.AWSMachineSpec{
-				AMI: infrav1.AMIReference{
-					ID: aws.String("abc"),
-				},
-				InstanceType: "m5.large",
-				PublicIP:     aws.Bool(true),
-			},
-			awsCluster: &infrav1.AWSCluster{
-				ObjectMeta: metav1.ObjectMeta{Name: "test"},
-				Spec: infrav1.AWSClusterSpec{
-					NetworkSpec: infrav1.NetworkSpec{
-						VPC: infrav1.VPCSpec{
-							ID: "vpc-id",
-						},
-						Subnets: infrav1.Subnets{
-							infrav1.SubnetSpec{
-								ID:       "private-subnet-1",
-								IsPublic: false,
-							},
-							infrav1.SubnetSpec{
-								ID:       "public-subnet-1",
-								IsPublic: true,
-							},
-						},
-					},
-				},
-				Status: infrav1.AWSClusterStatus{
-					Network: infrav1.NetworkStatus{
-						SecurityGroups: map[infrav1.SecurityGroupRole]infrav1.SecurityGroup{
-							infrav1.SecurityGroupControlPlane: {
-								ID: "1",
-							},
-							infrav1.SecurityGroupNode: {
-								ID: "2",
-							},
-							infrav1.SecurityGroupLB: {
-								ID: "3",
-							},
-						},
-						APIServerELB: infrav1.LoadBalancer{
-							DNSName: "test-apiserver.us-east-1.aws",
-						},
-					},
-				},
-			},
-			expect: func(m *mocks.MockEC2APIMockRecorder) {
-				m.
-					DescribeInstanceTypesWithContext(context.TODO(), gomock.Eq(&ec2.DescribeInstanceTypesInput{
-						InstanceTypes: []*string{
-							aws.String("m5.large"),
-						},
-					})).
-					Return(&ec2.DescribeInstanceTypesOutput{
-						InstanceTypes: []*ec2.InstanceTypeInfo{
-							{
-								ProcessorInfo: &ec2.ProcessorInfo{
-									SupportedArchitectures: []*string{
-										aws.String("x86_64"),
-									},
-								},
-							},
-						},
-					}, nil)
-				m.
-					DescribeSubnetsWithContext(context.TODO(), &ec2.DescribeSubnetsInput{
-						Filters: []*ec2.Filter{
-							{Name: aws.String("subnet-id"), Values: aws.StringSlice([]string{"public-subnet-1"})},
-						},
-					}).
-					Return(&ec2.DescribeSubnetsOutput{
-						Subnets: []*ec2.Subnet{{
-							SubnetId:            aws.String("public-subnet-1"),
-							MapPublicIpOnLaunch: aws.Bool(true),
-						}},
-					}, nil)
-				m.
-					RunInstancesWithContext(context.TODO(), gomock.Any()).
-					Return(&ec2.Reservation{
-						Instances: []*ec2.Instance{
-							{
-								State: &ec2.InstanceState{
-									Name: aws.String(ec2.InstanceStateNamePending),
-								},
-								IamInstanceProfile: &ec2.IamInstanceProfile{
-									Arn: aws.String("arn:aws:iam::123456789012:instance-profile/foo"),
-								},
-								InstanceId:     aws.String("two"),
-								InstanceType:   aws.String("m5.large"),
-								SubnetId:       aws.String("public-subnet-1"),
-								ImageId:        aws.String("ami-1"),
-								RootDeviceName: aws.String("device-1"),
-								BlockDeviceMappings: []*ec2.InstanceBlockDeviceMapping{
-									{
-										DeviceName: aws.String("device-1"),
-										Ebs: &ec2.EbsInstanceBlockDevice{
-											VolumeId: aws.String("volume-1"),
-										},
-									},
-								},
-								Placement: &ec2.Placement{
-									AvailabilityZone: &az,
-								},
-							},
-						},
-					}, nil)
-				m.
-					DescribeNetworkInterfacesWithContext(context.TODO(), gomock.Any()).
-					Return(&ec2.DescribeNetworkInterfacesOutput{
-						NetworkInterfaces: []*ec2.NetworkInterface{},
-						NextToken:         nil,
-					}, nil)
-			},
-			check: func(instance *infrav1.Instance, err error) {
-				if err != nil {
-					t.Fatalf("did not expect error: %v", err)
-				}
-			},
-		},
-		{
-			name: "public IP true, public subnet exists and MapPublicIpOnLaunch is false",
-			machine: &clusterv1.Machine{
-				ObjectMeta: metav1.ObjectMeta{
-					Labels: map[string]string{"set": "node"},
-				},
-				Spec: clusterv1.MachineSpec{
-					Bootstrap: clusterv1.Bootstrap{
-						DataSecretName: ptr.To[string]("bootstrap-data"),
-					},
-				},
-			},
-			machineConfig: &infrav1.AWSMachineSpec{
-				AMI: infrav1.AMIReference{
-					ID: aws.String("abc"),
-				},
-				InstanceType: "m5.large",
-				PublicIP:     aws.Bool(true),
-			},
-			awsCluster: &infrav1.AWSCluster{
-				ObjectMeta: metav1.ObjectMeta{Name: "test"},
-				Spec: infrav1.AWSClusterSpec{
-					NetworkSpec: infrav1.NetworkSpec{
-						VPC: infrav1.VPCSpec{
-							ID: "vpc-id",
-						},
-						Subnets: infrav1.Subnets{
-							infrav1.SubnetSpec{
-								ID:       "private-subnet-1",
-								IsPublic: false,
-							},
-							infrav1.SubnetSpec{
-								ID:       "public-subnet-1",
-								IsPublic: true,
-							},
-						},
-					},
-				},
-				Status: infrav1.AWSClusterStatus{
-					Network: infrav1.NetworkStatus{
-						SecurityGroups: map[infrav1.SecurityGroupRole]infrav1.SecurityGroup{
-							infrav1.SecurityGroupControlPlane: {
-								ID: "1",
-							},
-							infrav1.SecurityGroupNode: {
-								ID: "2",
-							},
-							infrav1.SecurityGroupLB: {
-								ID: "3",
-							},
-						},
-						APIServerELB: infrav1.LoadBalancer{
-							DNSName: "test-apiserver.us-east-1.aws",
-						},
-					},
-				},
-			},
-			expect: func(m *mocks.MockEC2APIMockRecorder) {
-				m.
-					DescribeInstanceTypesWithContext(context.TODO(), gomock.Eq(&ec2.DescribeInstanceTypesInput{
-						InstanceTypes: []*string{
-							aws.String("m5.large"),
-						},
-					})).
-					Return(&ec2.DescribeInstanceTypesOutput{
-						InstanceTypes: []*ec2.InstanceTypeInfo{
-							{
-								ProcessorInfo: &ec2.ProcessorInfo{
-									SupportedArchitectures: []*string{
-										aws.String("x86_64"),
-									},
-								},
-							},
-						},
-					}, nil)
-				m.
-					DescribeSubnetsWithContext(context.TODO(), &ec2.DescribeSubnetsInput{
-						Filters: []*ec2.Filter{
-							{Name: aws.String("subnet-id"), Values: aws.StringSlice([]string{"public-subnet-1"})},
-						},
-					}).
-					Return(&ec2.DescribeSubnetsOutput{
-						Subnets: []*ec2.Subnet{{
-							SubnetId:            aws.String("public-subnet-1"),
-							MapPublicIpOnLaunch: aws.Bool(false),
-						}},
-					}, nil)
-				m.
-					RunInstancesWithContext(context.TODO(), gomock.Any()).
-					Do(func(_ context.Context, in *ec2.RunInstancesInput, _ ...request.Option) {
-						if len(in.NetworkInterfaces) == 0 {
-							t.Fatalf("expected a NetworkInterface to be defined")
-						}
-						if !aws.BoolValue(in.NetworkInterfaces[0].AssociatePublicIpAddress) {
-							t.Fatalf("expected AssociatePublicIpAddress to be set and true")
-						}
-						if subnet := aws.StringValue(in.NetworkInterfaces[0].SubnetId); subnet != "public-subnet-1" {
-							t.Fatalf("expected subnet ID to be \"public-subnet-1\", got %q", subnet)
-						}
-						if in.NetworkInterfaces[0].Groups == nil {
-							t.Fatalf("expected security groups to be set")
-						}
-					}).
-					Return(&ec2.Reservation{
-						Instances: []*ec2.Instance{
-							{
-								State: &ec2.InstanceState{
-									Name: aws.String(ec2.InstanceStateNamePending),
-								},
-								IamInstanceProfile: &ec2.IamInstanceProfile{
-									Arn: aws.String("arn:aws:iam::123456789012:instance-profile/foo"),
-								},
-								InstanceId:     aws.String("two"),
-								InstanceType:   aws.String("m5.large"),
-								SubnetId:       aws.String("public-subnet-1"),
-								ImageId:        aws.String("ami-1"),
-								RootDeviceName: aws.String("device-1"),
-								BlockDeviceMappings: []*ec2.InstanceBlockDeviceMapping{
-									{
-										DeviceName: aws.String("device-1"),
-										Ebs: &ec2.EbsInstanceBlockDevice{
-											VolumeId: aws.String("volume-1"),
-										},
-									},
-								},
-								Placement: &ec2.Placement{
-									AvailabilityZone: &az,
-								},
-							},
-						},
-					}, nil)
-				m.
-					DescribeNetworkInterfacesWithContext(context.TODO(), gomock.Any()).
-					Return(&ec2.DescribeNetworkInterfacesOutput{
-						NetworkInterfaces: []*ec2.NetworkInterface{},
-						NextToken:         nil,
-					}, nil)
-			},
-			check: func(instance *infrav1.Instance, err error) {
-				if err != nil {
-					t.Fatalf("did not expect error: %v", err)
-				}
-			},
-		},
-		{
-			name: "public IP true and no public subnet exists",
+			name: "public IP true and no public subnet exists",
 			machine: &clusterv1.Machine{
 				ObjectMeta: metav1.ObjectMeta{
 					Labels: map[string]string{"set": "node"},
@@ -3160,9 +2644,6 @@ func TestCreateInstance(t *testing.T) {
 								IsPublic: false,
 							},
 						},
-						VPC: infrav1.VPCSpec{
-							ID: "vpc-test",
-						},
 					},
 				},
 				Status: infrav1.AWSClusterStatus{
@@ -3285,9 +2766,6 @@ func TestCreateInstance(t *testing.T) {
 								IsPublic: false,
 							},
 						},
-						VPC: infrav1.VPCSpec{
-							ID: "vpc-test",
-						},
 					},
 				},
 				Status: infrav1.AWSClusterStatus{
@@ -3444,9 +2922,6 @@ func TestCreateInstance(t *testing.T) {
 								IsPublic: false,
 							},
 						},
-						VPC: infrav1.VPCSpec{
-							ID: "vpc-test",
-						},
 					},
 				},
 				Status: infrav1.AWSClusterStatus{
@@ -3606,9 +3081,6 @@ func TestCreateInstance(t *testing.T) {
 								IsPublic: false,
 							},
 						},
-						VPC: infrav1.VPCSpec{
-							ID: "vpc-test",
-						},
 					},
 				},
 				Status: infrav1.AWSClusterStatus{
@@ -3688,290 +3160,47 @@ func TestCreateInstance(t *testing.T) {
 								},
 							},
 						},
-						UserData: aws.String(base64.StdEncoding.EncodeToString(data)),
-					})).
-					Return(&ec2.Reservation{
-						Instances: []*ec2.Instance{
-							{
-								State: &ec2.InstanceState{
-									Name: aws.String(ec2.InstanceStateNamePending),
-								},
-								IamInstanceProfile: &ec2.IamInstanceProfile{
-									Arn: aws.String("arn:aws:iam::123456789012:instance-profile/foo"),
-								},
-								InstanceId:     aws.String("two"),
-								InstanceType:   aws.String("m5.large"),
-								SubnetId:       aws.String("subnet-1"),
-								ImageId:        aws.String("ami-1"),
-								RootDeviceName: aws.String("device-1"),
-								BlockDeviceMappings: []*ec2.InstanceBlockDeviceMapping{
-									{
-										DeviceName: aws.String("device-1"),
-										Ebs: &ec2.EbsInstanceBlockDevice{
-											VolumeId: aws.String("volume-1"),
-										},
-									},
-								},
-								Placement: &ec2.Placement{
-									AvailabilityZone: &az,
-									Tenancy:          &tenancy,
-								},
-							},
-						},
-					}, nil)
-				m.
-					DescribeNetworkInterfacesWithContext(context.TODO(), gomock.Any()).
-					Return(&ec2.DescribeNetworkInterfacesOutput{
-						NetworkInterfaces: []*ec2.NetworkInterface{},
-						NextToken:         nil,
-					}, nil)
-			},
-			check: func(instance *infrav1.Instance, err error) {
-				if err != nil {
-					t.Fatalf("did not expect error: %v", err)
-				}
-			},
-		},
-		{
-			name: "with custom placement group and partition number",
-			machine: &clusterv1.Machine{
-				ObjectMeta: metav1.ObjectMeta{
-					Labels:    map[string]string{"set": "node"},
-					Namespace: "default",
-					Name:      "machine-aws-test1",
-				},
-				Spec: clusterv1.MachineSpec{
-					Bootstrap: clusterv1.Bootstrap{
-						DataSecretName: ptr.To[string]("bootstrap-data"),
-					},
-				},
-			},
-			machineConfig: &infrav1.AWSMachineSpec{
-				AMI: infrav1.AMIReference{
-					ID: aws.String("abc"),
-				},
-				InstanceType:            "m5.large",
-				PlacementGroupName:      "placement-group1",
-				PlacementGroupPartition: 2,
-				UncompressedUserData:    &isUncompressedFalse,
-			},
-			awsCluster: &infrav1.AWSCluster{
-				Spec: infrav1.AWSClusterSpec{
-					NetworkSpec: infrav1.NetworkSpec{
-						Subnets: infrav1.Subnets{
-							infrav1.SubnetSpec{
-								ID:       "subnet-1",
-								IsPublic: false,
-							},
-							infrav1.SubnetSpec{
-								IsPublic: false,
-							},
-						},
-					},
-				},
-				Status: infrav1.AWSClusterStatus{
-					Network: infrav1.NetworkStatus{
-						SecurityGroups: map[infrav1.SecurityGroupRole]infrav1.SecurityGroup{
-							infrav1.SecurityGroupControlPlane: {
-								ID: "1",
-							},
-							infrav1.SecurityGroupNode: {
-								ID: "2",
-							},
-							infrav1.SecurityGroupLB: {
-								ID: "3",
-							},
-						},
-						APIServerELB: infrav1.LoadBalancer{
-							DNSName: "test-apiserver.us-east-1.aws",
-						},
-					},
-				},
-			},
-			expect: func(m *mocks.MockEC2APIMockRecorder) {
-				m. // TODO: Restore these parameters, but with the tags as well
-					RunInstancesWithContext(context.TODO(), gomock.Eq(&ec2.RunInstancesInput{
-						ImageId:      aws.String("abc"),
-						InstanceType: aws.String("m5.large"),
-						KeyName:      aws.String("default"),
-						MaxCount:     aws.Int64(1),
-						MinCount:     aws.Int64(1),
-						Placement: &ec2.Placement{
-							GroupName:       aws.String("placement-group1"),
-							PartitionNumber: aws.Int64(2),
-						},
-						SecurityGroupIds: []*string{aws.String("2"), aws.String("3")},
-						SubnetId:         aws.String("subnet-1"),
-						TagSpecifications: []*ec2.TagSpecification{
-							{
-								ResourceType: aws.String("instance"),
-								Tags: []*ec2.Tag{
-									{
-										Key:   aws.String("MachineName"),
-										Value: aws.String("default/machine-aws-test1"),
-									},
-									{
-										Key:   aws.String("Name"),
-										Value: aws.String("aws-test1"),
-									},
-									{
-										Key:   aws.String("kubernetes.io/cluster/test1"),
-										Value: aws.String("owned"),
-									},
-									{
-										Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/cluster/test1"),
-										Value: aws.String("owned"),
-									},
-									{
-										Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/role"),
-										Value: aws.String("node"),
-									},
-								},
-							},
-						},
-						UserData: aws.String(base64.StdEncoding.EncodeToString(userDataCompressed)),
-					})).
-					Return(&ec2.Reservation{
-						Instances: []*ec2.Instance{
-							{
-								State: &ec2.InstanceState{
-									Name: aws.String(ec2.InstanceStateNamePending),
-								},
-								IamInstanceProfile: &ec2.IamInstanceProfile{
-									Arn: aws.String("arn:aws:iam::123456789012:instance-profile/foo"),
-								},
-								InstanceId:     aws.String("two"),
-								InstanceType:   aws.String("m5.large"),
-								SubnetId:       aws.String("subnet-1"),
-								ImageId:        aws.String("ami-1"),
-								RootDeviceName: aws.String("device-1"),
-								BlockDeviceMappings: []*ec2.InstanceBlockDeviceMapping{
-									{
-										DeviceName: aws.String("device-1"),
-										Ebs: &ec2.EbsInstanceBlockDevice{
-											VolumeId: aws.String("volume-1"),
-										},
-									},
-								},
-								Placement: &ec2.Placement{
-									AvailabilityZone: &az,
-									GroupName:        aws.String("placement-group1"),
-									PartitionNumber:  aws.Int64(2),
-								},
-							},
-						},
-					}, nil)
-				m.
-					DescribeInstanceTypesWithContext(context.TODO(), gomock.Eq(&ec2.DescribeInstanceTypesInput{
-						InstanceTypes: []*string{
-							aws.String("m5.large"),
-						},
-					})).
-					Return(&ec2.DescribeInstanceTypesOutput{
-						InstanceTypes: []*ec2.InstanceTypeInfo{
-							{
-								ProcessorInfo: &ec2.ProcessorInfo{
-									SupportedArchitectures: []*string{
-										aws.String("x86_64"),
-									},
-								},
-							},
-						},
-					}, nil)
-				m.
-					DescribeNetworkInterfacesWithContext(context.TODO(), gomock.Any()).
-					Return(&ec2.DescribeNetworkInterfacesOutput{
-						NetworkInterfaces: []*ec2.NetworkInterface{},
-						NextToken:         nil,
-					}, nil)
-			},
-			check: func(instance *infrav1.Instance, err error) {
-				if err != nil {
-					t.Fatalf("did not expect error: %v", err)
-				}
-			},
-		},
-		{
-			name: "expect error when placementGroupPartition is set, but placementGroupName is empty",
-			machine: &clusterv1.Machine{
-				ObjectMeta: metav1.ObjectMeta{
-					Labels:    map[string]string{"set": "node"},
-					Namespace: "default",
-					Name:      "machine-aws-test1",
-				},
-				Spec: clusterv1.MachineSpec{
-					Bootstrap: clusterv1.Bootstrap{
-						DataSecretName: ptr.To[string]("bootstrap-data"),
-					},
-				},
-			},
-			machineConfig: &infrav1.AWSMachineSpec{
-				AMI: infrav1.AMIReference{
-					ID: aws.String("abc"),
-				},
-				InstanceType:            "m5.large",
-				PlacementGroupPartition: 2,
-				UncompressedUserData:    &isUncompressedFalse,
-			},
-			awsCluster: &infrav1.AWSCluster{
-				Spec: infrav1.AWSClusterSpec{
-					NetworkSpec: infrav1.NetworkSpec{
-						Subnets: infrav1.Subnets{
-							infrav1.SubnetSpec{
-								ID:       "subnet-1",
-								IsPublic: false,
-							},
-							infrav1.SubnetSpec{
-								IsPublic: false,
-							},
-						},
-					},
-				},
-				Status: infrav1.AWSClusterStatus{
-					Network: infrav1.NetworkStatus{
-						SecurityGroups: map[infrav1.SecurityGroupRole]infrav1.SecurityGroup{
-							infrav1.SecurityGroupControlPlane: {
-								ID: "1",
-							},
-							infrav1.SecurityGroupNode: {
-								ID: "2",
-							},
-							infrav1.SecurityGroupLB: {
-								ID: "3",
-							},
-						},
-						APIServerELB: infrav1.LoadBalancer{
-							DNSName: "test-apiserver.us-east-1.aws",
-						},
-					},
-				},
-			},
-			expect: func(m *mocks.MockEC2APIMockRecorder) {
-				m.
-					DescribeInstanceTypesWithContext(context.TODO(), gomock.Eq(&ec2.DescribeInstanceTypesInput{
-						InstanceTypes: []*string{
-							aws.String("m5.large"),
-						},
+						UserData: aws.String(base64.StdEncoding.EncodeToString(data)),
 					})).
-					Return(&ec2.DescribeInstanceTypesOutput{
-						InstanceTypes: []*ec2.InstanceTypeInfo{
+					Return(&ec2.Reservation{
+						Instances: []*ec2.Instance{
 							{
-								ProcessorInfo: &ec2.ProcessorInfo{
-									SupportedArchitectures: []*string{
-										aws.String("x86_64"),
+								State: &ec2.InstanceState{
+									Name: aws.String(ec2.InstanceStateNamePending),
+								},
+								IamInstanceProfile: &ec2.IamInstanceProfile{
+									Arn: aws.String("arn:aws:iam::123456789012:instance-profile/foo"),
+								},
+								InstanceId:     aws.String("two"),
+								InstanceType:   aws.String("m5.large"),
+								SubnetId:       aws.String("subnet-1"),
+								ImageId:        aws.String("ami-1"),
+								RootDeviceName: aws.String("device-1"),
+								BlockDeviceMappings: []*ec2.InstanceBlockDeviceMapping{
+									{
+										DeviceName: aws.String("device-1"),
+										Ebs: &ec2.EbsInstanceBlockDevice{
+											VolumeId: aws.String("volume-1"),
+										},
 									},
 								},
+								Placement: &ec2.Placement{
+									AvailabilityZone: &az,
+									Tenancy:          &tenancy,
+								},
 							},
 						},
 					}, nil)
+				m.
+					DescribeNetworkInterfacesWithContext(context.TODO(), gomock.Any()).
+					Return(&ec2.DescribeNetworkInterfacesOutput{
+						NetworkInterfaces: []*ec2.NetworkInterface{},
+						NextToken:         nil,
+					}, nil)
 			},
 			check: func(instance *infrav1.Instance, err error) {
-				expectedErrMsg := "placementGroupPartition is set but placementGroupName is empty"
-				if err == nil {
-					t.Fatalf("Expected error, but got nil")
-				}
-				if !strings.Contains(err.Error(), expectedErrMsg) {
-					t.Fatalf("Expected error: %s\nInstead got: `%s", expectedErrMsg, err.Error())
+				if err != nil {
+					t.Fatalf("did not expect error: %v", err)
 				}
 			},
 		},
@@ -4004,9 +3233,6 @@ func TestCreateInstance(t *testing.T) {
 								IsPublic: false,
 							},
 						},
-						VPC: infrav1.VPCSpec{
-							ID: "vpc-test",
-						},
 					},
 				},
 				Status: infrav1.AWSClusterStatus{
@@ -4136,9 +3362,6 @@ func TestCreateInstance(t *testing.T) {
 								IsPublic: false,
 							},
 						},
-						VPC: infrav1.VPCSpec{
-							ID: "vpc-test",
-						},
 					},
 					SSHKeyName: aws.String("specific-cluster-key-name"),
 				},
@@ -4270,9 +3493,6 @@ func TestCreateInstance(t *testing.T) {
 								IsPublic: false,
 							},
 						},
-						VPC: infrav1.VPCSpec{
-							ID: "vpc-test",
-						},
 					},
 					SSHKeyName: aws.String("specific-cluster-key-name"),
 				},
@@ -4404,9 +3624,6 @@ func TestCreateInstance(t *testing.T) {
 								IsPublic: false,
 							},
 						},
-						VPC: infrav1.VPCSpec{
-							ID: "vpc-test",
-						},
 					},
 					SSHKeyName: aws.String(""),
 				},
@@ -4535,9 +3752,6 @@ func TestCreateInstance(t *testing.T) {
 								IsPublic: false,
 							},
 						},
-						VPC: infrav1.VPCSpec{
-							ID: "vpc-test",
-						},
 					},
 					SSHKeyName: aws.String(""),
 				},
@@ -4666,9 +3880,6 @@ func TestCreateInstance(t *testing.T) {
 								IsPublic: false,
 							},
 						},
-						VPC: infrav1.VPCSpec{
-							ID: "vpc-test",
-						},
 					},
 					SSHKeyName: nil,
 				},
@@ -4767,173 +3978,8 @@ func TestCreateInstance(t *testing.T) {
 				}
 			},
 		},
-		{
-			name: "expect instace PrivateDNSName to be different when DHCP Option has domain name is set in the VPC",
-			machine: &clusterv1.Machine{
-				ObjectMeta: metav1.ObjectMeta{
-					Labels: map[string]string{"set": "node"},
-				},
-				Spec: clusterv1.MachineSpec{
-					Bootstrap: clusterv1.Bootstrap{
-						DataSecretName: ptr.To[string]("bootstrap-data"),
-					},
-				},
-			},
-			machineConfig: &infrav1.AWSMachineSpec{
-				AMI: infrav1.AMIReference{
-					ID: aws.String("abc"),
-				},
-				InstanceType: "m5.large",
-			},
-			awsCluster: &infrav1.AWSCluster{
-				ObjectMeta: metav1.ObjectMeta{Name: "test"},
-				Spec: infrav1.AWSClusterSpec{
-					NetworkSpec: infrav1.NetworkSpec{
-						Subnets: infrav1.Subnets{
-							infrav1.SubnetSpec{
-								ID:       "subnet-1",
-								IsPublic: false,
-							},
-							infrav1.SubnetSpec{
-								IsPublic: false,
-							},
-						},
-						VPC: infrav1.VPCSpec{
-							ID: "vpc-exists",
-						},
-					},
-				},
-				Status: infrav1.AWSClusterStatus{
-					Network: infrav1.NetworkStatus{
-						SecurityGroups: map[infrav1.SecurityGroupRole]infrav1.SecurityGroup{
-							infrav1.SecurityGroupControlPlane: {
-								ID: "1",
-							},
-							infrav1.SecurityGroupNode: {
-								ID: "2",
-							},
-							infrav1.SecurityGroupLB: {
-								ID: "3",
-							},
-						},
-						APIServerELB: infrav1.LoadBalancer{
-							DNSName: "test-apiserver.us-east-1.aws",
-						},
-					},
-				},
-			},
-			expect: func(m *mocks.MockEC2APIMockRecorder) {
-				m. // TODO: Restore these parameters, but with the tags as well
-					RunInstancesWithContext(context.TODO(), gomock.Any()).
-					Return(&ec2.Reservation{
-						Instances: []*ec2.Instance{
-							{
-								State: &ec2.InstanceState{
-									Name: aws.String(ec2.InstanceStateNamePending),
-								},
-								IamInstanceProfile: &ec2.IamInstanceProfile{
-									Arn: aws.String("arn:aws:iam::123456789012:instance-profile/foo"),
-								},
-								InstanceId:     aws.String("two"),
-								InstanceType:   aws.String("m5.large"),
-								SubnetId:       aws.String("subnet-1"),
-								ImageId:        aws.String("ami-1"),
-								RootDeviceName: aws.String("device-1"),
-								BlockDeviceMappings: []*ec2.InstanceBlockDeviceMapping{
-									{
-										DeviceName: aws.String("device-1"),
-										Ebs: &ec2.EbsInstanceBlockDevice{
-											VolumeId: aws.String("volume-1"),
-										},
-									},
-								},
-								Placement: &ec2.Placement{
-									AvailabilityZone: &az,
-								},
-								NetworkInterfaces: []*ec2.InstanceNetworkInterface{
-									{
-										NetworkInterfaceId: aws.String("eni-1"),
-										PrivateIpAddress:   aws.String("192.168.1.10"),
-										PrivateDnsName:     aws.String("ip-192-168-1-10.ec2.internal"),
-									},
-								},
-								VpcId: aws.String("vpc-exists"),
-							},
-						},
-					}, nil)
-				m.
-					DescribeInstanceTypesWithContext(context.TODO(), gomock.Eq(&ec2.DescribeInstanceTypesInput{
-						InstanceTypes: []*string{
-							aws.String("m5.large"),
-						},
-					})).
-					Return(&ec2.DescribeInstanceTypesOutput{
-						InstanceTypes: []*ec2.InstanceTypeInfo{
-							{
-								ProcessorInfo: &ec2.ProcessorInfo{
-									SupportedArchitectures: []*string{
-										aws.String("x86_64"),
-									},
-								},
-							},
-						},
-					}, nil)
-				m.
-					DescribeNetworkInterfacesWithContext(context.TODO(), gomock.Any()).
-					Return(&ec2.DescribeNetworkInterfacesOutput{
-						NetworkInterfaces: []*ec2.NetworkInterface{},
-					}, nil)
-				m.
-					DescribeVpcs(&ec2.DescribeVpcsInput{
-						VpcIds: []*string{aws.String("vpc-exists")},
-					}).Return(&ec2.DescribeVpcsOutput{
-					Vpcs: []*ec2.Vpc{
-						{
-							VpcId:         aws.String("vpc-exists"),
-							CidrBlock:     aws.String("192.168.1.0/24"),
-							IsDefault:     aws.Bool(false),
-							State:         aws.String("available"),
-							DhcpOptionsId: aws.String("dopt-12345678"),
-						},
-					},
-				}, nil)
-				m.
-					DescribeDhcpOptions(&ec2.DescribeDhcpOptionsInput{
-						DhcpOptionsIds: []*string{aws.String("dopt-12345678")},
-					}).Return(&ec2.DescribeDhcpOptionsOutput{
-					DhcpOptions: []*ec2.DhcpOptions{
-						{
-							DhcpConfigurations: []*ec2.DhcpConfiguration{
-								{
-									Key: aws.String("domain-name"),
-									Values: []*ec2.AttributeValue{
-										{
-											Value: aws.String("example.com"),
-										},
-									},
-								},
-							},
-						},
-					},
-				}, nil)
-			},
-			check: func(instance *infrav1.Instance, err error) {
-				g := NewWithT(t)
-				g.Expect(err).ToNot(HaveOccurred())
-				g.Expect(len(instance.Addresses)).To(Equal(3))
-
-				for _, address := range instance.Addresses {
-					if address.Type == clusterv1.MachineInternalIP {
-						g.Expect(address.Address).To(Equal("192.168.1.10"))
-					}
-
-					if address.Type == clusterv1.MachineInternalDNS {
-						g.Expect(address.Address).To(Or(Equal("ip-192-168-1-10.ec2.internal"), Equal("ip-192-168-1-10.example.com")))
-					}
-				}
-			},
-		},
 	}
+
 	for _, tc := range testcases {
 		t.Run(tc.name, func(t *testing.T) {
 			mockCtrl := gomock.NewController(t)
@@ -5249,148 +4295,3 @@ func TestGetFilteredSecurityGroupID(t *testing.T) {
 		})
 	}
 }
-
-func TestGetDHCPOptionSetDomainName(t *testing.T) {
-	testsCases := []struct {
-		name                   string
-		vpcID                  string
-		dhcpOpt                *ec2.DhcpOptions
-		expectedPrivateDNSName *string
-		mockCalls              func(m *mocks.MockEC2APIMockRecorder)
-	}{
-		{
-			name:  "dhcpOptions with domain-name",
-			vpcID: "vpc-exists",
-			dhcpOpt: &ec2.DhcpOptions{
-				DhcpConfigurations: []*ec2.DhcpConfiguration{
-					{
-						Key: aws.String("domain-name"),
-						Values: []*ec2.AttributeValue{
-							{
-								Value: aws.String("example.com"),
-							},
-						},
-					},
-				},
-			},
-			expectedPrivateDNSName: aws.String("example.com"),
-			mockCalls:              mockedGetPrivateDNSDomainNameFromDHCPOptionsCalls,
-		},
-		{
-			name:  "dhcpOptions without domain-name",
-			vpcID: "vpc-empty-domain-name",
-			dhcpOpt: &ec2.DhcpOptions{
-				DhcpConfigurations: []*ec2.DhcpConfiguration{
-					{
-						Key:    aws.String("domain-name"),
-						Values: []*ec2.AttributeValue{},
-					},
-				},
-			},
-			expectedPrivateDNSName: nil,
-			mockCalls:              mockedGetPrivateDNSDomainNameFromDHCPOptionsEmptyCalls,
-		},
-	}
-	for _, tc := range testsCases {
-		t.Run(tc.name, func(t *testing.T) {
-			g := NewWithT(t)
-			mockCtrl := gomock.NewController(t)
-			defer mockCtrl.Finish()
-			ec2Mock := mocks.NewMockEC2API(mockCtrl)
-			scheme, err := setupScheme()
-			g.Expect(err).ToNot(HaveOccurred())
-			expect := func(m *mocks.MockEC2APIMockRecorder) {
-				tc.mockCalls(m)
-			}
-			expect(ec2Mock.EXPECT())
-
-			client := fake.NewClientBuilder().WithScheme(scheme).Build()
-
-			cs, err := scope.NewClusterScope(
-				scope.ClusterScopeParams{
-					Client:  client,
-					Cluster: &clusterv1.Cluster{},
-					AWSCluster: &infrav1.AWSCluster{
-						ObjectMeta: metav1.ObjectMeta{Name: "test"},
-						Spec: infrav1.AWSClusterSpec{
-							NetworkSpec: infrav1.NetworkSpec{
-								VPC: infrav1.VPCSpec{
-									ID: tc.vpcID,
-								},
-							},
-						},
-					},
-				})
-			g.Expect(err).ToNot(HaveOccurred())
-
-			ec2Svc := NewService(cs)
-			ec2Svc.EC2Client = ec2Mock
-			dhcpOptsDomainName := ec2Svc.GetDHCPOptionSetDomainName(ec2Svc.EC2Client, &cs.VPC().ID)
-			g.Expect(dhcpOptsDomainName).To(Equal(tc.expectedPrivateDNSName))
-		})
-	}
-}
-
-func mockedGetPrivateDNSDomainNameFromDHCPOptionsCalls(m *mocks.MockEC2APIMockRecorder) {
-	m.DescribeVpcs(&ec2.DescribeVpcsInput{
-		VpcIds: []*string{aws.String("vpc-exists")},
-	}).Return(&ec2.DescribeVpcsOutput{
-		Vpcs: []*ec2.Vpc{
-			{
-				VpcId:         aws.String("vpc-exists"),
-				CidrBlock:     aws.String("10.0.0.0/16"),
-				IsDefault:     aws.Bool(false),
-				State:         aws.String("available"),
-				DhcpOptionsId: aws.String("dopt-12345678"),
-			},
-		},
-	}, nil)
-	m.DescribeDhcpOptions(&ec2.DescribeDhcpOptionsInput{
-		DhcpOptionsIds: []*string{aws.String("dopt-12345678")},
-	}).Return(&ec2.DescribeDhcpOptionsOutput{
-		DhcpOptions: []*ec2.DhcpOptions{
-			{
-				DhcpConfigurations: []*ec2.DhcpConfiguration{
-					{
-						Key: aws.String("domain-name"),
-						Values: []*ec2.AttributeValue{
-							{
-								Value: aws.String("example.com"),
-							},
-						},
-					},
-				},
-			},
-		},
-	}, nil)
-}
-
-func mockedGetPrivateDNSDomainNameFromDHCPOptionsEmptyCalls(m *mocks.MockEC2APIMockRecorder) {
-	m.DescribeVpcs(&ec2.DescribeVpcsInput{
-		VpcIds: []*string{aws.String("vpc-empty-domain-name")},
-	}).Return(&ec2.DescribeVpcsOutput{
-		Vpcs: []*ec2.Vpc{
-			{
-				VpcId:         aws.String("vpc-exists"),
-				CidrBlock:     aws.String("10.0.0.0/16"),
-				IsDefault:     aws.Bool(false),
-				State:         aws.String("available"),
-				DhcpOptionsId: aws.String("dopt-empty"),
-			},
-		},
-	}, nil)
-	m.DescribeDhcpOptions(&ec2.DescribeDhcpOptionsInput{
-		DhcpOptionsIds: []*string{aws.String("dopt-empty")},
-	}).Return(&ec2.DescribeDhcpOptionsOutput{
-		DhcpOptions: []*ec2.DhcpOptions{
-			{
-				DhcpConfigurations: []*ec2.DhcpConfiguration{
-					{
-						Key:    aws.String("domain-name"),
-						Values: []*ec2.AttributeValue{},
-					},
-				},
-			},
-		},
-	}, nil)
-}
diff --git a/pkg/cloud/services/network/routetables_test.go b/pkg/cloud/services/network/routetables_test.go
index 0f38cbacf..b8feb2aae 100644
--- a/pkg/cloud/services/network/routetables_test.go
+++ b/pkg/cloud/services/network/routetables_test.go
@@ -519,44 +519,6 @@ func TestReconcileRouteTables(t *testing.T) {
 					}, nil)
 			},
 		},
-		{
-			name: "failed to create route, delete route table and fail",
-			input: &infrav1.NetworkSpec{
-				VPC: infrav1.VPCSpec{
-					InternetGatewayID: aws.String("igw-01"),
-					ID:                "vpc-rtbs",
-					Tags: infrav1.Tags{
-						infrav1.ClusterTagKey("test-cluster"): "owned",
-					},
-				},
-				Subnets: infrav1.Subnets{
-					infrav1.SubnetSpec{
-						ID:               "subnet-rtbs-public",
-						IsPublic:         true,
-						NatGatewayID:     aws.String("nat-01"),
-						AvailabilityZone: "us-east-1a",
-					},
-				},
-			},
-			expect: func(m *mocks.MockEC2APIMockRecorder) {
-				m.DescribeRouteTablesWithContext(context.TODO(), gomock.AssignableToTypeOf(&ec2.DescribeRouteTablesInput{})).
-					Return(&ec2.DescribeRouteTablesOutput{}, nil)
-
-				m.CreateRouteTableWithContext(context.TODO(), matchRouteTableInput(&ec2.CreateRouteTableInput{VpcId: aws.String("vpc-rtbs")})).
-					Return(&ec2.CreateRouteTableOutput{RouteTable: &ec2.RouteTable{RouteTableId: aws.String("rt-1")}}, nil)
-
-				m.CreateRouteWithContext(context.TODO(), gomock.Eq(&ec2.CreateRouteInput{
-					GatewayId:            aws.String("igw-01"),
-					DestinationCidrBlock: aws.String("0.0.0.0/0"),
-					RouteTableId:         aws.String("rt-1"),
-				})).
-					Return(nil, awserrors.NewNotFound("MissingParameter"))
-
-				m.DeleteRouteTableWithContext(context.TODO(), gomock.AssignableToTypeOf(&ec2.DeleteRouteTableInput{})).
-					Return(&ec2.DeleteRouteTableOutput{}, nil)
-			},
-			err: errors.New(`failed to create route in route table "rt-1"`),
-		},
 	}
 
 	for _, tc := range testCases {
@@ -598,65 +560,59 @@ func TestReconcileRouteTables(t *testing.T) {
 	}
 }
 
-// Delete Route Table(s).
-var (
-	stubEc2RouteTablePrivate = &ec2.RouteTable{
-		RouteTableId: aws.String("route-table-private"),
-		Associations: []*ec2.RouteTableAssociation{
-			{
-				SubnetId: nil,
-			},
-		},
-		Routes: []*ec2.Route{
-			{
-				DestinationCidrBlock: aws.String("0.0.0.0/0"),
-				NatGatewayId:         aws.String("outdated-nat-01"),
-			},
-		},
-	}
-	stubEc2RouteTablePublicWithAssociations = &ec2.RouteTable{
-		RouteTableId: aws.String("route-table-public"),
-		Associations: []*ec2.RouteTableAssociation{
-			{
-				SubnetId:                aws.String("subnet-routetables-public"),
-				RouteTableAssociationId: aws.String("route-table-public"),
-			},
-		},
-		Routes: []*ec2.Route{
-			{
-				DestinationCidrBlock: aws.String("0.0.0.0/0"),
-				GatewayId:            aws.String("igw-01"),
-			},
-		},
-		Tags: []*ec2.Tag{
-			{
-				Key:   aws.String("kubernetes.io/cluster/test-cluster"),
-				Value: aws.String("owned"),
-			},
-			{
-				Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/role"),
-				Value: aws.String("common"),
-			},
-			{
-				Key:   aws.String("Name"),
-				Value: aws.String("test-cluster-rt-public-us-east-1a"),
-			},
-			{
-				Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/cluster/test-cluster"),
-				Value: aws.String("owned"),
-			},
-		},
-	}
-)
-
 func TestDeleteRouteTables(t *testing.T) {
 	mockCtrl := gomock.NewController(t)
 	defer mockCtrl.Finish()
 
 	describeRouteTableOutput := &ec2.DescribeRouteTablesOutput{
 		RouteTables: []*ec2.RouteTable{
-			stubEc2RouteTablePrivate,
-			stubEc2RouteTablePublicWithAssociations,
+			{
+				RouteTableId: aws.String("route-table-private"),
+				Associations: []*ec2.RouteTableAssociation{
+					{
+						SubnetId: nil,
+					},
+				},
+				Routes: []*ec2.Route{
+					{
+						DestinationCidrBlock: aws.String("0.0.0.0/0"),
+						NatGatewayId:         aws.String("outdated-nat-01"),
+					},
+				},
+			},
+			{
+				RouteTableId: aws.String("route-table-public"),
+				Associations: []*ec2.RouteTableAssociation{
+					{
+						SubnetId:                aws.String("subnet-routetables-public"),
+						RouteTableAssociationId: aws.String("route-table-public"),
+					},
+				},
+				Routes: []*ec2.Route{
+					{
+						DestinationCidrBlock: aws.String("0.0.0.0/0"),
+						GatewayId:            aws.String("igw-01"),
+					},
+				},
+				Tags: []*ec2.Tag{
+					{
+						Key:   aws.String("kubernetes.io/cluster/test-cluster"),
+						Value: aws.String("owned"),
+					},
+					{
+						Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/role"),
+						Value: aws.String("common"),
+					},
+					{
+						Key:   aws.String("Name"),
+						Value: aws.String("test-cluster-rt-public-us-east-1a"),
+					},
+					{
+						Key:   aws.String("sigs.k8s.io/cluster-api-provider-aws/cluster/test-cluster"),
+						Value: aws.String("owned"),
+					},
+				},
+			},
 		},
 	}
 
@@ -774,81 +730,6 @@ func TestDeleteRouteTables(t *testing.T) {
 	}
 }
 
-func TestDeleteRouteTable(t *testing.T) {
-	mockCtrl := gomock.NewController(t)
-	defer mockCtrl.Finish()
-
-	testCases := []struct {
-		name    string
-		input   *ec2.RouteTable
-		expect  func(m *mocks.MockEC2APIMockRecorder)
-		wantErr bool
-	}{
-		{
-			name:  "Should delete route table successfully",
-			input: stubEc2RouteTablePrivate,
-			expect: func(m *mocks.MockEC2APIMockRecorder) {
-				m.DeleteRouteTableWithContext(context.TODO(), gomock.AssignableToTypeOf(&ec2.DeleteRouteTableInput{})).
-					Return(&ec2.DeleteRouteTableOutput{}, nil)
-			},
-		},
-		{
-			name:  "Should return error if delete route table fails",
-			input: stubEc2RouteTablePrivate,
-			expect: func(m *mocks.MockEC2APIMockRecorder) {
-				m.DeleteRouteTableWithContext(context.TODO(), gomock.AssignableToTypeOf(&ec2.DeleteRouteTableInput{})).
-					Return(nil, awserrors.NewNotFound("not found"))
-			},
-			wantErr: true,
-		},
-		{
-			name:  "Should return error if disassociate route table fails",
-			input: stubEc2RouteTablePublicWithAssociations,
-			expect: func(m *mocks.MockEC2APIMockRecorder) {
-				m.DisassociateRouteTableWithContext(context.TODO(), gomock.Eq(&ec2.DisassociateRouteTableInput{
-					AssociationId: aws.String("route-table-public"),
-				})).Return(nil, awserrors.NewNotFound("not found"))
-			},
-			wantErr: true,
-		},
-	}
-
-	for _, tc := range testCases {
-		t.Run(tc.name, func(t *testing.T) {
-			g := NewWithT(t)
-			ec2Mock := mocks.NewMockEC2API(mockCtrl)
-
-			scheme := runtime.NewScheme()
-			_ = infrav1.AddToScheme(scheme)
-			client := fake.NewClientBuilder().WithScheme(scheme).Build()
-			scope, err := scope.NewClusterScope(scope.ClusterScopeParams{
-				Client: client,
-				Cluster: &clusterv1.Cluster{
-					ObjectMeta: metav1.ObjectMeta{Name: "test-cluster"},
-				},
-				AWSCluster: &infrav1.AWSCluster{
-					ObjectMeta: metav1.ObjectMeta{Name: "test"},
-					Spec:       infrav1.AWSClusterSpec{},
-				},
-			})
-			g.Expect(err).NotTo(HaveOccurred())
-			if tc.expect != nil {
-				tc.expect(ec2Mock.EXPECT())
-			}
-
-			s := NewService(scope)
-			s.EC2Client = ec2Mock
-
-			err = s.deleteRouteTable(tc.input)
-			if tc.wantErr {
-				g.Expect(err).To(HaveOccurred())
-				return
-			}
-			g.Expect(err).NotTo(HaveOccurred())
-		})
-	}
-}
-
 type routeTableInputMatcher struct {
 	routeTableInput *ec2.CreateRouteTableInput
 }
diff --git a/pkg/cloud/services/s3/s3_test.go b/pkg/cloud/services/s3/s3_test.go
index 80422ffc4..baa44ff87 100644
--- a/pkg/cloud/services/s3/s3_test.go
+++ b/pkg/cloud/services/s3/s3_test.go
@@ -694,9 +694,11 @@ func TestDeleteObject(t *testing.T) {
 		}
 	})
 
-	t.Run("succeeds_when", func(t *testing.T) {
+	t.Run("succeeds_when_bucket_has_already_been_removed", func(t *testing.T) {
 		t.Parallel()
 
+		svc, s3Mock := testService(t, &testServiceInput{Bucket: &infrav1.S3Bucket{}})
+
 		machineScope := &scope.MachineScope{
 			Machine: &clusterv1.Machine{},
 			AWSMachine: &infrav1.AWSMachine{
@@ -706,38 +708,11 @@ func TestDeleteObject(t *testing.T) {
 			},
 		}
 
-		t.Run("bucket_has_already_been_removed", func(t *testing.T) {
-			t.Parallel()
-
-			svc, s3Mock := testService(t, &testServiceInput{Bucket: &infrav1.S3Bucket{}})
-			s3Mock.EXPECT().HeadObject(gomock.Any()).Return(nil, awserr.New(s3svc.ErrCodeNoSuchBucket, "", nil))
-
-			if err := svc.Delete(machineScope); err != nil {
-				t.Fatalf("Unexpected error, got: %v", err)
-			}
-		})
-
-		t.Run("object_has_already_been_removed", func(t *testing.T) {
-			t.Parallel()
-
-			svc, s3Mock := testService(t, &testServiceInput{Bucket: &infrav1.S3Bucket{}})
-			s3Mock.EXPECT().HeadObject(gomock.Any()).Return(nil, awserr.New(s3svc.ErrCodeNoSuchKey, "", nil))
-
-			if err := svc.Delete(machineScope); err != nil {
-				t.Fatalf("Unexpected error, got: %v", err)
-			}
-		})
-
-		t.Run("bucket_or_object_not_found", func(t *testing.T) {
-			t.Parallel()
-
-			svc, s3Mock := testService(t, &testServiceInput{Bucket: &infrav1.S3Bucket{}})
-			s3Mock.EXPECT().HeadObject(gomock.Any()).Return(nil, awserr.New("NotFound", "Not found", nil))
+		s3Mock.EXPECT().HeadObject(gomock.Any()).Return(nil, awserr.New(s3svc.ErrCodeNoSuchBucket, "", nil))
 
-			if err := svc.Delete(machineScope); err != nil {
-				t.Fatalf("Unexpected error, got: %v", err)
-			}
-		})
+		if err := svc.Delete(machineScope); err != nil {
+			t.Fatalf("Unexpected error, got: %v", err)
+		}
 	})
 
 	t.Run("returns_error_when", func(t *testing.T) {
diff --git a/pkg/cloud/services/securitygroup/securitygroups_test.go b/pkg/cloud/services/securitygroup/securitygroups_test.go
index 8f7d7c3ea..31466058d 100644
--- a/pkg/cloud/services/securitygroup/securitygroups_test.go
+++ b/pkg/cloud/services/securitygroup/securitygroups_test.go
@@ -1317,64 +1317,6 @@ func TestControlPlaneLoadBalancerIngressRules(t *testing.T) {
 				},
 			},
 		},
-		{
-			name: "defined rules are used when using internal and external LB",
-			awsCluster: &infrav1.AWSCluster{
-				Spec: infrav1.AWSClusterSpec{
-					ControlPlaneLoadBalancer: &infrav1.AWSLoadBalancerSpec{
-						IngressRules: []infrav1.IngressRule{
-							{
-								Description: "My custom ingress rule",
-								Protocol:    infrav1.SecurityGroupProtocolTCP,
-								FromPort:    1234,
-								ToPort:      1234,
-								CidrBlocks:  []string{"172.126.1.1/0"},
-							},
-						},
-						Scheme: &infrav1.ELBSchemeInternal,
-					},
-					SecondaryControlPlaneLoadBalancer: &infrav1.AWSLoadBalancerSpec{
-						IngressRules: []infrav1.IngressRule{
-							{
-								Description: "Another custom ingress rule",
-								Protocol:    infrav1.SecurityGroupProtocolTCP,
-								FromPort:    2345,
-								ToPort:      2345,
-								CidrBlocks:  []string{"0.0.0.0/0"},
-							},
-						},
-					},
-					NetworkSpec: infrav1.NetworkSpec{
-						VPC: infrav1.VPCSpec{
-							CidrBlock: "10.0.0.0/16",
-						},
-					},
-				},
-			},
-			expectedIngresRules: infrav1.IngressRules{
-				infrav1.IngressRule{
-					Description: "Kubernetes API",
-					Protocol:    infrav1.SecurityGroupProtocolTCP,
-					FromPort:    6443,
-					ToPort:      6443,
-					CidrBlocks:  []string{"10.0.0.0/16"},
-				},
-				infrav1.IngressRule{
-					Description: "My custom ingress rule",
-					Protocol:    infrav1.SecurityGroupProtocolTCP,
-					FromPort:    1234,
-					ToPort:      1234,
-					CidrBlocks:  []string{"172.126.1.1/0"},
-				},
-				infrav1.IngressRule{
-					Description: "Another custom ingress rule",
-					Protocol:    infrav1.SecurityGroupProtocolTCP,
-					FromPort:    2345,
-					ToPort:      2345,
-					CidrBlocks:  []string{"0.0.0.0/0"},
-				},
-			},
-		},
 	}
 
 	for _, tc := range testCases {