Create Golden Image using Packer

What's a Golden Image ?

A golden image is a base image on top of which developers can build applications, letting them focus on the application itself instead of system dependencies and patches. A typical golden image includes common system, logging, and monitoring tools, recent security patches, and application dependencies.

How it can be used?

Well, I have used it along with EC2 auto scaling. This golden image acted as the ami for our ec2. Since, this Golden Image already equipped with required application dependencies, application will be scaled up and accessible for end user in less time.

What is a packer?

Packer is an open source tool from Hashicorp, enables you to create identical machine images for multiple platforms from a single source template.

Let's start with installing Packer in Ubuntu.

$ wget -O- https://apt.releases.hashicorp.com/gpg | gpg --dearmor | sudo tee /usr/share/keyrings/hashicorp-archive-keyring.gpg
$ echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
$ sudo apt update && sudo apt install packer

Check for other installation at Packer.

Let's start building a simple image in which nginx will be installed.

Let's create a configuration file for Packer.

aws-ami-nginx.pkr.hcl

packer {
  required_plugins {
    amazon = {
      version = ">= 0.0.2"
      source  = "github.com/hashicorp/amazon"
    }
  }
}
data "amazon-ami" "ubuntu-focal" {
  region = "us-east-1"
  filters = {
    name                = "ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"
    root-device-type    = "ebs"
    virtualization-type = "hvm"
  }
  most_recent = true
  owners      = ["099720109477"]
}

source "amazon-ebs" "ubuntu" {
  ami_name      = "anils-packer-${formatdate("YYYY-MMM-DD-hh'hr'-mm'min'", "${timestamp()}")}" 

  instance_type = "t2.micro"
  region        = "us-east-1"
  source_ami = data.amazon-ami.ubuntu-focal.id    ##  ami-0c1704bac156af62c
  ssh_username = "ubuntu"
  tags = {
    Name        = "demo"
    environment = "production"
  }
}

build {
  name = "learn-packer"
  sources = [
    "source.amazon-ebs.ubuntu"
  ]
  provisioner "shell" {

    inline = [
      "sudo apt-get clean",
      "echo updating",
      "sudo apt update",
      "echo Installing nginx",
      "sudo apt install -y nginx",
    ]
  }
}

Let's start building it.

Export the aws credentials access key & secret key

export AWS_ACCESS_KEY_ID='************'
export AWS_SECRET_ACCESS_KEY='***********'

Create a folder and save the hcl file in it.

ubuntu@ip-172-31-31-137:~$ mkdir test-1
ubuntu@ip-172-31-31-137:~$ cd test-1/
ubuntu@ip-172-31-31-137:~/test-1$ ls
aws-ami-nginx.pkr.hcl

Initialize Packer

ubuntu@ip-172-31-31-137:~/test-1$ packer init aws-ami-nginx.pkr.hcl
Installed plugin github.com/hashicorp/amazon v1.1.5 in "/home/ubuntu/.config/packer/plugins/github.com/hashicorp/amazon/packer-plugin-amazon_v1.1.5_x5.0_linux_amd64"

Validate the hcl configuration

ubuntu@ip-172-31-31-137:~/test-1$ packer validate aws-ami-nginx.pkr.hcl
The configuration is valid.

Build the image

ubuntu@ip-172-31-31-137:~/test-1$ packer build aws-ami-nginx.pkr.hcl
learn-packer.amazon-ebs.ubuntu: output will be in this color.

==> learn-packer.amazon-ebs.ubuntu: Prevalidating any provided VPC information
==> learn-packer.amazon-ebs.ubuntu: Prevalidating AMI Name: anils-packer-2022-Oct-02-05hr-44min
    learn-packer.amazon-ebs.ubuntu: Found Image ID: ami-0c1704bac156af62c
==> learn-packer.amazon-ebs.ubuntu: Creating temporary keypair: packer_6339255b-da8d-1231-d110-a250540bbcca
==> learn-packer.amazon-ebs.ubuntu: Creating temporary security group for this instance: packer_6339255c-8ce2-034b-d80a-c93c7c405841
==> learn-packer.amazon-ebs.ubuntu: Authorizing access to port 22 from [0.0.0.0/0] in the temporary security groups...
==> learn-packer.amazon-ebs.ubuntu: Launching a source AWS instance...
    learn-packer.amazon-ebs.ubuntu: Instance ID: i-0385ead063ff2bf1f
==> learn-packer.amazon-ebs.ubuntu: Waiting for instance (i-0385ead063ff2bf1f) to become ready...
==> learn-packer.amazon-ebs.ubuntu: Using SSH communicator to connect: 34.239.119.127
==> learn-packer.amazon-ebs.ubuntu: Waiting for SSH to become available...
==> learn-packer.amazon-ebs.ubuntu: Connected to SSH!
==> learn-packer.amazon-ebs.ubuntu: Provisioning with shell script: /tmp/packer-shell1702171532
    learn-packer.amazon-ebs.ubuntu: updating

...........
...........
==> learn-packer.amazon-ebs.ubuntu: Tagging snapshot: snap-0f655f5811e2b066f
==> learn-packer.amazon-ebs.ubuntu: Creating AMI tags
    learn-packer.amazon-ebs.ubuntu: Adding tag: "Name": "demo"
    learn-packer.amazon-ebs.ubuntu: Adding tag: "environment": "production"
==> learn-packer.amazon-ebs.ubuntu: Creating snapshot tags
==> learn-packer.amazon-ebs.ubuntu: Terminating the source AWS instance...
==> learn-packer.amazon-ebs.ubuntu: Cleaning up any extra volumes...
==> learn-packer.amazon-ebs.ubuntu: No volumes to clean up, skipping
==> learn-packer.amazon-ebs.ubuntu: Deleting temporary security group...
==> learn-packer.amazon-ebs.ubuntu: Deleting temporary keypair...
Build 'learn-packer.amazon-ebs.ubuntu' finished after 3 minutes 45 seconds.

==> Wait completed after 3 minutes 45 seconds

==> Builds finished. The artifacts of successful builds are:
--> learn-packer.amazon-ebs.ubuntu: AMIs were created:
us-east-1: ami-0bcc39f53ee5ffb19

Check the AMI at AWS Dashboard

aws_dashboard_ami.JPG

Now let's deploy ec2 with this AMI. Select AMI and Click on "Launch Instance from AMI"

Fill the required..

demo4.JPG

Go to EC2 Console > Get Public IP of instance

ng.JPG

Based on your application, configure the script for installing required dependencies and try to build ami.

Packer Configuration file will be available at Github.

Thanks for reading...