diff --git a/packages/aws-cdk-lib/aws-eks/lib/managed-nodegroup.ts b/packages/aws-cdk-lib/aws-eks/lib/managed-nodegroup.ts index 4e3d4c7751d8a..cd8832381d944 100644 --- a/packages/aws-cdk-lib/aws-eks/lib/managed-nodegroup.ts +++ b/packages/aws-cdk-lib/aws-eks/lib/managed-nodegroup.ts @@ -563,8 +563,8 @@ export class Nodegroup extends Resource implements INodegroup { * AMI types of different architectures. Make sure AL2 is always the first element, which will be the default * AmiType if amiType and launchTemplateSpec are both undefined. */ -const arm64AmiTypes: NodegroupAmiType[] = [NodegroupAmiType.AL2_ARM_64, NodegroupAmiType.BOTTLEROCKET_ARM_64]; -const x8664AmiTypes: NodegroupAmiType[] = [NodegroupAmiType.AL2_X86_64, NodegroupAmiType.BOTTLEROCKET_X86_64, +const arm64AmiTypes: NodegroupAmiType[] = [NodegroupAmiType.AL2_ARM_64, NodegroupAmiType.AL2023_ARM_64_STANDARD, NodegroupAmiType.BOTTLEROCKET_ARM_64]; +const x8664AmiTypes: NodegroupAmiType[] = [NodegroupAmiType.AL2_X86_64, NodegroupAmiType.AL2023_X86_64_STANDARD, NodegroupAmiType.BOTTLEROCKET_X86_64, NodegroupAmiType.WINDOWS_CORE_2019_X86_64, NodegroupAmiType.WINDOWS_CORE_2022_X86_64, NodegroupAmiType.WINDOWS_FULL_2019_X86_64, NodegroupAmiType.WINDOWS_FULL_2022_X86_64]; const windowsAmiTypes: NodegroupAmiType[] = [NodegroupAmiType.WINDOWS_CORE_2019_X86_64, diff --git a/packages/aws-cdk-lib/aws-eks/test/cluster.test.ts b/packages/aws-cdk-lib/aws-eks/test/cluster.test.ts index 7bc91c4a0cf84..427b41206549f 100644 --- a/packages/aws-cdk-lib/aws-eks/test/cluster.test.ts +++ b/packages/aws-cdk-lib/aws-eks/test/cluster.test.ts @@ -12,13 +12,13 @@ import * as kms from '../../aws-kms'; import * as lambda from '../../aws-lambda'; import * as cdk from '../../core'; import * as eks from '../lib'; -import { HelmChart } from '../lib'; +import { HelmChart, NodegroupAmiType } from '../lib'; import { KubectlProvider } from '../lib/kubectl-provider'; import { BottleRocketImage } from '../lib/private/bottlerocket'; /* eslint-disable max-len */ -const CLUSTER_VERSION = eks.KubernetesVersion.V1_25; +const CLUSTER_VERSION = eks.KubernetesVersion.V1_29; describe('cluster', () => { test('can configure and access ALB controller', () => { @@ -27,7 +27,7 @@ describe('cluster', () => { const cluster = new eks.Cluster(stack, 'Cluster', { version: CLUSTER_VERSION, albController: { - version: eks.AlbControllerVersion.V2_4_1, + version: eks.AlbControllerVersion.V2_6_2, }, }); @@ -132,7 +132,7 @@ describe('cluster', () => { vpc: vpc, vpcSubnets: [{ subnetType: ec2.SubnetType.PUBLIC }, { subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS }], defaultCapacity: 0, - version: eks.KubernetesVersion.V1_21, + version: eks.KubernetesVersion.V1_29, })).toThrow(/cannot select multiple subnet groups/); }); @@ -142,7 +142,7 @@ describe('cluster', () => { vpc: vpc, vpcSubnets: [{ subnetType: ec2.SubnetType.PUBLIC }], defaultCapacity: 0, - version: eks.KubernetesVersion.V1_21, + version: eks.KubernetesVersion.V1_29, }); // THEN @@ -1543,7 +1543,7 @@ describe('cluster', () => { // THEN expect(() => cluster.addAutoScalingGroupCapacity('MyCapcity', { - instanceType: new ec2.InstanceType('m3.xlargs'), + instanceType: new ec2.InstanceType('m3.xlarge'), bootstrapEnabled: false, bootstrapOptions: { awsApiRetryAttempts: 10 }, })).toThrow(/Cannot specify "bootstrapOptions" if "bootstrapEnabled" is false/); @@ -1586,7 +1586,7 @@ describe('cluster', () => { )).toEqual(true); expect(Object.entries(parameters).some( ([k, v]) => k.startsWith('SsmParameterValueawsserviceeksoptimizedami') && - (v as any).Default.includes('/1.25/'), + (v as any).Default.includes('/1.29/'), )).toEqual(true); }); @@ -1608,6 +1608,48 @@ describe('cluster', () => { }); }); + test('addNodegroup with AL2023_X86_64_STANDARD instance type comes with nodegroup with correct AmiType', () => { + // GIVEN + const { stack } = testFixtureNoVpc(); + + // WHEN + new eks.Cluster(stack, 'cluster', { + defaultCapacity: 0, + version: CLUSTER_VERSION, + prune: false, + defaultCapacityInstance: new ec2.InstanceType('m5.large'), + }).addNodegroupCapacity('ng', { + amiType: NodegroupAmiType.AL2023_X86_64_STANDARD, + instanceTypes: [new ec2.InstanceType('m5.large')], + }); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::EKS::Nodegroup', { + AmiType: NodegroupAmiType.AL2023_X86_64_STANDARD, + }); + }); + + test('addNodegroup with AL2023_ARM_64_STANDARD instance type comes with nodegroup with correct AmiType', () => { + // GIVEN + const { stack } = testFixtureNoVpc(); + + // WHEN + new eks.Cluster(stack, 'cluster', { + defaultCapacity: 0, + version: CLUSTER_VERSION, + prune: false, + defaultCapacityInstance: new ec2.InstanceType('m6g.medium'), + }).addNodegroupCapacity('ng', { + amiType: NodegroupAmiType.AL2023_ARM_64_STANDARD, + instanceTypes: [new ec2.InstanceType('m6g.medium')], + }); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::EKS::Nodegroup', { + AmiType: NodegroupAmiType.AL2023_ARM_64_STANDARD, + }); + }); + test('addNodegroup with ARM64 instance type comes with nodegroup with correct AmiType', () => { // GIVEN const { stack } = testFixtureNoVpc(); @@ -1770,7 +1812,7 @@ describe('cluster', () => { )).toEqual(true); expect(Object.entries(parameters).some( ([k, v]) => k.startsWith('SsmParameterValueawsservicebottlerocketaws') && - (v as any).Default.includes('/aws-k8s-1.25/'), + (v as any).Default.includes('/aws-k8s-1.29/'), )).toEqual(true); }); diff --git a/packages/aws-cdk-lib/aws-eks/test/nodegroup.test.ts b/packages/aws-cdk-lib/aws-eks/test/nodegroup.test.ts index 32871fb042780..319d345e2d71c 100644 --- a/packages/aws-cdk-lib/aws-eks/test/nodegroup.test.ts +++ b/packages/aws-cdk-lib/aws-eks/test/nodegroup.test.ts @@ -561,6 +561,50 @@ describe('node group', () => { })).toThrow(/The specified AMI does not match the instance types architecture, either specify one of AL2_X86_64_GPU, BOTTLEROCKET_X86_64_NVIDIA, BOTTLEROCKET_ARM_64_NVIDIA or don't specify any/); }); + /** + * When LaunchTemplate is undefined, amiType is AL2023_X86_64_STANDARD and instanceTypes are not x86_64, + * we should throw an error. + */ + test('throws when LaunchTemplate is undefined, amiType is AL2023_X86_64_STANDARD and instanceTypes are not x86_64', () => { + // GIVEN + const { stack, vpc } = testFixture(); + const cluster = new eks.Cluster(stack, 'Cluster', { + vpc, + defaultCapacity: 0, + version: CLUSTER_VERSION, + }); + // THEN + expect(() => cluster.addNodegroupCapacity('ng', { + amiType: NodegroupAmiType.AL2023_X86_64_STANDARD, + instanceTypes: [ + new ec2.InstanceType('c6g.large'), + new ec2.InstanceType('t4g.large'), + ], + })).toThrow(/The specified AMI does not match the instance types architecture, either specify one of AL2_ARM_64, AL2023_ARM_64_STANDARD, BOTTLEROCKET_ARM_64 or don't specify any/); + }); + + /** + * When LaunchTemplate is undefined, amiType is AL2023_ARM_64_STANDARD and instanceTypes are not ARM_64, + * we should throw an error. + */ + test('throws when LaunchTemplate is undefined, amiType is AL2023_ARM_64_STANDARD and instanceTypes are not ARM_64', () => { + // GIVEN + const { stack, vpc } = testFixture(); + const cluster = new eks.Cluster(stack, 'Cluster', { + vpc, + defaultCapacity: 0, + version: CLUSTER_VERSION, + }); + // THEN + expect(() => cluster.addNodegroupCapacity('ng', { + amiType: NodegroupAmiType.AL2023_ARM_64_STANDARD, + instanceTypes: [ + new ec2.InstanceType('m5.large'), + new ec2.InstanceType('c5.large'), + ], + })).toThrow(/The specified AMI does not match the instance types architecture, either specify one of AL2_X86_64, AL2023_X86_64_STANDARD, BOTTLEROCKET_X86_64, WINDOWS_CORE_2019_X86_64, WINDOWS_CORE_2022_X86_64, WINDOWS_FULL_2019_X86_64, WINDOWS_FULL_2022_X86_64 or don't specify any/); + }); + /** * When LaunchTemplate is undefined, amiType is AL2_ARM_64 and instanceTypes are not ARM_64, * we should throw an error. @@ -580,7 +624,7 @@ describe('node group', () => { new ec2.InstanceType('c5.large'), new ec2.InstanceType('m5.large'), ], - })).toThrow(/The specified AMI does not match the instance types architecture, either specify one of AL2_X86_64, BOTTLEROCKET_X86_64, WINDOWS_CORE_2019_X86_64, WINDOWS_CORE_2022_X86_64, WINDOWS_FULL_2019_X86_64, WINDOWS_FULL_2022_X86_64 or don't specify any/); + })).toThrow(/The specified AMI does not match the instance types architecture, either specify one of AL2_X86_64, AL2023_X86_64_STANDARD, BOTTLEROCKET_X86_64, WINDOWS_CORE_2019_X86_64, WINDOWS_CORE_2022_X86_64, WINDOWS_FULL_2019_X86_64, WINDOWS_FULL_2022_X86_64 or don't specify any/); }); test('throws when AmiType is Windows and forbidden instanceType is selected', () => { @@ -619,7 +663,7 @@ describe('node group', () => { new ec2.InstanceType('c5.large'), new ec2.InstanceType('m5.large'), ], - })).toThrow(/The specified AMI does not match the instance types architecture, either specify one of AL2_X86_64, BOTTLEROCKET_X86_64, WINDOWS_CORE_2019_X86_64, WINDOWS_CORE_2022_X86_64, WINDOWS_FULL_2019_X86_64, WINDOWS_FULL_2022_X86_64 or don't specify any/); + })).toThrow(/The specified AMI does not match the instance types architecture, either specify one of AL2_X86_64, AL2023_X86_64_STANDARD, BOTTLEROCKET_X86_64, WINDOWS_CORE_2019_X86_64, WINDOWS_CORE_2022_X86_64, WINDOWS_FULL_2019_X86_64, WINDOWS_FULL_2022_X86_64 or don't specify any/); }); test('throws when LaunchTemplate is undefined, amiType is BOTTLEROCKET_ARM_64_NVIDIA and instanceTypes are not GPU', () => { @@ -637,7 +681,7 @@ describe('node group', () => { new ec2.InstanceType('c5.large'), new ec2.InstanceType('m5.large'), ], - })).toThrow(/The specified AMI does not match the instance types architecture, either specify one of AL2_X86_64, BOTTLEROCKET_X86_64, WINDOWS_CORE_2019_X86_64, WINDOWS_CORE_2022_X86_64, WINDOWS_FULL_2019_X86_64, WINDOWS_FULL_2022_X86_64 or don't specify any/); + })).toThrow(/The specified AMI does not match the instance types architecture, either specify one of AL2_X86_64, AL2023_X86_64_STANDARD, BOTTLEROCKET_X86_64, WINDOWS_CORE_2019_X86_64, WINDOWS_CORE_2022_X86_64, WINDOWS_FULL_2019_X86_64, WINDOWS_FULL_2022_X86_64 or don't specify any/); }); test('throws when LaunchTemplate is undefined, amiType is BOTTLEROCKET_X86_64_NVIDIA and instanceTypes are not GPU', () => { @@ -655,7 +699,7 @@ describe('node group', () => { new ec2.InstanceType('c5.large'), new ec2.InstanceType('m5.large'), ], - })).toThrow(/The specified AMI does not match the instance types architecture, either specify one of AL2_X86_64, BOTTLEROCKET_X86_64, WINDOWS_CORE_2019_X86_64, WINDOWS_CORE_2022_X86_64, WINDOWS_FULL_2019_X86_64, WINDOWS_FULL_2022_X86_64 or don't specify any/); + })).toThrow(/The specified AMI does not match the instance types architecture, either specify one of AL2_X86_64, AL2023_X86_64_STANDARD, BOTTLEROCKET_X86_64, WINDOWS_CORE_2019_X86_64, WINDOWS_CORE_2022_X86_64, WINDOWS_FULL_2019_X86_64, WINDOWS_FULL_2022_X86_64 or don't specify any/); }); /**