Skip to content

Resource: awsEksNodeGroup

Manages an EKS Node Group, which can provision and optionally update an Auto Scaling Group of Kubernetes worker nodes compatible with EKS. Additional documentation about this functionality can be found in the EKS User Guide.

Example Usage

/*Provider bindings are generated by running cdktf get.
See https://cdk.tf/provider-generation for more details.*/
import * as aws from "./.gen/providers/aws";
new aws.eksNodeGroup.EksNodeGroup(this, "example", {
  clusterName: "${aws_eks_cluster.example.name}",
  depends_on: [
    "${aws_iam_role_policy_attachment.example-AmazonEKSWorkerNodePolicy}",
    "${aws_iam_role_policy_attachment.example-AmazonEKS_CNI_Policy}",
    "${aws_iam_role_policy_attachment.example-AmazonEC2ContainerRegistryReadOnly}",
  ],
  nodeGroupName: "example",
  nodeRoleArn: "${aws_iam_role.example.arn}",
  scalingConfig: {
    desiredSize: 1,
    maxSize: 2,
    minSize: 1,
  },
  subnetIds: "${aws_subnet.example[*].id}",
  updateConfig: {
    maxUnavailable: 1,
  },
});

Ignoring Changes to Desired Size

You can utilize the generic Terraform resource lifecycle configuration block with ignoreChanges to create an EKS Node Group with an initial size of running instances, then ignore any changes to that count caused externally (e.g., Application Autoscaling).

/*Provider bindings are generated by running cdktf get.
See https://cdk.tf/provider-generation for more details.*/
import * as aws from "./.gen/providers/aws";
const awsEksNodeGroupExample = new aws.eksNodeGroup.EksNodeGroup(
  this,
  "example",
  {
    scalingConfig: {
      desiredSize: 2,
    },
  }
);
awsEksNodeGroupExample.addOverride("lifecycle", [
  {
    ignore_changes: ["${scaling_config[0].desired_size}"],
  },
]);

Tracking the latest EKS Node Group AMI releases

You can have the node group track the latest version of the Amazon EKS optimized Amazon Linux AMI for a given EKS version by querying an Amazon provided SSM parameter. Replace amazonLinux2 in the parameter name below with amazonLinux2Gpu to retrieve the accelerated AMI version and amazonLinux2Arm64 to retrieve the Arm version.

/*Provider bindings are generated by running cdktf get.
See https://cdk.tf/provider-generation for more details.*/
import * as aws from "./.gen/providers/aws";
const dataAwsSsmParameterEksAmiReleaseVersion =
  new aws.dataAwsSsmParameter.DataAwsSsmParameter(
    this,
    "eks_ami_release_version",
    {
      name: "/aws/service/eks/optimized-ami/${aws_eks_cluster.example.version}/amazon-linux-2/recommended/release_version",
    }
  );
new aws.eksNodeGroup.EksNodeGroup(this, "example", {
  clusterName: "${aws_eks_cluster.example.name}",
  nodeGroupName: "example",
  nodeRoleArn: "${aws_iam_role.example.arn}",
  releaseVersion: `\${nonsensitive(${dataAwsSsmParameterEksAmiReleaseVersion.value})}`,
  subnetIds: "${aws_subnet.example[*].id}",
  version: "${aws_eks_cluster.example.version}",
});

Example IAM Role for EKS Node Group

/*Provider bindings are generated by running cdktf get.
See https://cdk.tf/provider-generation for more details.*/
import * as aws from "./.gen/providers/aws";
const awsIamRoleExample = new aws.iamRole.IamRole(this, "example", {
  assumeRolePolicy:
    '${jsonencode({\n    Statement = [{\n      Action = "sts:AssumeRole"\n      Effect = "Allow"\n      Principal = {\n        Service = "ec2.amazonaws.com"\n      }\n    }]\n    Version = "2012-10-17"\n  })}',
  name: "eks-node-group-example",
});
new aws.iamRolePolicyAttachment.IamRolePolicyAttachment(
  this,
  "example-AmazonEC2ContainerRegistryReadOnly",
  {
    policyArn: "arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly",
    role: awsIamRoleExample.name,
  }
);
new aws.iamRolePolicyAttachment.IamRolePolicyAttachment(
  this,
  "example-AmazonEKSWorkerNodePolicy",
  {
    policyArn: "arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy",
    role: awsIamRoleExample.name,
  }
);
new aws.iamRolePolicyAttachment.IamRolePolicyAttachment(
  this,
  "example-AmazonEKS_CNI_Policy",
  {
    policyArn: "arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy",
    role: awsIamRoleExample.name,
  }
);

Example Subnets for EKS Node Group

/*Provider bindings are generated by running cdktf get.
See https://cdk.tf/provider-generation for more details.*/
import * as aws from "./.gen/providers/aws";
const dataAwsAvailabilityZonesAvailable =
  new aws.dataAwsAvailabilityZones.DataAwsAvailabilityZones(this, "available", {
    state: "available",
  });
const awsSubnetExample = new aws.subnet.Subnet(this, "example", {
  availabilityZone: `\${${dataAwsAvailabilityZonesAvailable.names.fqn}[count.index]}`,
  cidrBlock: "${cidrsubnet(aws_vpc.example.cidr_block, 8, count.index)}",
  tags: {
    "kubernetes.io/cluster/${aws_eks_cluster.example.name}": "shared",
  },
  vpcId: "${aws_vpc.example.id}",
});
/*In most cases loops should be handled in the programming language context and 
not inside of the Terraform context. If you are looping over something external, e.g. a variable or a file input
you should consider using a for loop. If you are looping over something only known to Terraform, e.g. a result of a data source
you need to keep this like it is.*/
awsSubnetExample.addOverride("count", 2);

Argument Reference

The following arguments are required:

  • clusterName – (Required) Name of the EKS Cluster. Must be between 1-100 characters in length. Must begin with an alphanumeric character, and must only contain alphanumeric characters, dashes and underscores (^[09AZaZ][aZaZ09\_]+$).
  • nodeRoleArn – (Required) Amazon Resource Name (ARN) of the IAM Role that provides permissions for the EKS Node Group.
  • scalingConfig - (Required) Configuration block with scaling settings. Detailed below.
  • subnetIds – (Required) Identifiers of EC2 Subnets to associate with the EKS Node Group. These subnets must have the following resource tag: kubernetesIo/cluster/clusterName (where CLUSTER_NAME is replaced with the name of the EKS Cluster).

The following arguments are optional:

  • amiType - (Optional) Type of Amazon Machine Image (AMI) associated with the EKS Node Group. See the AWS documentation for valid values. Terraform will only perform drift detection if a configuration value is provided.
  • capacityType - (Optional) Type of capacity associated with the EKS Node Group. Valid values: ON_DEMAND, spot. Terraform will only perform drift detection if a configuration value is provided.
  • diskSize - (Optional) Disk size in GiB for worker nodes. Defaults to 50 for Windows, 20 all other node groups. Terraform will only perform drift detection if a configuration value is provided.
  • forceUpdateVersion - (Optional) Force version update if existing pods are unable to be drained due to a pod disruption budget issue.
  • instanceTypes - (Optional) List of instance types associated with the EKS Node Group. Defaults to ["t3Medium"]. Terraform will only perform drift detection if a configuration value is provided.
  • labels - (Optional) Key-value map of Kubernetes labels. Only labels that are applied with the EKS API are managed by this argument. Other Kubernetes labels applied to the EKS Node Group will not be managed.
  • launchTemplate - (Optional) Configuration block with Launch Template settings. Detailed below.
  • nodeGroupName – (Optional) Name of the EKS Node Group. If omitted, Terraform will assign a random, unique name. Conflicts with nodeGroupNamePrefix.
  • nodeGroupNamePrefix – (Optional) Creates a unique name beginning with the specified prefix. Conflicts with nodeGroupName.
  • releaseVersion – (Optional) AMI version of the EKS Node Group. Defaults to latest version for Kubernetes version.
  • remoteAccess - (Optional) Configuration block with remote access settings. Detailed below.
  • tags - (Optional) Key-value map of resource tags. If configured with a provider defaultTags configuration block present, tags with matching keys will overwrite those defined at the provider-level.
  • taint - (Optional) The Kubernetes taints to be applied to the nodes in the node group. Maximum of 50 taints per node group. Detailed below.
  • version – (Optional) Kubernetes version. Defaults to EKS Cluster Kubernetes version. Terraform will only perform drift detection if a configuration value is provided.

launch_template Configuration Block

\~> NOTE: Either id or name must be specified.

  • id - (Optional) Identifier of the EC2 Launch Template. Conflicts with name.
  • name - (Optional) Name of the EC2 Launch Template. Conflicts with id.
  • version - (Required) EC2 Launch Template version number. While the API accepts values like $default and $latest, the API will convert the value to the associated version number (e.g., 1) on read and Terraform will show a difference on next plan. Using the defaultVersion or latestVersion attribute of the awsLaunchTemplate resource or data source is recommended for this argument.

remote_access Configuration Block

  • ec2SshKey - (Optional) EC2 Key Pair name that provides access for remote communication with the worker nodes in the EKS Node Group. If you specify this configuration, but do not specify sourceSecurityGroupIds when you create an EKS Node Group, either port 3389 for Windows, or port 22 for all other operating systems is opened on the worker nodes to the Internet (0.0.0.0/0). For Windows nodes, this will allow you to use RDP, for all others this allows you to SSH into the worker nodes.
  • sourceSecurityGroupIds - (Optional) Set of EC2 Security Group IDs to allow SSH access (port 22) from on the worker nodes. If you specify ec2SshKey, but do not specify this configuration when you create an EKS Node Group, port 22 on the worker nodes is opened to the Internet (0.0.0.0/0).

scaling_config Configuration Block

  • desiredSize - (Required) Desired number of worker nodes.
  • maxSize - (Required) Maximum number of worker nodes.
  • minSize - (Required) Minimum number of worker nodes.

taint Configuration Block

  • key - (Required) The key of the taint. Maximum length of 63.
  • value - (Optional) The value of the taint. Maximum length of 63.
  • effect - (Required) The effect of the taint. Valid values: NO_SCHEDULE, NO_EXECUTE, PREFER_NO_SCHEDULE.

update_config Configuration Block

The following arguments are mutually exclusive.

  • maxUnavailable - (Optional) Desired max number of unavailable worker nodes during node group update.
  • maxUnavailablePercentage - (Optional) Desired max percentage of unavailable worker nodes during node group update.

Attributes Reference

In addition to all arguments above, the following attributes are exported:

  • arn - Amazon Resource Name (ARN) of the EKS Node Group.
  • id - EKS Cluster name and EKS Node Group name separated by a colon (:).
  • resources - List of objects containing information about underlying resources.
  • autoscalingGroups - List of objects containing information about AutoScaling Groups.
    • name - Name of the AutoScaling Group.
  • remoteAccessSecurityGroupId - Identifier of the remote access EC2 Security Group.
  • tagsAll - A map of tags assigned to the resource, including those inherited from the provider defaultTags configuration block.
  • status - Status of the EKS Node Group.

Timeouts

Configuration options:

  • create - (Default 60M)
  • update - (Default 60M)
  • delete - (Default 60M)

Import

EKS Node Groups can be imported using the clusterName and nodeGroupName separated by a colon (:), e.g.,

$ terraform import aws_eks_node_group.my_node_group my_cluster:my_node_group