aws / aws/aws-cdk

aws-ec2: requireImdsv2 forces EC2 replacement

Open
#32,886 6 comments 0 reactions 0 assignees View on GitHub
@aws-cdk/aws-ec2 bug effort/small needs-cfn p2
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.