diff --git a/examples/45-upgrade-policy-example.yaml b/examples/45-upgrade-policy-example.yaml new file mode 100644 index 0000000000..6f14d657af --- /dev/null +++ b/examples/45-upgrade-policy-example.yaml @@ -0,0 +1,19 @@ +# A sample ClusterConfig file that creates a cluster with support type set as "EXTENDED (default)". + +# UpgradePolicy allows you to specify the support type for your cluster +# Valid values are "STANDARD" and "EXTENDED (default)" +# - https://docs.aws.amazon.com/eks/latest/APIReference/API_UpgradePolicyRequest.html + +apiVersion: eksctl.io/v1alpha5 +kind: ClusterConfig + +metadata: + name: upgrade-policy-cluster + region: us-west-2 + +upgradePolicy: + supportType: "EXTENDED" + +managedNodeGroups: + - name: mng-1 + desiredCapacity: 1 diff --git a/pkg/apis/eksctl.io/v1alpha5/assets/schema.json b/pkg/apis/eksctl.io/v1alpha5/assets/schema.json index 433939a36e..e2a15e4621 100755 --- a/pkg/apis/eksctl.io/v1alpha5/assets/schema.json +++ b/pkg/apis/eksctl.io/v1alpha5/assets/schema.json @@ -550,6 +550,11 @@ "secretsEncryption": { "$ref": "#/definitions/SecretsEncryption" }, + "upgradePolicy": { + "$ref": "#/definitions/UpgradePolicy", + "description": "specifies the upgrade policy for the cluster", + "x-intellij-html-description": "specifies the upgrade policy for the cluster" + }, "vpc": { "$ref": "#/definitions/ClusterVPC" }, @@ -563,6 +568,7 @@ "kind", "apiVersion", "metadata", + "upgradePolicy", "kubernetesNetworkConfig", "autoModeConfig", "remoteNetworkConfig", @@ -2719,6 +2725,26 @@ "description": "defines the configuration for KMS encryption provider", "x-intellij-html-description": "defines the configuration for KMS encryption provider" }, + "UpgradePolicy": { + "properties": { + "supportType": { + "type": "string", + "description": "specifies the support type for the cluster. Valid variants are: `\"STANDARD\"` standard support for the cluster, `\"EXTENDED\"` extended support for the cluster (default) defines the default support type.", + "x-intellij-html-description": "specifies the support type for the cluster. Valid variants are: "STANDARD" standard support for the cluster, "EXTENDED" extended support for the cluster (default) defines the default support type.", + "default": "EXTENDED", + "enum": [ + "STANDARD", + "EXTENDED" + ] + } + }, + "preferredOrder": [ + "supportType" + ], + "additionalProperties": false, + "description": "holds the upgrade policy configuration for the cluster", + "x-intellij-html-description": "holds the upgrade policy configuration for the cluster" + }, "VPCGateway": { "type": "string", "description": "VPCGatewayID the ID of the gateway that facilitates external connectivity from customer's VPC to their remote network(s). Valid options are Transit Gateway and Virtual Private Gateway.", diff --git a/pkg/apis/eksctl.io/v1alpha5/types.go b/pkg/apis/eksctl.io/v1alpha5/types.go index cda4a9f7b9..6671d6e944 100644 --- a/pkg/apis/eksctl.io/v1alpha5/types.go +++ b/pkg/apis/eksctl.io/v1alpha5/types.go @@ -451,6 +451,16 @@ const ( NoneCapacityReservation = "none" ) +// Values for `SupportType` +const ( + // SupportTypeStandard standard support for the cluster + SupportTypeStandard = "STANDARD" + // SupportTypeExtended extended support for the cluster (default) + SupportTypeExtended = "EXTENDED" + // DefaultSupportType defines the default support type + DefaultSupportType = SupportTypeExtended +) + var ( // DefaultIPFamily defines the default IP family to use when creating a new VPC and cluster. DefaultIPFamily = IPV4Family @@ -674,6 +684,14 @@ type ClusterMeta struct { AccountID string `json:"-"` } +// UpgradePolicy holds the upgrade policy configuration for the cluster +type UpgradePolicy struct { + // SupportType specifies the support type for the cluster. + // Valid variants are `SupportType` constants + // +optional + SupportType string `json:"supportType,omitempty"` +} + // KubernetesNetworkConfig contains cluster networking options type KubernetesNetworkConfig struct { // Valid variants are `IPFamily` constants @@ -935,6 +953,10 @@ type ClusterConfig struct { // +required Metadata *ClusterMeta `json:"metadata"` + // UpgradePolicy specifies the upgrade policy for the cluster + // +optional + UpgradePolicy *UpgradePolicy `json:"upgradePolicy,omitempty"` + // +optional KubernetesNetworkConfig *KubernetesNetworkConfig `json:"kubernetesNetworkConfig,omitempty"` diff --git a/pkg/apis/eksctl.io/v1alpha5/validation.go b/pkg/apis/eksctl.io/v1alpha5/validation.go index eb7a1181c1..4cee6b0470 100644 --- a/pkg/apis/eksctl.io/v1alpha5/validation.go +++ b/pkg/apis/eksctl.io/v1alpha5/validation.go @@ -143,8 +143,31 @@ func (c *ClusterConfig) validateRemoteNetworkingConfig() error { return nil } +// validateSupportType performs secure validation of the support type string +func validateSupportType(supportType string) error { + // Security: Validate characters to prevent injection attacks + for _, r := range supportType { + if r < 32 || r == 127 { // Control characters + return fmt.Errorf("upgradePolicy.supportType contains invalid control characters") + } + } + // Validate against allowed values + if supportType != SupportTypeStandard && supportType != SupportTypeExtended { + return fmt.Errorf("upgradePolicy.supportType must be either %q or %q", SupportTypeStandard, SupportTypeExtended) + } + return nil +} + // ValidateClusterConfig checks compatible fields of a given ClusterConfig func ValidateClusterConfig(cfg *ClusterConfig) error { + if cfg.UpgradePolicy != nil { + if cfg.UpgradePolicy.SupportType != "" { + if err := validateSupportType(cfg.UpgradePolicy.SupportType); err != nil { + return err + } + } + } + if IsDisabled(cfg.IAM.WithOIDC) && len(cfg.IAM.ServiceAccounts) > 0 { return fmt.Errorf("iam.withOIDC must be enabled explicitly for iam.serviceAccounts to be created") } diff --git a/pkg/apis/eksctl.io/v1alpha5/zz_generated.deepcopy.go b/pkg/apis/eksctl.io/v1alpha5/zz_generated.deepcopy.go index 6e3789ed76..8fa51a7250 100644 --- a/pkg/apis/eksctl.io/v1alpha5/zz_generated.deepcopy.go +++ b/pkg/apis/eksctl.io/v1alpha5/zz_generated.deepcopy.go @@ -554,6 +554,11 @@ func (in *ClusterConfig) DeepCopyInto(out *ClusterConfig) { *out = new(ZonalShiftConfig) (*in).DeepCopyInto(*out) } + if in.UpgradePolicy != nil { + in, out := &in.UpgradePolicy, &out.UpgradePolicy + *out = new(UpgradePolicy) + (*in).DeepCopyInto(*out) + } return } @@ -2388,6 +2393,22 @@ func (in *SecretsEncryption) DeepCopy() *SecretsEncryption { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *UpgradePolicy) DeepCopyInto(out *UpgradePolicy) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UpgradePolicy. +func (in *UpgradePolicy) DeepCopy() *UpgradePolicy { + if in == nil { + return nil + } + out := new(UpgradePolicy) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *VolumeMapping) DeepCopyInto(out *VolumeMapping) { *out = *in diff --git a/userdocs/mkdocs.yml b/userdocs/mkdocs.yml index c208bdd33a..c2f1823fe7 100644 --- a/userdocs/mkdocs.yml +++ b/userdocs/mkdocs.yml @@ -157,6 +157,7 @@ nav: - usage/fargate-support.md - usage/cluster-upgrade.md - usage/addon-upgrade.md + - usage/upgrade-policy.md - usage/zonal-shift.md - Nodegroups: - usage/nodegroups.md diff --git a/userdocs/src/usage/upgrade-policy.md b/userdocs/src/usage/upgrade-policy.md new file mode 100644 index 0000000000..fa650bbb2f --- /dev/null +++ b/userdocs/src/usage/upgrade-policy.md @@ -0,0 +1,42 @@ +# Cluster Upgrade Policy + +This document describes how to configure the upgrade policy for your EKS cluster using eksctl. + +## Overview + +The `upgradePolicy` field allows you to specify the support type for your EKS cluster. This determines the level of support AWS provides for your cluster version. + +## Support Types + +- **STANDARD**: The default support type that provides standard AWS support for the cluster +- **EXTENDED**: Provides extended support for older Kubernetes versions beyond the standard support period + +## Configuration + +You can specify the upgrade policy in your cluster configuration file: + +```yaml +apiVersion: eksctl.io/v1alpha5 +kind: ClusterConfig + +metadata: + name: my-cluster + region: us-west-2 + +upgradePolicy: + supportType: "EXTENDED" # or "STANDARD" +``` + +## Command Line Usage + +When creating a cluster with a specific upgrade policy: + +```bash +eksctl create cluster --config-file=cluster-config.yaml +``` + +## Notes + +- If no `upgradePolicy` is specified, AWS will use its default behavior +- The upgrade policy can only be set during cluster creation +- Extended support may incur additional costs - refer to AWS EKS pricing documentation