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

fix(ec2): AmazonLinuxImage construct generates incorrect SSM parameter name for AL2023 images #27698

Merged
merged 7 commits into from
Nov 10, 2023
Next Next commit
fix(ec2): AmazonLinuxImage construct generates incorrect SSM paramete…
…r name for AL2023 images
tam0ri committed Oct 26, 2023
commit 805a00713751952cca827c0498fec755475d1aa9

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

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

Large diffs are not rendered by default.

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

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

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

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -30,14 +30,23 @@ export class TestCase extends Stack {
vpc,
});

new ssm.CfnParameter(this, 'AmiParameter', {
new ec2.Instance(this, 'al2023 with minimal AMI', {
instanceType,
machineImage: new ec2.AmazonLinuxImage({
generation: ec2.AmazonLinuxGeneration.AMAZON_LINUX_2023,
edition: ec2.AmazonLinuxEdition.MINIMAL,
}),
vpc,
});

const parameter = new ssm.CfnParameter(this, 'AmiParameter', {
name: 'myAmi',
type: 'String',
dataType: 'aws:ec2:image',
value: 'ami-06ca3ca175f37dd66',
});

const machineImage = ec2.MachineImage.resolveSsmParameterAtLaunch('myAmi');
const machineImage = ec2.MachineImage.resolveSsmParameterAtLaunch(parameter.ref);
new ec2.Instance(this, 'ssm-resolve-instance', { instanceType, machineImage, vpc });

const launchTemplate = new ec2.LaunchTemplate(this, 'LT', { instanceType, machineImage });
20 changes: 17 additions & 3 deletions packages/aws-cdk-lib/aws-ec2/lib/machine-image/machine-image.ts
Original file line number Diff line number Diff line change
@@ -486,10 +486,18 @@ export class AmazonLinuxImage extends GenericSSMParameterImage {
if (generation === AmazonLinuxGeneration.AMAZON_LINUX_2022) {
kernel = AmazonLinuxKernel.KERNEL5_X;
if (props && props.storage) {
throw new Error('Storage parameter does not exist in smm parameter name for Amazon Linux 2022.');
throw new Error('Storage parameter does not exist in SSM parameter name for Amazon Linux 2022.');
}
if (props && props.virtualization) {
throw new Error('Virtualization parameter does not exist in smm parameter name for Amazon Linux 2022.');
throw new Error('Virtualization parameter does not exist in SSM parameter name for Amazon Linux 2022.');
}
} else if (generation === AmazonLinuxGeneration.AMAZON_LINUX_2023) {
kernel = AmazonLinuxKernel.KERNEL6_1;
if (props && props.storage) {
throw new Error('Storage parameter does not exist in SSM parameter name for Amazon Linux 2023.');
}
if (props && props.virtualization) {
throw new Error('Virtualization parameter does not exist in SSM parameter name for Amazon Linux 2023.');
}
} else {
virtualization = (props && props.virtualization) || AmazonLinuxVirt.HVM;
@@ -537,9 +545,15 @@ export class AmazonLinuxImage extends GenericSSMParameterImage {
*/
export enum AmazonLinuxKernel {
/**
* Standard edition
* Kernel version 5.10
*/
KERNEL5_X = 'kernel-5.10',

/**
* Kernel version 6.1
*/
KERNEL6_1 = 'kernel-6.1',

}

/**
33 changes: 31 additions & 2 deletions packages/aws-cdk-lib/aws-ec2/test/machine-image.test.ts
Original file line number Diff line number Diff line change
@@ -261,7 +261,7 @@ test('throw error if storage param is set for Amazon Linux 2022', () => {
generation: ec2.AmazonLinuxGeneration.AMAZON_LINUX_2022,
storage: ec2.AmazonLinuxStorage.GENERAL_PURPOSE,
}).getImage(stack).imageId;
}).toThrow(/Storage parameter does not exist in smm parameter name for Amazon Linux 2022./);
}).toThrow(/Storage parameter does not exist in SSM parameter name for Amazon Linux 2022./);
});

test('throw error if virtualization param is set for Amazon Linux 2022', () => {
@@ -271,7 +271,7 @@ test('throw error if virtualization param is set for Amazon Linux 2022', () => {
generation: ec2.AmazonLinuxGeneration.AMAZON_LINUX_2022,
virtualization: ec2.AmazonLinuxVirt.HVM,
}).getImage(stack).imageId;
}).toThrow(/Virtualization parameter does not exist in smm parameter name for Amazon Linux 2022./);
}).toThrow(/Virtualization parameter does not exist in SSM parameter name for Amazon Linux 2022./);
});

test('cached lookups of Amazon Linux 2022 with kernel 5.x', () => {
@@ -404,6 +404,35 @@ describe('latest amazon linux', () => {
},
]);
});

test('AmazonLinuxImage with AMAZON_LINUX_2023', () => {
// WHEN
new ec2.AmazonLinuxImage({ generation: ec2.AmazonLinuxGeneration.AMAZON_LINUX_2023 }).getImage(stack);

// THEN
Template.fromStack(stack).hasParameter('*', {
Type: 'AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>',
Default: '/aws/service/ami-amazon-linux-latest/al2023-ami-kernel-6.1-x86_64',
});
});
});

test('throw error if storage param is set for Amazon Linux 2023', () => {
expect(() => {
new ec2.AmazonLinuxImage({
generation: ec2.AmazonLinuxGeneration.AMAZON_LINUX_2023,
storage: ec2.AmazonLinuxStorage.GENERAL_PURPOSE,
}).getImage(stack);
}).toThrow(/Storage parameter does not exist in SSM parameter name for Amazon Linux 2023./);
});

test('throw error if virtualization param is set for Amazon Linux 2023', () => {
expect(() => {
new ec2.AmazonLinuxImage({
generation: ec2.AmazonLinuxGeneration.AMAZON_LINUX_2023,
virtualization: ec2.AmazonLinuxVirt.HVM,
}).getImage(stack);
}).toThrow(/Virtualization parameter does not exist in SSM parameter name for Amazon Linux 2023./);
Comment on lines +420 to +435
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These tests are outside of the describe block. Is that intended? It looks like theres a mix of 2022 and 2023 tests in the latest describe block. Is that intended too?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@scanlonp Thank you for your comment!

These tests are outside of the describe block. Is that intended?

Yes, this is intentional. I added three tests.

  1. 'AmazonLinuxImage with AMAZON_LINUX_2023'
  2. 'throw error if storage param is set for Amazon Linux 2023'
  3. 'throw error if virtualization param is set for Amazon Linux 2023'

1 is located in latest describe block. This is because I want to verify whether AmazonLinuxImage construct generates SSM parameter path for the latest AL2023 image by this change. 2 and 3 are not located in the describe block. This is also intentional because these tests are similar with the following tests located outside of the describe block.

test('throw error if storage param is set for Amazon Linux 2022', () => {
expect(() => {
ec2.MachineImage.latestAmazonLinux({
cachedInContext: true,
generation: ec2.AmazonLinuxGeneration.AMAZON_LINUX_2022,
storage: ec2.AmazonLinuxStorage.GENERAL_PURPOSE,
}).getImage(stack).imageId;
}).toThrow(/Storage parameter does not exist in smm parameter name for Amazon Linux 2022./);
});
test('throw error if virtualization param is set for Amazon Linux 2022', () => {
expect(() => {
ec2.MachineImage.latestAmazonLinux({
cachedInContext: true,
generation: ec2.AmazonLinuxGeneration.AMAZON_LINUX_2022,
virtualization: ec2.AmazonLinuxVirt.HVM,
}).getImage(stack).imageId;
}).toThrow(/Virtualization parameter does not exist in smm parameter name for Amazon Linux 2022./);
});

If I should move 2 and 3 into directly below the above tests, please let me know.

It looks like theres a mix of 2022 and 2023 tests in the latest describe block. Is that intended too?

This is not my intention. Before I added these tests, tests for both 2022 and 2023 are located in the describe block as below.
https://github.com/aws/aws-cdk/blob/main/packages/aws-cdk-lib/aws-ec2/test/machine-image.test.ts#L300-L407

});

function isWindowsUserData(ud: ec2.UserData) {