-
Notifications
You must be signed in to change notification settings - Fork 4k
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
aws-ec2: requireImdsv2 forces EC2 replacement #32886
Comments
This is my corporate github account. |
Per AWS::EC2::LaunchTemplate MetadataOptions, change to HttpTokens caused update that requires No interruption, which means Initially when below CDK code is synthesized and deployed: import * as cdk from 'aws-cdk-lib';
import * as ec2 from 'aws-cdk-lib/aws-ec2';
export class CdktestStackNew extends cdk.Stack {
constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const vpc = ec2.Vpc.fromLookup(this, 'MyDefaultVpc', { isDefault: true });
new ec2.Instance(this, 'MyEC2Instance', {
vpc,
instanceType: ec2.InstanceType.of(ec2.InstanceClass.T2, ec2.InstanceSize.MICRO),
machineImage: ec2.MachineImage.latestAmazonLinux2023(),
disableApiTermination: true
});
}
} it used the below CFN template: {
"Resources": {
"MyEC2InstanceInstanceSecurityGroup06C6622F": {
"Type": "AWS::EC2::SecurityGroup",
"Properties": {
"GroupDescription": "CdktestStackNew/MyEC2Instance/InstanceSecurityGroup",
"SecurityGroupEgress": [
{
"CidrIp": "0.0.0.0/0",
"Description": "Allow all outbound traffic by default",
"IpProtocol": "-1"
}
],
"Tags": [
{
"Key": "Name",
"Value": "CdktestStackNew/MyEC2Instance"
}
],
"VpcId": "vpc-0bcd157c9276f648b"
},
"Metadata": {
"aws:cdk:path": "CdktestStackNew/MyEC2Instance/InstanceSecurityGroup/Resource"
}
},
"MyEC2InstanceInstanceRole1A6C2310": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Statement": [
{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
}
}
],
"Version": "2012-10-17"
},
"Tags": [
{
"Key": "Name",
"Value": "CdktestStackNew/MyEC2Instance"
}
]
},
"Metadata": {
"aws:cdk:path": "CdktestStackNew/MyEC2Instance/InstanceRole/Resource"
}
},
"MyEC2InstanceInstanceProfile9377ECBE": {
"Type": "AWS::IAM::InstanceProfile",
"Properties": {
"Roles": [
{
"Ref": "MyEC2InstanceInstanceRole1A6C2310"
}
]
},
"Metadata": {
"aws:cdk:path": "CdktestStackNew/MyEC2Instance/InstanceProfile"
}
},
"MyEC2InstanceB097982C": {
"Type": "AWS::EC2::Instance",
"Properties": {
"AvailabilityZone": "us-east-2a",
"DisableApiTermination": true,
"IamInstanceProfile": {
"Ref": "MyEC2InstanceInstanceProfile9377ECBE"
},
"ImageId": {
"Ref": "SsmParameterValueawsserviceamiamazonlinuxlatestal2023amikernel61x8664C96584B6F00A464EAD1953AFF4B05118Parameter"
},
"InstanceType": "t2.micro",
"SecurityGroupIds": [
{
"Fn::GetAtt": [
"MyEC2InstanceInstanceSecurityGroup06C6622F",
"GroupId"
]
}
],
"SubnetId": "subnet-045c5a5af92ce5bf5",
"Tags": [
{
"Key": "Name",
"Value": "CdktestStackNew/MyEC2Instance"
}
],
"UserData": {
"Fn::Base64": "#!/bin/bash"
}
},
"DependsOn": [
"MyEC2InstanceInstanceRole1A6C2310"
],
"Metadata": {
"aws:cdk:path": "CdktestStackNew/MyEC2Instance/Resource"
}
},
...
},
...
} It doesn't uses launch template. When property {
"Resources": {
"MyEC2InstanceInstanceSecurityGroup06C6622F": {
"Type": "AWS::EC2::SecurityGroup",
"Properties": {
"GroupDescription": "CdktestStackNew/MyEC2Instance/InstanceSecurityGroup",
"SecurityGroupEgress": [
{
"CidrIp": "0.0.0.0/0",
"Description": "Allow all outbound traffic by default",
"IpProtocol": "-1"
}
],
"Tags": [
{
"Key": "Name",
"Value": "CdktestStackNew/MyEC2Instance"
}
],
"VpcId": "vpc-0bcd157c9276f648b"
},
"Metadata": {
"aws:cdk:path": "CdktestStackNew/MyEC2Instance/InstanceSecurityGroup/Resource"
}
},
"MyEC2InstanceInstanceRole1A6C2310": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Statement": [
{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
}
}
],
"Version": "2012-10-17"
},
"Tags": [
{
"Key": "Name",
"Value": "CdktestStackNew/MyEC2Instance"
}
]
},
"Metadata": {
"aws:cdk:path": "CdktestStackNew/MyEC2Instance/InstanceRole/Resource"
}
},
"MyEC2InstanceInstanceProfile9377ECBE": {
"Type": "AWS::IAM::InstanceProfile",
"Properties": {
"Roles": [
{
"Ref": "MyEC2InstanceInstanceRole1A6C2310"
}
]
},
"Metadata": {
"aws:cdk:path": "CdktestStackNew/MyEC2Instance/InstanceProfile"
}
},
"MyEC2InstanceB097982C": {
"Type": "AWS::EC2::Instance",
"Properties": {
"AvailabilityZone": "us-east-2a",
"DisableApiTermination": true,
"IamInstanceProfile": {
"Ref": "MyEC2InstanceInstanceProfile9377ECBE"
},
"ImageId": {
"Ref": "SsmParameterValueawsserviceamiamazonlinuxlatestal2023amikernel61x8664C96584B6F00A464EAD1953AFF4B05118Parameter"
},
"InstanceType": "t2.micro",
"LaunchTemplate": {
"LaunchTemplateName": "CdktestStackNewMyEC2InstanceLaunchTemplate88E948F0",
"Version": {
"Fn::GetAtt": [
"MyEC2InstanceLaunchTemplate7D3AFA7C",
"LatestVersionNumber"
]
}
},
"SecurityGroupIds": [
{
"Fn::GetAtt": [
"MyEC2InstanceInstanceSecurityGroup06C6622F",
"GroupId"
]
}
],
"SubnetId": "subnet-045c5a5af92ce5bf5",
"Tags": [
{
"Key": "Name",
"Value": "CdktestStackNew/MyEC2Instance"
}
],
"UserData": {
"Fn::Base64": "#!/bin/bash"
}
},
"DependsOn": [
"MyEC2InstanceInstanceRole1A6C2310"
],
"Metadata": {
"aws:cdk:path": "CdktestStackNew/MyEC2Instance/Resource"
}
},
"MyEC2InstanceLaunchTemplate7D3AFA7C": {
"Type": "AWS::EC2::LaunchTemplate",
"Properties": {
"LaunchTemplateData": {
"MetadataOptions": {
"HttpTokens": "required"
}
},
"LaunchTemplateName": "CdktestStackNewMyEC2InstanceLaunchTemplate88E948F0"
},
"Metadata": {
"aws:cdk:path": "CdktestStackNew/MyEC2Instance/LaunchTemplate"
}
},
"CDKMetadata": {
"Type": "AWS::CDK::Metadata",
"Properties": {
"Analytics": "v2:deflate64:H4sIAAAAAAAA/2WOuwrCQBREvyX95mqCon0KESxCYi/XzQ1u3EfYh0GW/XcxGhurgTNnYEoodlsoMpxczrt7LsUVYuuR31lDzgTLieHkLpF4CfGonUfNibXEgxX+ebAmjKzq9R/4qVWvTxg0v51JjRI9JSZQQWyMnMsll0FtTS8kpfSGNVpU5MnO5vdQYtp0BINbPYo9lGvYZIMTIrdBe6EImk++ALTh8tLbAAAA"
},
"Metadata": {
"aws:cdk:path": "CdktestStackNew/CDKMetadata/Default"
}
}
},
...
},
...
}
As of now, enabling IMDSv2 requires a Launch template. There is an open issue aws-cloudformation/cloudformation-coverage-roadmap#655 in CloudFormation coverage repository which is a feature request to have IMDSv2 option at EC2 instance level itself. Until that is fixed, there might not be a way around. Storage options for your Amazon EC2 instances lists some of the storage options for EC2 instances. To summarise:
@aws-cdk/aws-ec2:uniqueImdsv2TemplateName (enabled by default), mentioned at CDK Feature Flags might not help (also refer #20851 (comment)). @dil-mocsy The behavior appears to be expected based on CloudFormation implementation where enabling IMDSv2 is done via Launch Template and later when Launch Template is associated with EC2 instance, it causes replacement per CloudFormation docs. So this feature gap needs to be supported in CloudFormation first per aws-cloudformation/cloudformation-coverage-roadmap#655. |
@ashishdhingra If I read that properly, you basically confirmed what I wrote. I came to the same conclusion that this is a Cloudformation limitation for now. Found the same link #655 Launch template mandatoryToday's implementation makes a launchTemplate mandatory. If cdk users accept that reality, then the existing implementation is strage: if (node.instance.launchTemplate !== undefined) {
this.warn(node, 'Cannot toggle IMDSv1 because this Instance is associated with an existing Launch Template.');
return;
} If you already have a launch template then Shouldn't
|
Termination protectionTermination protection should be on. |
@dil-mocsy Unfortunately we cannot provide ETA on when aws-cloudformation/cloudformation-coverage-roadmap#655 would be addressed by CloudFormation team. Please try to add your comment on that issue and may be add 👍 to it. |
Describe the bug
When creating a new EC2 instance the IMDSv2 setting is handled in a surprising way.
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:
[packages/aws-cdk-lib/aws-ec2/lib/instance.ts#672
Then proceeds to add a new launchTemplate if there wasn't one, therefore replacing the instance #100:
Regression Issue
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:
Then add
requireImdsv2: true,
Either:
cdk diff
, it will show the new launchTemplate and the need to replace.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.
The text was updated successfully, but these errors were encountered: