How to Spin up Bottlerocket node in EKS via Terraform

gray laptop computer showing html codes in shallow focus photography
Reading Time: 3 minutes

In the previous blog, we went through the introduction of Bottlerocket. If you haven’t already read the previous blog, I would recommend to check that out before you begin this one. It walks you through several questions you have in mind with Bottlerocket. This blog will be a quick start for you to spin up Bottlerocket node in Amazon EKS with Terraform as IAAC tool.

There are many ways to spin up a Bottlerocket node. You can go to the AWS console -> Launch Instances -> Select the Bottlerocket AMI -> Configure instance settings and launch the instance.

This would be an easy way for you to actually get familiarized with the instance behavior and everything. Once you have a sound knowledge you can easily spin it up as a EKS worker node and manage your applications on it. Now lets look at how we can integrate Terraform to spin up a worker node that has Bottlerocket ami attached to it.

We will go through a sequence of events that we need to perform.

1. Get an AMI for Bottlerocket node

To get an AMI for Bottlerocket, you can visit the AMI console , and search for Bottlerocket under community AMIs. Based on the version of your EKS cluster, choose an AMI.

You can also use AWS CLI command to get the required AMI.

aws ssm get-parameter --region us-east-1 --name "/aws/service/bottlerocket/aws-k8s-1.18/x86_64/latest/image_id" --query Parameter.Value --output text

You might get Access Denied error, if you don’t have suitable permissions for this. Add the following policy to your role:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "ssm:DescribeParameters"
            ],
            "Resource": "*",
            "Effect": "Allow"
        },
        {
            "Action": [
                "ssm:GetParameter"
            ],
            "Resource": "*",
            "Effect": "Allow"
        }
    ]
}

Now that you have the access, type the following AWS CLI command:

aws ssm get-parameter --region us-east-1 --name "/aws/service/bottlerocket/aws-k8s-1.18/x86_64/latest/image_id" --query Parameter.Value --output text

[Note: Change it accordingly with respect to your EKS clutser version.]

As shown in the image above, this will generate the AMI for you to use. You can use this AMI in your code, but its easier if you use a data block in Terraform.

To generate it via Terraform, use the following Data block:

provider "aws" {
shared_credentials_file = "/path/to/aws/credentials"
region = "us-east-1"
}

data "aws_ami" "bottlerocket" {
  most_recent = true

  filter {
    name   = "name"
    values = ["/aws/service/bottlerocket/aws-k8s-1.18/x86_64/latest/*"]
  }
  owners = ["aws-marketplace"]
}

2. Create a user-data script for Bottlerocket node

We have to create a user-data script for Bottlerocket to provide configuration details to enroll into an Amazon EKS cluster. We will create a file called Bottlerocket_userdata.sh. This file contains the information regarding you EKS cluster including API-server, cluster-certificate, cluster-name, and cluster-dns-ip. You can easily get this information from your EKS console.

Bottlerocket_userdata.sh

[settings.kubernetes]
api-server = "https://2T7H4J3K4K5L5D9DED09HG78.sk1.us-east-1.eks.amazonaws.com"
cluster-certificate = "MS9lBD3FRWdY9H2AS1o="
cluster-name = "EKS-Cluster"
cluster-dns-ip = "10.0.0.10"

3. Create a new Launch Template

Use the following Terraform block to create the launch template. I am adding the minimum configurations required. You can refer to the Terraform documentation if you want to add more fields to it.

resource "aws_launch_template" "launch_bottlerocket" {
    name = "eks-bottlerocket"
    vpc_security_group_ids = ["sg-0dabcde543ab2c1"]
    image_id = data.aws_ami.bottlerocket.id
    block_device_mappings {
        device_name = "/dev/xvda"

        ebs {
            volume_size = 40
        }
    }
    tag_specifications {
        resource_type = "instance"
        tags = {
            Name = "bottlerocket"
        }
    }
    user_data = filebase64("bottlerocket_userdata.sh")
}

4. Create a new EKS Nodegroup

This Terraform block will create a new EKS nodegroup named: Bottlerocket-node-group for you. It will refer to the launch template you specified above. You can specify node role, instance type, scaling configurations, tags, etc. as per your requirements.

resource "aws_eks_node_group" "bottlerocket_node" {
    cluster_name    = "EKS-Cluster"
    node_group_name = "Bottlerocket-node-group"
    node_role_arn   = "arn:aws:iam::<Account-ID>:role/<RoleName>"
    subnet_ids      = ["subnet-07b23jk323k432kl3","subnet-109380bhj8sh3","subnet-012d32j32o932j"]
    instance_types  = ["t2.micro"]
    scaling_config {
        desired_size = 1
        max_size     = 1
        min_size     = 1
    }
    labels = {
        "nodetype" = "bottlerocket"
    }
    launch_template {
        id = aws_launch_template.launch_bottlerocket.id
        version = "latest"
    }
}

5. Run the following Terraform commands:

terraform init

terraform plan

terraform apply

Thank you readers for sticking up till the end. I hope you like this blog and you might have some questions regarding it. I am reachable at vidushi.bansal@knoldus.com. Drop in any queries/suggestions.

References:

https://github.com/bottlerocket-os/bottlerocket

knoldus

Written by 

Vidushi Bansal is a Software Consultant [Devops] at Knoldus Inc. She is passionate about learning and exploring new technologies.