Build AWS AMIs Using Packer

- By Manisha Sahasrabudhe on June 21, 2018

This tutorial explains how to build an AWS AMI using Packer. Before you start, you should be familiar with the following concepts:

The best way to get started is to install Packer and run scripts manually on your local machine to create an AMI. Once you understand the mechanics of it, you should consider automating your workflow by following our documentation on Automated AWS AMI creation using Packer.

 

Step-by-step instructions

Follow the steps below in order to build the AMI starting from a vanilla Ubuntu 16.04 image.

 

Step 1: Prep your machine

 

Step 1: Prep Packer template

  • Packer uses a json template that contains build instructions. The basic construct is one builder and multiple steps of provisioners and post-processors. You can read more about templates in the Packer docs and create your own template.
  • If you do not have your own Packer scripts, please feel free to clone our sample repo here: https://github.com/devops-recipes/aws_ami_with_packer. This repository contains the following key files:
    • baseAmi.json is the packer template
    • baseInit.sh is the shell script that will install packages inside the build machine
    • vars.json supplies the values for all the dynamic variables 
  • We are using a file based provisioner that copies the file into the build machine and executes it. We also have a manifest post-processor that enables us to output the amiId that was just built. Our Packer template looks like this:
{
  "variables": {
    "aws_access_key": "",
    "aws_secret_key": "",
    "vpc_region": "",
    "vpc_id": "",
    "vpc_public_sn_id": "",
    "source_ami": "test",
    "vpc_public_sg_id": "",
    "instance_type": "",
    "ssh_username": ""
  },
  "builders": [
    {
      "type": "amazon-ebs",
      "access_key": "",
      "secret_key": "",
      "region": "",
      "vpc_id": "",
      "subnet_id": "",
      "associate_public_ip_address": true,
      "security_group_id": "",
      "source_ami": "",
      "instance_type": "",
      "ssh_username": "",
      "ami_name": "base-ami-{{isotime \"2006-01-02-1504\"}}",
      "ami_groups": "all",
      "launch_block_device_mappings": [
        {
          "device_name": "/dev/sda1",
          "volume_type": "gp2",
          "volume_size": "30",
          "delete_on_termination": true
        }
      ]
    }
  ],
  "provisioners": [
    {
      "type": "shell",
      "script": "baseInit.sh"
    }
  ],
  "post-processors": [
    {
      "type": "manifest",
      "output": "manifest.json",
      "strip_path": true
    }
  ]
}

  • In vars.json, replace these wildcards (security group, subnet id, instance information etc.) with your desired values: ${AWS_ACCESS_KEY_ID} ${AWS_SECRET_ACCESS_KEY} ${vpc_region} ${vpc_public_sn_id} ${vpc_public_sg_id} ${source_ami} ${instance_type} ${ssh_username}.

 

Step 3:  Build AMI

  • Execute the following command to start Packer build from the directory that contains baseAmi.json file.
packer build -var-file=vars.json baseAMI.json
  • Verify on AWS if the AMI was built.

 

Challenges with manually executing Packer templates

If you build AMIs fairly often, you'll face a few challenges with manual execution of Packer templates:

  • Unless you want to create a Packer JSON for every single type of image you want to build, you will likely choose a template approach with one Packer template where wildcards can be replaced to build the right images. However, making sure the wildcards are correctly replaced can be error prone. Automation is key in ensuring that the wildcards are contextually replaced at runtime.
  • Once you create a build image, you likely want to provision some instances on AWS using that image. Sometimes there is an entire dependency tree of workflows that need to be triggered if the image changes. Manually triggering these dependent workflows and keeping stakeholders aware of changes can get challenging.
  • The machine has to be prepped with the right version of the CLI. If multiple teams are creating images and they have a need to use different versions of the CLI, you will need different deployment machines for each team. 

Automated AMI builds with Packer and Shippable

To show you how to automate the workflow described above, we have designed a step by step tutorial in our documentation:

 

 Schedule a demo

If you want a live demo of the Shippable platform and watch this scenario in action, schedule a demo with us: 

Topics: AWS, packer