Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
78717a7
Fixes aws/aws-cdk#11827
pahud Dec 9, 2020
554d0a4
chore(doc): update README
pahud Dec 9, 2020
93d300a
chore(doc): minor
pahud Dec 9, 2020
05a2c93
Merge branch 'master' into pahud/aws-eks-managed-nodegroup-11827
pahud Dec 9, 2020
7abc1cb
Merge branch 'master' into pahud/aws-eks-managed-nodegroup-11827
pahud Dec 11, 2020
0dd4b3c
Merge branch 'master' into pahud/aws-eks-managed-nodegroup-11827
pahud Dec 15, 2020
af765cd
use instanceTypes instead
pahud Dec 16, 2020
cf53f7f
Merge branch 'master' into pahud/aws-eks-managed-nodegroup-11827
pahud Dec 16, 2020
1d12a05
add integ tests
pahud Dec 16, 2020
ef1dff4
minor
pahud Dec 16, 2020
53c7c35
minor
pahud Dec 16, 2020
0e78865
minor
pahud Dec 16, 2020
d2d9ca5
add annotations
pahud Dec 16, 2020
1a02392
minor
pahud Dec 17, 2020
481e6f1
Update packages/@aws-cdk/aws-eks/lib/managed-nodegroup.ts
pahud Dec 18, 2020
f05ddbb
Update packages/@aws-cdk/aws-eks/lib/managed-nodegroup.ts
pahud Dec 18, 2020
0ab46c4
Merge branch 'master' into pahud/aws-eks-managed-nodegroup-11827
pahud Dec 18, 2020
fb13656
update the helper function
pahud Dec 18, 2020
9888f2f
Update packages/@aws-cdk/aws-eks/test/test.nodegroup.ts
pahud Dec 18, 2020
cdd304f
fix tests
pahud Dec 18, 2020
50c2ac6
minor
pahud Dec 18, 2020
7ec29a5
Merge branch 'master' into pahud/aws-eks-managed-nodegroup-11827
pahud Dec 22, 2020
437256c
Merge branch 'master' into pahud/aws-eks-managed-nodegroup-11827
pahud Dec 22, 2020
47725ad
fix tests
pahud Dec 22, 2020
a20441f
fix tests
pahud Dec 22, 2020
ef0ccd9
Some rephrasing
iliapolo Dec 22, 2020
265ffae
Some rephrasing
iliapolo Dec 22, 2020
6104476
Some rephrasing
iliapolo Dec 22, 2020
394cefe
Merge branch 'master' into pahud/aws-eks-managed-nodegroup-11827
iliapolo Dec 22, 2020
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
31 changes: 27 additions & 4 deletions packages/@aws-cdk/aws-eks/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -201,14 +201,35 @@ const cluster = new eks.Cluster(this, 'HelloEKS', {
});

cluster.addNodegroupCapacity('custom-node-group', {
instanceType: new ec2.InstanceType('m5.large'),
instanceType: [new ec2.InstanceType('m5.large')],
minSize: 4,
diskSize: 100,
amiType: eks.NodegroupAmiType.AL2_X86_64_GPU,
...
});
```

#### Spot Instances Support

Use `capacityType` to create the Spot managed node groups. To maximize the availability of your applications while using
Spot Instances, we recommend that you configure a Spot managed node group to use multiple instance types.

> For more details visit [Managed node group capacity types](https://docs.aws.amazon.com/eks/latest/userguide/managed-node-groups.html#managed-node-group-capacity-types).


```ts
cluster.addNodegroupCapacity('extra-ng-spot', {
instanceType: [
new ec2.InstanceType('c5.large'),
new ec2.InstanceType('c5a.large'),
new ec2.InstanceType('c5d.large'),
],
minSize: 3,
capacityType: eks.CapacityType.SPOT,
});

```

#### Launch Template Support

You can specify a launch template that the node group will use. Note that when using a custom AMI, Amazon EKS doesn't merge any user data.
Expand Down Expand Up @@ -236,7 +257,9 @@ cluster.addNodegroupCapacity('extra-ng', {
});
```

> For more details visit [Launch Template Support](https://docs.aws.amazon.com/en_ca/eks/latest/userguide/launch-templates.html).
You may specify one or multiple instance types in either `instanceType` property of `NodeGroup` or in the launch template but not both.

> For more details visit [Launch Template Support](https://docs.aws.amazon.com/eks/latest/userguide/launch-templates.html).

Graviton 2 instance types are supported including `c6g`, `m6g`, `r6g` and `t4g`.

Expand Down Expand Up @@ -527,13 +550,13 @@ Amazon Linux 2 AMI for ARM64 will be automatically selected.
```ts
// add a managed ARM64 nodegroup
cluster.addNodegroupCapacity('extra-ng-arm', {
instanceType: new ec2.InstanceType('m6g.medium'),
instanceType: [new ec2.InstanceType('m6g.medium')],
minSize: 2,
});

// add a self-managed ARM64 nodegroup
cluster.addAutoScalingGroupCapacity('self-ng-arm', {
instanceType: new ec2.InstanceType('m6g.medium'),
instanceType: [new ec2.InstanceType('m6g.medium')],
minCapacity: 2,
})
```
Expand Down
2 changes: 1 addition & 1 deletion packages/@aws-cdk/aws-eks/lib/cluster.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1119,7 +1119,7 @@ export class Cluster extends ClusterBase {
this.addAutoScalingGroupCapacity('DefaultCapacity', { instanceType, minCapacity }) : undefined;

this.defaultNodegroup = props.defaultCapacityType !== DefaultCapacityType.EC2 ?
this.addNodegroupCapacity('DefaultCapacity', { instanceType, minSize: minCapacity }) : undefined;
this.addNodegroupCapacity('DefaultCapacity', { instanceType: [instanceType], minSize: minCapacity }) : undefined;
}

const outputConfigCommand = props.outputConfigCommand === undefined ? true : props.outputConfigCommand;
Expand Down
2 changes: 1 addition & 1 deletion packages/@aws-cdk/aws-eks/lib/legacy-cluster.ts
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ export class LegacyCluster extends Resource implements ICluster {
this.addCapacity('DefaultCapacity', { instanceType, minCapacity }) : undefined;

this.defaultNodegroup = props.defaultCapacityType !== DefaultCapacityType.EC2 ?
this.addNodegroup('DefaultCapacity', { instanceType, minSize: minCapacity }) : undefined;
this.addNodegroup('DefaultCapacity', { instanceType: [instanceType], minSize: minCapacity }) : undefined;
}

const outputConfigCommand = props.outputConfigCommand === undefined ? true : props.outputConfigCommand;
Expand Down
40 changes: 32 additions & 8 deletions packages/@aws-cdk/aws-eks/lib/managed-nodegroup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,20 @@ export enum NodegroupAmiType {
AL2_ARM_64 = 'AL2_ARM_64'
}

/**
* Capacity type of the managed node group
*/
export enum CapacityType {
/**
* spot instances
*/
SPOT = 'SPOT',
/**
* on-demand instances
*/
ON_DEMAND = 'ON_DEMAND'
}

/**
* The remote access (SSH) configuration to use with your node group.
*
Expand Down Expand Up @@ -139,7 +153,7 @@ export interface NodegroupOptions {
*
* @default t3.medium
*/
readonly instanceType?: InstanceType;
readonly instanceType?: InstanceType[];
/**
* The Kubernetes labels to be applied to the nodes in the node group when they are created.
*
Expand Down Expand Up @@ -183,6 +197,12 @@ export interface NodegroupOptions {
* @default - no launch template
*/
readonly launchTemplateSpec?: LaunchTemplateSpec;
/**
* The capacity type of the nodegroup.
*
* @default - ON_DEMAND
*/
readonly capacityType?: CapacityType;
}

/**
Expand Down Expand Up @@ -271,11 +291,11 @@ export class Nodegroup extends Resource implements INodegroup {
nodegroupName: props.nodegroupName,
nodeRole: this.role.roleArn,
subnets: this.cluster.vpc.selectSubnets(props.subnets).subnetIds,
amiType: props.amiType ?? (props.instanceType ? getAmiTypeForInstanceType(props.instanceType).toString() :
amiType: props.amiType ?? (props.instanceType ? getAmiTypeForInstanceType(props.instanceType[0]).toString() :
undefined),
diskSize: props.diskSize,
forceUpdateEnabled: props.forceUpdate ?? true,
instanceTypes: props.instanceType ? [props.instanceType.toString()] : undefined,
instanceTypes: props.instanceType ? props.instanceType.map(t => t.toString()) : undefined,
labels: props.labels,
releaseVersion: props.releaseVersion,
remoteAccess: props.remoteAccess ? {
Expand All @@ -291,17 +311,21 @@ export class Nodegroup extends Resource implements INodegroup {
tags: props.tags,
});

if (props.capacityType) {
resource.addPropertyOverride('CapacityType', props.capacityType.valueOf());
}

if (props.launchTemplateSpec) {
if (props.diskSize) {
// see - https://docs.aws.amazon.com/eks/latest/userguide/launch-templates.html
// and https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-eks-nodegroup.html#cfn-eks-nodegroup-disksize
throw new Error('diskSize must be specified within the launch template');
}
if (props.instanceType) {
// see - https://docs.aws.amazon.com/eks/latest/userguide/launch-templates.html
// and https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-eks-nodegroup.html#cfn-eks-nodegroup-disksize
throw new Error('Instance types must be specified within the launch template');
}
/**
* Instance types can be specified either in `instanceType` or launch template but not both. AS we can not check the content of
* the provided launch template and the `instanceType` property is preferrable. We allow users to define `instanceType` property here.
* see - https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-eks-nodegroup.html#cfn-eks-nodegroup-instancetypes
*/
// TODO: update this when the L1 resource spec is updated.
resource.addPropertyOverride('LaunchTemplate', {
Id: props.launchTemplateSpec.id,
Expand Down
114 changes: 110 additions & 4 deletions packages/@aws-cdk/aws-eks/test/integ.eks-cluster.expected.json
Original file line number Diff line number Diff line change
Expand Up @@ -1251,6 +1251,13 @@
]
},
"\\\",\\\"username\\\":\\\"system:node:{{EC2PrivateDNSName}}\\\",\\\"groups\\\":[\\\"system:bootstrappers\\\",\\\"system:nodes\\\"]},{\\\"rolearn\\\":\\\"",
{
"Fn::GetAtt": [
"ClusterNodegroupextrangspotNodeGroupRoleB53B4857",
"Arn"
]
},
"\\\",\\\"username\\\":\\\"system:node:{{EC2PrivateDNSName}}\\\",\\\"groups\\\":[\\\"system:bootstrappers\\\",\\\"system:nodes\\\"]},{\\\"rolearn\\\":\\\"",
{
"Fn::GetAtt": [
"ClusterNodegroupextrangarmNodeGroupRoleADF5749F",
Expand Down Expand Up @@ -3208,18 +3215,117 @@
"Ref": "VpcPrivateSubnet3SubnetF258B56E"
}
],
"AmiType": "AL2_x86_64",
"ForceUpdateEnabled": true,
"InstanceTypes": [
"t3.small"
],
"ScalingConfig": {
"DesiredSize": 1,
"MaxSize": 1,
"MinSize": 1
}
}
},
"ClusterNodegroupextrangspotNodeGroupRoleB53B4857": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Statement": [
{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Principal": {
"Service": {
"Fn::Join": [
"",
[
"ec2.",
{
"Ref": "AWS::URLSuffix"
}
]
]
}
}
}
],
"Version": "2012-10-17"
},
"ManagedPolicyArns": [
{
"Fn::Join": [
"",
[
"arn:",
{
"Ref": "AWS::Partition"
},
":iam::aws:policy/AmazonEKSWorkerNodePolicy"
]
]
},
{
"Fn::Join": [
"",
[
"arn:",
{
"Ref": "AWS::Partition"
},
":iam::aws:policy/AmazonEKS_CNI_Policy"
]
]
},
{
"Fn::Join": [
"",
[
"arn:",
{
"Ref": "AWS::Partition"
},
":iam::aws:policy/AmazonEC2ContainerRegistryReadOnly"
]
]
}
]
}
},
"ClusterNodegroupextrangspotB327AE6B": {
"Type": "AWS::EKS::Nodegroup",
"Properties": {
"ClusterName": {
"Ref": "Cluster9EE0221C"
},
"NodeRole": {
"Fn::GetAtt": [
"ClusterNodegroupextrangspotNodeGroupRoleB53B4857",
"Arn"
]
},
"Subnets": [
{
"Ref": "VpcPrivateSubnet1Subnet536B997A"
},
{
"Ref": "VpcPrivateSubnet2Subnet3788AAA1"
},
{
"Ref": "VpcPrivateSubnet3SubnetF258B56E"
}
],
"AmiType": "AL2_x86_64",
"ForceUpdateEnabled": true,
"InstanceTypes": [
"c5.large",
"c5a.large",
"c5d.large"
],
"ScalingConfig": {
"DesiredSize": 3,
"MaxSize": 3,
"MinSize": 3
},
"CapacityType": "SPOT"
}
},
"ClusterNodegroupextrangarmNodeGroupRoleADF5749F": {
"Type": "AWS::IAM::Role",
"Properties": {
Expand Down
19 changes: 17 additions & 2 deletions packages/@aws-cdk/aws-eks/test/integ.eks-cluster.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ class EksClusterStack extends TestStack {

this.assertNodeGroupX86();

this.assertNodeGroupSpot();

this.assertNodeGroupArm();

this.assertNodeGroupCustomAmi();
Expand Down Expand Up @@ -140,12 +142,25 @@ class EksClusterStack extends TestStack {
private assertNodeGroupX86() {
// add a extra nodegroup
this.cluster.addNodegroupCapacity('extra-ng', {
instanceType: new ec2.InstanceType('t3.small'),
minSize: 1,
// reusing the default capacity nodegroup instance role when available
nodeRole: this.cluster.defaultCapacity ? this.cluster.defaultCapacity.role : undefined,
});
}
private assertNodeGroupSpot() {
// add a extra nodegroup
this.cluster.addNodegroupCapacity('extra-ng-spot', {
instanceType: [
new ec2.InstanceType('c5.large'),
new ec2.InstanceType('c5a.large'),
new ec2.InstanceType('c5d.large'),
],
minSize: 3,
// reusing the default capacity nodegroup instance role when available
nodeRole: this.cluster.defaultCapacity ? this.cluster.defaultCapacity.role : undefined,
capacityType: eks.CapacityType.SPOT,
});
}
private assertNodeGroupCustomAmi() {
// add a extra nodegroup
const userData = ec2.UserData.forLinux();
Expand Down Expand Up @@ -173,7 +188,7 @@ class EksClusterStack extends TestStack {
private assertNodeGroupArm() {
// add a extra nodegroup
this.cluster.addNodegroupCapacity('extra-ng-arm', {
instanceType: new ec2.InstanceType('m6g.medium'),
instanceType: [new ec2.InstanceType('m6g.medium')],
minSize: 1,
// reusing the default capacity nodegroup instance role when available
nodeRole: this.cluster.defaultCapacity ? this.cluster.defaultCapacity.role : undefined,
Expand Down
4 changes: 2 additions & 2 deletions packages/@aws-cdk/aws-eks/test/test.cluster.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1278,7 +1278,7 @@ export = {
prune: false,
defaultCapacityInstance: new ec2.InstanceType('m6g.medium'),
}).addNodegroupCapacity('ng', {
instanceType: new ec2.InstanceType('m6g.medium'),
instanceType: [new ec2.InstanceType('m6g.medium')],
});

// THEN
Expand All @@ -1299,7 +1299,7 @@ export = {
prune: false,
defaultCapacityInstance: new ec2.InstanceType('t4g.medium'),
}).addNodegroupCapacity('ng', {
instanceType: new ec2.InstanceType('t4g.medium'),
instanceType: [new ec2.InstanceType('t4g.medium')],
});

// THEN
Expand Down
Loading