Feature image for edge computing

As edge infrastructure scales outside the data center into remote locations, small-factor devices such as IoT, POS, and sensors that have Linux images, need a way to be updated at scale.

The rpm-ostree core premise is that by default, the updates should base on a whole base image that is created and tested offline, and once ready deployed everywhere into the remote locations, overriding the previous image and lowering the risks of patching at scale.

An illustration of the image builder.
Figure 1: The image builder.

We know many people are working in secure edge environments and need the ability to create and lifecycle manage operating systems. In order to help with this we have created a way to build, host and manage these images using the Red Hat Ansible Automation Platform.

This article will cover the Ansible collection for management of the osbuild composer to build rpm-ostree based images for Fedora, Red Hat Enterprise Linux, and CentOS Stream. This collection has roles to build an osbuild server, an apache httpd server to host images, and a role to build installer images and rpm-ostree updates.

2 roles of the infra.osbuild collection

There are two roles that are part of the infra.osbuild collection:

1. The infra.osbuild.setup_server role

The setup_server role checks to see what type of OS the remote system is running, ostree-based or non ostree-based. A remote system running an OS based on ostree will need to have packages already installed via a previous commit or with the initial install to continue. Non-ostree based hosts will have all the necessary packages installed.

At the same time the setup_server role also ensures all necessary services are enabled and started. Lastly it adds support for rpm custom repositories for adding custom packages to images.

2. The infra.osbuild.builder role

This builder role creates a blueprint based on information provided by the playbook variables such as packages, user info, and compose type. A rpm-ostree repository is initialized for the blueprint name to handle commits and upgrades. The builder role creates an image based on the previously created blueprint. Lastly it creates a kickstart file which supports an optional auto registration to be used on a system.

How to build images for edge deployment

Note: To test this collection you will need either a RHEL, CentOS Stream, or Fedora system.

Install the infra.osbuild collection using the ansible-galaxy command as follows:

ansible-galaxy collection install git+https://github.com/redhat-cop/infra.osbuild

Once installed we will make an empty directory to store the example playbooks and inventory file.

mkdir osbuild_example

Create an inventory file as follows:

touch inventory.ini

Inside the inventory file, create a group named all with the remote systems IP address underneath.

[all]
<Host IP>

Now that we have an inventory file and a remote system to point to. Let’s take a look into the setup_role. As explained above, this role simply sets up all the necessary packages and services to get osbuild up and running. If you plan on using a custom rpm repository to add custom packages that you would like to make available to osbuild then we need to add some configuration otherwise we can use the role as is.

Create a playbook named osbuild_setup_server.yaml with the sample playbook as its contents as follows:

---

- name: Run osbuild_server role

  hosts: all

  become: true

  tasks:

    - name: Run the role

      ansible.builtin.import_role:

        name: infra.osbuild.setup_server

For adding a custom rpm repository, we can pass a list to the setup_server_custom_repos role variable. Each list entry is a YAML dictionary type and has the following attributes:

  • repo_name
  • base_url
  • type
  • check_ssl
  • check_gpg
  • rhsm
  • state

If you wanted support for custom rpm repositories your playbook should something like the following:

---

- name: Run osbuild_server role

  hosts: all

  become: true

  vars:

    setup_server_custom_repos:

      - name: EPEL Everything

        base_url: "https://dl.fedoraproject.org/pub/epel/{{ hostvars[inventory_hostname].ansible_distribution_major_version }}/Everything/x86_64/"

        type: yum-baseurl

        check_ssl: true

        check_gpg: true

        state: present

      - name: My company custom repo

        base_url: "https://repo.example.com/company_repo/x86_64/"

        type: yum-baseurl

  tasks:

    - name: Run the role

      ansible.builtin.import_role:

        name: infra.osbuild.setup_server

Now that we have the osbuild_setup_server file completed, we can run the playbook using this command:

ansible-playbook -i inventory.ini  –ask-become –ask-pass playbooks/osbuild_setup_server.yaml

Note: We will run the playbook with –ask-become and –ask-pass flags to provide basic authentication, or if you want to set up proper authentication with ssh keys and proper user sudo management.

Once the playbook has finished running then the osbuild server is ready for us to start building images.

As explained  in the infra.osbuild.builder section, there are variables that are needed to create a blueprint. You can refer to the full list and their explanations.

Let’s create another playbook called osbuild_builder.yaml with the sample playbook as its contents as follows:

---

- name: Run osbuild_builder role

  become: true

  hosts: all

  vars:

    builder_compose_type: edge-commit

    builder_blueprint_name: mybuild

    builder_pub_key: ~/.ssh/id_rsa.pub

    builder_compose_pkgs:

      - vim-enhanced

      - httpd

      - ansible-core

      - tmux

    builder_compose_customizations:

      user:

        name: "testuser"

        description: "test user"

        password: "testpassword"

        key: "{{ builder_pub_key }}"

        groups: '["users", "wheel"]'

  tasks:

    - name: Run the role

      ansible.builtin.import_role:

        name: infra.osbuild.builder

If you would like to have your image automatically register with Ansible Automation Platform, add builder_aap_url, builder_set_hostname, builder_aap_ks_user and builder_aap_ks_password underneath the vars section in the osbuild_builder.yaml playbook.

Once you have finished writing your playbook run the osbuild_builder.yml playbook to begin building an image.

ansible-playbook -i inventory.ini –ask-become –ask-pass playbooks/osbuild_builder.yml

After the playbook finishes, log in into your remote system http://<ip_addr>/<blueprint_name>/ to see the hosted repo and kickstart file that can be used to provision a new system.

Find more resources

In summary, infra.osbuild is an easy-to-use solution for creating customizable images. Ansible validated content for infrastructure osbuild collection, will let you automate the provisioning and configuration of the required osbuild components and build a RHEL image for your edge deployments.

If you want to learn more about edge automation, here are a few suggestions:

Last updated: November 16, 2023