Skip to content

Commit 4056e14

Browse files
authored
feat(ec2): expose EC2 instance MetadataOptions (#35369)
### Issue # (if applicable) Closes #35357. ### Reason for this change The EC2 Instance construct lacked support for metadata options configuration, while the LaunchTemplate construct already had this capability. Users needed a way to configure instance metadata options (like IMDSv2 requirements, hop limits, etc.) directly on Instance constructs without resorting to escape hatches. ### Description of changes Added metadata options properties to Instance construct with flat properties matching LaunchTemplate API design for consistency across the EC2 module. **Key changes:** 1. **Instance construct enhancements** - Added individual metadata option properties directly to InstanceProps: - `httpEndpoint?: boolean` - Enables or disables the HTTP metadata endpoint - `httpProtocolIpv6?: boolean` - Enables or disables the IPv6 endpoint for IMDS - `httpPutResponseHopLimit?: number` - Sets the hop limit for metadata requests (1-64) - `httpTokens?: HttpTokens` - Controls IMDSv2 requirement (OPTIONAL or REQUIRED) - `instanceMetadataTags?: boolean` - Enables or disables instance tag access from metadata API 2. **Separate enum for cleaner API** - Defined `HttpTokens` enum in instance.ts: - Instance uses `HttpTokens` enum (cleaner API for new construct) - LaunchTemplate keeps `LaunchTemplateHttpTokens` enum (backward compatible, no JSII breaking change) - Both enums have identical members (OPTIONAL, REQUIRED) for consistency 3. **Validation and rendering** - Added validation to prevent conflicting use of metadata options with `requireImdsv2` and implemented smart rendering that only includes MetadataOptions when explicitly specified 4. **Testing** - Added 22 comprehensive unit tests covering all metadata options scenarios **Before (using escape hatch):** ```typescript const instance = new ec2.Instance(this, 'Instance', { vpc, instanceType, machineImage, }); const cfnInstance = instance.node.defaultChild as ec2.CfnInstance; cfnInstance.addPropertyOverride('MetadataOptions', { HttpTokens: 'required', HttpPutResponseHopLimit: 2, }); ``` **After (idiomatic L2 API):** ```typescript const instance = new ec2.Instance(this, 'Instance', { vpc, instanceType, machineImage, httpTokens: HttpTokens.REQUIRED, httpPutResponseHopLimit: 2, instanceMetadataTags: true, }); ``` **CloudFormation impact:** - When metadata options are specified, generates MetadataOptions object with only the specified properties - When not specified, CloudFormation template remains unchanged (backward compatible) - No breaking changes to existing behavior ### Accurate CloudFormation defaults All properties include evidence-based `@default` tags based on official AWS CloudFormation documentation: - `httpEndpoint`: @default true - CloudFormation default is "enabled" - `httpProtocolIpv6`: @default false - CloudFormation default is "disabled" - `httpPutResponseHopLimit`: @default - No default specified in CloudFormation - `httpTokens`: @default - Conditional default based on AMI and account settings - `instanceMetadataTags`: @default false - CloudFormation default is "disabled" ### Separate enum approach Instance defines its own `HttpTokens` enum with identical members: ```typescript export enum HttpTokens { OPTIONAL = 'optional', REQUIRED = 'required', } ``` This provides a cleaner API for Instance users while maintaining full backward compatibility: - Instance API uses `HttpTokens` enum (cleaner for users) - LaunchTemplate API uses `LaunchTemplateHttpTokens` enum (no JSII breaking change) - Both enums have identical members for consistency - Follows conventional CDK patterns (similar to ELBv2 shared enums) ### Description of how you validated changes - **Unit tests**: Added 22 comprehensive tests covering: - All metadata options with various values - Boolean to enabled/disabled string mapping - Hop limit validation (1-64 range) - Partial configuration (only specified properties rendered) - Conflict detection with requireImdsv2 - **Build verification**: TypeScript compilation, linting, and JSII build all pass successfully - **Integration tests**: Updated integ.instance-metadata-options.ts to use the new flat API - **CloudFormation validation**: Unit tests verify correct template generation with proper property structure - **API consistency**: Verified the API matches LaunchTemplate's flat property design - **Backward compatibility**: Verified LaunchTemplateHttpTokens alias works with existing code ### Checklist - [x] My code adheres to the [CONTRIBUTING GUIDE](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) and [DESIGN GUIDELINES](https://github.com/aws/aws-cdk/blob/main/docs/DESIGN_GUIDELINES.md) ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
1 parent d284733 commit 4056e14

File tree

15 files changed

+2663
-7
lines changed

15 files changed

+2663
-7
lines changed

packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.instance-metadata-options.js.snapshot/asset.a1acfc2b5f4f6b183fd2bb9863f486bc5edef6a357b355a070d9a0e502df418c/__entrypoint__.js

Lines changed: 155 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.instance-metadata-options.js.snapshot/asset.a1acfc2b5f4f6b183fd2bb9863f486bc5edef6a357b355a070d9a0e502df418c/index.js

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.instance-metadata-options.js.snapshot/cdk.out

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.instance-metadata-options.js.snapshot/instancemetadataoptionstestDefaultTestDeployAssert743E5801.assets.json

Lines changed: 20 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.instance-metadata-options.js.snapshot/instancemetadataoptionstestDefaultTestDeployAssert743E5801.template.json

Lines changed: 36 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.instance-metadata-options.js.snapshot/integ-ec2-instance-metadata-options.assets.json

Lines changed: 34 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)