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 lab, 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
Install Builder Utility
Note: When using the free lab environment, see Oracle Linux Lab Basics for connection and other usage instructions.
Open a terminal and connect via ssh to the devops-node instance.
ssh oracle@<ip_address_of_devops-node>
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 python39-ansible-builder
The Builder utility installs
python3.9
,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:latest builder_image: name: container-registry.oracle.com/oracle_linux_automation_manager/olam-builder:latest 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.9/site-packages
due to the Builder utility using the 3.9 version of Python.Note: This requires setting the
ansible_python_interpreter
variable later in this tutorial to/usr/bin/python3.9
as the latest version ofansible-core
uses Python 3.11.tee ~/my_custom_ee/requirements.txt > /dev/null <<EOF setuptools oci>=2.112.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.9, the same version the Builder utility uses.
Install Ansible Runner.
python3.9 -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 vars: ansible_python_interpreter: /usr/bin/python3.9 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. The playbook also handles setting the
ansible_python_interpreter
variable to find the OCI SDK for Python within the image.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.
Make the default configuration directory on the devops node.
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 from the Luna Desktop to the devops node.
scp ~/.oci/* oracle@<ip_address_of_devops-node>:~/.oci/.
Exit the current terminal.
exit
Switch to the terminal window connected to the devops node.
Review the SDK and CLI configuration file.
cat ~/.oci/config
Example Configuration:
The following example shows key values in a configuration file.[DEFAULT] user=ocid1.user.oc1..<unique_ID> fingerprint=<your_fingerprint> key_file=~/.oci/oci_api_key.pem tenancy=ocid1.tenancy.oc1..<unique_ID> region=us-ashburn-1
Note: When following this tutorial outside of the free lab environment, see the instructions provided within the SDK and CLI Configuration File and Required Keys and OCIDs sections of the OCI Documentation.
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 of the user namespace. 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
Summary
The output of the tenancy namespace confirms you have a working execution environment for running playbooks within Oracle Linux Automation Manager.
For More Information
Oracle Linux Automation Manager Documentation
Oracle Linux Automation Manager Training
Oracle Linux Training Station