Subscribe to the feed
validated content osbuild blog

Introduction to the Image builder use case

During the last year we met with multiple edge customers, covering the automation needs for IT Linux infrastructure at scale across remote locations where there is often no IT staff on site. Think about retail stores, dark stores and warehouses where self-checkout, handhelds and POS devices hosting RHEL are distributed everywhere. 

For industrial setups and manufacture, this could be the scenario for small factor servers and storage hosting logging monitoring to gather information about operational activities, which are located in secure facilities. 

One of the recurrent needs for our customers with distributed devices is the ability to upgrade Linux devices faster, at scale, mostly due to regulations or security risks. Ideally, you should be able to patch at scale as soon as a vulnerability is identified. 

The main challenge with the traditional RPM patching model is that it is incremental, and frequently some Linux devices might have slight differences. That is why there are new edge-focused capabilities and models that start with the premise that you could and should test a whole base image, and once it passes your validations, it should be deployed into all the target devices that would be located across your remote locations. Something like this:


There were some developments with an osbuild composer, but there wasn’t yet the automation available to deploy the components to automate this use case at scale. That is why the osbuild composer Collection was developed, to provide the automation content needed to build an osbuild server, an Apache HTTPD Server to host images, and a role to build installer images and rpm-ostree updates. All these components will allow you to build rpm-ostree based images for Fedora, Red Hat Enterprise Linux, and CentOS Stream. 

The Ansible Content Collection would automate the deployment of the following architecture:

In this blog we will walkthrough step by step how to use the infra.osbuild Collection to deploy the required components and build a RHEL Edge image using Red Hat Ansible Automation Platform.

Setting the testing environment

To get started using this Collection, we will first login into Ansible Automation Platform.

Before we can create osbuild images, there are a couple of things we need to set up.

Adding an automation execution environment for the osbuild Collection

First we need to create or import an automation execution environment for the osbuild Collection. 

Navigate to the Execution Environments link in the sidebar under Administration. To start creating a new execution environment, click the Add button at the top on the toolbar.There are two required fields and one optional that we will fill out: 

1. The Name field is a familiar name that you can use to distinguish each execution environment. Feel free to put whatever you like under the Name field. I will choose osbuild_ee.

2. The Image field is where the execution environment is hosted. There are many container registries, but we will use for this example. We are going to use a prebuilt osbuild execution environment for this example located at

3. The last field we are going to populate is Pull. This dictates how often Ansible Automation Platform should pull a new copy of the execution environment before running. For this tutorial we are going to select Only pull the image if not present before running.

Your finished execution environment should look something like this:

Once you have the correct information, click Save and we will move on to setting up an inventory.

Adding the Inventory and Hosts

Navigate to the Inventories link in the sidebar under Resources. To start creating a new inventory, click the Add button at the top on the toolbar. 

The only field that needs to be filled is Name because Organization is already prepopulated. For this example I will choose osbuild_inventory. Click Save when you are finished. 

After the inventory has been created. You will be redirected to the Details tab in the inventory you just created. Select the Hosts tab so that we can the remote system IP address that will be used to run osbuild on.

Once there, click the Add button to begin.

Fill out the Name field. In this setup I chose osbuild_remote_system inside the variables text area. Fill out two properties, ansible_host and ansible_user. I will be using a temporary AWS remote system for this example.

Your finished host should look something like this:

Once you have finished, click Save and we can move on to creating a project.

Creating the Project

Navigate to the Project link in the sidebar under Resources. To start creating a new project, click the Add button at the top on the toolbar.

For the Name field I will choose to use osbuild_project

Under the Source Control type we will choose Git. This gives us the ability to import or point to playbooks that are held in a Git repository. For this example I am going to use the infra.osbuild repository on GitHub located here

Feel free to use the same or point to a forked custom repository elsewhere.

Under the Execution Environment field we will populate this with our previously created one, osbuild_ee.

Your finished project should look something like this:

Once you have finished, we are going to do one last setup step before we start putting everything together to create a template to run a job.

Setting up the Credentials

Navigate to the Credentials link in the sidebar under Resources. To start creating a new credential, click the Add button at the top on the toolbar.

The credentials view allows us to store different types of credentials to connect to a variety of remote systems.

Since I’m using AWS for my remote osbuild system. I chose to use osbuild_aws_credential

For the Credential Type field I am going to choose Machine because I want to directly connect to a system. 

For this tutorial setup, I created private and public SSH keys on my local machine. I copied the private SSH key into the field SSH Private Key and the public SSH key is on my remote machine. 

Note: Once I validated that, Ansible Automation Platform and the remote system were able to talk to each other, so I removed the local SSH keys from my machine.

Your finished credential should look something like this:

Note: Ansible Automation Platform will automatically encrypt the credentials and save them in the vault. Now that we have all the configuration setup, we can start creating a template and then run our first job.

Setting up the Credentials

Navigate to the Templates link in the sidebar under Resources. To start creating a new template, click the Add button at the top on the toolbar.

There are many fields that can be filled in to customize the end result of the job, but we are going to focus on the required fields.

Name: osbuild_setup_server

Inventory: osbuild_inventory

Project: osbuild_project

Credentials: osbuild_aws_credential

The last three fields were previously created.

After you fill out those fields, let's move over to the last field: Playbook.

If you properly set up a repository in the project step, you should see several playbooks when you click on the drop down. For example, we used the infra.osbuild GitHub repository in the project, so I’m able to see playbooks/osbuild_builder.yml, playbooks/osbuild_setup_server.yml and playbooks/testbuild.yml as options to choose from.

Since the remote system hasn’t been set up or provisioned with osbuild, let’s choose the osbuild_setup_server playbook.

Your finished template should look something like this:

Click Save and wait for the page to reload. Once reloaded, you will see a Launch button. 

Executing the osbuild roles

Execute the osbuild_setup_server playbook

Let’s go ahead and click Launch and set up our osbuild server.

Once that job finishes successfully, navigate back to the Templates link. 

Execute the osbuild_builder playbook

You should see the previously created template osbuild_setup_server list on the table. This makes things easier for us to run the next playbook. 

Let’s click the copy icon (the two papers stacking upon each other) on our template. This will duplicate all information we just filled out to save us some time. The only thing we need to change is the playbook.

Click on the newly copied template, click Edit, and change the name to osbuild_build_image or something relevant and choose the osbuild_builder playbook in the Playbook field.

Once those changes have been made, click Save and then Launch to start building an image. The detailed output looks like this:

PLAY [Run osbuild_builder role] **********************************************************************************

TASK [Gathering Facts] *******************************************************************************************
ok: [osbuild_remote_system]

TASK [infra.osbuild.builder : Check if ssh key is defined] *******************************************************
skipping: [osbuild_remote_system]

TASK [infra.osbuild.builder : Set fact] **************************************************************************
skipping: [osbuild_remote_system]

TASK [infra.osbuild.builder : Enable Cockpit/Composer/Firewalld/Apache] ******************************************
ok: [osbuild_remote_system]

TASK [infra.osbuild.builder : Add user to weldr group] ***********************************************************
ok: [osbuild_remote_system]

TASK [infra.osbuild.builder : Include enable_custom_repos.yml] ***************************************************
included: /home/santiago/.ansible/collections/ansible_collections/infra/osbuild/roles/builder/tasks/enable_custom_repos.yml for osbuild_remote_system

TASK [infra.osbuild.builder : Loop through the repos to debug them] **********************************************
skipping: [osbuild_remote_system]

TASK [infra.osbuild.builder : Loop through the repos and configure them] *****************************************
skipping: [osbuild_remote_system]

TASK [infra.osbuild.builder : Loop through the RHSM repos to debug them] *****************************************
skipping: [osbuild_remote_system]

TASK [infra.osbuild.builder : Loop through the repos and configure them] *****************************************
skipping: [osbuild_remote_system]

TASK [infra.osbuild.builder : Create a blueprint] ****************************************************************
changed: [osbuild_remote_system]

TASK [infra.osbuild.builder : Push the blueprint into image builder] *********************************************
[WARNING]: Found internal 'results' key in module return, renamed to 'ansible_module_results'.
ok: [osbuild_remote_system]

TASK [infra.osbuild.builder : Check if blueprint directory exists] ***********************************************
ok: [osbuild_remote_system]

TASK [infra.osbuild.builder : Create blueprint directory] ********************************************************
skipping: [osbuild_remote_system]

TASK [infra.osbuild.builder : Initialize repository] *************************************************************
skipping: [osbuild_remote_system]

TASK [infra.osbuild.builder : Start compose] *********************************************************************
ok: [osbuild_remote_system]

TASK [infra.osbuild.builder : Wait for compose to finish] ********************************************************
ok: [osbuild_remote_system]

TASK [infra.osbuild.builder : Create tmp directory for blueprint] ************************************************
changed: [osbuild_remote_system]

TASK [infra.osbuild.builder : Export the compose artifact] *******************************************************
ok: [osbuild_remote_system]

TASK [infra.osbuild.builder : Untar artifact] ********************************************************************
changed: [osbuild_remote_system]

TASK [infra.osbuild.builder : Get checksum from artifact] ********************************************************
ok: [osbuild_remote_system]

TASK [infra.osbuild.builder : Pull commit from artifact] *********************************************************
changed: [osbuild_remote_system]

TASK [infra.osbuild.builder : Commit changes to repository] ******************************************************
changed: [osbuild_remote_system]

TASK [infra.osbuild.builder : Remove tar file] *******************************************************************
changed: [osbuild_remote_system]

TASK [infra.osbuild.builder : Create images directory] ***********************************************************
skipping: [osbuild_remote_system]

TASK [infra.osbuild.builder : Copy image to web dir] *************************************************************
skipping: [osbuild_remote_system]

TASK [infra.osbuild.builder : Create kickstart file] *************************************************************
changed: [osbuild_remote_system]

TASK [infra.osbuild.builder : Restore context on blueprint directory] ********************************************
changed: [osbuild_remote_system]

TASK [infra.osbuild.builder : Include disable_custom_repos.yml] **************************************************
skipping: [osbuild_remote_system]

TASK [infra.osbuild.builder : Create blank blueprint] ************************************************************
skipping: [osbuild_remote_system]

TASK [infra.osbuild.builder : Push the blueprint into image builder] *********************************************
skipping: [osbuild_remote_system]

TASK [infra.osbuild.builder : Start installer compose] ***********************************************************
skipping: [osbuild_remote_system]

TASK [infra.osbuild.builder : Start ostree installer compose] ****************************************************
skipping: [osbuild_remote_system]

TASK [infra.osbuild.builder : Wait for compose to finish] ********************************************************
skipping: [osbuild_remote_system]

TASK [infra.osbuild.builder : Create tmp directory for blueprint] ************************************************
skipping: [osbuild_remote_system]

TASK [infra.osbuild.builder : Export the compose artifact] *******************************************************
skipping: [osbuild_remote_system]

TASK [infra.osbuild.builder : Create images directory] ***********************************************************
skipping: [osbuild_remote_system]

TASK [infra.osbuild.builder : Inject kickstart into iso] *********************************************************
skipping: [osbuild_remote_system]

TASK [infra.osbuild.builder : Copy installer to web dir] *********************************************************
skipping: [osbuild_remote_system]

PLAY RECAP *******************************************************************************************************
osbuild_remote_system           	: ok=18   changed=8	unreachable=0	failed=0	skipped=21   rescued=0	ignored=0

Takeaways and next steps

As shown above, with the help of the Ansible validated content for infrastructure osbuild Collection, you can easily deploy the osbuild components and build a RHEL Edge image for your edge deployments. 

If you want to learn more about Ansible Automation Platform and edge automation, you can check out these resources:

You can read also some e-books:

Join us at Red Hat Summit and AnsibleFest 2023:

About the author

Chris Santiago is a full-stack Software Engineer at Red Hat. He is currently focusing on expanding the capabilities of Ansible Automation Platform for Edge Computing. Chris industry experience in software service delivery, cloud native software development, UX/UI development, and infrastructure automation.
Read full bio

Browse by channel

automation icon


The latest on IT automation for tech, teams, and environments

AI icon

Artificial intelligence

Updates on the platforms that free customers to run AI workloads anywhere

open hybrid cloud icon

Open hybrid cloud

Explore how we build a more flexible future with hybrid cloud

security icon


The latest on how we reduce risks across environments and technologies

edge icon

Edge computing

Updates on the platforms that simplify operations at the edge

Infrastructure icon


The latest on the world’s leading enterprise Linux platform

application development icon


Inside our solutions to the toughest application challenges

Original series icon

Original shows

Entertaining stories from the makers and leaders in enterprise tech