terraformamazon-eks

Terraform AWS EKS add or edit nodes user_data


I want to bootstrap my EKS nodes with adding some custom configurations by using the user_data feature.

I have a fairly simple configuration that creates my cluster and a managed node group. See below.

Is there a simple way to add a custom user_data to the node group's launch template?

module "eks" {
    source  = "terraform-aws-modules/eks/aws"

    cluster_name    = local.cluster_name
    cluster_version = "1.31"

    enable_cluster_creator_admin_permissions = true
    cluster_endpoint_public_access           = true
    cluster_endpoint_public_access_cidrs     = var.cluster_public_access_cidrs

    cluster_addons = {
        aws-ebs-csi-driver = {
            most_recent = true
            service_account_role_arn = module.ebs_csi_irsa_role.iam_role_arn
        }
    }

    vpc_id     = module.vpc.vpc_id
    subnet_ids = module.vpc.private_subnets

    eks_managed_node_group_defaults = {
        ami_type = "AL2_x86_64"
        iam_role_additional_policies = {
            AmazonEBSCSIDriverPolicy = "arn:aws:iam::aws:policy/service-role/AmazonEBSCSIDriverPolicy"
        }
    }

    eks_managed_node_groups = {
        one = {
            name = "node-group-1"

            instance_types = ["t3.small"]

            min_size     = 1
            max_size     = 3
            desired_size = 1
        }
    }
}

EDIT: For future seekers, I solved it by adding a simple pre_bootstrap_user_data in my eks_managed_node_group_defaults block in the following way:

...
    eks_managed_node_group_defaults = {
        ami_type = "AL2_ARM_64"
        iam_role_additional_policies = {
            AmazonEBSCSIDriverPolicy = "arn:aws:iam::aws:policy/service-role/AmazonEBSCSIDriverPolicy"
        }
        pre_bootstrap_user_data = <<-EOF
        yum install -y jq
        echo XYZ > /tmp/xyz.txt
        EOF
    }
...

This was injected before the EKS node's bootstrap.sh and installed jq for me on the node.


Solution

  • I have not used this module at all so this answer is provided just from looking at the docs it looks like you would just pass it the path to the user data template. In this example I have used your template. I have created a user_data.tpl file in my modules path.

    I then just pass this user data file path as an attribute of eks_managed_node_group_defaults

        eks_managed_node_group_defaults = {
            ami_type = "AL2_x86_64"
            iam_role_additional_policies = {
                AmazonEBSCSIDriverPolicy = "arn:aws:iam::aws:policy/service-role/AmazonEBSCSIDriverPolicy"
            }
            user_data_template_path = "${path.module}/user_data.tpl"
        }
    

    Before adding this attribute

      # module.eks.module.eks_managed_node_group["one"].aws_launch_template.this[0] will be created
      + resource "aws_launch_template" "this" {
          + arn                    = (known after apply)
          + default_version        = (known after apply)
          + description            = "Custom launch template for node-group-1 EKS managed node group"
          + id                     = (known after apply)
          + latest_version         = (known after apply)
          + name                   = (known after apply)
          + name_prefix            = "one-"
          + tags_all               = (known after apply)
          + update_default_version = true
          + vpc_security_group_ids = (known after apply)
    

    After adding user_data_template_path

     # module.eks.module.eks_managed_node_group["one"].aws_launch_template.this[0] will be created
      + resource "aws_launch_template" "this" {
          + arn                    = (known after apply)
          + default_version        = (known after apply)
          + description            = "Custom launch template for node-group-1 EKS managed node group"
          + id                     = (known after apply)
          + latest_version         = (known after apply)
          + name                   = (known after apply)
          + name_prefix            = "one-"
          + tags_all               = (known after apply)
          + update_default_version = true
          + user_data              = "ZXhwb3J0IGZvbz1iYXINCmVjaG8gIiRmb28i"
          + vpc_security_group_ids = (known after apply)
    

    I would suggest you try it for your self to be sure it works as you intend. You can read more in the docs here https://github.com/terraform-aws-modules/terraform-aws-eks/blob/master/docs/user_data.md#eks-managed-node-group

    Users can use the following variables to facilitate this process:

    user_data_template_path  = "./your/user_data.sh" # user supplied bootstrap user data template
    pre_bootstrap_user_data  = "..."
    bootstrap_extra_args     = "..."
    post_bootstrap_user_data = "..."