Hi friends!

Today’s blog post has to do with every sysadmin’s favorite task, baking images (insert sarcasm). In particular we’re going to talk about how to use Packer to bake images for Rackspace Public Cloud, and Private Openstack Cloud.

NOTE: Assume we are using Packer version v0.7.5

Packer by HashiCorp

Baking Rackspace Public Cloud Images

The common issue I discovered with baking openstack images is that it is super easy to set MORE environment variables than needed. Setting too many can cause packer builds to fail with strange error messages. For example, as noted in this packer git issue:

# source: https://github.com/mitchellh/packer/issues/1755
I've been trying with no success to use Packer to build an image with Rackspace. Currently here is my config:

{
  "variables": {
    "rackspace_username": "",
    "rackspace_password": ""
  },
  "builders": [
    {
      "type": "openstack",
      "username": "",
      "password": "",
      "provider": "rackspace-us",
      "region": "IAD",
      "ssh_username": "root",
      "image_name": "Test image ",
      "source_image": "ea98e34c-7a25-4670-9e2a-7fa9815f6c9f",
      "flavor": "2"
    }
  ],
  "provisioners": [
    {
      "type": "shell",
      "inline": [
        "sleep 30",
        "sudo apt-get update",
        "sudo apt-get upgrade -y"
      ]
    }
  ]
}
But when I run:

packer build -var "rackspace_username=foo" -var "rackspace_password=bar" test.json
I get:

openstack output will be in this color.

Build 'openstack' errored: Auth failed. Bad credentials.

==> Some builds didn't complete successfully and had errors:
--> openstack: Auth failed. Bad credentials.

==> Builds finished but no artifacts were created.
Any ideas?

If you look closely at the packer documentation, you’ll notice that both the OS_* and SDK_* env variables have different “weights” associated with them, meaning if you set too many at the same time, they can override each other. Rule of thumb is SDK_* has more presidence than OS_*.

I put the following into a small script full of environment variable named local-public.sh with contents:

export SDK_USERNAME="BLAH"
export SDK_PASSWORD='BLAH'
export SDK_API_KEY='BLAH'
export SDK_PROVIDER="rackspace-us"
export SDK_REGION="DFW"

NOTE: Notice for Rackspace Public Cloud I used only SDK_* environment variables.

Then in a new bash shell I ran source ./local-public.sh

Following that, I created a template that looks something like this:

{
  "variables": {
    "SSH_PASSWORD": "",
    "REGION": "us-east-1",
    "INSTANCE_TYPE": "m3.large",
    "SSH_USERNAME": "centos",
    "SSH_TIMEOUT": "5m"
  },
  "builders": [
    {
      "type": "openstack",
      "name": "rackspace-public",
      "username": "",
      "password": "",
      "api_key": "",
      "provider": "rackspace-us",
      "openstack_provider": "rackspace",
      "region": "DFW",
      "ssh_username": "root",
      "insecure": "false",
      "image_name": "centos66-",
      "source_image": "blah",
      "flavor": "performance1-1"
    },

NOTE: Notice I did not set any password/etc in the actual template. Packer reads in directly from your environment and populates everything accordingly.

Now packer build -only=rackspace-public openstack-centos66.json And boom! Good to go!

Baking Private Openstack Cloud

The steps for creating a private Openstack cloud image are very similar, but might require a little bit more information on your Openstack setup. Make sure you know how to query it for what you need!

I put the following into a small script named local-private.sh with contents:

# Source: https://www.packer.io/docs/builders/openstack.html

export OS_AUTH_URL="http://OPENSTACK_AUTH_IP_ADDRESS:PORT/v2.0"
export OS_USERNAME="BLAH"
export OS_PASSWORD="BLAH"
export OS_TENANT_ID="BLAH"

# should be the same as OS_USERNAME
export OS_TENANT_NAME="BLAH"
export OS_AUTH_STRATEGY="keystone"

NOTE: Notice for private openstack I used only OS_* environment variables.

Then in a new bash shell I ran source ./local-private.sh, make sure you don’t have any SDK_* variables set!!!!

Following that, I created a template that looks something like this:

{
  "variables": {
    "SSH_PASSWORD": "",
    "REGION": "us-east-1",
    "INSTANCE_TYPE": "m3.large",
    "SSH_USERNAME": "centos",
    "SSH_TIMEOUT": "5m"
  },
  "builders": [
    {
      "type": "openstack",
      "name": "rackspace-private",
      "insecure": true,
      "networks": "gfhjghfjgfhjhgf-gfjgfhjgh-fghjghfj-gfhjgfhj-gjh",
      "ssh_username": "",
      "image_name": "centos66-",
      "source_image": "gfhgfh-ghfhfg-4ac4-aghgfh74c-6575677",
      "flavor": "2"
    }
  ],

Now packer build -only=rackspace-private openstack-centos66.json and boom, private openstack image! Hope this helps someone! Feel free to tweet me if you have any questions / suggestions!