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