PowerVC: Image customization with Hashicorp Packer — Part 1

Ole Kristian Myklebust
Possimpible
Published in
10 min readFeb 26, 2021

Create custom image templates with Hashicorp Packer.

https://www.packer.io/ and https://ibm.com

I have been using Packer for some years now, and I was curious if we could use it against PowerVC as it is OpenStack based, and Packer does have an OpenStack builder so let us try.

So what is Packer?
Packer is an open-source tool for creating identical machine images for multiple platforms from a single source configuration. Packer is lightweight, runs on every major operating system, and is highly performant, creating machine images for multiple platforms in parallel. Packer does not replace configuration management like Ansible or Chef. In fact, when building images, Packer can use tools like Ansible to install software onto the image.

So I will try to cover how to make a simple example to customize existing images on your PowerVC. And as I tend to create too long articles, I will make this article a little shorter, and create a part 2 where I make it more dynamically and use Ansible.

Things to Know About Packer 📦

Template: Templates are the configuration files for Packer Images written in JSON format. Thepacker build command runs the builds defined in the template, creating the custom images.

Builders: builders is an array of objects that Packer uses to generate machine images. Builders create temporary PowerVC resources as Packer builds the source VM based on the template.

Provisioners: Provisioners can be used to pre-install and configure software within the running VM before turning it into a machine image. There can be multiple provisioners in a Packer template.

Variables: Variables block contains any user-provided variables that packer uses to create image. You can parameterize the packer template by configuring variables from the command line, storing them in a separate JSON or HCL file, or environment variables.

Packer Workflow

To get an overview of how a packer workflow for building a PowerVC image could look like I create this diagram.

Packer Build Steps: 🎯

To build on the diagram above, it can be practical to know what the Packer Openstack builder does step by step.

  • Authentication. The user is authenticated and scoped to a project in their domain.
  • Launch Server. Starts a server with the supplied image id and flavor
  • Allocate IP. Attempts to release an IP from the PowerVC pool or DHCP
  • Wait for SSH. Keep trying to ssh to the server.
  • Run Provisioners. Run whatever provisioner(s) you have configured. This step will wait until provisioning is completed before it continues.
  • Stop Server. The server is stopped so we safely create an image.
  • Create Image. An image creation
  • Delete Server. The server is deleted.
  • Other Steps (based on options)
    - Updating image visibility to shared, private
    - Updating image tags
  • Post-Processor. Run post-processors on the final image (optional)

Got it? Let's start building some image👷

Prereqs: ✅

  • This is tested on PowerVC 2.0 with HMC and PowerVM based.
  • I use Spectrum Virtualize Storage. (SVC) with Brocade Switches.
    I guess that this should also work fine with Shared Storage pool and other storage systems as longs it’s working inside PowerVC.
  • VM Image to use. (Se my other Articles on how to Import Create/Image)
  • Workstation to use Packer on.
  • Network access to PowerVC.
  • User and Password with the right permissions to create images on PowerVC.
  • Tenant/Project inside PowerVC.

Installing Packer

Packer can be downloaded from the official website (currently here ) and you’ll need to unzip it.

For Linux 64bits

wget https://releases.hashicorp.com/packer/1.7.0/packer_1.7.0_linux_amd64.zip
unzip packer_1.7.0_linux_amd64.zip

Power Linux ppc64le

wget https://releases.hashicorp.com/packer/1.7.0/packer_1.7.0_linux_ppc64le.zip

Print a colon-separated list of locations in your PATH.

echo $PATH

Move the Packer binary to one of the listed locations. This command assumes that the binary is currently in your downloads folder and that your PATH includes /usr/local/bin, but you can customize it if your locations are different.

mv ~/Downloads/packer /usr/local/bin/

After installing Packer, verify the installation worked by opening a new command prompt or console and checking that packer is available:

For Mac you can use HomeBrew or the same method as Linux

  • First, install the HashiCorp tap, a repository of all our Homebrew packages.
brew tap hashicorp/tap
  • Now, install Packer with hashicorp/tap/packer.
$ brew install hashicorp/tap/packer

Install jq (Optional)

jq is a command-line tool for parsing JSON document. It’ll be used to gather information.

apt-get install jq
yum install jq
brew install jq

Fetch your openvcrc configuration

Fetch your powervcrcpowervcrc configuration file. You can fetch it from PowerVC server /opt/ibm/powervc/powervcrc

This will include some information that we need: (mine is shortened down )

export OS_AUTH_URL=https://powervc01:5000/v3/
export OS_PROJECT_DOMAIN_NAME=Default
export OS_PROJECT_NAME=ibm-default
export OS_TENANT_NAME=$OS_PROJECT_NAME
export OS_USER_DOMAIN_NAME=Default
export OS_USERNAME=root
export OS_PASSWORD=password

Collect some more information:

Fetch the Image ID you want to use with openstack image list

[root@powervc01 ~]# openstack image list
+ — — — — — — — — —— — — — — — — — -+ — — — — +
| ID | Name | Status |
+ — — — — — — — — — — —— — — — — — — — — -+ — — — — - - - - - - -+
| 3aaf8bd4–45bd-4468-bae8–42efde242018 | rhel-83–100221 | active |
+ — — — — — — — — — — — — — — — — — — — + — — — — — — — — — — — -+ —

Optional: you can run openstack image list with JSON query after image name: mine is: rhel-83–080221

SOURCE_ID=`penstack image list -f json | jq -r '.[] | select(.Name == "rhel-83-080221") | .ID'06fbc93a-8290-4660-87c9-eacf9e3fa6e8

Find your flavor: (compute template size) openstack flavor list

root@powervc01 ~]# openstack flavor list
+ — — — — — — — — — — — — — — — — — — — + — — — — — — — — — — — — — — — — — + — — — — + — — — + — — — — — -+ — — — -+ — — — — — -+
| ID | Name | RAM | Disk | Ephemeral | VCPUs | Is Public |
+ — — — — — — — — — — — — — — — — — — — + — — — — — — — — — — — — —
| 0c77ba54–9770–4eff-8c50–8e8f0008cbde | tiny | 4096 | 0 | 0 | 1 | True |

Find your network ID: openstack network list

# openstack network list 
+ — — — — — — — — — — — — — — — — — — — + — — — — — — — -+ — — — — —
| ID | Name | Subnets |
+ — — — — — — — — — — — — — — — — — — — + — — — — — — — -+ — — — — —
| 007db6af-8149–433c-a945-c66aea39abc2 | Network-VLAN5 |

Optional: you can also set your options as environment variables.

SOURCE_ID=`openstack image list -f json | jq -r '.[] | select(.Name == "RedHat") | .ID'`FLAVOR_ID=`openstack flavor list -f json | jq -r '.[] | select(.Name == "tiny") | .ID'`NETWORK_ID=`openstack network list -f json | jq -r '.[] | select(.Name == "VLAN5") | .ID'`

So now we should have the information to fill into the openstack.pkr.hcl file

I will use the default tenant.

identity_endpoint       ="https://powervc01.oslo.forum.com:5000/v3/"
tenant_name = "ibm-default" # Default Tenant
password = "password" # PowerVC password
username = "root" # PowerVC User
domain_name = "Default" # This is set from PowerVC
flavor = "tiny"
insecure = "true"
networks = ["007db6af-8149-433c-a945-c66aea39abc2"]
ssh_password = "password" # OS SSH Password
ssh_username = "root" # OS SSH Username
ssh_timeout = "10000s" #So that packer don't timeout
source_image = "6f074476-3af0-4b70-afa7-617bd35db206"
image_name = "image-built-by-packer"
image_tags = ["test-tag"] # Can set tags on the image
image_visibility = "shared" # Public, Shared, Private

The example below uses packer HCL language (not JSON) and it will create a new VM from the source_image with the specified flavour. And then it will run the shell provisioner that sets timedatectl.

When the task is completed the VM is shutdown and removed, and the disk is used as an image and is available in PowerVC.

Note:
-
IP is collected from PowerVC IP Pool or DHCP.
- Packer will use the Default Storage provider and Connectivity Group in PowerVC

To see other Openstack options, check out the Packer Openstack Page
There is a lot of options there, however, some of those options will not work with PowerVC as it doesn't have all the function that Openstack Provide.

I don’t have a clear overview of all function but see my notes below on options that I tested, but did not work.
(Have not tested this in a PowerVC with NovaLink environment)

Let’s Build 🚧

Create the file openstack.pkr.hcl and change it to fit your environment.

If you don't want to write down your password, export the variables and remove them from the example file above.

export OS_USERNAME=root
export OS_PASSWORD=password

Run packer validate to check your files:

packer validate openstack.pkr.hcl

Everything god❓

Then build the image: 👷

packer build openstack.pkr.hcl

Output:

openstack.autogenerated_1: output will be in this color.==> openstack.autogenerated_1: Loading flavor: tiny
openstack.autogenerated_1: Verified flavor. ID: 0c77ba54-9770-4eff-8c50-8e8f0008cbde
==> openstack.autogenerated_1: Not using temporary keypair
==> openstack.autogenerated_1: Launching server...
==> openstack.autogenerated_1: Launching server...
openstack.autogenerated_1: Server ID: 621b1751-fd68-4696-8cf1-3d0d72db81cd
==> openstack.autogenerated_1: Waiting for server to become ready...
openstack.autogenerated_1: Floating IP not required
==> openstack.autogenerated_1: Using ssh communicator to connect: 10.x.x.160
==> openstack.autogenerated_1: Waiting for SSH to become available...
==> openstack.autogenerated_1: Connected to SSH!
==> openstack.autogenerated_1: Provisioning with shell script: /var/folders/9j/j_1c861x3vg459pgb60p60j40000gn/T/packer-shell586153547
==> openstack.autogenerated_1: + sudo timedatectl set-timezone UTC
==> openstack.autogenerated_1: Stopping server: 621b1751-fd68-4696-8cf1-3d0d72db81cd ...
openstack.autogenerated_1: Waiting for server to stop: 621b1751-fd68-4696-8cf1-3d0d72db81cd ...
==> openstack.autogenerated_1: Creating the image: test-image-packer
openstack.autogenerated_1: Image: 9dc0a91c-2f60-4167-892b-2bb33f82a77e
==> openstack.autogenerated_1: Waiting for image test-image-packer (image id: 9dc0a91c-2f60-4167-892b-2bb33f82a77e) to become ready...
==> openstack.autogenerated_1: Updating image tags to test-tag
==> openstack.autogenerated_1: Updating image visibility to shared
==> openstack.autogenerated_1: Terminating the source server: 621b1751-fd68-4696-8cf1-3d0d72db81cd ...
==> openstack.autogenerated_1: Running post-processor: (type manifest)
Build 'openstack.autogenerated_1' finished after 13 minutes 59 seconds.

You can list them with the following command: openstack image list

openstack image list --name image-built-by-packer+ — — — — — — — — — — — — — — — — — — — + — — — — — — — — — — — — — 
| ID | Name | Status |
+ — — — — — — — — — — — — — — — — — — — + — — — — — — — — — — — — —
| 0d0ea52c-0b53–46f6-af94-eb493a52b237 | image-built-by-packer | active |
+ — — — — — — — — — — — — — — — — — — — + — — — — — — — — — — — — —

List with more information use --longoption

openstack image list --name image-built-by-packer --long+ — — — — — — — — — — — — — — — — — — — + — — — — — — — — — — — — — 
| ID | Name | Disk Format | Container Format | Size | Checksum | Status | Visibility | Protected | Project | Tags |
+ — — — — — — — — — — — — — — — — — — — + — — — — — — — — — — — — —
| 0d0ea52c-0b53–46f6-af94-eb493a52b237 | image-built-by-packer | raw | bare | 1 | c4ca4238a0b923820dcc509a6f75849b | active | private | False | 424319879ebb42d8b8455fe345d93bdf | test-tag |
+ — — — — — — — — — — — — — — — — — — — + — — — — — — — — — — — — —

God to know:

Projects:

If you want to “move” an image to a certain project, then you can use the image set command:

openstack image set --private --project test-project 0d0ea52c-0b53–46f6-af94-eb493a52b237

If you want all project to see the image, set it to Public.

openstack image set --public --project test-project 0d0ea52c-0b53–46f6-af94-eb493a52b237

Image Comments

The existing powervc_comments field will be copied over to the new images.
I run the openstack image show <imageid>it will have a powervc_comments value.

Example: I check this with a JSON query.

openstack image show -f json 6f074476-3af0-4b70-afa7-617bd35db206 | jq '.properties.powervc_comments'"rhel83 created with pvsadm 080221-1800"

If haven’t found a way to set powervc_comments in packer when building.
(maybe we can use the metadata option?)

Anyway, to set a new description/comments on the image manually.

openstack image set --property powervc_comments=’test-images-packer’ 0d0ea52c-0b53–46f6-af94-eb493a52b237

Ta-da 🎉 🏁 🎏

You should now be able to start using your image 📸
As I said earlier, I will follow up with a more dynamic example using variables and Ansible as Provisioner.

Packer Build Options:

image_members
When I use image_members I get the error: “Not allowed to create members for image“
This is to create images for the different tenant by changing tenant_name but using the same UserName and Password.

Tried to use different image_visibility: shared and private

"image_members": ["test-project"],

volume_*

Not sure if I use the options volume correctly, but options don't seem to be picked up, if don’t use the option use_blockstorage_volume.

"use_blockstorage_volume": true,"volume_name": "test-volume",
"volume_type": "e76737d3-6c57-47bc-8b0c-4220fa2690cf"

Then the volume name was picked up and the name on svc was set, but I got an error from PowerVC as described below: have not investigated more on this.

An error occurred while performing a storage operation for the volume test-volume-name. Explanation: Failed to copy image to volume: Bad or unexpected response from the storage volume backend API: Unable to fetch connection information from backend: ‘NoneType’ object has no attribute ‘get’

I’m not sure if Volume_ Option is a big problem, as we can use PowerVC also help us with naming.

--

--

Ole Kristian Myklebust
Possimpible

Nerd, Loves the mountains and all that come with it. IBMer that works for IBM Lab Services. My own Words and opinion.