aws / aws/containers-roadmap

[EKS] [request]: Add "Enclave" Option Support for managed nodegroups created from cloudformation templates

Open
#1,472 0 comments 0 reactions 0 assignees View on GitHub
EKS Proposed
Dominant language
Shell
Stars
5.4k
Forks
334
PR merge metrics
No merged PRs in 30d

Description

### Community Note

* Please vote on this issue by adding a 👍 [reaction](https://blog.github.com/2016-03-10-add-reactions-to-pull-requests-issues-and-comments/) to the original issue to help the community and maintainers prioritize this request
* Please do not leave "+1" or "me too" comments, they generate extra noise for issue followers and do not help prioritize the request
* If you are interested in working on this issue or have submitted a pull request, please leave a comment

**Tell us about your request**

EKS cluster with managed nodegroup from Cloudformation template with Enclave Support enabled on nodes.

**Which service(s) is this request for?**
EKS

**Tell us about the problem you're trying to solve. What are you trying to do, and why is it hard?**
I'm deploying the k8s cluster (Control plane & Managed Node Groups) using AWS quick start CF guide and I need to have nodes with Enclave support enabled. For this, I added the corresponding option to launch template configuration - please, see the template below:
```
{
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "EKS Managed Nodes (SSH access: true)",
"Mappings": {
"ServicePrincipalPartitionMap": {
"aws": {
"EC2": "ec2.amazonaws.com",
"EKS": "eks.amazonaws.com",
"EKSFargatePods": "eks-fargate-pods.amazonaws.com"
},
"aws-cn": {
"EC2": "ec2.amazonaws.com.cn",
"EKS": "eks.amazonaws.com",
"EKSFargatePods": "eks-fargate-pods.amazonaws.com"
},
"aws-us-gov": {
"EC2": "ec2.amazonaws.com",
"EKS": "eks.amazonaws.com",
"EKSFargatePods": "eks-fargate-pods.amazonaws.com"
}
}
},
"Resources": {
"LaunchTemplate": {
"Type": "AWS::EC2::LaunchTemplate",
"Properties": {
"LaunchTemplateData": {
"BlockDeviceMappings": [
{
"DeviceName": "/dev/xvda",
"Ebs": {
"Iops": 3000,
"Throughput": 125,
"VolumeSize": 80,
"VolumeType": "gp3"
}
}
],
"KeyName": "NitroKeyNew",
"MetadataOptions": {
"HttpPutResponseHopLimit": 2,
"HttpTokens": "optional"
},
"EnclaveOptions": {
"Enabled": true
},
"SecurityGroupIds": [
{
"Fn::ImportValue": "eksctl-test-enclave-cluster::ClusterSecurityGroupId"
},
{
"Ref": "SSH"
}
],
"TagSpecifications": [
{
"ResourceType": "instance",
"Tags": [
{
"Key": "Name",
"Value": "k8s-ng-test-enclave-v3-Node"
},
{
"Key": "alpha.eksctl.io/nodegroup-name",
"Value": "ng-test-enclave-v3"
},
{
"Key": "alpha.eksctl.io/nodegroup-type",
"Value": "managed"
}
]
},
{
"ResourceType": "volume",
"Tags": [
{
"Key": "Name",
"Value": "k8s-ng-test-enclave-v3-Node"
},
{
"Key": "alpha.eksctl.io/nodegroup-name",
"Value": "ng-test-enclave-v3"
},
{
"Key": "alpha.eksctl.io/nodegroup-type",
"Value": "managed"
}
]
},
{
"ResourceType": "network-interface",
"Tags": [
{
"Key": "Name",
"Value": "k8s-ng-test-enclave-v3-Node"
},
{
"Key": "alpha.eksctl.io/nodegroup-name",
"Value": "ng-test-enclave-v3"
},
{
"Key": "alpha.eksctl.io/nodegroup-type",
"Value": "managed"
}
]
}
],
"UserData": {
"Fn::Base64" : {
"Fn::Join" : [ "\n", [
"MIME-Version: 1.0 ",
"Content-Type: multipart/mixed; boundary=\"//\"",
"",
"--//",
"Content-Type: text/x-shellscript; charset=\"us-ascii\"",
"#!/bin/bash",
"set -uxo pipefail",
"# Test to see if the Nitro enclaves module is loaded",
"lsmod | grep -q nitro_enclaves",
"RETURN=${?}",
"set -e",
"# Setup Nitro enclave on the host if the module is available as expected.",
"if [ ${RETURN} -eq 0 ]; then",
" sudo amazon-linux-extras install aws-nitro-enclaves-cli -y",
" sudo yum install aws-nitro-enclaves-cli-devel -y",
" sudo usermod -aG ne ec2-user",
" sudo usermod -aG docker ec2-user",
" # If needed, install custom allocator config here: /etc/nitro_enclaves/allocator.yaml",
" sed -i \"s/memory_mib: 512/memory_mib: 3072/g\" /etc/nitro_enclaves/allocator.yaml",
" sudo systemctl start nitro-enclaves-allocator.service",
" sudo systemctl enable nitro-enclaves-allocator.service",
" sudo systemctl start docker",
" sudo systemctl enable docker",
" #",
" # Note: After some testing we discovered that there is an apparent bug in the",
" # Nitro CLI RPM or underlying tools, that does not properly reload the",
" # udev rules when inside the AWS bootstrap environment. This means that we must",
" # manually fix the device permissions on `/dev/nitro_enclaves`, if we",
" # don't want to be forced to restart the instance to get everything working.",
" # See: https://github.com/aws/aws-nitro-enclaves-cli/issues/227",
" #",
" sudo chgrp ne /dev/nitro_enclaves",
" echo \"Done with AWS Nitro enclave Setup\"",
"fi",
"",
"--//--" ] ]
}
}
},
"LaunchTemplateName": {
"Fn::Sub": "${AWS::StackName}"
}
}
},
"ManagedNodeGroup": {
"Type": "AWS::EKS::Nodegroup",
"Properties": {
"AmiType": "AL2_x86_64",
"ClusterName": "test-enclave",
"InstanceTypes": [
"m5a.xlarge"
],
"Labels": {
"alpha.eksctl.io/cluster-name": "test-enclave",
"alpha.eksctl.io/nodegroup-name": "ng-test-enclave-v3",
"enclave.example.com/type": "nitro",
"smarter-device-manager": "enabled"
},
"LaunchTemplate": {
"Id": {
"Ref": "LaunchTemplate"
}
},
"NodeRole": {
"Fn::GetAtt": [
"NodeInstanceRole",
"Arn"
]
},
"NodegroupName": "ng-test-enclave-v3",
"ScalingConfig": {
"DesiredSize": 1,
"MaxSize": 1,
"MinSize": 1
},
"Subnets": {
"Fn::Split": [
",",
{
"Fn::ImportValue": "eksctl-test-enclave-cluster::SubnetsPublic"
}
]
},
"Taints": [
{
"Effect" : "NO_SCHEDULE",
"Key" : "node.example.com/enclave",
"Value" : "nitro"
}
],
"Tags": {
"alpha.eksctl.io/nodegroup-name": "ng-test-enclave-v3",
"alpha.eksctl.io/nodegroup-type": "managed"
}
}
},
"NodeInstanceRole": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Statement": [
{
"Action": [
"sts:AssumeRole"
],
"Effect": "Allow",
"Principal": {
"Service": [
{
"Fn::FindInMap": [
"ServicePrincipalPartitionMap",
{
"Ref": "AWS::Partition"
},
"EC2"
]
}
]
}
}
],
"Version": "2012-10-17"
},
"ManagedPolicyArns": [
{
"Fn::Sub": "arn:${AWS::Partition}:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly"
},
{
"Fn::Sub": "arn:${AWS::Partition}:iam::aws:policy/AmazonEKSWorkerNodePolicy"
},
{
"Fn::Sub": "arn:${AWS::Partition}:iam::aws:policy/AmazonEKS_CNI_Policy"
}
],
"Path": "/",
"Tags": [
{
"Key": "Name",
"Value": {
"Fn::Sub": "${AWS::StackName}/NodeInstanceRole"
}
}
]
}
},
"SSH": {
"Type": "AWS::EC2::SecurityGroup",
"Properties": {
"GroupDescription": "Allow SSH access",
"GroupName": {
"Fn::Sub": "${AWS::StackName}-remoteAccess"
},
"SecurityGroupIngress": [
{
"CidrIp": "0.0.0.0/0",
"Description": "Allow SSH access to managed worker nodes in group ng-test-enclave-v3",
"FromPort": 22,
"IpProtocol": "tcp",
"ToPort": 22
},
{
"CidrIpv6": "::/0",
"Description": "Allow SSH access to managed worker nodes in group ng-test-enclave-v3",
"FromPort": 22,
"IpProtocol": "tcp",
"ToPort": 22
}
],
"Tags": [
{
"Key": "Name",
"Value": {
"Fn::Sub": "${AWS::StackName}/SSH"
}
}
],
"VpcId": {
"Fn::ImportValue": "eksctl-test-enclave-cluster::VPC"
}
}
}
}
}
```

The Launch Template is created correctly and the required `Enclave Support` option is enabled:
![image](https://user-images.githubusercontent.com/2317037/128980768-eb548ae1-d942-41ed-a1ae-b2dcce89d4fa.png)

However, the issue is that AWS creates a companion launch template from the provided one and this companion launch template losts Enclave support option:
![image](https://user-images.githubusercontent.com/2317037/128981026-aedca4d7-3759-471d-943d-7b282ab138f0.png)
![image](https://user-images.githubusercontent.com/2317037/128981076-fa898ea1-397e-43c0-b9ae-0c95370f110b.png)

This launch template, and not the original one, is used by autoscaling group to start nodes. Therefore, the kubernetes nodes start without the Enclave support option which is a bug from my point of view.

**Are you currently working around this issue?**
For now, I have to manually modify the companion launch template - enable the Nitro Enclave option, then update the autoscaling group with the new launch template version and finally refresh nodes. This is very inconvenient.

**Additional context**
Anything else we should know?

**Attachments**
Cloudformation templates to reproduce the issue - eks cluster template and managed nodegroup - the resulting nodes will not have Enclave enabled:
```
{
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "EKS cluster (dedicated VPC: true, dedicated IAM: true) [created and managed by eksctl]",
"Mappings": {
"ServicePrincipalPartitionMap": {
"aws": {
"EC2": "ec2.amazonaws.com",
"EKS": "eks.amazonaws.com",
"EKSFargatePods": "eks-fargate-pods.amazonaws.com"
},
"aws-cn": {
"EC2": "ec2.amazonaws.com.cn",
"EKS": "eks.amazonaws.com",
"EKSFargatePods": "eks-fargate-pods.amazonaws.com"
},
"aws-us-gov": {
"EC2": "ec2.amazonaws.com",
"EKS": "eks.amazonaws.com",
"EKSFargatePods": "eks-fargate-pods.amazonaws.com"
}
}
},
"Resources": {
"ClusterSharedNodeSecurityGroup": {
"Type": "AWS::EC2::SecurityGroup",
"Properties": {
"GroupDescription": "Communication between all nodes in the cluster",
"Tags": [
{
"Key": "Name",
"Value": {
"Fn::Sub": "${AWS::StackName}/ClusterSharedNodeSecurityGroup"
}
}
],
"VpcId": {
"Ref": "VPC"
}
}
},
"ControlPlane": {
"Type": "AWS::EKS::Cluster",
"Properties": {
"Name": "test-enclave",
"ResourcesVpcConfig": {
"SecurityGroupIds": [
{
"Ref": "ControlPlaneSecurityGroup"
}
],
"SubnetIds": [
{
"Ref": "SubnetPublicUSEAST1B"
},
{
"Ref": "SubnetPublicUSEAST1C"
},
{
"Ref": "SubnetPublicUSEAST1D"
},
{
"Ref": "SubnetPublicUSEAST1A"
},
{
"Ref": "SubnetPrivateUSEAST1C"
},
{
"Ref": "SubnetPrivateUSEAST1D"
},
{
"Ref": "SubnetPrivateUSEAST1A"
},
{
"Ref": "SubnetPrivateUSEAST1B"
}
]
},
"RoleArn": {
"Fn::GetAtt": [
"ServiceRole",
"Arn"
]
},
"Version": "1.19"
}
},
"ControlPlaneSecurityGroup": {
"Type": "AWS::EC2::SecurityGroup",
"Properties": {
"GroupDescription": "Communication between the control plane and worker nodegroups",
"Tags": [
{
"Key": "Name",
"Value": {
"Fn::Sub": "${AWS::StackName}/ControlPlaneSecurityGroup"
}
}
],
"VpcId": {
"Ref": "VPC"
}
}
},
"IngressDefaultClusterToNodeSG": {
"Type": "AWS::EC2::SecurityGroupIngress",
"Properties": {
"Description": "Allow managed and unmanaged nodes to communicate with each other (all ports)",
"FromPort": 0,
"GroupId": {
"Ref": "ClusterSharedNodeSecurityGroup"
},
"IpProtocol": "-1",
"SourceSecurityGroupId": {
"Fn::GetAtt": [
"ControlPlane",
"ClusterSecurityGroupId"
]
},
"ToPort": 65535
}
},
"IngressInterNodeGroupSG": {
"Type": "AWS::EC2::SecurityGroupIngress",
"Properties": {
"Description": "Allow nodes to communicate with each other (all ports)",
"FromPort": 0,
"GroupId": {
"Ref": "ClusterSharedNodeSecurityGroup"
},
"IpProtocol": "-1",
"SourceSecurityGroupId": {
"Ref": "ClusterSharedNodeSecurityGroup"
},
"ToPort": 65535
}
},
"IngressNodeToDefaultClusterSG": {
"Type": "AWS::EC2::SecurityGroupIngress",
"Properties": {
"Description": "Allow unmanaged nodes to communicate with control plane (all ports)",
"FromPort": 0,
"GroupId": {
"Fn::GetAtt": [
"ControlPlane",
"ClusterSecurityGroupId"
]
},
"IpProtocol": "-1",
"SourceSecurityGroupId": {
"Ref": "ClusterSharedNodeSecurityGroup"
},
"ToPort": 65535
}
},
"InternetGateway": {
"Type": "AWS::EC2::InternetGateway",
"Properties": {
"Tags": [
{
"Key": "Name",
"Value": {
"Fn::Sub": "${AWS::StackName}/InternetGateway"
}
}
]
}
},
"NATGateway": {
"Type": "AWS::EC2::NatGateway",
"Properties": {
"AllocationId": {
"Fn::GetAtt": [
"NATIP",
"AllocationId"
]
},
"SubnetId": {
"Ref": "SubnetPublicUSEAST1A"
},
"Tags": [
{
"Key": "Name",
"Value": {
"Fn::Sub": "${AWS::StackName}/NATGateway"
}
}
]
}
},
"NATIP": {
"Type": "AWS::EC2::EIP",
"Properties": {
"Domain": "vpc",
"Tags": [
{
"Key": "Name",
"Value": {
"Fn::Sub": "${AWS::StackName}/NATIP"
}
}
]
}
},
"NATPrivateSubnetRouteUSEAST1A": {
"Type": "AWS::EC2::Route",
"Properties": {
"DestinationCidrBlock": "0.0.0.0/0",
"NatGatewayId": {
"Ref": "NATGateway"
},
"RouteTableId": {
"Ref": "PrivateRouteTableUSEAST1A"
}
}
},
"NATPrivateSubnetRouteUSEAST1B": {
"Type": "AWS::EC2::Route",
"Properties": {
"DestinationCidrBlock": "0.0.0.0/0",
"NatGatewayId": {
"Ref": "NATGateway"
},
"RouteTableId": {
"Ref": "PrivateRouteTableUSEAST1B"
}
}
},
"NATPrivateSubnetRouteUSEAST1C": {
"Type": "AWS::EC2::Route",
"Properties": {
"DestinationCidrBlock": "0.0.0.0/0",
"NatGatewayId": {
"Ref": "NATGateway"
},
"RouteTableId": {
"Ref": "PrivateRouteTableUSEAST1C"
}
}
},
"NATPrivateSubnetRouteUSEAST1D": {
"Type": "AWS::EC2::Route",
"Properties": {
"DestinationCidrBlock": "0.0.0.0/0",
"NatGatewayId": {
"Ref": "NATGateway"
},
"RouteTableId": {
"Ref": "PrivateRouteTableUSEAST1D"
}
}
},
"PolicyCloudWatchMetrics": {
"Type": "AWS::IAM::Policy",
"Properties": {
"PolicyDocument": {
"Statement": [
{
"Action": [
"cloudwatch:PutMetricData"
],
"Effect": "Allow",
"Resource": "*"
}
],
"Version": "2012-10-17"
},
"PolicyName": {
"Fn::Sub": "${AWS::StackName}-PolicyCloudWatchMetrics"
},
"Roles": [
{
"Ref": "ServiceRole"
}
]
}
},
"PolicyELBPermissions": {
"Type": "AWS::IAM::Policy",
"Properties": {
"PolicyDocument": {
"Statement": [
{
"Action": [
"ec2:DescribeAccountAttributes",
"ec2:DescribeAddresses",
"ec2:DescribeInternetGateways"
],
"Effect": "Allow",
"Resource": "*"
}
],
"Version": "2012-10-17"
},
"PolicyName": {
"Fn::Sub": "${AWS::StackName}-PolicyELBPermissions"
},
"Roles": [
{
"Ref": "ServiceRole"
}
]
}
},
"PrivateRouteTableUSEAST1A": {
"Type": "AWS::EC2::RouteTable",
"Properties": {
"Tags": [
{
"Key": "Name",
"Value": {
"Fn::Sub": "${AWS::StackName}/PrivateRouteTableUSEAST1A"
}
}
],
"VpcId": {
"Ref": "VPC"
}
}
},
"PrivateRouteTableUSEAST1B": {
"Type": "AWS::EC2::RouteTable",
"Properties": {
"Tags": [
{
"Key": "Name",
"Value": {
"Fn::Sub": "${AWS::StackName}/PrivateRouteTableUSEAST1B"
}
}
],
"VpcId": {
"Ref": "VPC"
}
}
},
"PrivateRouteTableUSEAST1C": {
"Type": "AWS::EC2::RouteTable",
"Properties": {
"Tags": [
{
"Key": "Name",
"Value": {
"Fn::Sub": "${AWS::StackName}/PrivateRouteTableUSEAST1C"
}
}
],
"VpcId": {
"Ref": "VPC"
}
}
},
"PrivateRouteTableUSEAST1D": {
"Type": "AWS::EC2::RouteTable",
"Properties": {
"Tags": [
{
"Key": "Name",
"Value": {
"Fn::Sub": "${AWS::StackName}/PrivateRouteTableUSEAST1D"
}
}
],
"VpcId": {
"Ref": "VPC"
}
}
},
"PublicRouteTable": {
"Type": "AWS::EC2::RouteTable",
"Properties": {
"Tags": [
{
"Key": "Name",
"Value": {
"Fn::Sub": "${AWS::StackName}/PublicRouteTable"
}
}
],
"VpcId": {
"Ref": "VPC"
}
}
},
"PublicSubnetRoute": {
"Type": "AWS::EC2::Route",
"Properties": {
"DestinationCidrBlock": "0.0.0.0/0",
"GatewayId": {
"Ref": "InternetGateway"
},
"RouteTableId": {
"Ref": "PublicRouteTable"
}
},
"DependsOn": [
"VPCGatewayAttachment"
]
},
"RouteTableAssociationPrivateUSEAST1A": {
"Type": "AWS::EC2::SubnetRouteTableAssociation",
"Properties": {
"RouteTableId": {
"Ref": "PrivateRouteTableUSEAST1A"
},
"SubnetId": {
"Ref": "SubnetPrivateUSEAST1A"
}
}
},
"RouteTableAssociationPrivateUSEAST1B": {
"Type": "AWS::EC2::SubnetRouteTableAssociation",
"Properties": {
"RouteTableId": {
"Ref": "PrivateRouteTableUSEAST1B"
},
"SubnetId": {
"Ref": "SubnetPrivateUSEAST1B"
}
}
},
"RouteTableAssociationPrivateUSEAST1C": {
"Type": "AWS::EC2::SubnetRouteTableAssociation",
"Properties": {
"RouteTableId": {
"Ref": "PrivateRouteTableUSEAST1C"
},
"SubnetId": {
"Ref": "SubnetPrivateUSEAST1C"
}
}
},
"RouteTableAssociationPrivateUSEAST1D": {
"Type": "AWS::EC2::SubnetRouteTableAssociation",
"Properties": {
"RouteTableId": {
"Ref": "PrivateRouteTableUSEAST1D"
},
"SubnetId": {
"Ref": "SubnetPrivateUSEAST1D"
}
}
},
"RouteTableAssociationPublicUSEAST1A": {
"Type": "AWS::EC2::SubnetRouteTableAssociation",
"Properties": {
"RouteTableId": {
"Ref": "PublicRouteTable"
},
"SubnetId": {
"Ref": "SubnetPublicUSEAST1A"
}
}
},
"RouteTableAssociationPublicUSEAST1B": {
"Type": "AWS::EC2::SubnetRouteTableAssociation",
"Properties": {
"RouteTableId": {
"Ref": "PublicRouteTable"
},
"SubnetId": {
"Ref": "SubnetPublicUSEAST1B"
}
}
},
"RouteTableAssociationPublicUSEAST1C": {
"Type": "AWS::EC2::SubnetRouteTableAssociation",
"Properties": {
"RouteTableId": {
"Ref": "PublicRouteTable"
},
"SubnetId": {
"Ref": "SubnetPublicUSEAST1C"
}
}
},
"RouteTableAssociationPublicUSEAST1D": {
"Type": "AWS::EC2::SubnetRouteTableAssociation",
"Properties": {
"RouteTableId": {
"Ref": "PublicRouteTable"
},
"SubnetId": {
"Ref": "SubnetPublicUSEAST1D"
}
}
},
"ServiceRole": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Statement": [
{
"Action": [
"sts:AssumeRole"
],
"Effect": "Allow",
"Principal": {
"Service": [
{
"Fn::FindInMap": [
"ServicePrincipalPartitionMap",
{
"Ref": "AWS::Partition"
},
"EKS"
]
}
]
}
}
],
"Version": "2012-10-17"
},
"ManagedPolicyArns": [
{
"Fn::Sub": "arn:${AWS::Partition}:iam::aws:policy/AmazonEKSClusterPolicy"
},
{
"Fn::Sub": "arn:${AWS::Partition}:iam::aws:policy/AmazonEKSVPCResourceController"
}
],
"Tags": [
{
"Key": "Name",
"Value": {
"Fn::Sub": "${AWS::StackName}/ServiceRole"
}
}
]
}
},
"SubnetPrivateUSEAST1A": {
"Type": "AWS::EC2::Subnet",
"Properties": {
"AvailabilityZone": "us-east-1a",
"CidrBlock": "192.168.128.0/19",
"Tags": [
{
"Key": "kubernetes.io/role/internal-elb",
"Value": "1"
},
{
"Key": "Name",
"Value": {
"Fn::Sub": "${AWS::StackName}/SubnetPrivateUSEAST1A"
}
}
],
"VpcId": {
"Ref": "VPC"
}
}
},
"SubnetPrivateUSEAST1B": {
"Type": "AWS::EC2::Subnet",
"Properties": {
"AvailabilityZone": "us-east-1b",
"CidrBlock": "192.168.160.0/19",
"Tags": [
{
"Key": "kubernetes.io/role/internal-elb",
"Value": "1"
},
{
"Key": "Name",
"Value": {
"Fn::Sub": "${AWS::StackName}/SubnetPrivateUSEAST1B"
}
}
],
"VpcId": {
"Ref": "VPC"
}
}
},
"SubnetPrivateUSEAST1C": {
"Type": "AWS::EC2::Subnet",
"Properties": {
"AvailabilityZone": "us-east-1c",
"CidrBlock": "192.168.192.0/19",
"Tags": [
{
"Key": "kubernetes.io/role/internal-elb",
"Value": "1"
},
{
"Key": "Name",
"Value": {
"Fn::Sub": "${AWS::StackName}/SubnetPrivateUSEAST1C"
}
}
],
"VpcId": {
"Ref": "VPC"
}
}
},
"SubnetPrivateUSEAST1D": {
"Type": "AWS::EC2::Subnet",
"Properties": {
"AvailabilityZone": "us-east-1d",
"CidrBlock": "192.168.224.0/19",
"Tags": [
{
"Key": "kubernetes.io/role/internal-elb",
"Value": "1"
},
{
"Key": "Name",
"Value": {
"Fn::Sub": "${AWS::StackName}/SubnetPrivateUSEAST1D"
}
}
],
"VpcId": {
"Ref": "VPC"
}
}
},
"SubnetPublicUSEAST1A": {
"Type": "AWS::EC2::Subnet",
"Properties": {
"AvailabilityZone": "us-east-1a",
"CidrBlock": "192.168.0.0/19",
"MapPublicIpOnLaunch": true,
"Tags": [
{
"Key": "kubernetes.io/role/elb",
"Value": "1"
},
{
"Key": "Name",
"Value": {
"Fn::Sub": "${AWS::StackName}/SubnetPublicUSEAST1A"
}
}
],
"VpcId": {
"Ref": "VPC"
}
}
},
"SubnetPublicUSEAST1B": {
"Type": "AWS::EC2::Subnet",
"Properties": {
"AvailabilityZone": "us-east-1b",
"CidrBlock": "192.168.32.0/19",
"MapPublicIpOnLaunch": true,
"Tags": [
{
"Key": "kubernetes.io/role/elb",
"Value": "1"
},
{
"Key": "Name",
"Value": {
"Fn::Sub": "${AWS::StackName}/SubnetPublicUSEAST1B"
}
}
],
"VpcId": {
"Ref": "VPC"
}
}
},
"SubnetPublicUSEAST1C": {
"Type": "AWS::EC2::Subnet",
"Properties": {
"AvailabilityZone": "us-east-1c",
"CidrBlock": "192.168.64.0/19",
"MapPublicIpOnLaunch": true,
"Tags": [
{
"Key": "kubernetes.io/role/elb",
"Value": "1"
},
{
"Key": "Name",
"Value": {
"Fn::Sub": "${AWS::StackName}/SubnetPublicUSEAST1C"
}
}
],
"VpcId": {
"Ref": "VPC"
}
}
},
"SubnetPublicUSEAST1D": {
"Type": "AWS::EC2::Subnet",
"Properties": {
"AvailabilityZone": "us-east-1d",
"CidrBlock": "192.168.96.0/19",
"MapPublicIpOnLaunch": true,
"Tags": [
{
"Key": "kubernetes.io/role/elb",
"Value": "1"
},
{
"Key": "Name",
"Value": {
"Fn::Sub": "${AWS::StackName}/SubnetPublicUSEAST1D"
}
}
],
"VpcId": {
"Ref": "VPC"
}
}
},
"VPC": {
"Type": "AWS::EC2::VPC",
"Properties": {
"CidrBlock": "192.168.0.0/16",
"EnableDnsHostnames": true,
"EnableDnsSupport": true,
"Tags": [
{
"Key": "Name",
"Value": {
"Fn::Sub": "${AWS::StackName}/VPC"
}
}
]
}
},
"VPCGatewayAttachment": {
"Type": "AWS::EC2::VPCGatewayAttachment",
"Properties": {
"InternetGatewayId": {
"Ref": "InternetGateway"
},
"VpcId": {
"Ref": "VPC"
}
}
}
},
"Outputs": {
"ARN": {
"Value": {
"Fn::GetAtt": [
"ControlPlane",
"Arn"
]
},
"Export": {
"Name": {
"Fn::Sub": "${AWS::StackName}::ARN"
}
}
},
"CertificateAuthorityData": {
"Value": {
"Fn::GetAtt": [
"ControlPlane",
"CertificateAuthorityData"
]
}
},
"ClusterSecurityGroupId": {
"Value": {
"Fn::GetAtt": [
"ControlPlane",
"ClusterSecurityGroupId"
]
},
"Export": {
"Name": {
"Fn::Sub": "${AWS::StackName}::ClusterSecurityGroupId"
}
}
},
"ClusterStackName": {
"Value": {
"Ref": "AWS::StackName"
}
},
"Endpoint": {
"Value": {
"Fn::GetAtt": [
"ControlPlane",
"Endpoint"
]
},
"Export": {
"Name": {
"Fn::Sub": "${AWS::StackName}::Endpoint"
}
}
},
"FeatureNATMode": {
"Value": "Single"
},
"SecurityGroup": {
"Value": {
"Ref": "ControlPlaneSecurityGroup"
},
"Export": {
"Name": {
"Fn::Sub": "${AWS::StackName}::SecurityGroup"
}
}
},
"ServiceRoleARN": {
"Value": {
"Fn::GetAtt": [
"ServiceRole",
"Arn"
]
},
"Export": {
"Name": {
"Fn::Sub": "${AWS::StackName}::ServiceRoleARN"
}
}
},
"SharedNodeSecurityGroup": {
"Value": {
"Ref": "ClusterSharedNodeSecurityGroup"
},
"Export": {
"Name": {
"Fn::Sub": "${AWS::StackName}::SharedNodeSecurityGroup"
}
}
},
"SubnetsPrivate": {
"Value": {
"Fn::Join": [
",",
[
{
"Ref": "SubnetPrivateUSEAST1C"
},
{
"Ref": "SubnetPrivateUSEAST1D"
},
{
"Ref": "SubnetPrivateUSEAST1A"
},
{
"Ref": "SubnetPrivateUSEAST1B"
}
]
]
},
"Export": {
"Name": {
"Fn::Sub": "${AWS::StackName}::SubnetsPrivate"
}
}
},
"SubnetsPublic": {
"Value": {
"Fn::Join": [
",",
[
{
"Ref": "SubnetPublicUSEAST1B"
},
{
"Ref": "SubnetPublicUSEAST1C"
},
{
"Ref": "SubnetPublicUSEAST1D"
},
{
"Ref": "SubnetPublicUSEAST1A"
}
]
]
},
"Export": {
"Name": {
"Fn::Sub": "${AWS::StackName}::SubnetsPublic"
}
}
},
"VPC": {
"Value": {
"Ref": "VPC"
},
"Export": {
"Name": {
"Fn::Sub": "${AWS::StackName}::VPC"
}
}
}
}
}
```
```
{
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "EKS Managed Nodes (SSH access: true)",
"Mappings": {
"ServicePrincipalPartitionMap": {
"aws": {
"EC2": "ec2.amazonaws.com",
"EKS": "eks.amazonaws.com",
"EKSFargatePods": "eks-fargate-pods.amazonaws.com"
},
"aws-cn": {
"EC2": "ec2.amazonaws.com.cn",
"EKS": "eks.amazonaws.com",
"EKSFargatePods": "eks-fargate-pods.amazonaws.com"
},
"aws-us-gov": {
"EC2": "ec2.amazonaws.com",
"EKS": "eks.amazonaws.com",
"EKSFargatePods": "eks-fargate-pods.amazonaws.com"
}
}
},
"Resources": {
"LaunchTemplate": {
"Type": "AWS::EC2::LaunchTemplate",
"Properties": {
"LaunchTemplateData": {
"BlockDeviceMappings": [
{
"DeviceName": "/dev/xvda",
"Ebs": {
"Iops": 3000,
"Throughput": 125,
"VolumeSize": 80,
"VolumeType": "gp3"
}
}
],
"KeyName": "NitroKeyNew",
"MetadataOptions": {
"HttpPutResponseHopLimit": 2,
"HttpTokens": "optional"
},
"EnclaveOptions": {
"Enabled": true
},
"SecurityGroupIds": [
{
"Fn::ImportValue": "eksctl-test-enclave-cluster::ClusterSecurityGroupId"
},
{
"Ref": "SSH"
}
],
"TagSpecifications": [
{
"ResourceType": "instance",
"Tags": [
{
"Key": "Name",
"Value": "k8s-ng-test-enclave-v3-Node"
},
{
"Key": "alpha.eksctl.io/nodegroup-name",
"Value": "ng-test-enclave-v3"
},
{
"Key": "alpha.eksctl.io/nodegroup-type",
"Value": "managed"
}
]
},
{
"ResourceType": "volume",
"Tags": [
{
"Key": "Name",
"Value": "k8s-ng-test-enclave-v3-Node"
},
{
"Key": "alpha.eksctl.io/nodegroup-name",
"Value": "ng-test-enclave-v3"
},
{
"Key": "alpha.eksctl.io/nodegroup-type",
"Value": "managed"
}
]
},
{
"ResourceType": "network-interface",
"Tags": [
{
"Key": "Name",
"Value": "k8s-ng-test-enclave-v3-Node"
},
{
"Key": "alpha.eksctl.io/nodegroup-name",
"Value": "ng-test-enclave-v3"
},
{
"Key": "alpha.eksctl.io/nodegroup-type",
"Value": "managed"
}
]
}
],
"UserData": {
"Fn::Base64" : {
"Fn::Join" : [ "\n", [
"MIME-Version: 1.0 ",
"Content-Type: multipart/mixed; boundary=\"//\"",
"",
"--//",
"Content-Type: text/x-shellscript; charset=\"us-ascii\"",
"#!/bin/bash",
"set -uxo pipefail",
"# Test to see if the Nitro enclaves module is loaded",
"lsmod | grep -q nitro_enclaves",
"RETURN=${?}",
"set -e",
"# Setup Nitro enclave on the host if the module is available as expected.",
"if [ ${RETURN} -eq 0 ]; then",
" sudo amazon-linux-extras install aws-nitro-enclaves-cli -y",
" sudo yum install aws-nitro-enclaves-cli-devel -y",
" sudo usermod -aG ne ec2-user",
" sudo usermod -aG docker ec2-user",
" # If needed, install custom allocator config here: /etc/nitro_enclaves/allocator.yaml",
" sed -i \"s/memory_mib: 512/memory_mib: 3072/g\" /etc/nitro_enclaves/allocator.yaml",
" sudo systemctl start nitro-enclaves-allocator.service",
" sudo systemctl enable nitro-enclaves-allocator.service",
" sudo systemctl start docker",
" sudo systemctl enable docker",
" #",
" # Note: After some testing we discovered that there is an apparent bug in the",
" # Nitro CLI RPM or underlying tools, that does not properly reload the",
" # udev rules when inside the AWS bootstrap environment. This means that we must",
" # manually fix the device permissions on `/dev/nitro_enclaves`, if we",
" # don't want to be forced to restart the instance to get everything working.",
" # See: https://github.com/aws/aws-nitro-enclaves-cli/issues/227",
" #",
" sudo chgrp ne /dev/nitro_enclaves",
" echo \"Done with AWS Nitro enclave Setup\"",
"fi",
"",
"--//--" ] ]
}
}
},
"LaunchTemplateName": {
"Fn::Sub": "${AWS::StackName}"
}
}
},
"ManagedNodeGroup": {
"Type": "AWS::EKS::Nodegroup",
"Properties": {
"AmiType": "AL2_x86_64",
"ClusterName": "test-enclave",
"InstanceTypes": [
"m5a.xlarge"
],
"Labels": {
"alpha.eksctl.io/cluster-name": "test-enclave",
"alpha.eksctl.io/nodegroup-name": "ng-test-enclave-v3",
"enclave.example.com/type": "nitro",
"smarter-device-manager": "enabled"
},
"LaunchTemplate": {
"Id": {
"Ref": "LaunchTemplate"
}
},
"NodeRole": {
"Fn::GetAtt": [
"NodeInstanceRole",
"Arn"
]
},
"NodegroupName": "ng-test-enclave-v3",
"ScalingConfig": {
"DesiredSize": 1,
"MaxSize": 1,
"MinSize": 1
},
"Subnets": {
"Fn::Split": [
",",
{
"Fn::ImportValue": "eksctl-test-enclave-cluster::SubnetsPublic"
}
]
},
"Taints": [
{
"Effect" : "NO_SCHEDULE",
"Key" : "node.example.com/enclave",
"Value" : "nitro"
}
],
"Tags": {
"alpha.eksctl.io/nodegroup-name": "ng-test-enclave-v3",
"alpha.eksctl.io/nodegroup-type": "managed"
}
}
},
"NodeInstanceRole": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Statement": [
{
"Action": [
"sts:AssumeRole"
],
"Effect": "Allow",
"Principal": {
"Service": [
{
"Fn::FindInMap": [
"ServicePrincipalPartitionMap",
{
"Ref": "AWS::Partition"
},
"EC2"
]
}
]
}
}
],
"Version": "2012-10-17"
},
"ManagedPolicyArns": [
{
"Fn::Sub": "arn:${AWS::Partition}:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly"
},
{
"Fn::Sub": "arn:${AWS::Partition}:iam::aws:policy/AmazonEKSWorkerNodePolicy"
},
{
"Fn::Sub": "arn:${AWS::Partition}:iam::aws:policy/AmazonEKS_CNI_Policy"
}
],
"Path": "/",
"Tags": [
{
"Key": "Name",
"Value": {
"Fn::Sub": "${AWS::StackName}/NodeInstanceRole"
}
}
]
}
},
"SSH": {
"Type": "AWS::EC2::SecurityGroup",
"Properties": {
"GroupDescription": "Allow SSH access",
"GroupName": {
"Fn::Sub": "${AWS::StackName}-remoteAccess"
},
"SecurityGroupIngress": [
{
"CidrIp": "0.0.0.0/0",
"Description": "Allow SSH access to managed worker nodes in group ng-test-enclave-v3",
"FromPort": 22,
"IpProtocol": "tcp",
"ToPort": 22
},
{
"CidrIpv6": "::/0",
"Description": "Allow SSH access to managed worker nodes in group ng-test-enclave-v3",
"FromPort": 22,
"IpProtocol": "tcp",
"ToPort": 22
}
],
"Tags": [
{
"Key": "Name",
"Value": {
"Fn::Sub": "${AWS::StackName}/SSH"
}
}
],
"VpcId": {
"Fn::ImportValue": "eksctl-test-enclave-cluster::VPC"
}
}
}
}
}
```

Contributor guide

Open the contributing guide

Research direction

Start with the CloudFormation LaunchTemplate and ManagedNodeGroup resources shown in the issue, then compare the original and companion launch template behavior. Reproduce the managed-nodegroup deployment with EnclaveOptions enabled and confirm that the launch template used by the autoscaling group retains Enclave support without manual updates.

Written by the indexing model from the issue text.

Assessment

Tech stack
aws, kubernetes
Domain
cloud, infrastructure
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
20/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.