RHEL OS Image Builder (part two)
This is part 2 of the blog series. Part one is here.
In part one, we setup the tooling to allow us to create RHEL OS Images. I've just noticed that the RHEL System Roles now includes a role for installing and configuring Image Builder, which is neat and makes it even easier to get started - checkout https://github.com/linux-system-roles/image_builder
In this article, we're now going to create some images.
This is basically a two stage process involving:
- Creating a template definition for our image contents, or blueprint, and,
- Creating an image from the blueprint
Creating a Blueprint
You can use the RHEL cockpit GUI if installed to guide you through this (I didn't install it in part one, but the system role will do it for you and configure the firewall as well if asked). But, it's just as easy to create a file by hand. As I want to automate the process and builds, then this latter route is for me.
We just need to create a .toml file somewhere on the server, and pass this to the image builder (using composer-cli). Nice and simples.
Here's a basic sample to get you started with:
# cat phil8-base.toml name = "phil8-base" description = "My initial image builds" version = "0.0.1" modules = [] [[groups]] name = "Minimal Install" [[packages]] name = "wget" version = "*" [customizations] hostname = "newbuild8" [[customizations.user]] name = "automation" description = "Default Automation Account for new builds" password = "$6$h.WqG3YoD3idasgdsgwerlC$5wnFoSZJsh5SipbxAQ2MFkl8hNhTvXPx9KSPi.W7vhWXInjfCHcs8LWFJDx7WxfasdfadsfasDJK0m2AbJdAmN7JZ7vJy1" key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC2t8OtfJ7Qiv2i/qYBoPsgGeiZHpDu+1ERl6htVGPxmW8apgCS6PlbnqdIlyCkKqBnTTV3tvUhrjTBGcXsQhr+Dveem+Tb9dwWowP/ONVrMs5x1TiEhokP+sgskgsg+asfdsafasfasf+03DiJwmrwyTK3CW8Gei3LhTeu+qK0o34ozss1jBaRwM58oMbeGSGKT3RKycZ2tWB/SLzrae30VqumLOHHv/2YxJNKj/mbh/GykWrINbBmYz5bXpNI2BI70wL1He2hYqikvqNUVJ8hBaIeGT5PxL6H9WDX1FbT6r4MP"
[For complete documentation, checkout https://weldr.io/lorax/composer-cli.html#blueprint-reference]
In the top section, we specify kind of 'metadata' about the build. It's important to get your name convention in order to start with, as the image builder uses this as a base for furthering naming of things, so give it more thought than I have here!
The version should be incremented for each build change, and uses the semver format, of X.Y.Z. This way you can use composer-cli blueprints diff/changes for potted history changes.
Under [[groups]] we can specify the packages groups if we want things like a minimal build, or development tools etc. [Tip: you can use 'dnf group list' on a server to see the options available]
If I then want supplementary tools, I can add them into the [[packages]] section.
Under [[customizations*]] we can do all sorts of things as part of the build. You could do this here, or use Ansible etc after to do the post configuration standards. I've included what I consider the real basics to get me up and running and allow my automation tooling to connect and do the rest.
I set hostname to something which I can easily identify in my Ansible inventory. The idea is for Ansible to pick up all new host builds and configure them with proper hostnames etc and disappear off the build list.
I ensure I have a default account baked into the image so I can use this for my first pass automation needs under [[customizations.user]]. You can set an encrypted password here or just the SSH public key if you like.
There are other customisations you can do like timezones, firewall and services if you need. I'm going to see if I can get away with leaving these out for now, but may need to revisit. Evolution not revolution :)
Using The Blueprint
The blueprint can now be pushed to the server so we can consume it. If you've got something wrong in the template it'll tell you, otherwise it'll be silent.
composer-cli blueprints push phil8-base.toml composer-cli blueprints list composer-cli blueprints show phil8-base
We're ready to build :)
We need to know what format our target provider uses, and then select one of the supported ones:
composer-cli compose types
ami <--- Amazon openstack qcow2 rhel-edge-commit tar vhd <--- Azure
vmdk <--- Vmware
We'll build an image for Microsoft Azure, so:
composer-cli compose start phil8-base vhd Compose 89427f8f-99c5-43e7-8a2f-dafe9bcd253d added to the queue
You'll get back a UUID for the build, which goes onto a build queue. Now one must wait until image builder has done its thing:
composer-cli compose status | grep 89427f8f-99c5-43e7-8a2f-dafe9bcd253d 89427f8f-99c5-43e7-8a2f-dafe9bcd253d FINISHED Wed Jan 13 13:59:41 2021 phil8-base 0.0.6 vhd 4294967296
A little bash script could help us out here:
cat > checkbuild.sh<<EOF #!/bin/env bash if [ -z $1 ] then echo "Pass me a UUID to check" exit 99 else UUID=$1 fi until composer-cli compose status | grep ${UUID} | grep FINISHED >/dev/null 2>&1 do sleep 10 done echo "BUILD DONE!" EOF chmod +x checkbuild.sh ./checkbuild.sh 89427f8f-99c5-43e7-8a2f-dafe9bcd253d [time passes...] BUILD DONE!
The server has finished the image build, so now we can download it:
composer-cli compose image 89427f8f-99c5-43e7-8a2f-dafe9bcd253d 89427f8f-99c5-43e7-8a2f-dafe9bcd253d-disk.vhd: 4096.00 MB
What Now?
So now we've got the image builder tooling installed, have a blueprint template and can generate images for various platforms.
At this point, we need to upload our images to the target provider so we can generate VMs from it. This is platform dependent, and will require cloud credentials and other permissions.
At this point it would be ideal to have an automation platform in place, so we could centrally store and manage credentials, source code etc and put access controls around generation/use.
Cue part 3.
TO BE CONTINUED!
Principal Consulting Engineer, ITC Messaging, CTC Over ITCM, Positive Train Control (PTC)
1 年Good one. Thanks for sharing. how does the blueprint you have here pick the version of the base OS?.