Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions examples/46-deletion-protection-example.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# A sample ClusterConfig file that creates a cluster with deletion protection enabled.

# DeletionProtection prevents accidental cluster deletion
# Valid values are true or false (default)
# - https://docs.aws.amazon.com/eks/latest/APIReference/API_CreateCluster.html
# - https://docs.aws.amazon.com/eks/latest/APIReference/API_CreateCluster.html#AmazonEKS-CreateCluster-request-deletionProtection

apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig

metadata:
name: deletion-protection-cluster
region: us-west-2

deletionProtection: true

managedNodeGroups:
- name: mng-1
desiredCapacity: 1
6 changes: 6 additions & 0 deletions pkg/apis/eksctl.io/v1alpha5/assets/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,11 @@
"description": "See [CloudWatch support](/usage/cloudwatch-cluster-logging/)",
"x-intellij-html-description": "See <a href=\"/usage/cloudwatch-cluster-logging/\">CloudWatch support</a>"
},
"deletionProtection": {
"type": "boolean",
"description": "specifies whether deletion protection is enabled for the cluster",
"x-intellij-html-description": "specifies whether deletion protection is enabled for the cluster"
},
"fargateProfiles": {
"items": {
"$ref": "#/definitions/FargateProfile"
Expand Down Expand Up @@ -569,6 +574,7 @@
"apiVersion",
"metadata",
"upgradePolicy",
"deletionProtection",
"kubernetesNetworkConfig",
"autoModeConfig",
"remoteNetworkConfig",
Expand Down
4 changes: 4 additions & 0 deletions pkg/apis/eksctl.io/v1alpha5/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -966,6 +966,10 @@ type ClusterConfig struct {
// +optional
UpgradePolicy *UpgradePolicy `json:"upgradePolicy,omitempty"`

// DeletionProtection specifies whether deletion protection is enabled for the cluster
// +optional
DeletionProtection *bool `json:"deletionProtection,omitempty"`

// +optional
KubernetesNetworkConfig *KubernetesNetworkConfig `json:"kubernetesNetworkConfig,omitempty"`

Expand Down
5 changes: 5 additions & 0 deletions pkg/apis/eksctl.io/v1alpha5/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions pkg/cfn/builder/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,11 @@ func (c *ClusterResourceSet) addResourcesForControlPlane(subnetDetails *SubnetDe
}
}

var deletionProtection *gfnt.Value
if c.spec.DeletionProtection != nil {
deletionProtection = gfnt.NewBoolean(*c.spec.DeletionProtection)
}

cluster := gfneks.Cluster{
EncryptionConfig: encryptionConfigs,
Logging: makeClusterLogging(c.spec),
Expand All @@ -372,6 +377,7 @@ func (c *ClusterResourceSet) addResourcesForControlPlane(subnetDetails *SubnetDe
RoleArn: serviceRoleARN,
BootstrapSelfManagedAddons: gfnt.NewBoolean(false),
UpgradePolicy: upgradePolicy,
DeletionProtection: deletionProtection,
AccessConfig: &gfneks.Cluster_AccessConfig{
AuthenticationMode: gfnt.NewString(string(c.spec.AccessConfig.AuthenticationMode)),
BootstrapClusterCreatorAdminPermissions: gfnt.NewBoolean(!api.IsDisabled(c.spec.AccessConfig.BootstrapClusterCreatorAdminPermissions)),
Expand Down
80 changes: 80 additions & 0 deletions pkg/ctl/utils/update_deletion_protection.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package utils

import (
"context"
"fmt"
"strconv"

"github.com/kris-nova/logger"
"github.com/spf13/cobra"
"github.com/spf13/pflag"

api "github.com/weaveworks/eksctl/pkg/apis/eksctl.io/v1alpha5"
"github.com/weaveworks/eksctl/pkg/ctl/cmdutils"
)

func updateClusterDeletionProtectionCmd(cmd *cmdutils.Cmd) {
cfg := api.NewClusterConfig()
cmd.ClusterConfig = cfg

var enabled string

cmd.SetDescription("deletion-protection", "Update cluster deletion protection", "")

cmdutils.AddCommonFlagsForAWS(cmd, &cmd.ProviderConfig, false)

cmd.FlagSetGroup.InFlagSet("General", func(fs *pflag.FlagSet) {
fs.StringVarP(&cfg.Metadata.Name, "name", "n", "", "EKS cluster name")
cmdutils.AddRegionFlag(fs, &cmd.ProviderConfig)
cmdutils.AddConfigFileFlag(fs, &cmd.ClusterConfigFile)
cmdutils.AddApproveFlag(fs, cmd)
fs.StringVar(&enabled, "enabled", "", "Enable or disable deletion protection (true|false)")
})

cmd.CobraCommand.RunE = func(_ *cobra.Command, args []string) error {
cmd.NameArg = cmdutils.GetNameArg(args)

if enabled == "" {
return fmt.Errorf("--enabled flag is required (true|false)")
}

val, err := strconv.ParseBool(enabled)
if err != nil {
return fmt.Errorf("--enabled must be 'true' or 'false', got: %s", enabled)
}

cfg.DeletionProtection = &val

return doUpdateClusterDeletionProtection(cmd)
}
}

func doUpdateClusterDeletionProtection(cmd *cmdutils.Cmd) error {
ctx := context.Background()
if err := cmdutils.NewMetadataLoader(cmd).Load(); err != nil {
return err
}

cfg := cmd.ClusterConfig
if cfg.Metadata.Name == "" {
return fmt.Errorf("cluster name is required")
}

ctl, err := cmd.NewProviderForExistingCluster(ctx)
if err != nil {
return err
}

if cmd.Plan {
logger.Critical("--dry-run is not supported for this command")
return nil
}

action := "disabling"
if cfg.DeletionProtection != nil && *cfg.DeletionProtection {
action = "enabling"
}

logger.Info("%s deletion protection for cluster %q", action, cfg.Metadata.Name)
return ctl.UpdateClusterConfigForDeletionProtection(ctx, cfg)
}
1 change: 1 addition & 0 deletions pkg/ctl/utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ func Command(flagGrouping *cmdutils.FlagGrouping) *cobra.Command {
cmdutils.AddResourceCmd(flagGrouping, verbCmd, updateClusterEndpointsCmd)
cmdutils.AddResourceCmd(flagGrouping, verbCmd, publicAccessCIDRsCmd)
cmdutils.AddResourceCmd(flagGrouping, verbCmd, updateClusterVPCConfigCmd)
cmdutils.AddResourceCmd(flagGrouping, verbCmd, updateClusterDeletionProtectionCmd)
cmdutils.AddResourceCmd(flagGrouping, verbCmd, enableSecretsEncryptionCmd)
cmdutils.AddResourceCmd(flagGrouping, verbCmd, schemaCmd)
cmdutils.AddResourceCmd(flagGrouping, verbCmd, nodeGroupHealthCmd)
Expand Down
9 changes: 9 additions & 0 deletions pkg/eks/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,15 @@ func (c *ClusterProvider) UpdatePublicAccessCIDRs(ctx context.Context, clusterCo
return c.UpdateClusterConfig(ctx, input)
}

// UpdateClusterConfigForDeletionProtection calls eks.UpdateClusterConfig and updates deletion protection
func (c *ClusterProvider) UpdateClusterConfigForDeletionProtection(ctx context.Context, cfg *api.ClusterConfig) error {
input := &eks.UpdateClusterConfigInput{
Name: &cfg.Metadata.Name,
DeletionProtection: cfg.DeletionProtection,
}
return c.UpdateClusterConfig(ctx, input)
}

// UpdateClusterConfig calls EKS.UpdateClusterConfig and waits for the update to complete.
func (c *ClusterProvider) UpdateClusterConfig(ctx context.Context, input *eks.UpdateClusterConfigInput) error {
output, err := c.AWSProvider.EKS().UpdateClusterConfig(ctx, input)
Expand Down
5 changes: 5 additions & 0 deletions pkg/goformation/cloudformation/eks/aws-eks-cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ type Cluster struct {
// See: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-eks-cluster.html#cfn-eks-cluster-computeconfig
ComputeConfig *Cluster_ComputeConfig `json:"ComputeConfig,omitempty"`

// DeletionProtection AWS CloudFormation Property
// Required: false
// See: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-eks-cluster.html#cfn-eks-cluster-deletionprotection
DeletionProtection *types.Value `json:"DeletionProtection,omitempty"`

// EncryptionConfig AWS CloudFormation Property
// Required: false
// See: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-eks-cluster.html#cfn-eks-cluster-encryptionconfig
Expand Down
1 change: 1 addition & 0 deletions userdocs/mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ nav:
- usage/cluster-upgrade.md
- usage/addon-upgrade.md
- usage/upgrade-policy.md
- usage/deletion-protection.md
- usage/zonal-shift.md
- Nodegroups:
- usage/nodegroups.md
Expand Down
46 changes: 46 additions & 0 deletions userdocs/src/usage/deletion-protection.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Cluster Deletion Protection

This document describes how to configure deletion protection for your EKS cluster using eksctl.

## Overview

The `deletionProtection` field allows you to enable deletion protection for your EKS cluster. This prevents accidental cluster deletion.

## Configuration

You can specify deletion protection in your cluster configuration file:

```yaml
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig

metadata:
name: my-cluster
region: us-west-2

deletionProtection: true
```

## Command Line Usage

When creating a cluster with deletion protection:

```bash
eksctl create cluster --config-file=cluster-config.yaml
```

To update deletion protection on an existing cluster:

```bash
# Enable deletion protection
eksctl utils deletion-protection --name=my-cluster --enabled=true --approve

# Disable deletion protection
eksctl utils deletion-protection --name=my-cluster --enabled=false --approve
```

## Notes

- If no `deletionProtection` is specified, AWS will use its default behavior (false)
- Deletion protection can be set during cluster creation and updated later
- When enabled, you must disable deletion protection before you can delete the cluster
Loading