PowerVC: Image customization with Hashicorp Packer — Part 1
Create custom image templates with Hashicorp Packer.
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 powervcrc
powervcrc 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 --long
option
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.