From 68049a811b244562008b071e97f26910c8865ff0 Mon Sep 17 00:00:00 2001 From: newlinedeveloper Date: Sat, 15 Nov 2025 16:07:53 +0530 Subject: [PATCH 1/3] updated the ec2 gp3 volume limit --- .../test/integ.volume-gp3-max-limits.ts | 46 +++++++++++++ .../aws-autoscaling/lib/auto-scaling-group.ts | 3 +- .../aws-cdk-lib/aws-autoscaling/lib/volume.ts | 2 +- .../test/auto-scaling-group.test.ts | 4 +- packages/aws-cdk-lib/aws-ec2/README.md | 2 +- .../aws-ec2/lib/private/ebs-util.ts | 4 +- packages/aws-cdk-lib/aws-ec2/lib/volume.ts | 8 +-- .../aws-ec2/test/launch-template.test.ts | 4 +- .../aws-cdk-lib/aws-ec2/test/volume.test.ts | 6 +- .../lib/base/service-managed-volume.ts | 6 +- .../test/fargate/fargate-service.test.ts | 64 +++++++------------ 11 files changed, 87 insertions(+), 62 deletions(-) create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.volume-gp3-max-limits.ts diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.volume-gp3-max-limits.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.volume-gp3-max-limits.ts new file mode 100644 index 0000000000000..002df7b6a7976 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.volume-gp3-max-limits.ts @@ -0,0 +1,46 @@ +import * as cdk from 'aws-cdk-lib'; +import * as integ from '@aws-cdk/integ-tests-alpha'; +import * as ec2 from 'aws-cdk-lib/aws-ec2'; +import { EC2_RESTRICT_DEFAULT_SECURITY_GROUP } from 'aws-cdk-lib/cx-api'; + +const app = new cdk.App(); + +const stack = new cdk.Stack(app, 'aws-cdk-ec2-volume-gp3-max-limits'); +stack.node.setContext(EC2_RESTRICT_DEFAULT_SECURITY_GROUP, false); + +// Test GP3 volume with maximum throughput (2000 MiB/s) +// Note: Requires at least 8000 IOPS (2000 / 0.25 ratio) and at least 16 GiB (8000 / 500 IOPS/GiB) +new ec2.Volume(stack, 'TestVolumeMaxThroughput', { + availabilityZone: 'us-east-1a', + size: cdk.Size.gibibytes(16), // Minimum size for 8000 IOPS + volumeType: ec2.EbsDeviceVolumeType.GP3, + throughput: 2000, + iops: 8000, // Minimum IOPS to support 2000 MiB/s (2000 / 0.25 = 8000) +}); + +// Test GP3 volume with maximum IOPS (80000) +// Note: Maximum IOPS requires at least 160 GiB (80000 / 500 ratio) +new ec2.Volume(stack, 'TestVolumeMaxIOPS', { + availabilityZone: 'us-east-1a', + size: cdk.Size.gibibytes(160), + volumeType: ec2.EbsDeviceVolumeType.GP3, + iops: 80000, + throughput: 125, // Default throughput +}); + +// Test GP3 volume with both maximum throughput and IOPS +// Note: 2000 MiB/s requires at least 8000 IOPS, but we're using 80000 IOPS which is fine +// Ratio = 2000 / 80000 = 0.025 (well below 0.25 limit) +new ec2.Volume(stack, 'TestVolumeMaxBoth', { + availabilityZone: 'us-east-1a', + size: cdk.Size.gibibytes(160), + volumeType: ec2.EbsDeviceVolumeType.GP3, + iops: 80000, + throughput: 2000, +}); + +new integ.IntegTest(app, 'VolumeGP3MaxLimitsTest', { + testCases: [stack], +}); + +app.synth(); diff --git a/packages/aws-cdk-lib/aws-autoscaling/lib/auto-scaling-group.ts b/packages/aws-cdk-lib/aws-autoscaling/lib/auto-scaling-group.ts index 0c21fe62e2888..778721a8a8f09 100644 --- a/packages/aws-cdk-lib/aws-autoscaling/lib/auto-scaling-group.ts +++ b/packages/aws-cdk-lib/aws-autoscaling/lib/auto-scaling-group.ts @@ -1,4 +1,3 @@ - import { Construct } from 'constructs'; import { AutoScalingGroupRequireImdsv2Aspect } from './aspects'; import { CfnAutoScalingGroup, CfnAutoScalingGroupProps, CfnLaunchConfiguration } from './autoscaling.generated'; @@ -2610,7 +2609,7 @@ function synthesizeBlockDeviceMappings(construct: Construct, blockDevices: Block const { iops, volumeType, throughput } = ebs; if (throughput) { - const throughputRange = { Min: 125, Max: 1000 }; + const throughputRange = { Min: 125, Max: 2000 }; const { Min, Max } = throughputRange; if (volumeType != EbsDeviceVolumeType.GP3) { diff --git a/packages/aws-cdk-lib/aws-autoscaling/lib/volume.ts b/packages/aws-cdk-lib/aws-autoscaling/lib/volume.ts index bca59497c1766..5f9c833230cb3 100644 --- a/packages/aws-cdk-lib/aws-autoscaling/lib/volume.ts +++ b/packages/aws-cdk-lib/aws-autoscaling/lib/volume.ts @@ -71,7 +71,7 @@ export interface EbsDeviceOptionsBase { /** * The throughput that the volume supports, in MiB/s - * Takes a minimum of 125 and maximum of 1000. + * Takes a minimum of 125 and maximum of 2000. * @see https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSVolumeTypes.html * @default - 125 MiB/s. Only valid on gp3 volumes. */ diff --git a/packages/aws-cdk-lib/aws-autoscaling/test/auto-scaling-group.test.ts b/packages/aws-cdk-lib/aws-autoscaling/test/auto-scaling-group.test.ts index 7c059ceecf474..f501ed3cdfe83 100644 --- a/packages/aws-cdk-lib/aws-autoscaling/test/auto-scaling-group.test.ts +++ b/packages/aws-cdk-lib/aws-autoscaling/test/auto-scaling-group.test.ts @@ -1170,7 +1170,7 @@ describe('auto scaling group', () => { }).toThrow(/maxInstanceLifetime must be between 1 and 365 days \(inclusive\)/); }); - test.each([124, 1001])('throws if throughput is set less than 125 or more than 1000', (throughput) => { + test.each([124, 2001])('throws if throughput is set less than 125 or more than 2000', (throughput) => { const stack = new cdk.Stack(); const vpc = mockVpc(stack); @@ -1188,7 +1188,7 @@ describe('auto scaling group', () => { }), }], }); - }).toThrow(/throughput property takes a minimum of 125 and a maximum of 1000/); + }).toThrow(/throughput property takes a minimum of 125 and a maximum of 2000/); }); test.each([ diff --git a/packages/aws-cdk-lib/aws-ec2/README.md b/packages/aws-cdk-lib/aws-ec2/README.md index 19d70abc78971..1d8f281fcb9c9 100644 --- a/packages/aws-cdk-lib/aws-ec2/README.md +++ b/packages/aws-cdk-lib/aws-ec2/README.md @@ -1907,7 +1907,7 @@ You can configure [tag propagation on volume creation](https://docs.aws.amazon.c #### Throughput on GP3 Volumes -You can specify the `throughput` of a GP3 volume from 125 (default) to 1000. +You can specify the `throughput` of a GP3 volume from 125 (default) to 2000. ```ts new ec2.Volume(this, 'Volume', { diff --git a/packages/aws-cdk-lib/aws-ec2/lib/private/ebs-util.ts b/packages/aws-cdk-lib/aws-ec2/lib/private/ebs-util.ts index 5ae004d009973..fd4a4d3c5060a 100644 --- a/packages/aws-cdk-lib/aws-ec2/lib/private/ebs-util.ts +++ b/packages/aws-cdk-lib/aws-ec2/lib/private/ebs-util.ts @@ -43,8 +43,8 @@ function synthesizeBlockDeviceMappings(construct: Construct, blockDevic throw new ValidationError(`'throughput' must be an integer, got: ${throughput}.`, construct); } - if (throughput < 125 || throughput > 1000) { - throw new ValidationError(`'throughput' must be between 125 and 1000, got ${throughput}.`, construct); + if (throughput < 125 || throughput > 2000) { + throw new ValidationError(`'throughput' must be between 125 and 2000, got ${throughput}.`, construct); } const maximumThroughputRatio = 0.25; diff --git a/packages/aws-cdk-lib/aws-ec2/lib/volume.ts b/packages/aws-cdk-lib/aws-ec2/lib/volume.ts index 8a854f88683c0..6ef88c8900576 100644 --- a/packages/aws-cdk-lib/aws-ec2/lib/volume.ts +++ b/packages/aws-cdk-lib/aws-ec2/lib/volume.ts @@ -88,7 +88,7 @@ export interface EbsDeviceOptionsBase { /** * The throughput to provision for a `gp3` volume. * - * Valid Range: Minimum value of 125. Maximum value of 1000. + * Valid Range: Minimum value of 125. Maximum value of 2000. * * `gp3` volumes deliver a consistent baseline throughput performance of 125 MiB/s. * You can provision additional throughput for an additional cost at a ratio of 0.25 MiB/s per provisioned IOPS. @@ -475,7 +475,7 @@ export interface VolumeProps { /** * The throughput that the volume supports, in MiB/s - * Takes a minimum of 125 and maximum of 1000. + * Takes a minimum of 125 and maximum of 2000. * @see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-volume.html#cfn-ec2-volume-throughput * @default - 125 MiB/s. Only valid on gp3 volumes. */ @@ -756,7 +756,7 @@ export class Volume extends VolumeBase { // Enforce minimum & maximum IOPS: // https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-volume.html const iopsRanges: { [key: string]: { Min: number; Max: number } } = {}; - iopsRanges[EbsDeviceVolumeType.GENERAL_PURPOSE_SSD_GP3] = { Min: 3000, Max: 16000 }; + iopsRanges[EbsDeviceVolumeType.GENERAL_PURPOSE_SSD_GP3] = { Min: 3000, Max: 80000 }; iopsRanges[EbsDeviceVolumeType.PROVISIONED_IOPS_SSD] = { Min: 100, Max: 64000 }; iopsRanges[EbsDeviceVolumeType.PROVISIONED_IOPS_SSD_IO2] = { Min: 100, Max: 256000 }; const { Min, Max } = iopsRanges[volumeType]; @@ -818,7 +818,7 @@ export class Volume extends VolumeBase { } if (props.throughput) { - const throughputRange = { Min: 125, Max: 1000 }; + const throughputRange = { Min: 125, Max: 2000 }; const { Min, Max } = throughputRange; if (props.volumeType != EbsDeviceVolumeType.GP3) { throw new ValidationError( diff --git a/packages/aws-cdk-lib/aws-ec2/test/launch-template.test.ts b/packages/aws-cdk-lib/aws-ec2/test/launch-template.test.ts index 5807388493a7b..d4278cc394aba 100644 --- a/packages/aws-cdk-lib/aws-ec2/test/launch-template.test.ts +++ b/packages/aws-cdk-lib/aws-ec2/test/launch-template.test.ts @@ -408,7 +408,7 @@ describe('LaunchTemplate', () => { }, }); }); - test.each([124, 1001])('throws if throughput is set less than 125 or more than 1000', (throughput) => { + test.each([124, 2001])('throws if throughput is set less than 125 or more than 2000', (throughput) => { expect(() => { new LaunchTemplate(stack, 'LaunchTemplate', { blockDevices: [{ @@ -419,7 +419,7 @@ describe('LaunchTemplate', () => { }), }], }); - }).toThrow(/'throughput' must be between 125 and 1000, got/); + }).toThrow(/'throughput' must be between 125 and 2000, got/); }); test('throws if throughput is not an integer', () => { expect(() => { diff --git a/packages/aws-cdk-lib/aws-ec2/test/volume.test.ts b/packages/aws-cdk-lib/aws-ec2/test/volume.test.ts index 3849443c4dd7e..936dac43858ff 100644 --- a/packages/aws-cdk-lib/aws-ec2/test/volume.test.ts +++ b/packages/aws-cdk-lib/aws-ec2/test/volume.test.ts @@ -1297,7 +1297,7 @@ describe('volume', () => { // Test: iops in range for (const testData of [ - [EbsDeviceVolumeType.GENERAL_PURPOSE_SSD_GP3, 3000, 16000], + [EbsDeviceVolumeType.GENERAL_PURPOSE_SSD_GP3, 3000, 80000], [EbsDeviceVolumeType.PROVISIONED_IOPS_SSD, 100, 64000], [EbsDeviceVolumeType.PROVISIONED_IOPS_SSD_IO2, 100, 256000], ]) { @@ -1475,7 +1475,7 @@ describe('volume', () => { } }); - test.each([124, 1001])('throws if throughput is set less than 125 or more than 1000', (throughput) => { + test.each([124, 2001])('throws if throughput is set less than 125 or more than 2000', (throughput) => { const stack = new cdk.Stack(); expect(() => { new Volume(stack, 'Volume', { @@ -1484,7 +1484,7 @@ describe('volume', () => { volumeType: EbsDeviceVolumeType.GP3, throughput, }); - }).toThrow(/throughput property takes a minimum of 125 and a maximum of 1000/); + }).toThrow(/throughput property takes a minimum of 125 and a maximum of 2000/); }); test.each([ diff --git a/packages/aws-cdk-lib/aws-ecs/lib/base/service-managed-volume.ts b/packages/aws-cdk-lib/aws-ecs/lib/base/service-managed-volume.ts index 2fec0724b1e49..282fe649572c7 100644 --- a/packages/aws-cdk-lib/aws-ecs/lib/base/service-managed-volume.ts +++ b/packages/aws-cdk-lib/aws-ecs/lib/base/service-managed-volume.ts @@ -301,8 +301,8 @@ export class ServiceManagedVolume extends Construct { if (throughput !== undefined) { if (volumeType !== ec2.EbsDeviceVolumeType.GP3) { throw new ValidationError(`'throughput' can only be configured with gp3 volume type, got ${volumeType}`, this); - } else if (!Token.isUnresolved(throughput) && throughput > 1000) { - throw new ValidationError(`'throughput' must be less than or equal to 1000 MiB/s, got ${throughput} MiB/s`, this); + } else if (!Token.isUnresolved(throughput) && throughput > 2000) { + throw new ValidationError(`'throughput' must be less than or equal to 2000 MiB/s, got ${throughput} MiB/s`, this); } } @@ -320,7 +320,7 @@ export class ServiceManagedVolume extends Construct { // Validate IOPS range if specified. const iopsRanges: { [key: string]: { min: number; max: number } } = {}; - iopsRanges[ec2.EbsDeviceVolumeType.GP3]= { min: 3000, max: 16000 }; + iopsRanges[ec2.EbsDeviceVolumeType.GP3]= { min: 3000, max: 80000 }; iopsRanges[ec2.EbsDeviceVolumeType.IO1]= { min: 100, max: 64000 }; iopsRanges[ec2.EbsDeviceVolumeType.IO2]= { min: 100, max: 256000 }; if (iops !== undefined && !Token.isUnresolved(iops)) { diff --git a/packages/aws-cdk-lib/aws-ecs/test/fargate/fargate-service.test.ts b/packages/aws-cdk-lib/aws-ecs/test/fargate/fargate-service.test.ts index 90193899b4e7c..a54f68456cdec 100644 --- a/packages/aws-cdk-lib/aws-ecs/test/fargate/fargate-service.test.ts +++ b/packages/aws-cdk-lib/aws-ecs/test/fargate/fargate-service.test.ts @@ -2328,48 +2328,6 @@ describe('fargate service', () => { }).toThrow(/'throughput' can only be configured with gp3 volume type, got gp2/); }); - test('throw an error if throughput is greater tahn 1000 for volume type gp3', ()=> { - // WHEN - container.addMountPoints({ - containerPath: '/var/lib', - readOnly: false, - sourceVolume: 'nginx-vol', - }); - - expect(() => { - service.addVolume(new ServiceManagedVolume(stack, 'EBS Volume', { - name: 'nginx-vol', - managedEBSVolume: { - fileSystemType: ecs.FileSystemType.XFS, - volumeType: ec2.EbsDeviceVolumeType.GP3, - size: cdk.Size.gibibytes(10), - throughput: 10001, - }, - })); - }).toThrow("'throughput' must be less than or equal to 1000 MiB/s, got 10001 MiB/s"); - }); - - test('throw an error if throughput is greater tahn 1000 for volume type gp3', ()=> { - // WHEN - container.addMountPoints({ - containerPath: '/var/lib', - readOnly: false, - sourceVolume: 'nginx-vol', - }); - - expect(() => { - service.addVolume(new ServiceManagedVolume(stack, 'EBS Volume', { - name: 'nginx-vol', - managedEBSVolume: { - fileSystemType: ecs.FileSystemType.XFS, - volumeType: ec2.EbsDeviceVolumeType.GP3, - size: cdk.Size.gibibytes(10), - throughput: 10001, - }, - })); - }).toThrow("'throughput' must be less than or equal to 1000 MiB/s, got 10001 MiB/s"); - }); - test('throw an error if iops is not supported for volume type sc1', ()=> { // WHEN container.addMountPoints({ @@ -2580,6 +2538,28 @@ describe('fargate service', () => { ], }); }); + + test('throw an error if throughput is greater than 2000 for volume type gp3', () => { + // WHEN + container.addMountPoints({ + containerPath: '/var/lib', + readOnly: false, + sourceVolume: 'nginx-vol', + }); + + expect(() => { + service.addVolume(new ServiceManagedVolume(stack, 'EBS Volume', { + name: 'nginx-vol', + managedEBSVolume: { + fileSystemType: ecs.FileSystemType.XFS, + volumeType: ec2.EbsDeviceVolumeType.GP3, + size: cdk.Size.gibibytes(10), + throughput: 2001, + }, + })); + }).toThrow("'throughput' must be less than or equal to 2000 MiB/s, got 2001 MiB/s"); + }); + }); describe('When setting up a health check', () => { From 8eeccdb0e6958ab54cc92cf3669ca300df0ff0ed Mon Sep 17 00:00:00 2001 From: newlinedeveloper Date: Sun, 16 Nov 2025 14:11:09 +0530 Subject: [PATCH 2/3] fixed lint issue --- .../aws-cdk-lib/aws-ecs/test/fargate/fargate-service.test.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/aws-cdk-lib/aws-ecs/test/fargate/fargate-service.test.ts b/packages/aws-cdk-lib/aws-ecs/test/fargate/fargate-service.test.ts index a54f68456cdec..0a97e44b82fb5 100644 --- a/packages/aws-cdk-lib/aws-ecs/test/fargate/fargate-service.test.ts +++ b/packages/aws-cdk-lib/aws-ecs/test/fargate/fargate-service.test.ts @@ -2559,7 +2559,6 @@ describe('fargate service', () => { })); }).toThrow("'throughput' must be less than or equal to 2000 MiB/s, got 2001 MiB/s"); }); - }); describe('When setting up a health check', () => { From b3245016a1fdb576f3fd7d8a6b2fd777222e6beb Mon Sep 17 00:00:00 2001 From: newlinedeveloper Date: Tue, 18 Nov 2025 07:33:35 +0530 Subject: [PATCH 3/3] removed integration testing --- .../test/integ.volume-gp3-max-limits.ts | 46 ------------------- 1 file changed, 46 deletions(-) delete mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.volume-gp3-max-limits.ts diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.volume-gp3-max-limits.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.volume-gp3-max-limits.ts deleted file mode 100644 index 002df7b6a7976..0000000000000 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.volume-gp3-max-limits.ts +++ /dev/null @@ -1,46 +0,0 @@ -import * as cdk from 'aws-cdk-lib'; -import * as integ from '@aws-cdk/integ-tests-alpha'; -import * as ec2 from 'aws-cdk-lib/aws-ec2'; -import { EC2_RESTRICT_DEFAULT_SECURITY_GROUP } from 'aws-cdk-lib/cx-api'; - -const app = new cdk.App(); - -const stack = new cdk.Stack(app, 'aws-cdk-ec2-volume-gp3-max-limits'); -stack.node.setContext(EC2_RESTRICT_DEFAULT_SECURITY_GROUP, false); - -// Test GP3 volume with maximum throughput (2000 MiB/s) -// Note: Requires at least 8000 IOPS (2000 / 0.25 ratio) and at least 16 GiB (8000 / 500 IOPS/GiB) -new ec2.Volume(stack, 'TestVolumeMaxThroughput', { - availabilityZone: 'us-east-1a', - size: cdk.Size.gibibytes(16), // Minimum size for 8000 IOPS - volumeType: ec2.EbsDeviceVolumeType.GP3, - throughput: 2000, - iops: 8000, // Minimum IOPS to support 2000 MiB/s (2000 / 0.25 = 8000) -}); - -// Test GP3 volume with maximum IOPS (80000) -// Note: Maximum IOPS requires at least 160 GiB (80000 / 500 ratio) -new ec2.Volume(stack, 'TestVolumeMaxIOPS', { - availabilityZone: 'us-east-1a', - size: cdk.Size.gibibytes(160), - volumeType: ec2.EbsDeviceVolumeType.GP3, - iops: 80000, - throughput: 125, // Default throughput -}); - -// Test GP3 volume with both maximum throughput and IOPS -// Note: 2000 MiB/s requires at least 8000 IOPS, but we're using 80000 IOPS which is fine -// Ratio = 2000 / 80000 = 0.025 (well below 0.25 limit) -new ec2.Volume(stack, 'TestVolumeMaxBoth', { - availabilityZone: 'us-east-1a', - size: cdk.Size.gibibytes(160), - volumeType: ec2.EbsDeviceVolumeType.GP3, - iops: 80000, - throughput: 2000, -}); - -new integ.IntegTest(app, 'VolumeGP3MaxLimitsTest', { - testCases: [stack], -}); - -app.synth();