aws-ec2: requireImdsv2 forces EC2 replacement
- Dominant language
- TypeScript
- Stars
- 12.9k
- Forks
- 4.6k
- Avg merge
- 2d 3h
- Merged PRs (30d)
- 83
Description
### Describe the bug
When creating a new EC2 instance the IMDSv2 setting is handled in a surprising way.
```typescript
new ec2.Instance(this, myInstanceId, {
requireImdsv2: true,
...
}
```
Creates a launch template at the background if one didn't exists yet.
This is problematic as attaching a launch template to an existing instance results in a **replace**.
Replacing an EC2 instance is a destructive operation:
- any data/config stored on there is lost
- the server is taken offline
- availability disruption
- blackout/outage scenarios come to mind
[packages/aws-cdk-lib/aws-ec2/lib/instance.ts#672
```typescript
```](https://github.com/aws/aws-cdk/blob/f0e2f2a0aeeb9538bac101b523decb25d96cfc8a/packages/aws-cdk-lib/aws-ec2/lib/instance.ts#L672)
points to [InstanceRequireImdsv2Aspect](https://github.com/aws/aws-cdk/blob/f0e2f2a0aeeb9538bac101b523decb25d96cfc8a/packages/aws-cdk-lib/aws-ec2/lib/aspects/require-imdsv2-aspect.ts#L71).
Which identifies the scenario in the bug, but I think it got it backwards #83:
```typescript
if (node.instance.launchTemplate !== undefined) {
this.warn(node, 'Cannot toggle IMDSv1 because this Instance is associated with an existing Launch Template.');
return;
}
```
Then proceeds to add a new launchTemplate if there wasn't one, therefore replacing the instance #100:
```typescript
node.instance.launchTemplate = {
launchTemplateName: launchTemplate.launchTemplateName,
version: launchTemplate.getAtt('LatestVersionNumber').toString(),
};
```
### Regression Issue
- [ ] Select this option if this issue appears to be a regression.
### Last Known Working CDK Version
_No response_
### Expected Behavior
EC2 is not replaced by changing a simple bool from false to true.
This setting can be toggled on AWS Console without EC2 replace, it is a CDK bug.
### Current Behavior
EC2 is replaced when IMDSv2 is set to required from CDK because it forces a new launchTemplate to be associated.
### Reproduction Steps
Deploy a new instance from cdk without:
```typescript
new ec2.Instance(this, myInstanceId, {
...
}
```
Then add `requireImdsv2: true,`
```typescript
new ec2.Instance(this, myInstanceId, {
requireImdsv2: true,
...
}
```
Either:
- Observe the template.json changes.
- Use `cdk diff`, it will show the new launchTemplate and the need to replace.
- Turn on termination protection and try `cdk deploy`
All of these will show this.
### Possible Solution
_No response_
### Additional Information/Context
_No response_
### CDK CLI Version
2.174.1 (build f353fc7)
### Framework Version
_No response_
### Node.js Version
20
### OS
macos
### Language
TypeScript
### Language Version
_No response_
### Other information
It's not OS or nodejs version related.
Contributor guide
Research direction
Start with packages/aws-cdk-lib/aws-ec2/lib/instance.ts around line 672 and packages/aws-cdk-lib/aws-ec2/lib/aspects/require-imdsv2-aspect.ts around line 71. Reproduce the change with cdk diff and inspect how InstanceRequireImdsv2Aspect handles an instance without a launch template. Done means enabling requireImdsv2 no longer causes an existing EC2 instance to be replaced, while the requested setting remains applied.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- aws, typescript
- Domain
- cloud, infrastructure
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100