From 60d5cf3f50b8c51af4073216e261761321fc7244 Mon Sep 17 00:00:00 2001 From: Siarhei Rasiukevich Date: Fri, 3 Oct 2025 21:44:45 +0300 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20Add=20ability=20to=20control=20"EKS?= =?UTF-8?q?=20Auto=20Mode"=20for=20EKS=20clusters?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Siarhei Rasiukevich --- ...ster.x-k8s.io_awsmanagedcontrolplanes.yaml | 27 + ...8s.io_awsmanagedcontrolplanetemplates.yaml | 28 + controlplane/eks/api/v1beta1/conversion.go | 1 + .../api/v1beta1/zz_generated.conversion.go | 1 + .../v1beta2/awsmanagedcontrolplane_types.go | 26 + .../v1beta2/awsmanagedcontrolplane_webhook.go | 54 +- .../awsmanagedcontrolplane_webhook_test.go | 60 + .../eks/api/v1beta2/zz_generated.deepcopy.go | 46 + docs/book/src/crd/index.md | 1235 ++++++++++++++++- pkg/cloud/scope/managedcontrolplane.go | 8 + pkg/cloud/services/eks/cluster.go | 38 +- 11 files changed, 1443 insertions(+), 81 deletions(-) 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 858dac8a4c..b0131f7b12 100644 --- a/config/crd/bases/controlplane.cluster.x-k8s.io_awsmanagedcontrolplanes.yaml +++ b/config/crd/bases/controlplane.cluster.x-k8s.io_awsmanagedcontrolplanes.yaml @@ -2345,6 +2345,33 @@ spec: AssociateOIDCProvider can be enabled to automatically create an identity provider for the controller for use with IAM roles for service accounts type: boolean + autoMode: + description: |- + AutoMode is the EKS Auto Mode. + allows to create cluster with aws compute, ebs, elb capabilities. + properties: + compute: + description: Compute capability configuration for EKS Auto Mode. + properties: + nodePools: + description: NodePools that defines the compute resources + for your EKS Auto Mode cluster. + items: + type: string + type: array + nodeRoleArn: + description: |- + NodeRoleArn the ARN of the IAM Role EKS will assign to EC2 Managed Instances in your EKS + Auto Mode cluster. This value cannot be changed after the compute capability of + EKS Auto Mode is enabled. For more information, see the IAM Reference in the + Amazon EKS User Guide. + type: string + type: object + enabled: + default: false + description: Enabled will enable EKS Auto Mode. + type: boolean + type: object bastion: description: Bastion contains options to configure the bastion host. properties: diff --git a/config/crd/bases/controlplane.cluster.x-k8s.io_awsmanagedcontrolplanetemplates.yaml b/config/crd/bases/controlplane.cluster.x-k8s.io_awsmanagedcontrolplanetemplates.yaml index ad5c56c54b..c48ad4a5fa 100644 --- a/config/crd/bases/controlplane.cluster.x-k8s.io_awsmanagedcontrolplanetemplates.yaml +++ b/config/crd/bases/controlplane.cluster.x-k8s.io_awsmanagedcontrolplanetemplates.yaml @@ -129,6 +129,34 @@ spec: AssociateOIDCProvider can be enabled to automatically create an identity provider for the controller for use with IAM roles for service accounts type: boolean + autoMode: + description: |- + AutoMode is the EKS Auto Mode. + allows to create cluster with aws compute, ebs, elb capabilities. + properties: + compute: + description: Compute capability configuration for EKS + Auto Mode. + properties: + nodePools: + description: NodePools that defines the compute resources + for your EKS Auto Mode cluster. + items: + type: string + type: array + nodeRoleArn: + description: |- + NodeRoleArn the ARN of the IAM Role EKS will assign to EC2 Managed Instances in your EKS + Auto Mode cluster. This value cannot be changed after the compute capability of + EKS Auto Mode is enabled. For more information, see the IAM Reference in the + Amazon EKS User Guide. + type: string + type: object + enabled: + default: false + description: Enabled will enable EKS Auto Mode. + type: boolean + type: object bastion: description: Bastion contains options to configure the bastion host. diff --git a/controlplane/eks/api/v1beta1/conversion.go b/controlplane/eks/api/v1beta1/conversion.go index 0985ef66d5..7f3a33e95f 100644 --- a/controlplane/eks/api/v1beta1/conversion.go +++ b/controlplane/eks/api/v1beta1/conversion.go @@ -122,6 +122,7 @@ func (r *AWSManagedControlPlane) ConvertTo(dstRaw conversion.Hub) error { dst.Spec.RolePermissionsBoundary = restored.Spec.RolePermissionsBoundary dst.Status.Version = restored.Status.Version dst.Spec.BootstrapSelfManagedAddons = restored.Spec.BootstrapSelfManagedAddons + dst.Spec.AutoMode = restored.Spec.AutoMode return nil } diff --git a/controlplane/eks/api/v1beta1/zz_generated.conversion.go b/controlplane/eks/api/v1beta1/zz_generated.conversion.go index 48f326b2dc..006f789ea7 100644 --- a/controlplane/eks/api/v1beta1/zz_generated.conversion.go +++ b/controlplane/eks/api/v1beta1/zz_generated.conversion.go @@ -380,6 +380,7 @@ func autoConvert_v1beta2_AWSManagedControlPlaneSpec_To_v1beta1_AWSManagedControl return err } // WARNING: in.BootstrapSelfManagedAddons requires manual conversion: does not exist in peer-type + // WARNING: in.AutoMode requires manual conversion: does not exist in peer-type // WARNING: in.RestrictPrivateSubnets requires manual conversion: does not exist in peer-type if err := Convert_v1beta2_KubeProxy_To_v1beta1_KubeProxy(&in.KubeProxy, &out.KubeProxy, s); err != nil { return err diff --git a/controlplane/eks/api/v1beta2/awsmanagedcontrolplane_types.go b/controlplane/eks/api/v1beta2/awsmanagedcontrolplane_types.go index 9112863e35..14a05c52c8 100644 --- a/controlplane/eks/api/v1beta2/awsmanagedcontrolplane_types.go +++ b/controlplane/eks/api/v1beta2/awsmanagedcontrolplane_types.go @@ -206,6 +206,9 @@ type AWSManagedControlPlaneSpec struct { //nolint: maligned // +kubebuilder:default=true BootstrapSelfManagedAddons bool `json:"bootstrapSelfManagedAddons,omitempty"` + // +optional + AutoMode *AutoMode `json:"autoMode,omitempty"` + // RestrictPrivateSubnets indicates that the EKS control plane should only use private subnets. // +kubebuilder:default=false RestrictPrivateSubnets bool `json:"restrictPrivateSubnets,omitempty"` @@ -225,6 +228,29 @@ type KubeProxy struct { Disable bool `json:"disable,omitempty"` } +// AutoMode is the EKS Auto Mode. +// allows to create cluster with aws compute, ebs, elb capabilities. +type AutoMode struct { + // Enabled will enable EKS Auto Mode. + // +kubebuilder:default=false + Enabled bool `json:"enabled,omitempty"` + // Compute capability configuration for EKS Auto Mode. + // +optional + Compute Compute `json:"compute,omitempty"` +} + +// Compute allows to run compute capability with EKS AutoMode. +type Compute struct { + // NodePools that defines the compute resources for your EKS Auto Mode cluster. + NodePools []string `json:"nodePools,omitempty"` + // NodeRoleArn the ARN of the IAM Role EKS will assign to EC2 Managed Instances in your EKS + // Auto Mode cluster. This value cannot be changed after the compute capability of + // EKS Auto Mode is enabled. For more information, see the IAM Reference in the + // Amazon EKS User Guide. + // +optional + NodeRoleArn *string `json:"nodeRoleArn,omitempty"` +} + // VpcCni specifies configuration related to the VPC CNI. type VpcCni struct { // Disable indicates that the Amazon VPC CNI should be disabled. With EKS clusters the diff --git a/controlplane/eks/api/v1beta2/awsmanagedcontrolplane_webhook.go b/controlplane/eks/api/v1beta2/awsmanagedcontrolplane_webhook.go index 5554eff7c1..4a290e1189 100644 --- a/controlplane/eks/api/v1beta2/awsmanagedcontrolplane_webhook.go +++ b/controlplane/eks/api/v1beta2/awsmanagedcontrolplane_webhook.go @@ -25,6 +25,7 @@ import ( "github.com/pkg/errors" apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/validation/field" "k8s.io/apimachinery/pkg/util/version" "k8s.io/klog/v2" @@ -52,6 +53,9 @@ const ( cidrSizeMin = 16 vpcCniAddon = "vpc-cni" kubeProxyAddon = "kube-proxy" + + autoModeComputeNodePoolSystem = "system" + autoModeComputeNodePoolGeneral = "general-purpose" ) // SetupWebhookWithManager will setup the webhooks for the AWSManagedControlPlane. @@ -102,6 +106,7 @@ func (*awsManagedControlPlaneWebhook) ValidateCreate(_ context.Context, obj runt allErrs = append(allErrs, r.validateSecondaryCIDR()...) allErrs = append(allErrs, r.validateEKSAddons()...) allErrs = append(allErrs, r.validateDisableVPCCNI()...) + allErrs = append(allErrs, r.validateAutoMode(nil)...) allErrs = append(allErrs, r.validateRestrictPrivateSubnets()...) allErrs = append(allErrs, r.validateKubeProxy()...) allErrs = append(allErrs, r.Spec.AdditionalTags.Validate()...) @@ -144,6 +149,7 @@ func (*awsManagedControlPlaneWebhook) ValidateUpdate(ctx context.Context, oldObj allErrs = append(allErrs, r.validateAccessConfigUpdate(oldAWSManagedControlplane)...) allErrs = append(allErrs, r.validateIAMAuthConfig()...) allErrs = append(allErrs, r.validateSecondaryCIDR()...) + allErrs = append(allErrs, r.validateAutoMode(oldAWSManagedControlplane)...) allErrs = append(allErrs, r.validateEKSAddons()...) allErrs = append(allErrs, r.validateDisableVPCCNI()...) allErrs = append(allErrs, r.validateRestrictPrivateSubnets()...) @@ -472,6 +478,52 @@ func validateDisableVPCCNI(vpcCni VpcCni, addons *[]Addon, path *field.Path) fie return allErrs } +func (r *AWSManagedControlPlane) validateAutoMode(old *AWSManagedControlPlane) field.ErrorList { + return validateAutoMode(r.Spec, old, field.NewPath("spec")) +} + +func validateAutoMode(spec AWSManagedControlPlaneSpec, old *AWSManagedControlPlane, path *field.Path) field.ErrorList { + var allErrs field.ErrorList + + if spec.AutoMode == nil { + return nil + } + + if spec.AutoMode.Enabled { + // EKS Auto mode is not compatible with configmap AuthenticationMode. + if spec.AccessConfig.AuthenticationMode == EKSAuthenticationModeConfigMap { + authConfigField := path.Child("accessConfig", "authenticationMode") + allErrs = append(allErrs, field.Invalid(authConfigField, spec.AccessConfig.AuthenticationMode, "authenticationMode CONFIG_MAP couldn't be used with autoMode")) + } + + if old != nil { + // nodeRoleArn cannot be changed after the compute capability of EKS Auto Mode is enabled. + if old.Spec.AutoMode.Compute.NodeRoleArn != spec.AutoMode.Compute.NodeRoleArn { + nodeRoleArnField := path.Child("autoMode", "compute", "nodeRoleArn") + allErrs = append(allErrs, field.Invalid(nodeRoleArnField, spec.AutoMode.Compute.NodeRoleArn, "nodeRoleArn could not be changed")) + } + } + + if len(spec.AutoMode.Compute.NodePools) > 0 { + // nodeRoleArn should be always defined with node pools. + if spec.AutoMode.Compute.NodeRoleArn == nil { + nodeRoleArnField := path.Child("autoMode", "compute", "nodeRoleArn") + allErrs = append(allErrs, field.Invalid(nodeRoleArnField, spec.AutoMode.Compute.NodeRoleArn, "nodeRoleArn is required when nodePools specified")) + } + + allowedPoolNames := sets.New[string](autoModeComputeNodePoolSystem, autoModeComputeNodePoolGeneral) + for _, poolName := range spec.AutoMode.Compute.NodePools { + nodePoolsField := path.Child("autoMode", "compute", "nodePools") + if !allowedPoolNames.Has(poolName) { + allErrs = append(allErrs, field.Invalid(nodePoolsField, poolName, "nodePools contains an invalid pool")) + } + } + } + } + + return allErrs +} + func (r *AWSManagedControlPlane) validateRestrictPrivateSubnets() field.ErrorList { return validateRestrictPrivateSubnets(r.Spec.RestrictPrivateSubnets, r.Spec.NetworkSpec, r.Spec.EKSClusterName, field.NewPath("spec")) } @@ -620,7 +672,5 @@ func (*awsManagedControlPlaneWebhook) Default(_ context.Context, obj runtime.Obj infrav1.SetDefaults_Bastion(&r.Spec.Bastion) infrav1.SetDefaults_NetworkSpec(&r.Spec.NetworkSpec) - // Set default value for BootstrapSelfManagedAddons - r.Spec.BootstrapSelfManagedAddons = true return nil } diff --git a/controlplane/eks/api/v1beta2/awsmanagedcontrolplane_webhook_test.go b/controlplane/eks/api/v1beta2/awsmanagedcontrolplane_webhook_test.go index 40de7b369b..e28e19a521 100644 --- a/controlplane/eks/api/v1beta2/awsmanagedcontrolplane_webhook_test.go +++ b/controlplane/eks/api/v1beta2/awsmanagedcontrolplane_webhook_test.go @@ -179,6 +179,7 @@ func TestWebhookCreate(t *testing.T) { secondaryCidr *string secondaryCidrBlocks []infrav1.VpcCidrBlock kubeProxy KubeProxy + AutoMode *AutoMode accessConfig *AccessConfig }{ { @@ -364,6 +365,30 @@ func TestWebhookCreate(t *testing.T) { BootstrapClusterCreatorAdminPermissions: ptr.To(false), }, }, + { + name: "autoMode compute not allowed with authenticationMode CONFIG_MAP", + eksClusterName: "default_cluster1", + eksVersion: "v1.19", + expectError: true, + vpcCNI: VpcCni{Disable: false}, + AutoMode: &AutoMode{Enabled: true}, + }, + { + name: "autoMode compute nodeRoleArn should be defined with nodePools", + eksClusterName: "default_cluster1", + eksVersion: "v1.19", + expectError: true, + vpcCNI: VpcCni{Disable: false}, + AutoMode: &AutoMode{Enabled: true, Compute: Compute{NodePools: []string{"system", "general-purpose"}}}, + }, + { + name: "autoMode compute nodeRoleArn defined with nodePools", + eksClusterName: "default_cluster1", + eksVersion: "v1.19", + expectError: false, + vpcCNI: VpcCni{Disable: false}, + AutoMode: &AutoMode{Enabled: true, Compute: Compute{NodePools: []string{"system", "general-purpose"}, NodeRoleArn: aws.String("foo")}}, + }, } for _, tc := range tests { @@ -411,6 +436,10 @@ func TestWebhookCreate(t *testing.T) { mcp.Spec.AccessConfig = tc.accessConfig } + if tc.AutoMode != nil { + mcp.Spec.AutoMode = tc.AutoMode + } + err := testEnv.Create(ctx, mcp) if tc.expectError { @@ -877,6 +906,37 @@ func TestWebhookUpdate(t *testing.T) { }, expectError: true, }, + { + name: "changing noderolearn is not allowed after it has been set", + oldClusterSpec: AWSManagedControlPlaneSpec{ + EKSClusterName: "default_cluster1", + NetworkSpec: infrav1.NetworkSpec{ + VPC: infrav1.VPCSpec{}, + }, + Version: ptr.To[string]("1.22"), + AutoMode: &AutoMode{ + Compute: Compute{ + NodeRoleArn: aws.String("fooarn"), + NodePools: []string{"pool1", "pool2"}, + }, + }, + }, + newClusterSpec: AWSManagedControlPlaneSpec{ + EKSClusterName: "default_cluster1", + NetworkSpec: infrav1.NetworkSpec{ + VPC: infrav1.VPCSpec{ + IPv6: &infrav1.IPv6{}, + }, + }, + AutoMode: &AutoMode{ + Compute: Compute{ + NodeRoleArn: aws.String("bararn"), + NodePools: []string{"pool1", "pool2"}, + }, + }, + }, + expectError: true, + }, } for _, tc := range tests { diff --git a/controlplane/eks/api/v1beta2/zz_generated.deepcopy.go b/controlplane/eks/api/v1beta2/zz_generated.deepcopy.go index 678a641e9c..869d29f7cd 100644 --- a/controlplane/eks/api/v1beta2/zz_generated.deepcopy.go +++ b/controlplane/eks/api/v1beta2/zz_generated.deepcopy.go @@ -176,6 +176,11 @@ func (in *AWSManagedControlPlaneSpec) DeepCopyInto(out *AWSManagedControlPlaneSp (*in).DeepCopyInto(*out) } in.VpcCni.DeepCopyInto(&out.VpcCni) + if in.AutoMode != nil { + in, out := &in.AutoMode, &out.AutoMode + *out = new(AutoMode) + (*in).DeepCopyInto(*out) + } out.KubeProxy = in.KubeProxy } @@ -447,6 +452,47 @@ func (in *AddonState) DeepCopy() *AddonState { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AutoMode) DeepCopyInto(out *AutoMode) { + *out = *in + in.Compute.DeepCopyInto(&out.Compute) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AutoMode. +func (in *AutoMode) DeepCopy() *AutoMode { + if in == nil { + return nil + } + out := new(AutoMode) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Compute) DeepCopyInto(out *Compute) { + *out = *in + if in.NodePools != nil { + in, out := &in.NodePools, &out.NodePools + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.NodeRoleArn != nil { + in, out := &in.NodeRoleArn, &out.NodeRoleArn + *out = new(string) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Compute. +func (in *Compute) DeepCopy() *Compute { + if in == nil { + return nil + } + out := new(Compute) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ControlPlaneLoggingSpec) DeepCopyInto(out *ControlPlaneLoggingSpec) { *out = *in diff --git a/docs/book/src/crd/index.md b/docs/book/src/crd/index.md index 363550ffb5..2fe02d63e8 100644 --- a/docs/book/src/crd/index.md +++ b/docs/book/src/crd/index.md @@ -5374,6 +5374,19 @@ string

ServiceAccountRoleArn is the ARN of an IAM role to bind to the addons service account

+ + +preserveOnDelete
+ +bool + + + +(Optional) +

PreserveOnDelete indicates that the addon resources should be +preserved in the cluster on delete.

+ +

AddonIssue @@ -6265,6 +6278,7 @@ AWSIdentityReference +(Optional)

IdentityRef is a reference to an identity to be used when reconciling the managed control plane. If no identity is specified, the default identity for this controller will be used.

@@ -6650,6 +6664,19 @@ If you set this value to false when creating a cluster, the default networking a +autoMode
+ + +AutoMode + + + + +(Optional) + + + + restrictPrivateSubnets
bool @@ -6692,7 +6719,7 @@ AWSManagedControlPlaneStatus

AWSManagedControlPlaneSpec

-(Appears on:AWSManagedControlPlane) +(Appears on:AWSManagedControlPlane, AWSManagedControlPlaneTemplateResource)

AWSManagedControlPlaneSpec defines the desired state of an Amazon EKS Cluster.

@@ -6729,6 +6756,7 @@ AWSIdentityReference
+(Optional)

IdentityRef is a reference to an identity to be used when reconciling the managed control plane. If no identity is specified, the default identity for this controller will be used.

@@ -7114,6 +7142,19 @@ If you set this value to false when creating a cluster, the default networking a +autoMode
+ + +AutoMode + + + + +(Optional) + + + + restrictPrivateSubnets
bool @@ -7156,163 +7197,729 @@ KubeProxy -networkStatus
+networkStatus
+ + +NetworkStatus + + + + +(Optional) +

Networks holds details about the AWS networking resources used by the control plane

+ + + + +failureDomains
+ + +Cluster API api/v1beta1.FailureDomains + + + + +(Optional) +

FailureDomains specifies a list fo available availability zones that can be used

+ + + + +bastion
+ + +Instance + + + + +(Optional) +

Bastion holds details of the instance that is used as a bastion jump box

+ + + + +oidcProvider
+ + +OIDCProviderStatus + + + + +(Optional) +

OIDCProvider holds the status of the identity provider for this cluster

+ + + + +externalManagedControlPlane
+ +bool + + + +

ExternalManagedControlPlane indicates to cluster-api that the control plane +is managed by an external service such as AKS, EKS, GKE, etc.

+ + + + +initialized
+ +bool + + + +(Optional) +

Initialized denotes whether or not the control plane has the +uploaded kubernetes config-map.

+ + + + +ready
+ +bool + + + +

Ready denotes that the AWSManagedControlPlane API Server is ready to +receive requests and that the VPC infra is ready.

+ + + + +failureMessage
+ +string + + + +(Optional) +

ErrorMessage indicates that there is a terminal problem reconciling the +state, and will be set to a descriptive error message.

+ + + + +conditions
+ + +Cluster API api/v1beta1.Conditions + + + + +

Conditions specifies the cpnditions for the managed control plane

+ + + + +addons
+ + +[]AddonState + + + + +(Optional) +

Addons holds the current status of the EKS addons

+ + + + +identityProviderStatus
+ + +IdentityProviderStatus + + + + +(Optional) +

IdentityProviderStatus holds the status for +associated identity provider

+ + + + +version
+ +string + + + +(Optional) +

Version represents the minimum Kubernetes version for the control plane machines +in the cluster.

+ + + + +

AWSManagedControlPlaneTemplate +

+

+

AWSManagedControlPlaneTemplate is the Schema for the AWSManagedControlPlaneTemplates API.

+

+ + + + + + + + + + + + + + + + + +
FieldDescription
+metadata
+ + +Kubernetes meta/v1.ObjectMeta + + +
+Refer to the Kubernetes API documentation for the fields of the +metadata field. +
+spec
+ + +AWSManagedControlPlaneTemplateSpec + + +
+
+
+ + + + + +
+template
+ + +AWSManagedControlPlaneTemplateResource + + +
+
+
+

AWSManagedControlPlaneTemplateResource +

+

+(Appears on:AWSManagedControlPlaneTemplateSpec) +

+

+

AWSManagedControlPlaneTemplateResource describes the data needed to create an AWSManagedCluster from a template.

+

+ + + + + + + + + + + + +
FieldDescription
+spec
+ + +AWSManagedControlPlaneSpec + + +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+eksClusterName
+ +string + +
+(Optional) +

EKSClusterName allows you to specify the name of the EKS cluster in +AWS. If you don’t specify a name then a default name will be created +based on the namespace and name of the managed control plane.

+
+identityRef
+ + +AWSIdentityReference + + +
+(Optional) +

IdentityRef is a reference to an identity to be used when reconciling the managed control plane. +If no identity is specified, the default identity for this controller will be used.

+
+network
+ + +NetworkSpec + + +
+

NetworkSpec encapsulates all things related to AWS network.

+
+secondaryCidrBlock
+ +string + +
+(Optional) +

SecondaryCidrBlock is the additional CIDR range to use for pod IPs. +Must be within the 100.64.0.0/10 or 198.19.0.0/16 range.

+
+region
+ +string + +
+

The AWS Region the cluster lives in.

+
+partition
+ +string + +
+(Optional) +

Partition is the AWS security partition being used. Defaults to “aws”

+
+sshKeyName
+ +string + +
+(Optional) +

SSHKeyName is the name of the ssh key to attach to the bastion host. Valid values are empty string (do not use SSH keys), a valid SSH key name, or omitted (use the default SSH key name)

+
+version
+ +string + +
+(Optional) +

Version defines the desired Kubernetes version. If no version number +is supplied then the latest version of Kubernetes that EKS supports +will be used.

+
+roleName
+ +string + +
+(Optional) +

RoleName specifies the name of IAM role that gives EKS +permission to make API calls. If the role is pre-existing +we will treat it as unmanaged and not delete it on +deletion. If the EKSEnableIAM feature flag is true +and no name is supplied then a role is created.

+
+roleAdditionalPolicies
+ +[]string + +
+(Optional) +

RoleAdditionalPolicies allows you to attach additional polices to +the control plane role. You must enable the EKSAllowAddRoles +feature flag to incorporate these into the created role.

+
+rolePath
+ +string + +
+(Optional) +

RolePath sets the path to the role. For more information about paths, see IAM Identifiers +(https://docs.aws.amazon.com/IAM/latest/UserGuide/Using_Identifiers.html) +in the IAM User Guide.

+

This parameter is optional. If it is not included, it defaults to a slash +(/).

+
+rolePermissionsBoundary
+ +string + +
+(Optional) +

RolePermissionsBoundary sets the ARN of the managed policy that is used +to set the permissions boundary for the role.

+

A permissions boundary policy defines the maximum permissions that identity-based +policies can grant to an entity, but does not grant permissions. Permissions +boundaries do not define the maximum permissions that a resource-based policy +can grant to an entity. To learn more, see Permissions boundaries for IAM +entities (https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_boundaries.html) +in the IAM User Guide.

+

For more information about policy types, see Policy types (https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#access_policy-types) +in the IAM User Guide.

+
+logging
+ + +ControlPlaneLoggingSpec + + +
+(Optional) +

Logging specifies which EKS Cluster logs should be enabled. Entries for +each of the enabled logs will be sent to CloudWatch

+
+encryptionConfig
+ + +EncryptionConfig + + +
+(Optional) +

EncryptionConfig specifies the encryption configuration for the cluster

+
+additionalTags
+ + +Tags + + +
+(Optional) +

AdditionalTags is an optional set of tags to add to AWS resources managed by the AWS provider, in addition to the +ones added by default.

+
+iamAuthenticatorConfig
+ + +IAMAuthenticatorConfig + + +
+(Optional) +

IAMAuthenticatorConfig allows the specification of any additional user or role mappings +for use when generating the aws-iam-authenticator configuration. If this is nil the +default configuration is still generated for the cluster.

+
+endpointAccess
+ + +EndpointAccess + + +
+(Optional) +

Endpoints specifies access to this cluster’s control plane endpoints

+
+controlPlaneEndpoint
+ + +Cluster API api/v1beta1.APIEndpoint + + +
+(Optional) +

ControlPlaneEndpoint represents the endpoint used to communicate with the control plane.

+
+imageLookupFormat
+ +string + +
+(Optional) +

ImageLookupFormat is the AMI naming format to look up machine images when +a machine does not specify an AMI. When set, this will be used for all +cluster machines unless a machine specifies a different ImageLookupOrg. +Supports substitutions for {{.BaseOS}} and {{.K8sVersion}} with the base +OS and kubernetes version, respectively. The BaseOS will be the value in +ImageLookupBaseOS or ubuntu (the default), and the kubernetes version as +defined by the packages produced by kubernetes/release without v as a +prefix: 1.13.0, 1.12.5-mybuild.1, or 1.17.3. For example, the default +image format of capa-ami-{{.BaseOS}}-?{{.K8sVersion}}-* will end up +searching for AMIs that match the pattern capa-ami-ubuntu-?1.18.0-* for a +Machine that is targeting kubernetes v1.18.0 and the ubuntu base OS. See +also: https://golang.org/pkg/text/template/

+
+imageLookupOrg
- -NetworkStatus - +string
(Optional) -

Networks holds details about the AWS networking resources used by the control plane

+

ImageLookupOrg is the AWS Organization ID to look up machine images when a +machine does not specify an AMI. When set, this will be used for all +cluster machines unless a machine specifies a different ImageLookupOrg.

-failureDomains
+imageLookupBaseOS
- -Cluster API api/v1beta1.FailureDomains - +string
-(Optional) -

FailureDomains specifies a list fo available availability zones that can be used

+

ImageLookupBaseOS is the name of the base operating system used to look +up machine images when a machine does not specify an AMI. When set, this +will be used for all cluster machines unless a machine specifies a +different ImageLookupBaseOS.

bastion
- -Instance + +Bastion
(Optional) -

Bastion holds details of the instance that is used as a bastion jump box

+

Bastion contains options to configure the bastion host.

-oidcProvider
+tokenMethod
- -OIDCProviderStatus + +EKSTokenMethod
-(Optional) -

OIDCProvider holds the status of the identity provider for this cluster

+

TokenMethod is used to specify the method for obtaining a client token for communicating with EKS +iam-authenticator - obtains a client token using iam-authentictor +aws-cli - obtains a client token using the AWS CLI +Defaults to iam-authenticator

-externalManagedControlPlane
+associateOIDCProvider
bool
-

ExternalManagedControlPlane indicates to cluster-api that the control plane -is managed by an external service such as AKS, EKS, GKE, etc.

+

AssociateOIDCProvider can be enabled to automatically create an identity +provider for the controller for use with IAM roles for service accounts

-initialized
+addons
-bool + +[]sigs.k8s.io/cluster-api-provider-aws/v2/controlplane/eks/api/v1beta2.Addon +
(Optional) -

Initialized denotes whether or not the control plane has the -uploaded kubernetes config-map.

+

Addons defines the EKS addons to enable with the EKS cluster.

-ready
+oidcIdentityProviderConfig
-bool + +OIDCIdentityProviderConfig +
-

Ready denotes that the AWSManagedControlPlane API Server is ready to -receive requests and that the VPC infra is ready.

+(Optional) +

IdentityProviderconfig is used to specify the oidc provider config +to be attached with this eks cluster

-failureMessage
+vpcCni
-string + +VpcCni +
(Optional) -

ErrorMessage indicates that there is a terminal problem reconciling the -state, and will be set to a descriptive error message.

+

VpcCni is used to set configuration options for the VPC CNI plugin

-conditions
+bootstrapSelfManagedAddons
- -Cluster API api/v1beta1.Conditions - +bool
-

Conditions specifies the cpnditions for the managed control plane

+

BootstrapSelfManagedAddons is used to set configuration options for +bare EKS cluster without EKS default networking addons +If you set this value to false when creating a cluster, the default networking add-ons will not be installed

-addons
+autoMode
- -[]AddonState + +AutoMode
(Optional) -

Addons holds the current status of the EKS addons

-identityProviderStatus
+restrictPrivateSubnets
- -IdentityProviderStatus +bool + +
+

RestrictPrivateSubnets indicates that the EKS control plane should only use private subnets.

+
+kubeProxy
+ + +KubeProxy
-(Optional) -

IdentityProviderStatus holds the status for -associated identity provider

+

KubeProxy defines managed attributes of the kube-proxy daemonset

+
+

AWSManagedControlPlaneTemplateSpec +

+

+(Appears on:AWSManagedControlPlaneTemplate) +

+

+

AWSManagedControlPlaneTemplateSpec defines the desired state of AWSManagedControlPlaneTemplate.

+

+ + + + + + + + @@ -7375,7 +7982,7 @@ AddonResolution @@ -7390,6 +7997,19 @@ string

ServiceAccountRoleArn is the ARN of an IAM role to bind to the addons service account

+ + + +
FieldDescription
-version
+template
-string + +AWSManagedControlPlaneTemplateResource +
-(Optional) -

Version represents the minimum Kubernetes version for the control plane machines -in the cluster.

ConflictResolution is used to declare what should happen if there -are parameter conflicts. Defaults to none

+are parameter conflicts. Defaults to overwrite

+preserveOnDelete
+ +bool + +
+(Optional) +

PreserveOnDelete indicates that the addon resources should be +preserved in the cluster on delete.

+

AddonIssue @@ -7568,6 +8188,94 @@ string

AddonStatus defines the status for an addon.

+

AutoMode +

+

+(Appears on:AWSManagedControlPlaneSpec) +

+

+

AutoMode is the EKS Auto Mode. +allows to create cluster with aws compute, ebs, elb capabilities.

+

+ + + + + + + + + + + + + + + + + +
FieldDescription
+enabled
+ +bool + +
+

Enabled will enable EKS Auto Mode.

+
+compute
+ + +Compute + + +
+(Optional) +

Compute capability configuration for EKS Auto Mode.

+
+

Compute +

+

+(Appears on:AutoMode) +

+

+

Compute allows to run compute capability with EKS AutoMode.

+

+ + + + + + + + + + + + + + + + + +
FieldDescription
+nodePools
+ +[]string + +
+

NodePools that defines the compute resources for your EKS Auto Mode cluster.

+
+nodeRoleArn
+ +string + +
+(Optional) +

NodeRoleArn the ARN of the IAM Role EKS will assign to EC2 Managed Instances in your EKS +Auto Mode cluster. This value cannot be changed after the compute capability of +EKS Auto Mode is enabled. For more information, see the IAM Reference in the +Amazon EKS User Guide.

+

ControlPlaneLoggingSpec

@@ -8682,6 +9390,9 @@ string

"candidate"

Candidate channel group is for testing candidate builds.

+

"fast"

+

Fast channel group is for fast channel releases.

+

"nightly"

Nightly channel group is for testing nigtly builds.

@@ -20034,21 +20745,65 @@ string -marketType
+marketType
+ + +MarketType + + + + +(Optional) +

MarketType specifies the type of market for the EC2 instance. Valid values include: +“OnDemand” (default): The instance runs as a standard OnDemand instance. +“Spot”: The instance runs as a Spot instance. When SpotMarketOptions is provided, the marketType defaults to “Spot”. +“CapacityBlock”: The instance utilizes pre-purchased compute capacity (capacity blocks) with AWS Capacity Reservations. +If this value is selected, CapacityReservationID must be specified to identify the target reservation. +If marketType is not specified and spotMarketOptions is provided, the marketType defaults to “Spot”.

+ + + + +hostID
+ +string + + + +(Optional) +

HostID specifies the Dedicated Host on which the instance must be started.

+ + + + +hostAffinity
+ +string + + + +(Optional) +

HostAffinity specifies the dedicated host affinity setting for the instance. +When hostAffinity is set to host, an instance started onto a specific host always restarts on the same host if stopped. +When hostAffinity is set to default, and you stop and restart the instance, it can be restarted on any available host. +When HostAffinity is defined, HostID is required.

+ + + + +capacityReservationPreference
- -MarketType + +CapacityReservationPreference (Optional) -

MarketType specifies the type of market for the EC2 instance. Valid values include: -“OnDemand” (default): The instance runs as a standard OnDemand instance. -“Spot”: The instance runs as a Spot instance. When SpotMarketOptions is provided, the marketType defaults to “Spot”. -“CapacityBlock”: The instance utilizes pre-purchased compute capacity (capacity blocks) with AWS Capacity Reservations. -If this value is selected, CapacityReservationID must be specified to identify the target reservation. -If marketType is not specified and spotMarketOptions is provided, the marketType defaults to “Spot”.

+

CapacityReservationPreference specifies the preference for use of Capacity Reservations by the instance. Valid values include: +“Open”: The instance may make use of open Capacity Reservations that match its AZ and InstanceType +“None”: The instance may not make use of any Capacity Reservations. This is to conserve open reservations for desired workloads +“CapacityReservationsOnly”: The instance will only run if matched or targeted to a Capacity Reservation. Note that this is incompatible with a MarketType of Spot

@@ -20505,6 +21260,50 @@ If this value is selected, CapacityReservationID must be specified to identify t If marketType is not specified and spotMarketOptions is provided, the marketType defaults to “Spot”.

+ + +hostID
+ +string + + + +(Optional) +

HostID specifies the Dedicated Host on which the instance must be started.

+ + + + +hostAffinity
+ +string + + + +(Optional) +

HostAffinity specifies the dedicated host affinity setting for the instance. +When hostAffinity is set to host, an instance started onto a specific host always restarts on the same host if stopped. +When hostAffinity is set to default, and you stop and restart the instance, it can be restarted on any available host. +When HostAffinity is defined, HostID is required.

+ + + + +capacityReservationPreference
+ + +CapacityReservationPreference + + + + +(Optional) +

CapacityReservationPreference specifies the preference for use of Capacity Reservations by the instance. Valid values include: +“Open”: The instance may make use of open Capacity Reservations that match its AZ and InstanceType +“None”: The instance may not make use of any Capacity Reservations. This is to conserve open reservations for desired workloads +“CapacityReservationsOnly”: The instance will only run if matched or targeted to a Capacity Reservation. Note that this is incompatible with a MarketType of Spot

+ +

AWSMachineStatus @@ -21173,6 +21972,50 @@ If this value is selected, CapacityReservationID must be specified to identify t If marketType is not specified and spotMarketOptions is provided, the marketType defaults to “Spot”.

+ + +hostID
+ +string + + + +(Optional) +

HostID specifies the Dedicated Host on which the instance must be started.

+ + + + +hostAffinity
+ +string + + + +(Optional) +

HostAffinity specifies the dedicated host affinity setting for the instance. +When hostAffinity is set to host, an instance started onto a specific host always restarts on the same host if stopped. +When hostAffinity is set to default, and you stop and restart the instance, it can be restarted on any available host. +When HostAffinity is defined, HostID is required.

+ + + + +capacityReservationPreference
+ + +CapacityReservationPreference + + + + +(Optional) +

CapacityReservationPreference specifies the preference for use of Capacity Reservations by the instance. Valid values include: +“Open”: The instance may make use of open Capacity Reservations that match its AZ and InstanceType +“None”: The instance may not make use of any Capacity Reservations. This is to conserve open reservations for desired workloads +“CapacityReservationsOnly”: The instance will only run if matched or targeted to a Capacity Reservation. Note that this is incompatible with a MarketType of Spot

+ + @@ -21322,7 +22165,7 @@ AWSManagedClusterStatus

AWSManagedClusterSpec

-(Appears on:AWSManagedCluster) +(Appears on:AWSManagedCluster, AWSManagedClusterTemplateResource)

AWSManagedClusterSpec defines the desired state of AWSManagedCluster

@@ -21409,6 +22252,141 @@ Cluster API api/v1beta1.Conditions +

AWSManagedClusterTemplate +

+

+

AWSManagedClusterTemplate is the Schema for the AWSManagedClusterTemplates API.

+

+ + + + + + + + + + + + + + + + + +
FieldDescription
+metadata
+ + +Kubernetes meta/v1.ObjectMeta + + +
+Refer to the Kubernetes API documentation for the fields of the +metadata field. +
+spec
+ + +AWSManagedClusterTemplateSpec + + +
+
+
+ + + + + +
+template
+ + +AWSManagedClusterTemplateResource + + +
+
+
+

AWSManagedClusterTemplateResource +

+

+(Appears on:AWSManagedClusterTemplateSpec) +

+

+

AWSManagedClusterTemplateResource describes the data needed to create an AWSManagedCluster from a template.

+

+ + + + + + + + + + + + + +
FieldDescription
+spec
+ + +AWSManagedClusterSpec + + +
+
+
+ + + + + +
+controlPlaneEndpoint
+ + +Cluster API api/v1beta1.APIEndpoint + + +
+(Optional) +

ControlPlaneEndpoint represents the endpoint used to communicate with the control plane.

+
+
+

AWSManagedClusterTemplateSpec +

+

+(Appears on:AWSManagedClusterTemplate) +

+

+

AWSManagedClusterTemplateSpec defines the desired state of AWSManagedClusterTemplate.

+

+ + + + + + + + + + + + + +
FieldDescription
+template
+ + +AWSManagedClusterTemplateResource + + +
+

AWSResourceReference

@@ -21914,6 +22892,15 @@ The source for the rule will be set to control plane and worker security group I +

CapacityReservationPreference +(string alias)

+

+(Appears on:AWSMachineSpec, Instance, AWSLaunchTemplate) +

+

+

CapacityReservationPreference describes the preferred use of capacity reservations +of an instance

+

ClassicELBAttributes

@@ -22447,7 +23434,9 @@ string (Optional) -

Version defines which version of Ignition will be used to generate bootstrap data.

+

Version defines which version of Ignition will be used to generate bootstrap data. +Defaults to 2.3 if storageType is set to ClusterObjectStore. +It will be ignored if storageType is set to UnencryptedUserData, as the userdata defines its own version.

@@ -23150,6 +24139,50 @@ If this value is selected, CapacityReservationID must be specified to identify t If marketType is not specified and spotMarketOptions is provided, the marketType defaults to “Spot”.

+ + +hostAffinity
+ +string + + + +(Optional) +

HostAffinity specifies the dedicated host affinity setting for the instance. +When hostAffinity is set to host, an instance started onto a specific host always restarts on the same host if stopped. +When hostAffinity is set to default, and you stop and restart the instance, it can be restarted on any available host. +When HostAffinity is defined, HostID is required.

+ + + + +hostID
+ +string + + + +(Optional) +

HostID specifies the dedicated host on which the instance should be started.

+ + + + +capacityReservationPreference
+ + +CapacityReservationPreference + + + + +(Optional) +

CapacityReservationPreference specifies the preference for use of Capacity Reservations by the instance. Valid values include: +“Open”: The instance may make use of open Capacity Reservations that match its AZ and InstanceType +“None”: The instance may not make use of any Capacity Reservations. This is to conserve open reservations for desired workloads +“CapacityReservationsOnly”: The instance will only run if matched or targeted to a Capacity Reservation. Note that this is incompatible with a MarketType of Spot

+ +

InstanceMetadataOptions @@ -25375,6 +26408,23 @@ If this value is selected, CapacityReservationID must be specified to identify t If marketType is not specified and spotMarketOptions is provided, the marketType defaults to “Spot”.

+ + +capacityReservationPreference
+ + +CapacityReservationPreference + + + + +(Optional) +

CapacityReservationPreference specifies the preference for use of Capacity Reservations by the instance. Valid values include: +“Open”: The instance may make use of open Capacity Reservations that match its AZ and InstanceType +“None”: The instance may not make use of any Capacity Reservations. This is to conserve open reservations for desired workloads +“CapacityReservationsOnly”: The instance will only run if matched or targeted to a Capacity Reservation

+ +

AWSLifecycleHook @@ -26225,6 +27275,11 @@ ASGStatus +

AWSMachinePoolWebhook +

+

+

AWSMachinePoolWebhook implements a custom validation webhook for AWSMachinePool.

+

AWSManagedMachinePool

@@ -27735,7 +28790,9 @@ int64 (Appears on:AWSManagedMachinePoolSpec)

-

ManagedMachineAMIType specifies which AWS AMI to use for a managed MachinePool.

+

ManagedMachineAMIType specifies which AWS AMI to use for a managed MachinePool. +Source of truth can be found using the link below: +https://docs.aws.amazon.com/eks/latest/APIReference/API_CreateNodegroup.html#AmazonEKS-CreateNodegroup-request-amiType

@@ -27747,9 +28804,18 @@ int64 + + + + + + @@ -27759,6 +28825,39 @@ int64 + + + + + + + + + + + + + + + + + + + + + +

"AL2023_ARM_64_STANDARD"

Al2023Arm64 is the AL2023 Arm AMI type.

"AL2023_ARM_64_NVIDIA"

Al2023Arm64Nvidia is the AL2023 Arm Nvidia AMI type.

+

"AL2023_x86_64_STANDARD"

Al2023x86_64 is the AL2023 x86-64 AMI type.

"AL2023_x86_64_NEURON"

Al2023x86_64Neuron is the AL2023 x86-64 Neuron AMI type.

+

"AL2023_x86_64_NVIDIA"

Al2023x86_64Nvidia is the AL2023 x86-64 Nvidia AMI type.

+

"AL2_ARM_64"

Al2Arm64 is the Arm AMI type.

"AL2_x86_64_GPU"

Al2x86_64GPU is the x86-64 GPU AMI type.

"BOTTLEROCKET_ARM_64"

BottleRocketArm64 is the Arm AMI type.

+

"BOTTLEROCKET_ARM_64_FIPS"

BottleRocketArm64Fips is the BottleRocket Arm Fips AMI type.

+

"BOTTLEROCKET_ARM_64_NVIDIA"

BottleRocketArm64Nvidia is the BottleRocket Arm Nvidia AMI type.

+

"BOTTLEROCKET_x86_64"

BottleRocketx86_64 is the BottleRocket x86-64 AMI type.

+

"BOTTLEROCKET_x86_64_FIPS"

BottleRocketx86_64Fips is the BottleRocket x86-64 Fips AMI type.

+

"BOTTLEROCKET_x86_64_NVIDIA"

BottleRocketx86_64Nvidia is the BottleRocket x86-64 Nvidia AMI type.

+

"CUSTOM"

Custom is the custom AMI type.

+

"WINDOWS_CORE_2019_x86_64"

WindowsCore2019x86_64 is the Windows Core 2019 x86-64 AMI type.

+

"WINDOWS_CORE_2022_x86_64"

WindowsCore2022x86_64 is the Windows Core 2022 x86-64 AMI type.

+

"WINDOWS_FULL_2019_x86_64"

WindowsFull2019x86_64 is the Windows Full 2019 x86-64 AMI type.

+

"WINDOWS_FULL_2022_x86_64"

WindowsFull2022x86_64 is the Windows Full 2022 x86-64 AMI type.

+

ManagedMachinePoolCapacityType diff --git a/pkg/cloud/scope/managedcontrolplane.go b/pkg/cloud/scope/managedcontrolplane.go index be0bc76864..c966f5cac4 100644 --- a/pkg/cloud/scope/managedcontrolplane.go +++ b/pkg/cloud/scope/managedcontrolplane.go @@ -430,6 +430,14 @@ func (s *ManagedControlPlaneScope) BootstrapSelfManagedAddons() *bool { return &s.ControlPlane.Spec.BootstrapSelfManagedAddons } +// IsAutoModeEnabled returns whether compute capability should be enabled with EKS Auto Mode. +func (s *ManagedControlPlaneScope) IsAutoModeEnabled() bool { + if s.ControlPlane.Spec.AutoMode != nil { + return s.ControlPlane.Spec.AutoMode.Enabled + } + return false +} + // VpcCni returns a list of environment variables to apply to the `aws-node` DaemonSet. func (s *ManagedControlPlaneScope) VpcCni() ekscontrolplanev1.VpcCni { return s.ControlPlane.Spec.VpcCni diff --git a/pkg/cloud/services/eks/cluster.go b/pkg/cloud/services/eks/cluster.go index b1b480e0b2..cfd2c0b898 100644 --- a/pkg/cloud/services/eks/cluster.go +++ b/pkg/cloud/services/eks/cluster.go @@ -301,7 +301,18 @@ func makeEksEncryptionConfigs(encryptionConfig *ekscontrolplanev1.EncryptionConf }) } -func makeKubernetesNetworkConfig(serviceCidrs *clusterv1.NetworkRanges) (*ekstypes.KubernetesNetworkConfigRequest, error) { +func makeKubernetesNetworkConfig(serviceCidrs *clusterv1.NetworkRanges, isIPv6Enabled, isAutoModeEnabled bool) (*ekstypes.KubernetesNetworkConfigRequest, error) { + netConfig := new(ekstypes.KubernetesNetworkConfigRequest) + + if isAutoModeEnabled { + netConfig.ElasticLoadBalancing = &ekstypes.ElasticLoadBalancing{Enabled: aws.Bool(true)} + } + + if isIPv6Enabled { + netConfig.IpFamily = ekstypes.IpFamilyIpv6 + return netConfig, nil + } + if serviceCidrs == nil || len(serviceCidrs.CIDRBlocks) == 0 { return nil, nil } @@ -440,16 +451,9 @@ func (s *Service) createCluster(ctx context.Context, eksClusterName string) (*ek accessConfig.BootstrapClusterCreatorAdminPermissions = s.scope.ControlPlane.Spec.AccessConfig.BootstrapClusterCreatorAdminPermissions } - var netConfig *ekstypes.KubernetesNetworkConfigRequest - if s.scope.VPC().IsIPv6Enabled() { - netConfig = &ekstypes.KubernetesNetworkConfigRequest{ - IpFamily: ekstypes.IpFamilyIpv6, - } - } else { - netConfig, err = makeKubernetesNetworkConfig(s.scope.ServiceCidrs()) - if err != nil { - return nil, errors.Wrap(err, "couldn't create Kubernetes network config for cluster") - } + netConfig, err := makeKubernetesNetworkConfig(s.scope.ServiceCidrs(), s.scope.VPC().IsIPv6Enabled(), s.scope.IsAutoModeEnabled()) + if err != nil { + return nil, errors.Wrap(err, "couldn't create Kubernetes network config for cluster") } // Make sure to use the MachineScope here to get the merger of AWSCluster and AWSMachine tags @@ -492,6 +496,18 @@ func (s *Service) createCluster(ctx context.Context, eksClusterName string) (*ek BootstrapSelfManagedAddons: bootstrapAddon, } + // Enable EKS Auto Mode compute capability enabled. + if s.scope.IsAutoModeEnabled() { + input.ComputeConfig = &ekstypes.ComputeConfigRequest{Enabled: aws.Bool(true)} + input.StorageConfig = &ekstypes.StorageConfigRequest{BlockStorage: &ekstypes.BlockStorage{Enabled: aws.Bool(true)}} + + // nodePools could be not set, that's ok. + if len(s.scope.ControlPlane.Spec.AutoMode.Compute.NodePools) > 0 { + input.ComputeConfig.NodePools = s.scope.ControlPlane.Spec.AutoMode.Compute.NodePools + input.ComputeConfig.NodeRoleArn = s.scope.ControlPlane.Spec.AutoMode.Compute.NodeRoleArn + } + } + var out *eks.CreateClusterOutput if err := wait.WaitForWithRetryable(wait.NewBackoff(), func() (bool, error) { if out, err = s.EKSClient.CreateCluster(ctx, input); err != nil {