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.
Before EEs, Ansible just used whatever Python setup was on the control machine running the playbook. This could cause headaches:
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.
An Execution Environment is a container image used to run Ansible playbooks. It contains:
requests
, netmiko
)cisco.ios
, junipernetworks.junos
, arista.eos
) and generic networking (ansible.netcommon
).ip
, netmiko
, nmap
, ping
or openssh-clients
etc.)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
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:
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.
A custom EE is an image you build tailored to your project or team. You pack it with exactly what you need, like:
cisco.ios
, junipernetworks.junos
, arista.eos
, f5networks.f5_modules
etc)ntc-templates
, pyATS
, netmiko
, napalm
,nornir
)Lets see how to tailor EEs for your specific and build a custom EE using the Ansible Execution Environment builder (ansible-builder).
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.
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)
collections:
- name: cisco.ios
- name: junipernetworks.junos
- name: arista.eos
- name: f5networks.f5_modules
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)"
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
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
In the AAP or AWX web UI, go to Execution Environments under the Administration tab.
Click Add.
Fill in:
Save.
Open the desired Job Template.
Under Execution Environment, choose Network Automation EE.
Save.
Now your playbooks will run using the precise environment you built.
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
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
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
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. |
EEs make it easier to use other advanced Ansible features for networking:
ansible.netcommon
have modules (cli_command
, cli_config
) that work across different vendors. EEs ensure these collections are always available.paramiko
, requests
) needed by connection plugins (network_cli
, httpapi
) and modules (netmiko
) for solid SSH/API communication.network_cli
, httpapi
) that handle device quirks (prompts, timeouts) better than raw SSH/API calls.textfsm
and libraries like ntc-templates
in your EE to parse unstructured CLI output into usable JSON – vital for automating older gear.execution-environment.yml
and related files in Git. Tag your EE image builds alongside your code releases.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.
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.
Here are some helpful resources for learning more about Ansible:
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.
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.
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.
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.