Build Custom Execution Environments with Oracle Linux Automation Manager Builder Utility
Introduction
The Builder utility is a tool based on the upstream ansible-builder project for generating custom execution environments for Oracle Linux Automation Manager.
This tutorial shows how to install the Builder utility and then create and verify a custom execution environment.
Objectives
In this tutorial, you'll learn how to:
- Install the Builder utility
- Define the schemas and tools the environment requires
- Build the custom execution environment container
- Verify the container works
Prerequisites
- A system running Oracle Linux
Deploy Oracle Linux
Note: If running in your own tenancy, read the linux-virt-labs
GitHub project README.md and complete the prerequisites before deploying the lab environment.
Open a terminal on the Luna Desktop.
Clone the
linux-virt-labs
GitHub project.git clone https://github.com/oracle-devrel/linux-virt-labs.git
Change into the working directory.
cd linux-virt-labs/olam
Install the required collections.
ansible-galaxy collection install -r requirements.yml
Update the Oracle Linux instance configuration.
cat << EOF | tee instances.yml > /dev/null compute_instances: 1: instance_name: "devops-node" type: "server" EOF
Deploy the lab environment.
ansible-playbook create_instance.yml -e ansible_python_interpreter="/usr/bin/python3.6" -e "@instances.yml"
The free lab environment requires the extra variable
ansible_python_interpreter
because it installs the RPM package for the Oracle Cloud Infrastructure SDK for Python. The location for this package's installation is under the python3.6 modules.The default deployment shape uses the AMD CPU and Oracle Linux 8. To use an Intel CPU or Oracle Linux 9, add
-e instance_shape="VM.Standard3.Flex"
or-e os_version="9"
to the deployment command.Important: Wait for the playbook to run successfully and reach the pause task. The Oracle Linux Automation Manager installation is complete at this stage of the playbook, and the instances are ready. Take note of the previous play, which prints the public and private IP addresses of the nodes it deploys.
Install Builder Utility
Open a terminal and connect via ssh to the devops-node instance.
ssh oracle@<ip_address_of_instance>
Install the Oracle Linux Automation Manager repository.
sudo dnf install -y oraclelinux-automation-manager-release-el8
Install the Builder utility package.
sudo dnf install -y python3.11-ansible-builder
The Builder utility installs
python3.11
,podman
, and other package dependencies.
Create the Custom Execution Environment Definition
When building your execution environment, you define the content in a YAML file. The Builder utility Oracle Linux Automation Manager provides uses either the version 1 or version 2 schemas. For this tutorial, we'll focus on version 2.
Create a project directory.
mkdir ~/my_custom_ee
Create the default file.
The
execution_enviroment.yml
file tells the Builder utility how to construct the instruction file, aContainerfile
for Podman, and any additional build context for our container image.tee ~/my_custom_ee/execution-environment.yml > /dev/null <<EOF --- version: 2 build_arg_defaults: ANSIBLE_GALAXY_CLI_COLLECTION_OPTS: "--ignore-certs" ansible_config: 'ansible.cfg' dependencies: galaxy: requirements.yml python: requirements.txt system: bindep.txt images: base_image: name: container-registry.oracle.com/oracle_linux_automation_manager/olam-ee:2.2 builder_image: name: container-registry.oracle.com/oracle_linux_automation_manager/olam-builder:2.2 additional_build_steps: prepend: | RUN whoami RUN cat /etc/os-release append: - RUN echo This is a post-install command! - RUN ls -la /etc EOF
Details on constructing this file exist in the Oracle Linux Automation Manager or the upstream documentation.
Add additional Ansible Collections.
These are a list of dependencies that the Builder utility installs using the
ansible-galaxy collection install -r requirements.yml
command.tee ~/my_custom_ee/requirements.yml > /dev/null <<EOF --- collections: - name: https://github.com/oracle/oci-ansible-collection.git type: git version: master - name: https://github.com/ovirt/ovirt-ansible-collection type: git version: master EOF
This
requirements.yml
pulls two collections:- the Oracle OCI collection to enable a playbook to interact with your OCI tenancy
- the oVirt collection for managing libvirt environments such as KVM and Oracle Linux Virtualization Manager.
Include Python dependencies.
This file instructs the Builder utility to install the list of Python dependencies using the
pip3 install -r requirements.txt
command. Thepip3
command installs these dependencies under the/usr/local/lib/python3.11/site-packages
due to the Builder utility using the 3.11 version of Python.tee ~/my_custom_ee/requirements.txt > /dev/null <<EOF setuptools oci>=2.141.1 EOF
This file pulls the latest Python packages for
setuptools
and the Oracle OCI SDK for Python.Define additional system packages.
The Builder utility includes binary packages using the
[bindep](https://docs.opendev.org/opendev/bindep/latest/readme.html)
tool by runningdnf
.tee ~/my_custom_ee/bindep.txt > /dev/null <<EOF libxml2-devel EOF
The
libxml2-devel
package provides the necessary libraries, includes, etc., to develop XML and HTML applications. The OCI Ansible Collection or OCI SDK for Python does not require this package and is just an example of using thebindep.txt
file.Create an Ansible configuration settings file.
We are not using this file in this lab, so create it and leave it empty.
touch ~/my_custom_ee/ansible.cfg
Build the Custom Execution Environment
The ansible-builder build
command takes our execution environment definition, generates the build instructions for our custom image, and then builds it.
Change into our project directory.
cd ~/my_custom_ee
Build the image.
ansible-builder build --tag my_custom_ee -v 3
The
--tag
customizes the tagged name applied to the image, while the-v
sets the verbosity of the command's output.Monitor the output as the build steps complete.
Verify the image exists.
podman images
As the Builder utility runs as a non-root user,
podman
creates and then stores the container imagelocalhost/my_custom_ee
under the user's home directory in$HOME/.local/share/containers/storage
as a default. You'll also see other images for this user, including the base and builder images we define in the custom execution environment definition file.
Test the Custom Execution Environment Image
Before loading our custom execution environment image into Oracle Linux Automation Manager, we should test it and ensure it behaves as expected. To accomplish this task, we'll introduce the upstream project Ansible Runner . Oracle does not provide this utility, so it is not supported.
Runner requires Python version 3.8 or greater, and we'll use Python 3.11, the same version the Builder utility uses.
Install the Python3.11 pip module.
sudo dnf install -y python3.11-pip
Install Ansible Runner.
python3.11 -m pip install ansible-runner
Verify the success of the Ansible Runner installation.
ansible-runner -h
Make a project directory for our test playbook.
mkdir -p /tmp/private/project
Write the playbook.
tee /tmp/private/project/playbook.yml > /dev/null <<'EOF' --- - name: get namespace name hosts: localhost collections: - oracle.oci tasks: - name: get namespace oracle.oci.oci_object_storage_namespace_facts: register: output - name: print namespace debug: msg: "{{ output }}" EOF
This playbook prints the namespace for the associated tenancy, which we define in a local OCI SDK and CLI configuration file.
Create the SDK and CLI default configuration file.
The free lab environment provides a pre-generated SDK and CLI configuration file, which we can copy from the Luna Desktop to our devops-node instance. If running in your environment and tenancy, see the instructions provided within the SDK and CLI Configuration File and Required Keys and OCIDs sections of the OCI Documentation.
Make the default configuration directory on the devops-node instance.
mkdir ~/.oci
Open a new terminal from the Luna Desktop environment.
Note: Do not connect to the devops-node.
Copy all of the configuration files to the devops-node instance.
scp ~/.oci/* oracle@<ip_address_of_devops-node_instance>:~/.oci/.
Exit the current terminal.
exit
Switch to the open terminal window connected to the devops-node instance.
Review the SDK and CLI configuration file.
cat ~/.oci/config
Update the location of the key_file in the SDK configuration file.
Since we plan to test the playbook inside our custom execution environment image, we must set this value to the container's root user $HOME.
Information: When mounting the SDK configuration directory to the container, podman maps the local user's userID (UID) into the container as root. Since we'll be in the root user namespace, the $HOME directory within the container will be
/root
.sed -i 's|/home/luna.user|/root|g' ~/.oci/config
If you modify the file manually with your favorite editor of choice, you can replace
/home/luna.user
with the shorthand syntax of~
.Run the playbook with Ansible Runner.
ansible-runner run --container-volume-mount /home/oracle/.oci/:/root/.oci/:Z --process-isolation --container-image=my_custom_ee -p playbook.yml /tmp/private
run
: is the command mode for the Ansible Runner--container-volume-mount
: mounts the local SDK and CLI configuration file to the container's root users $HOME. The:Z
creates a private unshared SELinux label ofcontainer_file_t
--process-isolation
: creates a new mount namespace where the root is on a tmpfs that is invisible from the host and automatically cleans up when the last process exits--container-image
: name of the custom execution environment image-p
: playbook run within the custom execution environment image/tmp/private
: a single location containing theprivate_data_dir
structure for inputs following the Runner Input Directory Hierarchy
Next Steps
The output of the tenancy namespace confirms you have a working execution environment for running playbooks within Oracle Linux Automation Manager. Check out our other tutorials covering Oracle Linux Automation Manager and Oracle Linux technologies.