ADR-0006: Development Environment Setup¶
Status: Accepted
Date: 2026-04-20
Deciders: Development Team
Tags: development, python, environment, tooling, setup
Context¶
The ansible-execution-environment project requires specific tools for building and testing: - ansible-builder: Builds execution environment container images - ansible-navigator: Tests execution environments and runs playbooks - ansible-core: Core Ansible functionality - Python 3.10+: Required by ansible-navigator (Python 3.9 is insufficient)
Current challenges: 1. RHEL 9 systems ship with Python 3.9 by default 2. ansible-navigator requires Python 3.10 or later 3. System-wide Python upgrades can break system tools 4. Multiple developers need consistent environments 5. CI/CD needs reproducible builds 6. Users may not have sudo access for system packages
The current make setup target detects issues but doesn't provide automated solutions for Python version conflicts.
Decision¶
Adopt a virtual environment (venv) based development setup with support for Python 3.11+ and automated tool installation.
Core Principles¶
- Never modify system Python: Use venv to isolate development dependencies
- Support Python 3.11 and 3.12: RHEL 9 provides these via appstream
- Automated setup:
make setupshould create and activate venv - Reproducible environments: Pin tool versions in requirements-dev.txt
- CI/CD alignment: Use same venv approach in GitHub Actions
Implementation¶
1. Virtual Environment Creation¶
# Detect Python 3.11, 3.12, or 3.10 (in order of preference)
PYTHON_BIN=$(command -v python3.11 || command -v python3.12 || command -v python3.10)
# Create venv if it doesn't exist
if [ ! -d .venv ]; then
$PYTHON_BIN -m venv .venv
fi
# Activate venv
source .venv/bin/activate
2. Development Dependencies¶
Create requirements-dev.txt:
# Ansible Automation Platform tools
ansible-builder>=3.0.0
ansible-navigator>=3.0.0
ansible-core>=2.15.0
# Development tools
yamllint>=1.26.0
ansible-lint>=6.0.0 # Optional linting
3. Enhanced Setup Target¶
Update make setup:
- Detect available Python 3.10+ versions
- Create or activate venv
- Install tools via pip in venv
- Verify ANSIBLE_HUB_TOKEN
- Provide clear instructions if prerequisites missing
4. Activation Helper¶
Create .venv-activate.sh:
#!/bin/bash
# Source this file to activate the development environment
# Usage: source .venv-activate.sh
if [ -d .venv ]; then
source .venv/bin/activate
echo "✓ Development environment activated"
echo " Python: $(python --version)"
echo " ansible-builder: $(ansible-builder --version 2>/dev/null || echo 'not found')"
echo " ansible-navigator: $(ansible-navigator --version 2>/dev/null || echo 'not found')"
else
echo "ERROR: .venv not found. Run 'make setup' first."
return 1
fi
5. Updated .gitignore¶
Add venv directories:
# Virtual environments
.venv/
venv/
.venv-*/
Makefile Integration¶
All build/test targets should activate venv first:
# Ensure venv is activated for targets that need it
.PHONY: activate-venv
activate-venv:
@if [ ! -d .venv ]; then \
echo "ERROR: Virtual environment not found. Run 'make setup' first."; \
exit 1; \
fi
build: activate-venv
@. .venv/bin/activate && ansible-builder build ...
test: activate-venv
@. .venv/bin/activate && ansible-navigator run ...
Consequences¶
Positive¶
- No system Python conflicts: Venv isolates development tools
- Consistent across environments: Same Python version and tools everywhere
- No sudo required: Users can set up without system admin access
- CI/CD reproducibility: GitHub Actions can use same venv approach
- Version pinning: requirements-dev.txt locks tool versions
- Easy cleanup:
rm -rf .venvto reset environment - Python 3.11+ support: Newer Python features available
- Better error messages: Setup detects and guides installation
Negative¶
- Additional step: Developers must activate venv (can be automated)
- Disk space: Each checkout has its own venv (~100MB)
- Learning curve: New users may not understand venv
- Makefile complexity: Targets need venv activation logic
Neutral¶
- Python 3.9 still supported via system Python for users who have 3.10+ alternatives
- Venv needs periodic recreation if Python version changes
- Documentation needs update to explain venv workflow
Alternatives Considered¶
System-Wide Installation¶
Install ansible-builder/navigator system-wide via dnf or pip
Pros: - Single installation for all projects - No venv management needed
Cons: - Requires sudo access - Can conflict with other projects' versions - System Python 3.9 insufficient for ansible-navigator - Upgrading system Python risky
Rejected because: System-wide installation breaks in Python 3.9 environments and requires sudo.
Conda/Mamba Environment¶
Use conda for environment management instead of venv
Pros: - Handles both Python and system packages - Popular in data science community
Cons: - Large installation footprint - Not standard Python tooling - Adds external dependency - Overkill for our use case
Rejected because: venv is Python standard library, lighter weight, and sufficient.
Docker-Based Development¶
Run all development tools in a container
Pros: - Complete isolation - Includes all system dependencies
Cons: - Nested containers (developing containers in containers) - Complex IDE integration - Slower filesystem operations - More complex setup
Rejected because: Adds unnecessary complexity when venv solves the problem.
Python Version Detection Only¶
Keep current approach: detect and warn about Python version
Pros: - No changes needed - Users choose their own solution
Cons: - Doesn't solve the problem - Users stuck without clear path forward - Inconsistent environments
Rejected because: Doesn't provide automated solution, creates friction.
Implementation Notes¶
Phase 1: Core venv Support¶
- Create requirements-dev.txt
- Update make setup to create venv
- Create .venv-activate.sh helper
- Update .gitignore
Phase 2: Makefile Integration¶
- Add activate-venv target
- Update build, test, lint targets to use venv
- Update CI/CD workflows to use venv
Phase 3: Documentation¶
- Update docs/tutorials/getting-started.md
- Update README.md with venv instructions
- Add troubleshooting for venv issues
Installation of Python 3.11 on RHEL 9¶
For users without Python 3.11/3.12:
# Install Python 3.11 from appstream
sudo dnf install -y python3.11 python3.11-pip python3.11-devel
# Verify
python3.11 --version # Should show 3.11.x
Testing¶
Verify venv setup works:
# Clean start
rm -rf .venv
# Run setup
make setup
# Activate venv
source .venv/bin/activate
# Verify tools
ansible-builder --version
ansible-navigator --version
python --version # Should show 3.11+ or 3.10+
# Test build
make build
Migration Path¶
For Existing Users¶
Users with system-wide ansible-builder/navigator:
1. Continue using system installation (still supported)
2. Optional: Switch to venv for isolation
3. make setup creates venv but doesn't force it
For New Users¶
- Run
make setup(creates venv automatically) - Source
.venv-activate.shorsource .venv/bin/activate - Run
make build(automatically uses venv)
For CI/CD¶
Update GitHub Actions workflows:
- name: Set up development environment
run: |
python3.11 -m venv .venv
source .venv/bin/activate
pip install -r requirements-dev.txt
- name: Build
run: |
source .venv/bin/activate
make build
Success Criteria¶
- [ ]
make setupcreates functional venv on RHEL 9 - [ ] Python 3.11 and 3.12 both work
- [ ]
make buildandmake testwork in venv - [ ] CI/CD uses venv approach
- [ ] Documentation updated
- [ ] Users can develop without sudo access
- [ ] No Python version conflicts