From 393da7ec0ed158cf783356ab10959d91430c1d80 Mon Sep 17 00:00:00 2001 From: Bryant Biggs Date: Fri, 8 Mar 2024 22:48:38 -0500 Subject: [PATCH] feat: Add support for tracking latest AMI release version on managed nodegroups (#2951) --- examples/eks_managed_node_group/main.tf | 4 ++ modules/eks-managed-node-group/README.md | 2 + modules/eks-managed-node-group/main.tf | 41 ++++++++++++++++++++- modules/eks-managed-node-group/variables.tf | 6 +++ node_groups.tf | 7 ++-- 5 files changed, 56 insertions(+), 4 deletions(-) diff --git a/examples/eks_managed_node_group/main.tf b/examples/eks_managed_node_group/main.tf index f2f8b13875..e31d2b2fb6 100644 --- a/examples/eks_managed_node_group/main.tf +++ b/examples/eks_managed_node_group/main.tf @@ -92,6 +92,8 @@ module "eks" { ami_type = "AL2023_x86_64_STANDARD" platform = "al2023" + use_latest_ami_release_version = true + cloudinit_pre_nodeadm = [ { content_type = "application/node.eks.aws" @@ -125,6 +127,8 @@ module "eks" { ami_type = "BOTTLEROCKET_x86_64" platform = "bottlerocket" + use_latest_ami_release_version = true + # This will get added to what AWS provides bootstrap_extra_args = <<-EOT # extra args added diff --git a/modules/eks-managed-node-group/README.md b/modules/eks-managed-node-group/README.md index 76852373da..82c3515cee 100644 --- a/modules/eks-managed-node-group/README.md +++ b/modules/eks-managed-node-group/README.md @@ -94,6 +94,7 @@ module "eks_managed_node_group" { | [aws_ec2_instance_type_offerings.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ec2_instance_type_offerings) | data source | | [aws_iam_policy_document.assume_role_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | | [aws_partition.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/partition) | data source | +| [aws_ssm_parameter.ami](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ssm_parameter) | data source | | [aws_subnets.efa](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/subnets) | data source | ## Inputs @@ -176,6 +177,7 @@ module "eks_managed_node_group" { | [update\_config](#input\_update\_config) | Configuration block of settings for max unavailable resources during node group updates | `map(string)` |
{
"max_unavailable_percentage": 33
}
| no | | [update\_launch\_template\_default\_version](#input\_update\_launch\_template\_default\_version) | Whether to update the launch templates default version on each update. Conflicts with `launch_template_default_version` | `bool` | `true` | no | | [use\_custom\_launch\_template](#input\_use\_custom\_launch\_template) | Determines whether to use a custom launch template or not. If set to `false`, EKS will use its own default launch template | `bool` | `true` | no | +| [use\_latest\_ami\_release\_version](#input\_use\_latest\_ami\_release\_version) | Determines whether to use the latest AMI release version for the given `ami_type` (except for `CUSTOM`). Note: `ami_type` and `cluster_version` must be supplied in order to enable this feature | `bool` | `false` | no | | [use\_name\_prefix](#input\_use\_name\_prefix) | Determines whether to use `name` as is or create a unique name beginning with the `name` as the prefix | `bool` | `true` | no | | [user\_data\_template\_path](#input\_user\_data\_template\_path) | Path to a local, custom user data template file to use when rendering user data | `string` | `""` | no | | [vpc\_security\_group\_ids](#input\_vpc\_security\_group\_ids) | A list of security group IDs to associate | `list(string)` | `[]` | no | diff --git a/modules/eks-managed-node-group/main.tf b/modules/eks-managed-node-group/main.tf index 3e9ce1d07e..b10b71e6b5 100644 --- a/modules/eks-managed-node-group/main.tf +++ b/modules/eks-managed-node-group/main.tf @@ -329,6 +329,45 @@ resource "aws_launch_template" "this" { } } +################################################################################ +# AMI SSM Parameter +################################################################################ + +locals { + # Just to ensure templating doesn't fail when values are not provided + ssm_cluster_version = var.cluster_version != null ? var.cluster_version : "" + ssm_ami_type = var.ami_type != null ? var.ami_type : "" + + # Map the AMI type to the respective SSM param path + ssm_ami_type_to_ssm_param = { + AL2_x86_64 = "/aws/service/eks/optimized-ami/${local.ssm_cluster_version}/amazon-linux-2/recommended/release_version" + AL2_x86_64_GPU = "/aws/service/eks/optimized-ami/${local.ssm_cluster_version}/amazon-linux-2-gpu/recommended/release_version" + AL2_ARM_64 = "/aws/service/eks/optimized-ami/${local.ssm_cluster_version}/amazon-linux-2-arm64/recommended/release_version" + CUSTOM = "NONE" + BOTTLEROCKET_ARM_64 = "/aws/service/bottlerocket/aws-k8s-${local.ssm_cluster_version}/arm64/latest/image_version" + BOTTLEROCKET_x86_64 = "/aws/service/bottlerocket/aws-k8s-${local.ssm_cluster_version}/x86_64/latest/image_version" + BOTTLEROCKET_ARM_64_NVIDIA = "/aws/service/bottlerocket/aws-k8s-${local.ssm_cluster_version}-nvidia/arm64/latest/image_version" + BOTTLEROCKET_x86_64_NVIDIA = "/aws/service/bottlerocket/aws-k8s-${local.ssm_cluster_version}-nvidia/x86_64/latest/image_version" + WINDOWS_CORE_2019_x86_64 = "/aws/service/ami-windows-latest/Windows_Server-2019-English-Full-EKS_Optimized-${local.ssm_cluster_version}" + WINDOWS_FULL_2019_x86_64 = "/aws/service/ami-windows-latest/Windows_Server-2019-English-Core-EKS_Optimized-${local.ssm_cluster_version}" + WINDOWS_CORE_2022_x86_64 = "/aws/service/ami-windows-latest/Windows_Server-2022-English-Full-EKS_Optimized-${local.ssm_cluster_version}" + WINDOWS_FULL_2022_x86_64 = "/aws/service/ami-windows-latest/Windows_Server-2022-English-Core-EKS_Optimized-${local.ssm_cluster_version}" + AL2023_x86_64_STANDARD = "/aws/service/eks/optimized-ami/${local.ssm_cluster_version}/amazon-linux-2023/x86_64/standard/recommended/release_version" + AL2023_ARM_64_STANDARD = "/aws/service/eks/optimized-ami/${local.ssm_cluster_version}/amazon-linux-2023/arm64/standard/recommended/release_version" + } + + # The Windows SSM params currently do not have a release version, so we have to get the full output JSON blob and parse out the release version + windows_latest_ami_release_version = var.create && var.use_latest_ami_release_version && startswith(local.ssm_ami_type, "WINDOWS") ? nonsensitive(jsondecode(data.aws_ssm_parameter.ami[0].value)["release_version"]) : null + # Based on the steps above, try to get an AMI release version - if not, `null` is returned + latest_ami_release_version = startswith(local.ssm_ami_type, "WINDOWS") ? local.windows_latest_ami_release_version : try(nonsensitive(data.aws_ssm_parameter.ami[0].value), null) +} + +data "aws_ssm_parameter" "ami" { + count = var.create && var.use_latest_ami_release_version ? 1 : 0 + + name = local.ssm_ami_type_to_ssm_param[var.ami_type] +} + ################################################################################ # Node Group ################################################################################ @@ -359,7 +398,7 @@ resource "aws_eks_node_group" "this" { # https://docs.aws.amazon.com/eks/latest/userguide/launch-templates.html#launch-template-custom-ami ami_type = var.ami_id != "" ? null : var.ami_type - release_version = var.ami_id != "" ? null : var.ami_release_version + release_version = var.ami_id != "" ? null : var.use_latest_ami_release_version ? local.latest_ami_release_version : var.ami_release_version version = var.ami_id != "" ? null : var.cluster_version capacity_type = var.capacity_type diff --git a/modules/eks-managed-node-group/variables.tf b/modules/eks-managed-node-group/variables.tf index eb4cc86b56..b5494e9dda 100644 --- a/modules/eks-managed-node-group/variables.tf +++ b/modules/eks-managed-node-group/variables.tf @@ -346,6 +346,12 @@ variable "ami_release_version" { default = null } +variable "use_latest_ami_release_version" { + description = "Determines whether to use the latest AMI release version for the given `ami_type` (except for `CUSTOM`). Note: `ami_type` and `cluster_version` must be supplied in order to enable this feature" + type = bool + default = false +} + variable "capacity_type" { description = "Type of capacity associated with the EKS Node Group. Valid values: `ON_DEMAND`, `SPOT`" type = string diff --git a/node_groups.tf b/node_groups.tf index 34a0735ff1..457e903d64 100644 --- a/node_groups.tf +++ b/node_groups.tf @@ -310,9 +310,10 @@ module "eks_managed_node_group" { max_size = try(each.value.max_size, var.eks_managed_node_group_defaults.max_size, 3) desired_size = try(each.value.desired_size, var.eks_managed_node_group_defaults.desired_size, 1) - ami_id = try(each.value.ami_id, var.eks_managed_node_group_defaults.ami_id, "") - ami_type = try(each.value.ami_type, var.eks_managed_node_group_defaults.ami_type, null) - ami_release_version = try(each.value.ami_release_version, var.eks_managed_node_group_defaults.ami_release_version, null) + ami_id = try(each.value.ami_id, var.eks_managed_node_group_defaults.ami_id, "") + ami_type = try(each.value.ami_type, var.eks_managed_node_group_defaults.ami_type, null) + ami_release_version = try(each.value.ami_release_version, var.eks_managed_node_group_defaults.ami_release_version, null) + use_latest_ami_release_version = try(each.value.use_latest_ami_release_version, var.eks_managed_node_group_defaults.use_latest_ami_release_version, false) capacity_type = try(each.value.capacity_type, var.eks_managed_node_group_defaults.capacity_type, null) disk_size = try(each.value.disk_size, var.eks_managed_node_group_defaults.disk_size, null)