Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ AWSManagedMachinePool (EKS managed nodegroup) support #1916

Merged
merged 8 commits into from
Oct 2, 2020
5 changes: 5 additions & 0 deletions cmd/clusterawsadm/api/bootstrap/v1alpha1/defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ func SetDefaults_AWSIAMConfigurationSpec(obj *AWSIAMConfigurationSpec) { //nolin
} else if obj.EKS.Enable {
obj.Nodes.EC2ContainerRegistryReadOnly = true
}
if obj.EKS.ManagedMachinePool == nil {
obj.EKS.ManagedMachinePool = &AWSIAMRoleSpec{
Disable: true,
}
}
}

// SetDefaults_AWSIAMConfiguration is used by defaulter-gen
Expand Down
3 changes: 3 additions & 0 deletions cmd/clusterawsadm/api/bootstrap/v1alpha1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,9 @@ type EKSConfig struct {
// no role is included in the spec and automatic creation of the role
// isn't enabled
DefaultControlPlaneRole AWSIAMRoleSpec `json:"defaultControlPlaneRole,omitempty"`
// ManagedMachinePool controls the configuration of the AWS IAM role for
// used by EKS managed machine pools.
ManagedMachinePool *AWSIAMRoleSpec `json:"managedMachinePool,omitempty"`
}

// ClusterAPIControllers controls the configuration of the AWS IAM role for
Expand Down

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

Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ func (t Template) controllersPolicy() *iamv1.PolicyDocument {
"iam:GetPolicy",
},
Resource: iamv1.Resources{
"arn:aws:iam::aws:policy/AmazonEKSClusterPolicy",
EKSClusterPolicy,
},
Effect: iamv1.EffectAllow,
}, {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,23 @@ Resources:
- arn:aws:iam::aws:policy/AmazonEKSClusterPolicy
RoleName: eks-controlplane.cluster-api-provider-aws.sigs.k8s.io
Type: AWS::IAM::Role
AWSIAMRoleEKSNodegroup:
Properties:
AssumeRolePolicyDocument:
Statement:
- Action:
- sts:AssumeRole
Effect: Allow
Principal:
Service:
- eks.amazonaws.com
Version: 2012-10-17
ManagedPolicyArns:
- arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy
- arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy
- arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly
RoleName: eks-nodegroup.cluster-api-provider-aws.sigs.k8s.io
Type: AWS::IAM::Role
AWSIAMRoleNodes:
Properties:
AssumeRolePolicyDocument:
Expand Down
30 changes: 30 additions & 0 deletions cmd/clusterawsadm/cloudformation/bootstrap/managed_nodegroup.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
Copyright 2020 The Kubernetes Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package bootstrap

import "sigs.k8s.io/cluster-api-provider-aws/pkg/cloud/services/eks"

func (t Template) eksMachinePoolPolicies() []string {
policies := eks.NodegroupRolePolicies()
if t.Spec.EKS.ManagedMachinePool.ExtraPolicyAttachments != nil {
for _, policy := range t.Spec.EKS.ManagedMachinePool.ExtraPolicyAttachments {
policies = append(policies, policy)
}
}

return policies
}
11 changes: 11 additions & 0 deletions cmd/clusterawsadm/cloudformation/bootstrap/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
iamv1 "sigs.k8s.io/cluster-api-provider-aws/cmd/clusterawsadm/api/iam/v1alpha1"
"sigs.k8s.io/cluster-api-provider-aws/cmd/clusterawsadm/converters"
ekscontrolplanev1 "sigs.k8s.io/cluster-api-provider-aws/controlplane/eks/api/v1alpha3"
infrav1exp "sigs.k8s.io/cluster-api-provider-aws/exp/api/v1alpha3"
)

const (
Expand All @@ -37,6 +38,7 @@ const (
AWSIAMRoleControlPlane = "AWSIAMRoleControlPlane"
AWSIAMRoleNodes = "AWSIAMRoleNodes"
AWSIAMRoleEKSControlPlane = "AWSIAMRoleEKSControlPlane"
AWSIAMRoleEKSNodegroup = "AWSIAMRoleEKSNodegroup"
AWSIAMUserBootstrapper = "AWSIAMUserBootstrapper"
ControllersPolicy PolicyName = "AWSIAMManagedPolicyControllers"
ControlPlanePolicy PolicyName = "AWSIAMManagedPolicyCloudProviderControlPlane"
Expand Down Expand Up @@ -167,6 +169,15 @@ func (t Template) RenderCloudFormation() *cloudformation.Template {
}
}

if !t.Spec.EKS.ManagedMachinePool.Disable {
template.Resources[AWSIAMRoleEKSNodegroup] = &cfn_iam.Role{
RoleName: infrav1exp.DefaultEKSNodegroupRole,
AssumeRolePolicyDocument: eksAssumeRolePolicy(),
ManagedPolicyArns: t.eksMachinePoolPolicies(),
Tags: converters.MapToCloudFormationTags(t.Spec.EKS.ManagedMachinePool.Tags),
}
}

return template
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ func Test_RenderCloudformation(t *testing.T) {
t.Spec.EKS.Enable = true
t.Spec.Nodes.EC2ContainerRegistryReadOnly = true
t.Spec.EKS.DefaultControlPlaneRole.Disable = false
t.Spec.EKS.ManagedMachinePool.Disable = false
return t
},
},
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@

---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.2.9
creationTimestamp: null
name: awsmanagedmachinepools.infrastructure.cluster.x-k8s.io
spec:
group: infrastructure.cluster.x-k8s.io
names:
categories:
- cluster-api
kind: AWSManagedMachinePool
listKind: AWSManagedMachinePoolList
plural: awsmanagedmachinepools
singular: awsmanagedmachinepool
scope: Namespaced
versions:
- additionalPrinterColumns:
- description: MachinePool ready status
jsonPath: .status.ready
name: Ready
type: string
- description: Number of replicas
jsonPath: .status.replicas
name: Replicas
type: integer
name: v1alpha3
schema:
openAPIV3Schema:
description: AWSManagedMachinePool is the Schema for the awsmanagedmachinepools API
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
type: string
kind:
description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
metadata:
type: object
spec:
description: AWSManagedMachinePoolSpec defines the desired state of AWSManagedMachinePool
properties:
additionalTags:
additionalProperties:
type: string
description: 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.
type: object
amiType:
default: AL2_x86_64
description: AMIType defines the AMI type
enum:
- AL2_x86_64
- AL2_x86_64_GPU
- AL2_ARM_64
type: string
amiVersion:
description: AMIVersion defines the desired AMI release version. If no version number is supplied then the latest version for the Kubernetes version will be used
minLength: 2
type: string
diskSize:
description: DiskSize specifies the root disk size
format: int32
type: integer
eksNodegroupName:
description: EKSNodegroupName specifies the name of the nodegroup in AWS corresponding to this MachinePool. If you don't specify a name then a default name will be created based on the namespace and name of the managed machine pool.
type: string
instanceType:
description: InstanceType specifies the AWS instance type
type: string
labels:
additionalProperties:
type: string
description: Labels specifies labels for the Kubernetes node objects
type: object
providerIDList:
description: ProviderIDList are the provider IDs of instances in the autoscaling group corresponding to the nodegroup represented by this machine pool
items:
type: string
type: array
remoteAccess:
description: RemoteAccess specifies how machines can be accessed remotely
properties:
sourceSecurityGroups:
description: SourceSecurityGroups specifies which security groups are allowed access An empty array opens port 22 to the public internet
items:
type: string
type: array
sshKeyName:
description: SSHKeyName specifies which EC2 SSH key can be used to access machines
type: string
type: object
roleName:
description: RoleName specifies the name of IAM role for the node group. 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.
type: string
scaling:
description: Scaling specifies scaling for the ASG behind this pool
properties:
maxSize:
format: int32
type: integer
minSize:
format: int32
type: integer
type: object
subnetIDs:
description: SubnetIDs specifies which subnets are used for the auto scaling group of this nodegroup
items:
type: string
type: array
type: object
status:
description: AWSManagedMachinePoolStatus defines the observed state of AWSManagedMachinePool
properties:
conditions:
description: Conditions defines current service state of the managed machine pool
items:
description: Condition defines an observation of a Cluster API resource operational state.
properties:
lastTransitionTime:
description: Last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
format: date-time
type: string
message:
description: A human readable message indicating details about the transition. This field may be empty.
type: string
reason:
description: The reason for the condition's last transition in CamelCase. The specific API may choose whether or not this field is considered a guaranteed API. This field may not be empty.
type: string
severity:
description: Severity provides an explicit classification of Reason code, so the users or machines can immediately understand the current situation and act accordingly. The Severity field MUST be set only when Status=False.
type: string
status:
description: Status of the condition, one of True, False, Unknown.
type: string
type:
description: Type of condition in CamelCase or in foo.example.com/CamelCase. Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important.
type: string
required:
- status
- type
type: object
type: array
failureMessage:
description: "FailureMessage will be set in the event that there is a terminal problem reconciling the MachinePool and will contain a more verbose string suitable for logging and human consumption. \n This field should not be set for transitive errors that a controller faces that are expected to be fixed automatically over time (like service outages), but instead indicate that something is fundamentally wrong with the MachinePool's spec or the configuration of the controller, and that manual intervention is required. Examples of terminal errors would be invalid combinations of settings in the spec, values that are unsupported by the controller, or the responsible controller itself being critically misconfigured. \n Any transient errors that occur during the reconciliation of MachinePools can be added as events to the MachinePool object and/or logged in the controller's output."
type: string
failureReason:
description: "FailureReason will be set in the event that there is a terminal problem reconciling the MachinePool and will contain a succinct value suitable for machine interpretation. \n This field should not be set for transitive errors that a controller faces that are expected to be fixed automatically over time (like service outages), but instead indicate that something is fundamentally wrong with the Machine's spec or the configuration of the controller, and that manual intervention is required. Examples of terminal errors would be invalid combinations of settings in the spec, values that are unsupported by the controller, or the responsible controller itself being critically misconfigured. \n Any transient errors that occur during the reconciliation of MachinePools can be added as events to the MachinePool object and/or logged in the controller's output."
type: string
ready:
default: false
description: Ready denotes that the AWSManagedMachinePool nodegroup has joined the cluster
type: boolean
replicas:
description: Replicas is the most recently observed number of replicas.
format: int32
type: integer
required:
- ready
type: object
type: object
served: true
storage: true
subresources:
status: {}
status:
acceptedNames:
kind: ""
plural: ""
conditions: []
storedVersions: []
1 change: 1 addition & 0 deletions config/crd/kustomization.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ resources:
- bases/infrastructure.cluster.x-k8s.io_awsmachinetemplates.yaml
- bases/infrastructure.cluster.x-k8s.io_awsmanagedclusters.yaml
- bases/infrastructure.cluster.x-k8s.io_awsmachinepools.yaml
- bases/infrastructure.cluster.x-k8s.io_awsmanagedmachinepools.yaml
# +kubebuilder:scaffold:crdkustomizeresource

patchesStrategicMerge:
Expand Down
2 changes: 1 addition & 1 deletion config/manager/manager.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ spec:
containers:
- args:
- --enable-leader-election
- "--feature-gates=EKS=${EXP_EKS:=false}"
- "--feature-gates=EKS=${EXP_EKS:=false},EKSEnableIAM=${EXP_EKS_IAM:=false},EKSAllowAddRoles=${EXP_EKS_ADD_ROLES:=false}"
randomvariable marked this conversation as resolved.
Show resolved Hide resolved
image: controller:latest
imagePullPolicy: Always
name: manager
Expand Down
30 changes: 30 additions & 0 deletions config/rbac/role.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,16 @@ rules:
- get
- list
- watch
- apiGroups:
- ""
resources:
- events
verbs:
- create
- get
- list
- patch
- watch
- apiGroups:
- exp.cluster.x-k8s.io
resources:
Expand Down Expand Up @@ -145,3 +155,23 @@ rules:
- get
- patch
- update
- apiGroups:
- infrastructure.cluster.x-k8s.io
resources:
- awsmanagedmachinepools
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- infrastructure.cluster.x-k8s.io
resources:
- awsmanagedmachinepools/status
verbs:
- get
- patch
- update
Loading