Image Creation: Packer and OpenStack
Solinea services help enterprises build step-by-step modernization plans to evolve from legacy infrastructure and processes to modern cloud and open source infrastructure driven by DevOps and Agile processes.
Better processes and tools equal better customer (and employee) satisfaction, lower IT costs, and easier recruiting, with fewer legacy headaches.
In today’s post we will be talking about image creation. If you have been around the cloud game for any length of time, you know how important it can be to get your images right from the outset. It’s important to have all the basics baked in, security settings just right, and users and keys already created. You probably also know, if you have done this by hand, that it can be a huge pain and you just never quite trust your image. The key to mitigating this is having a process to follow for each environment you deploy into and have a set of documented steps that you can point to. Enter Packer. Packer is a tool developed by HashiCorp (the people behind Vagrant) to help you create identical cloud images for a variety of different environments. It also allows you to create image templates that are easy to version control and understand what happens during the image creation process.
Sounds awesome, right? Exactly right. So let’s see it in action in our OpenStack environment!
- In terminal, ensure that you have homebrew setup by issuing brew.
- Add the necessary tap with brew tap homebrew/binary.
- Finally, install packer with brew install packer.
- You can test it’s installed by simply issuing packerin the terminal.
Get OpenStack Ready
I’ll be running Packer against an all-in-one deployment of RDO OpenStack. It’s important to note that in my lab, instances come alive on a private network, then get access to my router’s 192.168.1.0/24 block via floating IPs. This will come in to play a bit later with the Packer template.
- Get a known good image into Glance by importing one of the big distros. I used the Ubuntu 14.04 LTS image found here. You can just put that link into OpenStack Glance’s import dialog. My final dialog looked like this:
- Now, let’s take note of the new image’s UUID, we’ll need that later:
$ nova image-list
| ID | Name | Status | Server
| bf2ad7f1-3823-4ad2-a788-44a25827c93e | cirros | ACTIVE |
| b3a4368b-7368-45e5-bfe4-63f59d732c41 | ubuntu 14.04 | ACTIVE |
Write Packer Template
Okay, time to get busy. Let’s write a template for Packer to create an image with. First, we’ll introduce builders. Builders are the different cloud environments that Packer supports. There are several different supported environments, but I will focus only on OpenStack for now. Let’s gather some info about our OpenStack setup.
- Get your keystone info by catting out your keystone credentials file. For me, this was cat keystonerc_admin.
$ cat keystonerc_admin
export PS1='[\u@\h \W(keystone_admin)]\$ ‘
- Create a new json file somewhere on your machine. I simply called mine json.
- There’s a lot of options for OpenStack in Packer (found here). Some of this will vary by the way your particular OpenStack deployment is set up, but for me, this template contains all of the necessary basic fields:
“image_name”: “Packer Test Image”,
Notes about what’s what:
- username & password: Map to OS_USERNAME and OS_PASSWORD from source file
- provider: Maps to OS_AUTH_URL
- region: Maps to OS_REGION_NAME
- source image: UUID of the Ubuntu image we talked about earlier
- flavor: UUID of my m1.tiny flavor. Beware, this changes on any flavor update!
- networks: UUID of my private network. Can be an array of several networks.
- use_floating_ip: Allocates a floating IP and attaches to the instance. This is necessary in my environment so that I can actually SSH into the instance across the network.
If you need to run some commands against the Openstack API to discover your UUIDs, you can refer to the CLI Guide to help.
Let’s see if this thing will actually create an image for us.
- Save your template if you haven’t already.
- Validate the template to make sure there aren’t any glaring errors with packer validate NAME_OF_TEMPLATE.json. This should return the text ‘Template validated successfully.’
- Run the template with packer build NAME_OF_TEMPLATE.json. For me, this gave the following output when everything completely worked:
$ packer build packer_template
openstack output will be in this color.
==> openstack: Creating temporary keypair for this instance…
==> openstack: Waiting for server (82db25b2-e1a5-4aef-be4a-cfccf744e103) to become ready…
==> openstack: Created temporary floating IP 192.168.1.204…
==> openstack: Added floating IP 192.168.1.204 to instance…
==> openstack: Waiting for SSH to become available…
==> openstack: Connected to SSH!
==> openstack: Creating the image: Packer Test Image
==> openstack: Image: 70a610e9-302a-40f4-a4ca-59b6ad260e63
==> openstack: Waiting for image to become ready…
==> openstack: Terminating the source server…
==> openstack: Deleting temporary keypair…
Build ‘openstack’ finished.
- Nice! Seemed to work. Now if we head out to the Glance UI, we can see that our shiny new image hanging out!
Well, Now What?
So we’ve built an image with Packer, which is great. But it isn’t actually any different from the Ubuntu image we started with. The real value here comes with building on multiple platforms at the same time and also doing some provisioning to install the necessities before creating the image.
This tutorial won’t be focusing on any other cloud environments, but you can view all of the other builders in the sidebar here. In the meantime, let’s exercise Packer’s “provisioner” functionality by installing Apache and deploying a simple webpage with Bash. Packer supports lots of other provisioners, such as Ansible and Chef, but I’ll stick with some basic bash for now since it is likely more familiar to everyone.
- First, we’ll create a simple bash script to install Apache and write a very simple webpage to /var/www/html/index.html. I called my script ‘provision-apache.sh’.
sudo apt-get update
sudo apt-get install -y apache2
sudo sh -c “echo \”<html><h3>Hello, World</h3></html>\” > /var/www/html/index.html”
- Next, we will edit our template to make use of our new provisioning script. We will also call our new image “Packer Webserver Image”. Here’s the template:
“image_name”: “Packer Webserver Image”,
- Finally, go ahead and run this through the ‘packer build’ command and you will again see a new image in the Glance UI. This image will spin up with an Apache server preinstalled and ready to serving our web page for us!
That wraps up this post. I hope you found my tutorial on using Packer to be helpful. I also encourage you to read up on other cloud builders you may wish to use as well as explore the variety of different options with provisioners. This tool really takes a lot of the pain out of image building and I hope you get to add it to your toolbox. Feel free to reply below with any questions/concerns.
Author: Spencer Smith