Ansible role rhel_iso_kickstart
Table of contents
Preface #
I have been playing around with the idea of writing a blog post series about my Ansible roles for quite a while now. Not only to ‘promote’ my Ansible roles, but also to show case how extremely flexible Ansible really is. Often times people think of Ansible as “just another configuration management tool”. While this is absolutely true, Ansible - in my opinion - is so much more than that. Ansible is great in automating a series of tasks across multiple systems - that is really the strength of Ansible.
To disclose it right away: I am working at Red Hat as Senior Technical Account Manager Ansible - so please take the above with a grain of salt, as I am most probably biased.
With that being said, let’s dive into my Ansible role rhel_iso_kickstart
Introduction #
I regularly deploy new Red Hat Satellite instances - for testing purposes. Or when I broke one of the Satellite instances (again) while playing around a bit too much. Or when I (once again) move to a new server or basically revamp my complete infrastructure. So you see, I have quite a need for that .
I also noticed that a few of my colleagues had the same need, as well as some of our customers. I couldn’t find an existing automated way of downloading a given RHEL
ISO image
and implanting a Kickstart into it, while also allowing to customize certain things, such as enabling
FIPS
.
So I decided, I’ll just write an Ansible role for everybody to use to ease this regular task.
Prerequisite: Obtaining an API token to authenticate to the Red Hat Customer Portal #
First off, to download an ISO image
from the Red Hat Customer Portal you need to be a Red Hat subscriber. If you don’t own any subscriptions,
you can make use of Red Hat’s Developer Subscription which is provided at no cost by Red Hat.
Once you created your account and are able to download from the Red Hat Customer Portal, you need to create an API Token, which we’ll use to authenticate to the Red Hat Customer Portal. For that, simply login to Red Hat’s Customer Portal and create an API Token.
Note down that token, as we are going to need it for the role to function.
Prerequisite: Obtaining the checksum of an ISO image
to download #
The Red Hat Customer Portal API enables downloading of ISO images
only by checksum. To download an ISO image
, you first need to identify the checksum to pass to the
role. This checksum can be retrieved for any ISO image
on the Red Hat Customer Portal and can be found on the respective download page of the ISO image
itself.
For RHEL you can visit https://access.redhat.com/downloads/content/rhel and simply click on Show details. As an example, the Red Hat Enterprise Linux 8.8 Binary DVD will show the following additional details:
File name: rhel-8.8-x86_64-dvd.iso
File Size: 11.7 GB
SHA-256 Checksum: 517abcc67ee3b7212f57e180f5d30be3e8269e7a99e127a3399b7935c7e00a09
Last Updated: 2023-04-26
We are going to need the SHA-256 Checksum
.
Installation #
Installation is easy and straight forward. I tag my Role releases using semantic versioning on GitHub. Installing a specific tag works through providing
a requirements.yml
to the ansible-galaxy
command.
If you’d want to install v2.0.0 of my Role, you could use the following requirements.yml
:
---
roles:
- name: 'rhel_iso_kickstart'
src: 'https://github.com/sscheib/ansible-role-rhel_iso_kickstart.git'
scm: 'git'
version: 'v2.0.0'
Installing it is as easy as that:
ansible-galaxy role install -r requirements.yml
A deeper look into the role #
So what actually does this role?
The role does the following:
- Download a RHEL
ISO image
to your local filesystem - that can be your local machine or a server in a data center - Optional: Unpack the
ISO image
- Optional: Add a custom Kickstart or the Kickstart shipped with the role to the unpacked
ISO image
- Optional: Adjust the Kickstart to set a root password, create users and add custom
%post
sections - Optional: Validate the Kickstart using
ksvalidator
- Optional: Adjust the kernel parameters to load the Kickstart automatically
- Optional: Enable
FIPS
in the kernel parameters - Optional: Adjust the timeout of GRUB, so you don’t have to wait 60 seconds for the installation to start
- Optional: Adjust the GRUB menu entry to use; Either validate the
ISO image
before installing or directly install it - Optional: Create the actual
ISO image
- Optional: Make the
ISO image
bootable onBIOS
andUEFI
systems - Optional: Implant an MD5 sum so it can be checked during booting
TL;DR: Quite a lot.
Chances are that you do not need or want to use certain features of the role, such as enabling FIPS
. Then I have good news for you: All steps but the very first are optional
and can be configured through variables.
Use cases #
I have identified three major use cases for the role:
- Only download an
ISO image
, don’t touch it - Download the
ISO image
and enableFIPS
, so you don’t have to do it manually every time before thISO image
boots, but do not perform any other changes to theISO image
- Embed a customized Kickstart into the
ISO image
to use it for unattended installing
I am sure, there plenty of other use cases I haven’t thought of yet. If you happen to have a different use case, consider contributing with a feature request or simply comment on this blog post
Now, let’s take look at the above use cases and how to configure the role to achieve each of them.
Downloading an ISO image
#
Downloading the ISO image
is the easiest of the three use cases. You’ll only need to configure:
- Which
ISO image
to download - Where to download it to
- The permissions of both the download directory and the
ISO image
- Provide the API token to authenticate against the Red Hat Customer Portal
An example of a playbook could look something like this:
- hosts: 'localhost'
gather_facts: false
roles:
- name: 'rhel_iso_kickstart'
vars:
# the checksum of a RHEL 8.8 ISO to download from the Red Hat Customer Portal
checksum: '517abcc67ee3b7212f57e180f5d30be3e8269e7a99e127a3399b7935c7e00a09'
download_directory: '/home/steffen/workdir'
download_timeout: '3600'
download_directory_owner: 'steffen'
download_directory_group: 'steffen'
download_directory_mode: '0755'
iso_owner: 'steffen'
iso_group: 'steffen'
iso_mode: '0600'
api_token: !vault |
$ANSIBLE_VAULT;1.1;AES256
[..]
Downloading an ISO image
and enabling FIPS
for the ISO image
#
Enabling FIPS
on top of downloading the image is not much more complicated. You need to configure the following:
- Which
ISO image
to download - Where to download it to
- The permissions of both the download directory and the
ISO image
- Provide the API token to authenticate against the Red Hat Customer Portal
- Disable Kickstart validation
- Specify a temporary work directory and the permissions to it
- Specify a temporary mount path to mount the original downloaded
ISO image
(to extract it’s content) - Destination path to the custom
ISO image
along with the permissions of it - Enabling the option to enable
FIPS
- Enabling the option to recreate the custom
ISO image
every time - Enabling the option to implanting an MD5 checksum which can be checked during booting
An example playbook could look something like this:
- hosts: 'localhost'
gather_facts: false
roles:
- name: 'rhel_iso_kickstart'
vars:
# the checksum of a RHEL 8.8 ISO to download from the Red Hat Customer Portal
checksum: '517abcc67ee3b7212f57e180f5d30be3e8269e7a99e127a3399b7935c7e00a09'
download_directory: '/home/steffen/workdir'
download_directory_owner: 'root'
download_directory_group: 'root'
download_directory_mode: '0755'
iso_owner: 'root'
iso_group: 'root'
iso_mode: '0600'
validate_kickstart: false
temporary_mount_path: '/mnt'
temporary_work_dir_path: '/home/steffen/workdir'
temporary_work_dir_path_owner: 'root'
temporary_work_dir_path_group: 'root'
temporary_work_dir_path_mode: '0755'
temporary_work_dir_source_files_path: 'src'
temporary_work_dir_source_files_path_owner: 'root'
temporary_work_dir_source_files_path_group: 'root'
temporary_work_dir_source_files_path_mode: '0755'
dest_dir_path: '/home/steffen/workdir'
custom_iso_owner: 'root'
custom_iso_group: 'root'
custom_iso_mode: '0755'
force_recreate_custom_iso: true
implant_md5: true
enable_fips: true
api_token: !vault |
$ANSIBLE_VAULT;1.1;AES256
Download a RHEL ISO image
, implant a Kickstart, create users, add custom %post
sections, implant an MD5
checksum and enable FIPS
#
This use case leverages basically all the functionality the role offers. It will:
- Download a RHEL
ISO image
- Implant a Kickstart into the
ISO image
- Add create user statements to the Kickstart
- Implant custom
%post
sections, but adding to the default ones - Configure SSH keys for the users that are created
- Implant a MD5 checksum
- Enable
FIPS
A thorough example of the possible usage can be found down below. Some of the variables are redundant, as they merely reflect the defaults already set, but I wanted to show what can be changed.
Example playbook:
---
- hosts: 'localhost'
gather_facts: false
roles:
- name: 'rhel_iso_kickstart'
vars:
# the checksum of a RHEL 8.8 ISO to download from the Red Hat Customer Portal
checksum: '517abcc67ee3b7212f57e180f5d30be3e8269e7a99e127a3399b7935c7e00a09'
download_directory: '/home/steffen/workdir'
download_timeout: 3600
kickstart_path: 'example.ks'
validate_kickstart: true
ksvalidator_package_name: 'pykickstart'
temporary_mount_path: '/mnt'
temporary_work_dir_path: '/home/steffen/workdir'
temporary_work_dir_path_owner: 'root'
temporary_work_dir_path_group: 'root'
temporary_work_dir_path_mode: '0755'
temporary_work_dir_source_files_path: 'src'
temporary_work_dir_source_files_path_owner: 'root'
temporary_work_dir_source_files_path_group: 'root'
temporary_work_dir_source_files_path_mode: '0755'
dest_dir_path: '/home/steffen'
xorriso_package_name: 'xorriso'
isolinux_bin_path: 'isolinux/isolinux.bin'
boot_cat_path: 'isolinux/boot.cat'
pxelinux_cfg_path: 'isolinux/isolinux.cfg'
grub_cfg_path: 'isolinux/grub.conf'
download_directory_owner: 'steffen'
download_directory_group: 'steffen'
download_directory_mode: '0755'
cleanup_iso: false
cleanup_work_dir: false
iso_owner: 'steffen'
iso_group: 'steffen'
iso_mode: '0600'
custom_iso_owner: 'root'
custom_iso_group: 'root'
custom_iso_mode: '0755'
force_recreate_custom_iso: true
grub_menu_selection_timeout: 3
implant_md5: false
implantisomd5_package_name: 'isomd5sum'
quiet_assert: false
enable_fips: true
post_sections: >
{{
_def_post_sections +
[
{
'name': 'Custom %post section',
'template': 'custom_post.j2'
},
{
'name': 'Another %post section',
'template': 'another_post.j2'
}
]
}}
users:
- name: 'ansible-user'
gid: 2000
uid: 2000
gecos: 'Ansible User'
create_user_group: true
groups:
- 'wheel'
shell: '/bin/bash'
home: '/home/remote-ansible'
privileged: true
lock: false
password: !vault |
$ANSIBLE_VAULT;1.1;AES256
[..]
authorized_keys:
- !vault |
$ANSIBLE_VAULT;1.1;AES256
[..]
- !vault |
$ANSIBLE_VAULT;1.1;AES256
[..]
kickstart_root_password: !vault |
$ANSIBLE_VAULT;1.1;AES256
[..]
api_token: !vault |
$ANSIBLE_VAULT;1.1;AES256
[..]
Conclusion #
I hope this role spares you a little time in your day to day work. That’s already it for the time being - I hope you enjoyed it
Change log #
2024-03-11 #
- Adding change log
-
markdownlint
fixes - Spelling fixes