Skip to content
All posts

Deep Dive into Ansible Execution Environment for Network Automation

When Ansible grew from a simple command-line tool to a full-blown platform, keeping automation consistent, portable, and scalable became a big deal. Enter Ansible Execution Environments (EEs). They were created to tackle exactly these challenges, especially in network automation where dependencies can get messy. For any serious network automation project, EEs help make sure your code runs the same way every time, whether you're on your laptop, in a test lab, or pushing to production.

Why Execution Environments?

Before EEs, Ansible just used whatever Python setup was on the control machine running the playbook. This could cause headaches:

  • Conflicts between dependencies. Network automation often requires specific libraries (e.g., netmiko, napalm) that might clash with other tools.
  • "Works on My Machine" Syndrome. Different team members or servers might have slightly different Python versions or libraries installed, leading to inconsistent results.
  • Challenges in scaling or containerizing Ansible jobs.

To fix this, Ansible introduced the Execution Environment (EE) concept, a container-based runtime built on Podman or Docker, with all required collections, Python libraries, and tools baked in.

What is an Ansible Execution Environment?

An Execution Environment is a container image used to run Ansible playbooks. It contains:

  • Ansible Core (or Automation Platform Ansible Engine)
  • The exact Python libraries needed (e.g., specific versions of requests, netmiko)
  • Ansible Collections Certified collections for network vendors (e.g., cisco.ios, junipernetworks.junos, arista.eos) and generic networking (ansible.netcommon).
  • CLI tools (e.g., ip, netmiko, nmap, ping or openssh-clients etc.)
  • Any custom scripts or internal tools your automation relies on.

These ansible execution environment images provide consistent automation runtimes that ensure your network automation code works identically regardless of where it runs. By packaging all dependencies, EEs get rid of that frustrating "but it works on my machine!" problem.

Read more: Ansible Setup Guide

The Default Ansible Automation Platform and AWX Execution Environments

Both Ansible Automation Platform (AAP) and its open-source upstream, AWX, ship with default Ansible Execution Environment images. These are usually lean, built on a Red Hat Universal Base Image (UBI). Both are hosted at Quay.io, a Red Hat container registry service.

This image includes:

  • Ansible Core
  • Core Red Hat certified collections
  • Python 3.x
  • Networking libraries (netaddr, netmiko, paramiko, etc.)

These defaults are a decent starting point, but honestly? For real-world, complex network automation, they're often missing the specific vendor modules (cisco.ios, anyone?), specialized libraries (pyats, ntc-templates), or custom tools you actually need. This is where building custom Execution Environments comes in.

What is a Custom Execution Environment?

A custom EE is an image you build tailored to your project or team. You pack it with exactly what you need, like:

  • Cisco/Juniper/Fortinet collections (cisco.ios, junipernetworks.junos, arista.eos, f5networks.f5_modules etc)
  • Network libraries (ntc-templates, pyATS, netmiko, napalm,nornir)
  • Your team's internal Python scripts, custom Ansible roles, or other utilities.

Building a Custom Ansible Execution Environment

Lets see how to tailor EEs for your specific and build a custom EE using the Ansible Execution Environment builder (ansible-builder).

Step 1: Define Your EE Configuration

Create a definition file, usually execution-environment.yml. This file tells ansible-builder what to put in your EE: the base image to start from, Python requirements, Ansible Galaxy collections, and any extra build steps. Using this file means you can track your EE's configuration in Git, just like your automation code.

execution-environment.yml

version: 1

build_arg_defaults:
EE_BASE_IMAGE: 'quay.io/ansible/awx-ee:latest'
EE_BUILDER_IMAGE: 'quay.io/ansible/ansible-builder:latest'

dependencies:
galaxy: requirements.yml
python: requirements.txt

additional_build_steps:
prepend: |
   RUN pip3 install ntc_templates
append: |
   RUN echo
"Custom EE for Network Automation"

(You might also need separate requirements.txt for Python or requirements.yml for Galaxy if not defining directly in the main YAML file)

requirements.yml

collections:
- name: cisco.ios
- name: junipernetworks.junos
- name: arista.eos
- name: f5networks.f5_modules

 

requirements.txt

netmiko
nornir
napalm
textfsm

 

Here’s another example based on the latest ansible-builder v3:

version: 3
images:
  base_image:
    name: quay.io/ansible/awx-ee:latest
dependencies:
  python:
    - netmiko
    - napalm
    - pyats
  system:
    - iputils
    - openssh-clients
  galaxy:
    collections:
      - cisco.ios
      - junipernetworks.junos
      - arista.eos
      - ansible.netcommon
additional_build_steps:
  prepend: |
    RUN pip3 install ntc_templates
  append: |
    RUN echo "Custom EE for Network Automation Built on $(date)"

 

Step 2: Build the Custom EE Using Podman

First, make sure you have ansible-builder and podman installed:

pip install ansible-builder
sudo dnf install podman # or apt/yum depending on your OS

Now, build the image using your definition file:

ansible-builder build -f execution-environment.yml -t network-ee

This creates a local container image named localhost/network-ee:latest.

You can quickly test it locally:

podman run -it localhost/network-ee:latest ansible --version

 

Step 3: Push Custom EE to Quay.io

Lets push to Red Hat's container registry service Quay.io now.

Log in to your registry:

podman login quay.io

Tag the image with your registry namespace and push it:

podman tag localhost/network-ee quay.io/<your-username>/network-ee:latest

podman push quay.io
/<your-username>/network-ee:latest

Step 4: Add EE to Ansible Automation Platform

Create a New Execution Environment in AAP:

In the AAP or AWX web UI, go to Execution Environments under the Administration tab.

Click Add.

Fill in:

  • Name: Network Automation EE
  • Image: quay.io/<your-username>/network-ee:latest
  • Add credentials if your repo is private.

Save.

Use It in Job Templates:

Open the desired Job Template.

Under Execution Environment, choose Network Automation EE.

Save.

Now your playbooks will run using the precise environment you built.

Using Ansible-Navigator Execution Environments tips

ansible-navigator is a command-line tool with a nice text-based UI (TUI) that's designed to work well with EEs. It makes running playbooks, exploring inventory, and browsing collections inside the EE much easier.

ansible-navigator run playbook.yml --eei quay.io/your_username/my-network-ee:latest

Explore collections available inside the EE:

ansible-navigator collections --eei quay.io/your_username/my-network-ee:latest

Look up module documentation from within the EE:

ansible-navigator doc ios_command --eei quay.io/your_username/my-network-ee:latest

Read more: Ansible Modules Types Explained

Ansible Execution Environment Example: Automating VLAN Configuration

Here's a simple playbook to configure VLANs on Cisco IOS and Arista EOS devices. The custom EE makes sure the cisco.ios and arista.eos collections (and their dependencies) are present.

- name: Configure VLANs on network devices
  hosts: all
  gather_facts: no
  tasks:
    - name: Configure VLAN on Cisco IOS
      cisco.ios.ios_vlans:
        config:
          - vlan_id: 100
            name: TEST_VLAN
        state: merged
      when: ansible_network_os == 'cisco.ios.ios'

    - name: Configure VLAN on Arista EOS
      arista.eos.eos_vlans:
        config:
          - vlan_id: 100
            name: TEST_VLAN
        state: merged
      when: ansible_network_os == 'arista.eos.eos'

Run this playbook with ansible-navigator using your EE:

ansible-navigator run vlan_config.yml --eei quay.io/your_username/my-network-ee:latest

(Optional) Run Your EE Locally

Before pushing, you can jump inside your built EE image for a quick check:

podman run -it localhost/network-ee bash

Once inside, verify things are installed:

ansible --version 
ansible-galaxy collection list
python3 -m pip list

 

Why Use Execution Environments?

Feature

Advantage

Portability

Runs the same everywhere: dev, test, prod.

Python Isolation

No more Python dependency clashes. Critical for network libraries.

Modular

Build specific EEs for different vendors, teams, or tasks.

Scalable

Works with AAP clusters and automation mesh for distributed network tasks.

Testable

Build and test EEs locally before deploying.

Secure

Start from hardened base images; control exactly what's included.

Additional Features for Network Automation Enabled by EEs


EEs make it easier to use other advanced Ansible features for networking:

  • Agnostic Modules: Collections like ansible.netcommon have modules (cli_command, cli_config) that work across different vendors. EEs ensure these collections are always available.
  • Reliable Connections: EEs bundle libraries (paramiko, requests) needed by connection plugins (network_cli, httpapi) and modules (netmiko) for solid SSH/API communication.
  • Structured Data: Network modules often return detailed JSON output. EEs guarantee you have the module versions that provide this useful data for validation.
  • Event-Driven Automation (EDA): EEs can hold the specific tools or libraries needed for EDA playbooks that react to network events (syslog, SNMP traps).
  • Connection Plugins: EEs support connection plugins (network_cli, httpapi) that handle device quirks (prompts, timeouts) better than raw SSH/API calls.
  • CLI Parsing: Include tools like textfsm and libraries like ntc-templates in your EE to parse unstructured CLI output into usable JSON – vital for automating older gear.

Best Practices for Using EEs

  • Version Control Everything: Keep execution-environment.yml and related files in Git. Tag your EE image builds alongside your code releases.
  • Keep it Lean: Only include what you absolutely need. Smaller images build faster and use less storage. Prune unused stuff regularly.
  • Test Your Builds: Validate new EE versions against test devices or in staging before using them for production jobs.
  • Document: Note the purpose and contents of custom EEs (in Git's README or embedded in the image).
  • Security Mindset: Use trusted base images (like Red Hat UBI). Update dependencies regularly. Scan images for vulnerabilities.
  • Be Modular: Maybe create separate EEs for routing vs. firewall tasks instead of one giant EE. Easier to maintain.
  • Performance (Minor): For huge scale, pre-compiling Python bytecode during the build might slightly speed up runtime (often negligible). You may check out our Ansible performance optimization guide as well.

Wrapping Up

Execution Environments are a big step forward for doing network automation properly with Ansible. They bring consistency and solve dependency headaches, letting network engineers build, test, and roll out automation more reliably, no matter the environment or scale.

How CloudMyLab Simplifies Execution Environments

While powerful, building and managing EEs takes some effort. CloudMyLab offers services to help:

Ansible Instant Env: Get pre-configured EEs, ready to go quickly, avoiding setup hassles. We have pre-built EEs optimized for Cisco, Juniper, Fortinet, etc.

Realistic Testing: Test your own custom EEs in complex network labs using our Lab as a Service (EVE-NG Pro, Cisco CML). Validate everything safely before it hits production.

Expert Help: Our Professional Services team can help design and build custom EEs tailored exactly to your network and automation goals.

💡 Why risk breaking production with untested automation? Use CloudMyLab's sandbox environments to test with confidence.

Check out our Ansible Network Automation offerings or start a free trial.

 

Learning Resources

Here are some helpful resources for learning more about Ansible:

 

FAQ

What is the Ansible Automation Platform Execution Environment?

The Ansible Automation Platform Execution Environment (EE) is the official container runtime from Red Hat for AAP. It bundles Ansible, certified content, and dependencies for consistent execution within AAP.

What is the Ansible AWX Execution Environment?

The Ansible AWX Execution Environment (EE) is the container image used by the open-source AWX project (upstream for AAP controller). Usually found at quay.io/ansible/awx-ee, it provides the runtime for jobs managed by AWX.

What is ansible-navigator and how does it work with Execution Environments?

Ansible-navigator is a command-line tool (with a text UI) made for working with Ansible, especially EEs. It handles running playbooks inside an EE container for you. Use the --eei <image_name> flag to specify which EE to use.

What are Ansible execution environment images and where can I find them?

Ansible execution environment images are container images packaging Ansible and everything needed to run playbooks consistently. Official ones are on registries like Red Hat Automation Hub or Quay.io. You build custom ones and store them in your preferred registry. CloudMyLab also offers pre-built, network-focused EEs via services like Ansible Instant Env.