Skip to content

Commit

Permalink
fix: always set AMI ID for custom LaunchTemplates with ManagedNodeGro…
Browse files Browse the repository at this point in the history
…ups (#1166)

### Proposed changes

#1163 enabled setting custom user data in MIME format. However, AWS will
attempt to merge the user data with its own copy if an AMI ID is not
supplied in the LaunchTemplate. This results in the nodes being unable
to join the cluster due to conflicting bootstrap script runs. This PR
explicitly sets the ami id within the launch template.

Testing:

- Updated the existing tests to provision a cluster within a VPC to
surface any node joining issues which CI was previously ignoring

Fixes: #1165
  • Loading branch information
rquitales authored May 24, 2024
1 parent 515d31f commit 161e7af
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 19 deletions.
52 changes: 36 additions & 16 deletions examples/managed-nodegroups/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import * as aws from "@pulumi/aws";
import * as awsx from "@pulumi/awsx";
import * as eks from "@pulumi/eks";
import * as iam from "./iam";

Expand All @@ -7,11 +7,22 @@ const role0 = iam.createRole("example-role0");
const role1 = iam.createRole("example-role1");
const role2 = iam.createRole("example-role2");

// Create a new VPC
const eksVpc = new awsx.ec2.Vpc("eks-vpc", {
enableDnsHostnames: true,
cidrBlock: "10.0.0.0/16",
});

// Create an EKS cluster.
const cluster = new eks.Cluster("example-managed-nodegroups", {
skipDefaultNodeGroup: true,
deployDashboard: false,
instanceRoles: [role0, role1, role2],
skipDefaultNodeGroup: true,
deployDashboard: false,
vpcId: eksVpc.vpcId,
// Public subnets will be used for load balancers
publicSubnetIds: eksVpc.publicSubnetIds,
// Private subnets will be used for cluster nodes
privateSubnetIds: eksVpc.privateSubnetIds,
instanceRoles: [role0, role1, role2],
});

// Export the cluster's kubeconfig.
Expand All @@ -20,32 +31,41 @@ export const kubeconfig = cluster.kubeconfig;
// Create a simple AWS managed node group using a cluster as input and the
// refactored API.
const managedNodeGroup0 = eks.createManagedNodeGroup("example-managed-ng0", {
cluster: cluster,
nodeRole: role0,
kubeletExtraArgs: "--max-pods=500",
cluster: cluster,
nodeRole: role0,
kubeletExtraArgs: "--max-pods=500",
enableIMDSv2: true,
});

// Create a simple AWS managed node group using a cluster as input and the
// initial API.
const managedNodeGroup1 = eks.createManagedNodeGroup("example-managed-ng1", {
const managedNodeGroup1 = eks.createManagedNodeGroup(
"example-managed-ng1",
{
cluster: cluster,
nodeGroupName: "aws-managed-ng1",
nodeRoleArn: role1.arn,
}, cluster);
},
cluster
);

// Create an explicit AWS managed node group using a cluster as input and the
// initial API.
const managedNodeGroup2 = eks.createManagedNodeGroup("example-managed-ng2", {
const managedNodeGroup2 = eks.createManagedNodeGroup(
"example-managed-ng2",
{
cluster: cluster,
nodeGroupName: "aws-managed-ng2",
nodeRoleArn: role2.arn,
scalingConfig: {
desiredSize: 1,
minSize: 1,
maxSize: 2,
desiredSize: 1,
minSize: 1,
maxSize: 2,
},
diskSize: 20,
instanceTypes: ["t3.medium"],
labels: {"ondemand": "true"},
tags: {"org": "pulumi"},
}, cluster);
labels: { ondemand: "true" },
tags: { org: "pulumi" },
},
cluster
);
2 changes: 1 addition & 1 deletion examples/managed-nodegroups/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"typescript": "^4.0.0"
},
"dependencies": {
"@pulumi/aws": "^6.0.4",
"@pulumi/awsx": "^2.0.0",
"@pulumi/eks": "latest",
"@pulumi/pulumi": "^3.0.0"
}
Expand Down
10 changes: 8 additions & 2 deletions nodejs/eks/nodegroup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1800,6 +1800,9 @@ Content-Type: text/x-shellscript; charset="us-ascii"
{
userData,
metadataOptions,
// We need to always supply an imageId, otherwise AWS will attempt to merge the user data which will result in
// nodes failing to join the cluster.
imageId: getRecommendedAMI(args, core.cluster.version, parent),
},
{ parent, provider },
);
Expand All @@ -1812,11 +1815,14 @@ Content-Type: text/x-shellscript; charset="us-ascii"
* See: https://docs.aws.amazon.com/eks/latest/userguide/retrieve-ami-id.html
*/
function getRecommendedAMI(
args: Omit<NodeGroupOptions, "cluster"> | Omit<NodeGroupV2Options, "cluster">,
args: Omit<NodeGroupOptions, "cluster"> | Omit<NodeGroupV2Options, "cluster"> | Omit<ManagedNodeGroupOptions, "cluster">,
k8sVersion: pulumi.Output<string>,
parent: pulumi.Resource | undefined,
): pulumi.Input<string> {
const amiType = getAMIType(args.amiType, args.gpu, args.instanceType);
const gpu = "gpu" in args ? args.gpu : undefined;
const instanceType = "instanceType" in args ? args.instanceType : undefined;

const amiType = getAMIType(args.amiType, gpu, instanceType);
const amiID = k8sVersion.apply((v) => {
const parameterName = `/aws/service/eks/optimized-ami/${v}/${amiType}/recommended/image_id`;
return pulumi.output(aws.ssm.getParameter({ name: parameterName }, { parent, async: true }))
Expand Down

0 comments on commit 161e7af

Please sign in to comment.