DEV Community


Posted on • Updated on

Introduction to Packer by creating an AMI (Amazon Machine Images)

What is Packer ?

A tool from Hashicorp to build machine images for most platforms (AWS,Google Cloud,Digital Ocean,Docker,Azure to name a few) and automate configurations and installation of softwares that need to be present.

We define how to build the image in a JSON template file.This should be version controlled and is treated like any other code.

Infrastructure As Code.

Sections of Packer template


A builder takes care of creating an image.Packer provides builders for various platforms.
For this example we will be using amazon-ebs as builder.
We provide platform specific configurations in the builder section of the template.Like what type of instance (t2-micro m4-large etc) to spin up to create the image, SSH/Access details or credentials. You can create custom builders as well though we wont be covering this.

Builders use Communicators to establish connection with the created instance. Either it can be a SSH connection or WINRM for Windows machine.


Once a machine is created by the builder we will use provisioners to install softwares and configure the machine to a desired state.Packer provide provisioners for configuration management tools like Chef/Puppet/Ansible or good old shell script.


Once the machine is created and softwares installed and configurations applied by Provisioners Post-Processors are run. We can use them for example to push a docker image to a registry. We wont be covering this and for details please refer this documentation.


Packer template should be made generic so it can be used in different environment and keeping secrets/credentials secure by not providing them in the template file. Use user variables in place of such configurations.

In the template below we use user variables for name, sourceami, accesskey, secretkey, region. For some of these we have provided a default value in the variable sections other are left as empty,We can pass in the value while building the image using -var parameter.

So What exactly does Packer do ?

  • Packer will spin up an instance for the specified platform based on the type of builder.
  • Use the Communicator specified to connect to the machine.
  • Run all the provisioners to configure and install softwares.
  • It the runs any post-processors specified in the JSON template.
  • Finally it terminates machines and any temporary resources it created in the process, eg: security group, temporary ssh key-pair etc.

Getting hands dirty with Packer

What are we going to do ?

  • Create an AMI with Nginx pre-installed
    • Choose source_ami as CentOS 7
    • Install EPEL (Extra packages for enterprise Linux)
    • Install nginx
    • Enable nginx to start on boot
    "variables": {
      "name": "centos_7_nginx",
      "source_ami": "ami-d5bf2caa",
    "builders": [{
      "type": "amazon-ebs",
      "access_key": "{{user `access_key`}}",
      "secret_key":"{{user `secret_key`}}",
      "ami_name": "{{user `name`}}",
      "region": "{{user `region`}}",
      "source_ami": "{{user `source_ami`}}",
      "instance_type": "t2.micro",
      "communicator": "ssh",
      "ssh_username": "centos",
    "provisioners": [
            "type": "shell",
            "inline": "sudo yum install -y epel-release"
            "type": "shell",
            "inline": ["sudo yum install -y nginx","sudo systemctl enable nginx", "sudo systemctl start nginx"]
Enter fullscreen mode Exit fullscreen mode

Command to build image :

packer build -var 'access_key=XXXXXXXXXXX' -var 'secret_key=XXXXXXXXXXXXXXXXXXXXXXXX' aws_centos_nginx.json 
Enter fullscreen mode Exit fullscreen mode

Before running the above command you can validate the file using packer validate template.json


  • Generate a secret key and access key from AWS which have authorization for creating image and pass the packer build command.
  • The source AMI specified above is CentOS Linux 7 x86_64 HVM EBS.
  • Communicator used is SSH and we specify the default username which is centos.
  • AMI are region specific so ensure you select us-east-1 or N.Virginia as your current region.
  • run_tags are tags assigned to the machine used to create the image.This machine will be terminated once the image is created.
  • We have used shell prvisioner in the above example with inline mode. First with just a single command then with an array of commands to run.

Originally posted in JigsawCode

Where to next ?

Packer Recipes to bake an EC2 AMI


Packer Documentation

P.S If you find it useful,I will write a second part exploring more features of Packer.

Top comments (2)

Sloan, the sloth mascot
Comment deleted
__init__adan profile image
Adan Patience

Not too sure how far you got with your problem. But what I'd done with SpringBoot applications, I created a unit file in Systemd and enabled it to start at boot. Maybe thats a better way to circumvent the issue you having ?

Let me know if you need any examples are something, would be happy to help.