PoshJosh's Blog

Packer - an introduction

October 02, 2019

Why Use Packer?

Pre-baked machine images have a lot of advantages, but most have been unable to benefit from them because images have been too tedious to create and manage. There were either no existing tools to automate the creation of machine images or they had too high of a learning curve. The result is that, prior to Packer, creating machine images threatened the agility of operations teams, and therefore aren’t used, despite the massive benefits.

Packer changes all of this. Packer is easy to use and automates the creation of any type of machine image. It embraces modern configuration management by encouraging you to use a framework such as Chef or Puppet to install and configure the software within your Packer-made images.

Installing Packer

To install the precompiled binary, download the appropriate package for your system. Packer is currently packaged as a zip file. We do not have any near term plans to provide system packages.

Next, unzip the downloaded package into a directory where Packer will be installed. On Unix systems, ~/packer or /usr/local/packer is generally good, depending on whether you want to restrict the install to just your user or install it system-wide. If you intend to access it from the command-line, make sure to place it somewhere on your PATH before /usr/sbin. On Windows systems, you can put it wherever you’d like. The packer (or packer.exe for Windows) binary inside is all that is necessary to run Packer. Any additional files aren’t required to run Packer.

After unzipping the package, the directory should contain a single binary program called packer. The final step to installation is to make sure the directory you installed Packer to is on the PATH. See this page for instructions on setting the PATH on Linux and Mac. This page contains instructions for setting the PATH on Windows.

Packer GNU/Linux Example with Provisioners

Create a file named welcome.txt and add the following:

This is my first packer. It was made deliberately detailed for a beginner

Create another file named start.sh and add the following

#!/bin/bash
echo "Hello World"

Set your access key and id as environment variables, so we don’t need to pass them in through the command line:

export AWS_ACCESS_KEY_ID=MYACCESSKEYID
export AWS_SECRET_ACCESS_KEY=MYSECRETACCESSKEY

Now save the following packer template, which is in [JSON](http://www.json.org/) format in a file named hellowold.json

{
    "variables": {
        "aws_access_key": "{{env `AWS_ACCESS_KEY_ID`}}",
        "aws_secret_key": "{{env `AWS_SECRET_ACCESS_KEY`}}",
        "region":         "us-east-1"
    },
    "builders": [
        {
            "access_key": "{{user `aws_access_key`}}",
            "ami_name": "packer-linux-aws-demo-{{timestamp}}",
            "instance_type": "t2.micro",
            "region": "{{user `region`}}",
            "secret_key": "{{user `aws_secret_key`}}",
            "source_ami_filter": {
              "filters": {
              "virtualization-type": "hvm",
              "name": "ubuntu/images/*ubuntu-xenial-16.04-amd64-server-*",
              "root-device-type": "ebs"
              },
              "owners": ["099720109477"],
              "most_recent": true
            },
            "ssh_username": "ubuntu",
            "type": "amazon-ebs"
        }
    ],
    "provisioners": [
        {
            "type": "file",
            "source": "./welcome.txt",
            "destination": "/home/ubuntu/"
        },
        {
            "type": "shell",
            "inline":[
                "sleep 30",
                "sudo apt-get update",
                "ls -al /home/ubuntu",
                "cat /home/ubuntu/welcome.txt"
            ]
        },
        {
            "type": "shell",
            "script": "./example.sh"
        }
    ]
}

Variables

The variables section contains variables which may be referenced/used in other sections of the template. In this example they are gotten from the earlier exported environment variables. However, you could leave them blank as shown below.

{
    "variables": {
        "aws_access_key": "",
        "aws_secret_key": "",
        "region":         "us-east-1"
    }
}

If you leave the variables blank as shown above, then you have to enter them with the build command as shown below:

packer build -var 'aws_access_key=YOUR ACCESS KEY' -var 'aws_secret_key=YOUR SECRET KEY' myfirstpacker.json

In the above, for windows systems, use double quotes.

Builders

The builders section contains an array of JSON objects configuring a specific builder. A builder is a component of Packer that is responsible for creating a machine and turning that machine into an image.

In this case, we’re only configuring a single builder of type amazon-ebs. This is the Amazon EC2 AMI builder that ships with Packer. This builder builds an EBS-backed AMI by launching a source AMI, provisioning on top of that, and re-packaging it into a new AMI.

The additional keys within the object are configuration for this builder, specifying things such as access keys, the source AMI to build from and more. The exact set of configuration variables available for a builder are specific to each builder and can be found within the packer documentation

Provisioners

The provisioners section is an array of provisioners to run. If multiple provisioners are specified, they are run in the order given. By default, each provisioner is run for every builder defined. So if we had two builders defined in our template, such as both Amazon and DigitalOcean, then the shell script would run as part of both builds. There are ways to restrict provisioners to certain builds, covered in more detail in the packer documentation.

In the above example, we use the built-in shell provisioner that comes with Packer to update the linux system via sudo apt-get update

Notes

  • The .txt and .sh files should be in the safe directory as myfirstpacker.json
  • Use an ami available in the region you specify
  • Note that if you wanted to use a source_ami instead of a source_ami_filter

it might look something like this: "source_ami": "ami-fce3c696".

  • The sleep 30 in the shell provisioner above is very important. Because Packer is able to

detect and SSH into the instance as soon as SSH is available, Ubuntu actually doesn’t get proper amounts of time to initialize. The sleep makes sure that the OS properly initializes.

Before we take this template and build an image from it, let’s validate the template by running packer validate example.json. This command checks the syntax as well as the configuration values to verify they look valid. The output should look similar to below, because the template should be valid. If there are any errors, this command will tell you.

$ packer validate myfirstpacker.json
Template validated successfully.

Next, let’s build the image from this template.

$ packer build myfirstpacker.json

At the end of running packer build, Packer outputs the artifacts that were created as part of the build. Artifacts are the results of a build, and typically represent an ID (such as in the case of an AMI) or a set of files (such as for a VMware virtual machine). In this example, we only have a single artifact: the AMI in us-east-1 that was created. This AMI is ready to use. If you wanted you could go and launch this AMI right now and it would work great.

Notes

  • If you see a VPCResourceNotSpecified error, Packer might not be able to determine

the default VPC, which the t2 instance types require. This can happen if you created your AWS account before 2013-12-04. You can either change the instance_type to m3.medium, or specify a VPC. Please see this amazon document for more information. If you specify a vpc_id, you will also need to set subnet_id. Unless you modify your subnet’s IPv4 public addressing attribute, you will also need to set associate_public_ip_address to true, or set up a VPN.

  • Packer only builds images. It does not attempt to manage them in any way. After they’re

built, it is up to you to launch or destroy them as you see fit. After running the above example, your AWS account now has an AMI associated with it. AMIs are stored in S3 by Amazon, so unless you want to be charged about $0.01 per month, you’ll probably want to remove it. Remove the AMI by first deregistering it on the AWS AMI management page. Next, delete the associated snapshot on the AWS snapshot management page.

References


Written byChinomso IkwuagwuExcélsior

Limited conversations with distributed systems.

Modifying legacy applications using domain driven design (DDD)

Gherkin Best Practices

Code Review Best Practices

Hacking Cypress in 9 minutes

Some common mistakes when developing java web applications

How to make a Spring Boot application production ready

SQL JOINS - A Refresher

Add Elasticsearch to Spring Boot Application

Add entities/tables to an existing Jhipster based project

CSS 3 Media Queries - All over again

Maven Dependency Convergence - quick reference

Amazon SNS Quick Reference

AWS API Gateway Quick Reference

Amazon SQS Quick Reference

AWS API Gateway Quick Reference

AWS Lambda Quick Reference

Amazon DynamoDB - Quick Reference

Amazon Aurora

Amazon Relational Database Service

AWS Database Services

AWS Security Essentials

Amazon Virtual Private Cloud Connectivity Options

Summary of AWS Services

AWS Certified Solutions Architect - Quick Reference

AWS CloudFront FAQs - Curated

AWS VPC FAQs - Curated

AWS EC2 FAQs - Curated

AWS Achritect 5 - Architecting for Cost Optimization

AWS Achritect 4 - Architecting for Performance Efficiency

AWS Achritect - 6 - Passing the Certification Exam

AWS Achitect 3 - Architecting for Operational Excellence

AWS Achitect 2 - Architecting for Security

AWS Achitect 1 - Architecting for Reliability

Amazon DynamoDB Accelerator (DAX)

Questions and Answers - AWS Certified Cloud Architect Associate

Questions and Answers - AWS Certified Cloud Architect Associate

AWS Connectivity - PrivateLink, VPC-Peering, Transit-gateway and Direct-connect

AWS - VPC peering vs PrivateLink

Designing Low Latency Systems

AWS EFS vs FSx

AWS Regions, Availability Zones and Local Zones

AWS VPC Endpoints and VPC Endpoint Services (AWS Private Link)

AWS - IP Addresses

AWS Elastic Network Interfaces

AWS Titbits

Jenkins on AWS - Automation

Jenkins on AWS - Setup

Jenkins on AWS - Best practices

Introduction to CIDR Blocks

AWS Lamda - Limitations and Use Cases

AWS Certified Solutions Architect Associate - Part 10 - Services and design scenarios

AWS Certified Solutions Architect Associate - Part 9 - Databases

AWS Certified Solutions Architect Associate - Part - 8 Application deployment

AWS Certified Solutions Architect Associate - Part 7 - Autoscaling and virtual network services

AWS Certified Solutions Architect Associate - Part 6 - Identity and access management

AWS Certified Solutions Architect Associate - Part 5 - Compute services design

AWS Certified Solutions Architect Associate - Part 4 - Virtual Private Cloud

AWS Certified Solutions Architect Associate - Part 3 - Storage services

AWS Certified Solutions Architect Associate - Part 2 - Introduction to Security

AWS Certified Solutions Architect Associate - Part 1 - Key services relating to the Exam

AWS Certifications - Part 1 - Certified solutions architect associate

AWS Virtual Private Cloud (VPC) Examples

Curated info on AWS Virtual Private Cloud (VPC)

Notes on Amazon Web Services 8 - Command Line Interface (CLI)

Notes on Amazon Web Services 7 - Elastic Beanstalk

Notes on Amazon Web Services 6 - Developer, Media, Migration, Productivity, IoT and Gaming

Notes on Amazon Web Services 5 - Security, Identity and Compliance

Notes on Amazon Web Services 4 - Analytics and Machine Learning

Notes on Amazon Web Services 3 - Managment Tools, App Integration and Customer Engagement

Notes on Amazon Web Services 2 - Storages databases compute and content delivery

Notes on Amazon Web Services 1 - Introduction

AWS Auto Scaling - All you need to know

AWS Load Balancers - How they work and differences between them

AWS EC2 Instance Types - Curated

Amazon Web Services - Identity and Access Management Primer

Amazon Web Services - Create IAM User

Preparing Jenkins after Installation

Jenkins titbits, and then some

Docker Titbits

How to Add Chat Functionality to a Maven Java Web App

Packer - an introduction

Terraform - an introduction

Versioning REST Resources with Spring Data REST

Installing and running Jenkins in Docker

Automate deployment of Jenkins to AWS - Part 2 - Full automation - Single EC2 instance

Automate deployment of Jenkins to AWS - Part 1 - Semi automation - Single EC2 instance

Introduction to Jenkins

Software Engineers Reference - Dictionary, Encyclopedia or Wiki - For Software Engineers