Skip to content

Commit

Permalink
Support EKS managed nodegroup node repair config (#8087)
Browse files Browse the repository at this point in the history
  • Loading branch information
cheeseandcereal authored Dec 13, 2024
1 parent 39899b0 commit 3a96038
Show file tree
Hide file tree
Showing 16 changed files with 349 additions and 7 deletions.
13 changes: 13 additions & 0 deletions examples/44-node-repair.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# An example ClusterConfig that uses a managed node group with auto repair.

apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig

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

managedNodeGroups:
- name: ng-1
nodeRepairConfig:
enabled: true
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ require (
github.com/aws/aws-sdk-go-v2/credentials v1.17.11
github.com/aws/aws-sdk-go-v2/service/autoscaling v1.51.1
github.com/aws/aws-sdk-go-v2/service/cloudformation v1.56.1
github.com/aws/aws-sdk-go-v2/service/cloudtrail v1.46.2
github.com/aws/aws-sdk-go-v2/service/cloudtrail v1.46.3
github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs v1.45.0
github.com/aws/aws-sdk-go-v2/service/cognitoidentityprovider v1.36.3
github.com/aws/aws-sdk-go-v2/service/ec2 v1.166.0
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -740,6 +740,8 @@ github.com/aws/aws-sdk-go-v2/service/cloudformation v1.56.1 h1:EqRhsrEoXFFyzcNuq
github.com/aws/aws-sdk-go-v2/service/cloudformation v1.56.1/go.mod h1:75rrfzgrN4Ol0m9Xo4+8S09KBoGAd1t6eafFHMt5wDI=
github.com/aws/aws-sdk-go-v2/service/cloudtrail v1.46.2 h1:DrN2vg75JseLCepYjMVav43e+v7+AhArtWlm2F0OJ6Y=
github.com/aws/aws-sdk-go-v2/service/cloudtrail v1.46.2/go.mod h1:WcTfALKgqv+VCMRCLtG4155sAwcfdYhFADc/yDJgSlc=
github.com/aws/aws-sdk-go-v2/service/cloudtrail v1.46.3 h1:DfrEQMWCfk0wkuv/r0zwcGoykCuYWCLoGolbax6O3sw=
github.com/aws/aws-sdk-go-v2/service/cloudtrail v1.46.3/go.mod h1:WcTfALKgqv+VCMRCLtG4155sAwcfdYhFADc/yDJgSlc=
github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs v1.45.0 h1:j9rGKWaYglZpf9KbJCQVM/L85Y4UdGMgK80A1OddR24=
github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs v1.45.0/go.mod h1:LZafBHU62ByizrdhNLMnzWGsUX+abAW4q35PN+FOj+A=
github.com/aws/aws-sdk-go-v2/service/cognitoidentityprovider v1.36.3 h1:JNWpkjImTP2e308bv7ihfwgOawf640BY/pyZWrBb9rw=
Expand Down
5 changes: 5 additions & 0 deletions goformation/cloudformation/eks/aws-eks-nodegroup.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ type Nodegroup struct {
// See: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-eks-nodegroup.html#cfn-eks-nodegroup-launchtemplate
LaunchTemplate *Nodegroup_LaunchTemplateSpecification `json:"LaunchTemplate,omitempty"`

// NodeRepairConfig AWS CloudFormation Property
// Required: false
// See: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-eks-nodegroup.html#cfn-eks-nodegroup-noderepairconfig
NodeRepairConfig *Nodegroup_NodeRepairConfig `json:"NodeRepairConfig,omitempty"`

// NodeRole AWS CloudFormation Property
// Required: true
// See: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-eks-nodegroup.html#cfn-eks-nodegroup-noderole
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package eks

import (
"goformation/v4/cloudformation/types"

"goformation/v4/cloudformation/policies"
)

// Nodegroup_NodeRepairConfig AWS CloudFormation Resource (AWS::EKS::Nodegroup.NodeRepairConfig)
type Nodegroup_NodeRepairConfig struct {
Enabled *types.Value `json:"Enabled,omitempty"`

// AWSCloudFormationDeletionPolicy represents a CloudFormation DeletionPolicy
AWSCloudFormationDeletionPolicy policies.DeletionPolicy `json:"-"`

// AWSCloudFormationUpdateReplacePolicy represents a CloudFormation UpdateReplacePolicy
AWSCloudFormationUpdateReplacePolicy policies.UpdateReplacePolicy `json:"-"`

// AWSCloudFormationDependsOn stores the logical ID of the resources to be created before this resource
AWSCloudFormationDependsOn []string `json:"-"`

// AWSCloudFormationMetadata stores structured data associated with this resource
AWSCloudFormationMetadata map[string]interface{} `json:"-"`

// AWSCloudFormationCondition stores the logical ID of the condition that must be satisfied for this resource to be created
AWSCloudFormationCondition string `json:"-"`
}

// AWSCloudFormationType returns the AWS CloudFormation resource type
func (r *Nodegroup_NodeRepairConfig) AWSCloudFormationType() string {
return "AWS::EKS::Nodegroup.NodeRepairConfig"
}
23 changes: 22 additions & 1 deletion pkg/apis/eksctl.io/v1alpha5/assets/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -1469,6 +1469,11 @@
"name": {
"type": "string"
},
"nodeRepairConfig": {
"$ref": "#/definitions/NodeGroupNodeRepairConfig",
"description": "configures the auto repair feature of the nodegroup",
"x-intellij-html-description": "configures the auto repair feature of the nodegroup"
},
"outpostARN": {
"type": "string",
"description": "specifies the Outpost ARN in which the nodegroup should be created.",
Expand Down Expand Up @@ -1633,7 +1638,8 @@
"taints",
"updateConfig",
"launchTemplate",
"releaseVersion"
"releaseVersion",
"nodeRepairConfig"
],
"additionalProperties": false,
"description": "represents an EKS-managed nodegroup",
Expand Down Expand Up @@ -2205,6 +2211,21 @@
"description": "holds the configuration for [spot instances](/usage/spot-instances/)",
"x-intellij-html-description": "holds the configuration for <a href=\"/usage/spot-instances/\">spot instances</a>"
},
"NodeGroupNodeRepairConfig": {
"properties": {
"enabled": {
"type": "boolean",
"description": "Enables the auto repair feature for the nodegroup",
"x-intellij-html-description": "Enables the auto repair feature for the nodegroup"
}
},
"preferredOrder": [
"enabled"
],
"additionalProperties": false,
"description": "contains the auto repair configuration for the nodegroup",
"x-intellij-html-description": "contains the auto repair configuration for the nodegroup"
},
"NodeGroupSGs": {
"properties": {
"attachIDs": {
Expand Down
11 changes: 11 additions & 0 deletions pkg/apis/eksctl.io/v1alpha5/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -1596,6 +1596,13 @@ type (
// +optional
MaxUnavailablePercentage *int `json:"maxUnavailablePercentage,omitempty"`
}

// NodeGroupNodeRepairConfig contains the auto repair configuration for the nodegroup
NodeGroupNodeRepairConfig struct {
// Enables the auto repair feature for the nodegroup
// +optional
Enabled *bool `json:"enabled,omitempty"`
}
)

// MetricsCollection used by the scaling config,
Expand Down Expand Up @@ -1883,6 +1890,10 @@ type ManagedNodeGroup struct {
// ReleaseVersion the AMI version of the EKS optimized AMI to use
ReleaseVersion string `json:"releaseVersion"`

// NodeRepairConfig configures the auto repair feature of the nodegroup
// +optional
NodeRepairConfig *NodeGroupNodeRepairConfig `json:"nodeRepairConfig,omitempty"`

// Internal fields

Unowned bool `json:"-"`
Expand Down
13 changes: 13 additions & 0 deletions pkg/cfn/builder/managed_launch_template_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,19 @@ API_SERVER_URL=https://test.com
resourcesFilename: "spot.json",
}),

Entry("With node repair enabled", &mngCase{
ng: &api.ManagedNodeGroup{
NodeGroupBase: &api.NodeGroupBase{
Name: "node-repair-enabled",
InstanceType: "m5.xlarge",
},
NodeRepairConfig: &api.NodeGroupNodeRepairConfig{
Enabled: aws.Bool(true),
},
},
resourcesFilename: "node-repair-enabled.json",
}),

Entry("Without instance type set in the launch template", &mngCase{
ng: &api.ManagedNodeGroup{
NodeGroupBase: &api.NodeGroupBase{
Expand Down
8 changes: 8 additions & 0 deletions pkg/cfn/builder/managed_nodegroup.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,14 @@ func (m *ManagedNodeGroupResourceSet) AddAllResources(ctx context.Context) error
managedResource.UpdateConfig = updateConfig
}

if m.nodeGroup.NodeRepairConfig != nil {
nodeRepairConfig := &gfneks.Nodegroup_NodeRepairConfig{}
if m.nodeGroup.NodeRepairConfig.Enabled != nil {
nodeRepairConfig.Enabled = gfnt.NewBoolean(*m.nodeGroup.NodeRepairConfig.Enabled)
}
managedResource.NodeRepairConfig = nodeRepairConfig
}

if m.nodeGroup.Spot {
// TODO use constant from SDK
managedResource.CapacityType = gfnt.NewString("SPOT")
Expand Down
176 changes: 176 additions & 0 deletions pkg/cfn/builder/testdata/launch_template/node-repair-enabled.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
{
"LaunchTemplate": {
"Type": "AWS::EC2::LaunchTemplate",
"Properties": {
"LaunchTemplateData": {
"BlockDeviceMappings": [
{
"DeviceName": "/dev/xvda",
"Ebs": {
"Iops": 3000,
"Throughput": 125,
"VolumeSize": 80,
"VolumeType": "gp3"
}
}
],
"MetadataOptions": {
"HttpPutResponseHopLimit": 2,
"HttpTokens": "required"
},
"SecurityGroupIds": [
{
"Fn::ImportValue": "eksctl-lt::ClusterSecurityGroupId"
}
],
"TagSpecifications": [
{
"ResourceType": "instance",
"Tags": [
{
"Key": "Name",
"Value": "lt-node-repair-enabled-Node"
},
{
"Key": "alpha.eksctl.io/nodegroup-name",
"Value": "node-repair-enabled"
},
{
"Key": "alpha.eksctl.io/nodegroup-type",
"Value": "managed"
}
]
},
{
"ResourceType": "volume",
"Tags": [
{
"Key": "Name",
"Value": "lt-node-repair-enabled-Node"
},
{
"Key": "alpha.eksctl.io/nodegroup-name",
"Value": "node-repair-enabled"
},
{
"Key": "alpha.eksctl.io/nodegroup-type",
"Value": "managed"
}
]
},
{
"ResourceType": "network-interface",
"Tags": [
{
"Key": "Name",
"Value": "lt-node-repair-enabled-Node"
},
{
"Key": "alpha.eksctl.io/nodegroup-name",
"Value": "node-repair-enabled"
},
{
"Key": "alpha.eksctl.io/nodegroup-type",
"Value": "managed"
}
]
}
]
},
"LaunchTemplateName": {
"Fn::Sub": "${AWS::StackName}"
}
}
},
"ManagedNodeGroup": {
"Type": "AWS::EKS::Nodegroup",
"Properties": {
"AmiType": "AL2023_x86_64_STANDARD",
"ClusterName": "lt",
"Labels": {
"alpha.eksctl.io/cluster-name": "lt",
"alpha.eksctl.io/nodegroup-name": "node-repair-enabled"
},
"InstanceTypes": ["m5.xlarge"],
"NodeRole": {
"Fn::GetAtt": [
"NodeInstanceRole",
"Arn"
]
},
"NodegroupName": "node-repair-enabled",
"ScalingConfig": {
"DesiredSize": 2,
"MaxSize": 2,
"MinSize": 2
},
"Subnets": [
"subnet-public-us-west-2a"
],
"Tags": {
"alpha.eksctl.io/nodegroup-name": "node-repair-enabled",
"alpha.eksctl.io/nodegroup-type": "managed"
},
"LaunchTemplate": {
"Id": {
"Ref": "LaunchTemplate"
}
},
"NodeRepairConfig": {
"Enabled": true
}
}
},
"NodeInstanceRole": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Statement": [
{
"Action": [
"sts:AssumeRole"
],
"Effect": "Allow",
"Principal": {
"Service": [
{
"Fn::FindInMap": [
"ServicePrincipalPartitionMap",
{
"Ref": "AWS::Partition"
},
"EC2"
]
}
]
}
}
],
"Version": "2012-10-17"
},
"ManagedPolicyArns": [
{
"Fn::Sub": "arn:${AWS::Partition}:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly"
},
{
"Fn::Sub": "arn:${AWS::Partition}:iam::aws:policy/AmazonEKSWorkerNodePolicy"
},
{
"Fn::Sub": "arn:${AWS::Partition}:iam::aws:policy/AmazonEKS_CNI_Policy"
},
{
"Fn::Sub": "arn:${AWS::Partition}:iam::aws:policy/AmazonSSMManagedInstanceCore"
}
],
"Path": "/",
"Tags": [
{
"Key": "Name",
"Value": {
"Fn::Sub": "${AWS::StackName}/NodeInstanceRole"
}
}
]
}
}
}
11 changes: 9 additions & 2 deletions pkg/ctl/cmdutils/configfile.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ var (
commonNGFlagsIncompatibleWithConfigFile = []string{
"managed",
"spot",
"enable-node-repair",
"instance-types",
"nodes",
"nodes-min",
Expand Down Expand Up @@ -605,11 +606,17 @@ func makeManagedNodegroup(nodeGroup *api.NodeGroup, options CreateManagedNGOptio
AttachIDs: ngBase.SecurityGroups.AttachIDs,
}
}
return &api.ManagedNodeGroup{
mng := &api.ManagedNodeGroup{
NodeGroupBase: &ngBase,
Spot: options.Spot,
InstanceTypes: options.InstanceTypes,
}
if options.NodeRepairEnabled {
mng.NodeRepairConfig = &api.NodeGroupNodeRepairConfig{
Enabled: &options.NodeRepairEnabled,
}
}
return mng
}

func validateUnsupportedCLIFeatures(ng *api.ManagedNodeGroup) error {
Expand All @@ -620,7 +627,7 @@ func validateManagedNGFlags(cmd *cobra.Command, managed bool) error {
if managed {
return nil
}
flagsValidOnlyWithMNG := []string{"spot", "instance-types"}
flagsValidOnlyWithMNG := []string{"spot", "enable-node-repair", "instance-types"}
if flagName, found := findChangedFlag(cmd, flagsValidOnlyWithMNG); found {
return errors.Errorf("--%s is only valid with managed nodegroups (--managed)", flagName)
}
Expand Down
Loading

0 comments on commit 3a96038

Please sign in to comment.