AnsiblePilot — Master Ansible Automation

AnsiblePilot is the leading resource for learning Ansible automation, DevOps, and infrastructure as code. Browse over 1,400 tutorials covering Ansible modules, playbooks, roles, collections, and real-world examples. Whether you are a beginner or an experienced engineer, our step-by-step guides help you automate Linux, Windows, cloud, containers, and network infrastructure.

Popular Topics

About Luca Berton

Luca Berton is an Ansible automation expert, author of 8 Ansible books published by Apress and Leanpub including "Ansible for VMware by Examples" and "Ansible for Kubernetes by Example", and creator of the Ansible Pilot YouTube channel. He shares practical automation knowledge through tutorials, books, and video courses to help IT professionals and DevOps engineers master infrastructure automation.

Ansible Execution Environments: Build Custom EEs for Enterprise Automation

By Luca Berton · Published 2024-01-01 · Category: installation

How to build custom Ansible Execution Environments with ansible-builder. Package Python dependencies, collections, and system packages for consistent.

Introduction

Execution Environments (EEs) are containerized images that package everything needed to run Ansible automation: ansible-core, Python dependencies, system packages, and Ansible collections. They solve the "works on my machine" problem by ensuring consistent execution across development laptops, CI/CD pipelines, and Ansible Automation Platform.

See also: Ansible Builder & Execution Environments: Complete Guide (2026)

Why Execution Environments?

Before EEs, teams struggled with: • Dependency conflicts — Different playbooks needing different Python library versions • Inconsistent results — Playbook works locally but fails in AAP • Manual setup — Each automation host needs its own dependency installation • Security concerns — Uncontrolled Python packages on shared infrastructure

EEs solve all of these by packaging dependencies into immutable container images.

Architecture

┌─────────────────────────────────┐
│      Execution Environment      │
│                                 │
│  ┌───────────────────────────┐  │
│  │ ansible-core 2.20         │  │
│  ├───────────────────────────┤  │
│  │ Python packages           │  │
│  │  - boto3, azure-cli       │  │
│  │  - hvac, netaddr          │  │
│  ├───────────────────────────┤  │
│  │ System packages           │  │
│  │  - openssh-clients        │  │
│  │  - git, unzip             │  │
│  ├───────────────────────────┤  │
│  │ Ansible collections       │  │
│  │  - amazon.aws             │  │
│  │  - community.general      │  │
│  │  - community.docker       │  │
│  └───────────────────────────┘  │
│  Base: RHEL UBI 9 Minimal      │
└─────────────────────────────────┘

See also: AAP 2.6 Execution Environments: Build, Manage, and Deploy Custom EEs

Install ansible-builder

pip install ansible-builder

# Verify ansible-builder --version

Define Your Execution Environment

Create an execution-environment.yml file:

---
version: 3

images: base_image: name: quay.io/ansible/ansible-runner:latest

dependencies: ansible_core: package_pip: ansible-core>=2.16,<2.21 ansible_runner: package_pip: ansible-runner galaxy: requirements.yml python: requirements.txt system: bindep.txt

additional_build_files: - src: ansible.cfg dest: configs

additional_build_steps: prepend_galaxy: - COPY _build/configs/ansible.cfg /etc/ansible/ansible.cfg append_final: - RUN chmod -R 755 /usr/share/ansible

requirements.yml (Collections)

---
collections:
  - name: amazon.aws
    version: ">=8.0.0"
  - name: community.general
    version: ">=10.0.0"
  - name: community.docker
    version: ">=4.0.0"
  - name: community.hashi_vault
    version: ">=6.0.0"
  - name: ansible.posix
  - name: ansible.utils

requirements.txt (Python)

boto3>=1.34
botocore>=1.34
hvac>=2.0
netaddr>=0.10
jmespath>=1.0
pywinrm>=0.4
requests>=2.31
cryptography>=42.0

bindep.txt (System Packages)

openssh-clients [platform:redhat]
git [platform:redhat]
unzip [platform:redhat]
python3-devel [platform:redhat]
gcc [platform:redhat compile]

See also: Build a Custom Ansible Execution Environment Easily

Build the EE

# Build with Podman (default)
ansible-builder build \
  --tag my-org/ansible-ee:latest \
  --container-runtime podman

# Build with Docker ansible-builder build \ --tag my-org/ansible-ee:latest \ --container-runtime docker

# Build with verbose output ansible-builder build \ --tag my-org/ansible-ee:1.0.0 \ --verbosity 3

Test the EE

# Run a playbook inside the EE
ansible-runner run . \
  --container-image my-org/ansible-ee:latest \
  --process-isolation \
  -p site.yml

# Interactive shell podman run -it my-org/ansible-ee:latest /bin/bash

# Verify collections podman run my-org/ansible-ee:latest \ ansible-galaxy collection list

# Verify Python packages podman run my-org/ansible-ee:latest \ pip list | grep boto3

Push to Registry

# Tag and push to private registry
podman tag my-org/ansible-ee:latest \
  registry.example.com/ansible-ee:1.0.0

podman push registry.example.com/ansible-ee:1.0.0

# Push to Quay.io podman push my-org/ansible-ee:latest \ quay.io/my-org/ansible-ee:latest

Use in AAP

Go to Administration → Execution Environments Click Add Enter: • Name: Custom AWS EE • Image: registry.example.com/ansible-ee:1.0.0Pull: Always (recommended for mutable tags) Assign to Job Templates

EE for Different Use Cases

Cloud Automation EE

# requirements.yml
collections:
  - amazon.aws
  - azure.azcollection
  - google.cloud
  - community.general
# requirements.txt
boto3
azure-cli-core
google-auth

Network Automation EE

collections:
  - cisco.ios
  - arista.eos
  - junipernetworks.junos
  - ansible.netcommon
# requirements.txt
paramiko
ncclient
netaddr
xmltodict

Security Automation EE

collections:
  - community.hashi_vault
  - community.crypto
  - ansible.posix
# requirements.txt
hvac
cryptography
pyOpenSSL

CI/CD Pipeline for EE Builds

# .github/workflows/build-ee.yml
name: Build Execution Environment
on:
  push:
    paths:
      - 'execution-environment.yml'
      - 'requirements.*'
      - 'bindep.txt'

jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4

- name: Install ansible-builder run: pip install ansible-builder

- name: Build EE run: | ansible-builder build \ --tag ${{ github.repository }}/ansible-ee:${{ github.sha }} \ --container-runtime docker

- name: Push to registry run: | echo "${{ secrets.REGISTRY_TOKEN }}" | \ docker login registry.example.com -u bot --password-stdin docker push ${{ github.repository }}/ansible-ee:${{ github.sha }}

Best Practices

Pin versions — Use exact versions in requirements to ensure reproducible builds Use semantic versioning — Tag EE images with version numbers, not just latest Minimize image size — Only include dependencies you actually need Automate builds — CI/CD pipeline triggers on requirement changes Test before deploying — Run playbooks against the EE locally before pushing to AAP One EE per use case — Separate cloud, network, and security EEs rather than one mega-image Base on official images — Start from Red Hat's ansible-runner or ee-minimal-rhel9 base Document your EEs — README explaining what each EE contains and its intended use

Troubleshooting

"Collection not found" in AAP

The EE doesn't include the collection. Rebuild with it in requirements.yml.

Build fails on system packages

Check bindep.txt syntax and ensure packages exist for the base image's OS (RHEL UBI).

Image too large

Remove unnecessary system packages and compile-only dependencies. Use multi-stage builds.

FAQ

Can I use EEs with ansible-playbook CLI?

Yes — use ansible-navigator which supports EEs locally:

pip install ansible-navigator
ansible-navigator run site.yml --eei my-org/ansible-ee:latest

EEs vs Python virtualenvs?

EEs package system dependencies too (not just Python). They're immutable, portable, and work identically everywhere. Virtualenvs only handle Python packages.

How often should I rebuild EEs?

Rebuild when: dependencies update (security patches), new collections needed, or ansible-core version changes. Monthly minimum for security updates.

Conclusion

Execution Environments are the foundation of reliable enterprise automation. By packaging all dependencies into immutable containers, you eliminate "works on my machine" issues and ensure every playbook runs consistently — from development through production.

Related Articles

Ansible Automation Platform 2.6Ansible Docker Complete GuideWhat is Ansible AWX?

Category: installation

Browse all Ansible tutorials · AnsiblePilot Home