Skip to content
Jan 13 / Greg

Creating And Using Execution Environments For The Ansible Automation Platform

As of version 2.0, AAP has replaced Python virtual environments with Execution Environments(EEs). In short it’s running all of your automations inside of containers. The advantages are many, but I’m not here to talk about why, rather I’m here to talk about the how. There is a lot of documentation on the various pieces(which I’ll link to here and there), but it’s not necessarily all put together in one place, so I’m aiming to do that here. This guide is really just showing how to get it done in the shortest time possible 🙂

Installing The Tools

One assumption is that you already have AAP2.X installed/working, and you are ready to build some custom EEs.

Part of the AAP2.X install configures podman, which is Red Hat’s container engine. It should feel familiar if you have used docker before as many of the commands are identical. Podman will be used to pull containers down to my host(used to build my EEs), and it’s used to push them up to my container registry. Think of a container registry as a repo that stores containers for AAP to pull and use.

The next, and most important, tool is ansible-builder(I often just refer to it as builder). This tool will take all of the various collections and their requirements, and combine them together with a container to create my EEs. At the time of this writing it’s not auto-installed when installing AAP, but I’d expect it to very soon.
Installation is pretty simple:

1
pip3 install ansible-builder

Pulling Containers To Build From

Red Hat is kind enough to build and supply us with some existing EEs that perform different functions. When you install AAP2.1 these are included in your control nodes.
At the time of this writing they are:

  • Ansible Engine 2.9 execution environment(ee-29-rhel8) – This is a backwards compatible EE for running older playbooks that require Ansible Engine 2.9.
  • Minimal execution environment(ee-minimal-rhel8) – This is a small minimal EE that only contains base objects.
  • Default(or “Supported”) execution environment(ee-supported-rhel8) – This is the EE I’ll use most often either directly or to build from. It includes all of the certified collections Red Hat supports.
  • To build an EE, you have to have something to build from. If you don’t specify anything, it will use the base ansible-runner EE which really contains nothing…why start from scratch?
    Keeping this in mind I’m going to pull and use the supported EE. First I’ll login to registry.redhat.io to pull content from my account:

    1
    2
    3
    4
    
    podman login registry.redhat.io
    Username: *****
    Password: *****
    Login Succeeded!

    Now that I’m logged in, I’ll pull the newest supported EE:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    
    podman pull registry.redhat.io/ansible-automation-platform-21/ee-supported-rhel8:latest
    Trying to pull registry.redhat.io/ansible-automation-platform-21/ee-supported-rhel8:latest...
    Getting image source signatures
    Checking if image destination supports signatures
    Copying blob d43e71f3b46c skipped: already exists
    Copying blob a873fa241620 skipped: already exists
    Copying blob 131f1a26eef0 skipped: already exists
    Copying blob 16b78ed2e822 skipped: already exists
    Copying blob 183445aff41b [--------------------------------------] 0.0b / 0.0b
    Copying config 6a3817e80b done
    Writing manifest to image destination
    Storing signatures
    6a3817e80b0c03bac2327986a32e2ba495fbe742a1c8cd33241c15a6c404f229

    ^^You can see from the above it would have pulled the EE if I hadn’t already done it.

    At this point I’ll do a quick list to see what I’ve got available:

    1
    2
    3
    4
    5
    
    podman image list
    REPOSITORY                                                            TAG         IMAGE ID      CREATED       SIZE
    quay.io/ansible/ansible-runner                                        latest      43736a7bc136  2 days ago    761 MB
    quay.io/ansible/ansible-builder                                       latest      16689884a603  2 days ago    655 MB
    registry.redhat.io/ansible-automation-platform-21/ee-supported-rhel8  latest      6a3817e80b0c  2 days ago    1.13 GB

    Build A Custom EE

    Now that I’ve successfully grabbed the supported EE to build from, I’ll put together the files required.
    In my home directory I’m going to create an “ee” folder to collect all of my custom EE files in.
    Inside of that directory I’m creating a folder for my custom EE. I’m going to create one to utilize the community VMWare community as I’m automating against a slightly older VCenter. Keeping this in mind the folder will be named “vmware”. Now I’m going to create three required files.

    The first file is “execution-environment.yml“. This is an instruction file for ansible-builder to tell it which components to use to build the EE:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    
    ---
    version: 1
     
    build_arg_defaults:
      EE_BASE_IMAGE: 'registry.redhat.io/ansible-automation-platform-21/ee-supported-rhel8'
     
    # ansible_config: 'ansible.cfg'
     
    dependencies:
      galaxy: requirements.yml
      python: requirements.txt
    #  system: bindep.txt
     
    # additional_build_steps:
    #   prepend: |
    #     RUN whoami
    #     RUN cat /etc/os-release
    #   append:
    #     - RUN echo This is a post-install command!
    #     - RUN ls -la /etc

    You will quickly notice that I have a lot of things commented out in the below; I didn’t choose to use them and they weren’t required for my configuration. For now I’ll start near the top with the “build_arg_defaults:” section. Here I’m listing the EE I’m building from exactly as it’s shown when I did the “podman image list” command.

    Next I can supply a custom ansible.cfg if I so choose; for this simple demo I just left it commented out.

    After that is the “dependencies” section which is the only required portion really. Here I’m specifying a galaxy section(what collections to install), a python section(what python dependencies I need to install), and commented out here is the system section(what packages need to be installed with “DNF install”).

    Last is the commented out “additional_build_steps” section. This allows arbitrary commands to be run before all the dependencies are placed as well as some appended to the end once everything is done.

    Next is the galaxy “requirements.yml” file:

    1
    2
    3
    
    ---
    collections:
      - name: community.vmware

    As you can see I just put in the list of collections to install. At run time, builder will connect to the requisite service and download the specified files.

    Last is the python “requirements.txt” file:

    1
    2
    
    pyVmomi>=6.7
    git+https://github.com/vmware/vsphere-automation-sdk-python.git ; python_version >= '2.7'  # Python 2.6 is not supported

    If you are wondering how to figure out what this should consist of, each of your collections should either specify which packages to install, or they should include a requirements.txt file directly(I just found the requirements file in the git repo and went from there).

    Now it’s go time; I’m going to compile the EE:

    1
    2
    3
    4
    5
    6
    
    [[email protected] vmware]# pwd
    /root/ee/vmware
    [[email protected] vmware]# ansible-builder build --tag vmware_ee_supported
    Running command:
      podman build -f context/Containerfile -t ansible-execution-env:latest context
    Complete! The build context can be found at: /root/ee/vmware/context

    Notice that I added “–tag vmware_ee_supported” to the build command. This adds a unique name to the EE, otherwise it just shows up as “localhost/ansible-execution-env”…which isn’t that useful. In my vmware folder I now have a new folder structure/set of files(in a directory named context).

    To view the new EE I’ll list my podman containers:

    1
    2
    3
    4
    5
    6
    
    [[email protected] vmware]# podman image list
    REPOSITORY                                                            TAG         IMAGE ID      CREATED       SIZE
    localhost/vmware_ee_supported                                         latest      9b26f91c4487  42 hours ago  1.25 GB
    quay.io/ansible/ansible-runner                                        latest      43736a7bc136  2 days ago    761 MB
    quay.io/ansible/ansible-builder                                       latest      16689884a603  2 days ago    655 MB
    registry.redhat.io/ansible-automation-platform-21/ee-supported-rhel8  latest      6a3817e80b0c  2 days ago    1.13 GB

    I’ve now successfully built my EE, and I can use it in ansible-navigator, but right now I can’t use it in AAP…that is not until I push it to a container registry.

    Installing Private Automation Hub

    There are a lot of different container registries you can use; I mean even github has options. I’m going to use Red Hat’s Private Automation Hub(I’ll refer to it as PAH or pah moving forward) to host mine since it’s a great repository for collections anyway.

    Installing it is pretty easy. All I really do is standup a RHEL8 box, edit the inventory file I installed my controller from, and fire off setup again.
    Here’s the snippit from my inventory I configured for my PAH:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    
    [automationhub]
    pah.gregsowell.com ansible_user=Greg ansible_password=HeIsAwesome
     
    # Automation Hub Configuration
    #
     
    automationhub_admin_password='SoupIsntAMeal'
     
    automationhub_pg_host=''
    automationhub_pg_port=''
     
    automationhub_pg_database='automationhub'
    automationhub_pg_username='automationhub'
    automationhub_pg_password='SoupIsntAMeal'
    automationhub_pg_sslmode='prefer'
     
    # When using Single Sign-On, specify the main automation hub URL that
    # clients will connect to (e.g. https://<load balancer host>).
    # If not specified, the first node in the [automationhub] group will be used.
    #
    automationhub_main_url = 'https://pah.gregsowell.com'
     
    # By default if the automation hub package and its dependencies
    # are installed they won't get upgraded when running the installer
    # even if newer packages are available. One needs to run the ./setup.sh
    # script with the following set to True.
    #
    automationhub_upgrade = True

    A couple of notes about this are needed. First you will notice I put a username and password on the line of my pah server, because I wanted to be lazy and keep the connection simple. When you do this it will fail by default, because it doesn’t have the SSH key cached for this host. To fix this just SSH to the host on the CLI and accept the key…EZPZ.
    You will also notice I put in a main URL, because it will yell at me if I don’t.
    Last and pretty importantly is the fact that I set upgrade to true. By default it won’t do an upgrade on an existing PAH…I’m really not sure why. If you want to perform an upgrade if you have an older version, then set this to true.

    You can now run the ./setup file in your install folder(I always go with bundled BTW), and Bob’s your uncle.

    Pushing EEs To A Container Registry

    This could be any CR, but in my case, it’s going to be my PAH.
    Step one, connect podman to the CR:

    1
    
    podman login pah.gregsowell.com --tls-verify=false

    I have tls-verify off because this is in my lab and it doesn’t have a valid cert on it.

    Now that I’ve logged in I can push the EE up:

    1
    2
    3
    4
    5
    
    [[email protected] vmware]# podman image list
    REPOSITORY                                                            TAG         IMAGE ID      CREATED       SIZE
    localhost/vmware_ee_supported                                         latest      9b26f91c4487  42 hours ago  1.25 GB
     
    [[email protected] vmware]# podman push localhost/vmware_ee_supported:latest docker://pah.gregsowell.com/vmware_ee_supported:1.0.0 --tls-verify=false

    You can see in the podman push command I specified a version number to assign to the EE when it hits the registry. If I update my EE I want to update the version number I push also.

    Nooooooow I need to set AAP to pull the new EE.

    Pull EE Into AAP

    PAH Server

    I’m going to pop into my PAH server and take a look at the container section:

    At the bottom I see my new EE “vmware_ee_supported”.

    If I click on it, it will initially supply me with the pull instructions:

    There’s also a helpful link to install it in the controller even quicker:

    The screen it presents allows me to click the link for my controller and it will prepopulate it in AAP for me:

    AAP Controller Server

    I’m now going to jump into my AAP server and take a look at the configuration for the EE:

    I’ve highlighted two things here.
    First is the pull options. You can choose to: always pull before running, never pull before running, or pull if image not present. Pick whatever makes sense for you.
    Second is the registry credentials. When you run the install script with a PAH specified, then a credential will automatically be added for you allowing you access to your PAH. By default it won’t be populated when initially adding a new EE to your controller. All you have to do is click the magnifying glass and add the “Automation Hub Container Registry” credential.

    Conclusion

    Now that it’s all done, it really isn’t that bad of a process. I’m assuming I’ll automate a chunk of this in the future, but for now, here’s the manual way. I plan to build my EEs off of the “supported” image to pack as much functionality into my EE as possible(again, I’m lazy). As things progress and change, I’ll try and revisit this document to keep it updated.

    As always, if you have any questions/comments, please let me know.

    Good luck and happy automating!

    Leave a Comment

     

    *