A professional, security-hardened Ansible automation framework for standardized, repeatable infrastructure and application deployments.
The framework is organized into namespaces, each mapped as an Ansible roles_path entry in ansible.cfg:
| Namespace | Purpose |
|---|---|
applications/ |
Application-specific roles (e.g., python3_pip, nginx) |
operating_systems/ |
OS bootstrap and hardening roles |
utilities/ |
Shared utility roles and helper functions |
Roles are referenced directly by name — no path prefix required. Ansible resolves them via roles_path.
Every role ships a shared tasks/main.yml loader that provides a consistent execution contract:
- Requires a mandatory
ENVvariable (e.g.,dev,staging,prod) - Enforced regex: alphanumeric, hyphens, underscores only
Config is built from least to most specific, merged with combine(recursive=True):
role defaults/main.yml
→ vars/<os_family>.yml
→ vars/<os_family>_<dist>.yml
→ vars/<os_family>_<dist>_<ver>.yml
→ vars/<os_family>_<dist>_<ver>_<env>.yml
→ caller-supplied role var overrides
The loader selects the most specific matching task file that exists:
tasks/redhat_rocky_10.yml ← most specific (family + distro + version)
tasks/redhat_rocky.yml ← distro-level fallback
tasks/redhat.yml ← family-level fallback
A role like python3_pip can ship a single redhat.yml that works across all RedHat-family systems, while roles with version-specific logic provide redhat_rocky_10.yml.
A 0700 root:root temp directory is created before task execution and always cleaned up in an always: block — even on failure.
| Role | Description | Status |
|---|---|---|
python3_pip |
Installs, upgrades, and configures Python3 pip with a security-hardened pip.conf |
Stable |
| Role | Description | Status |
|---|---|---|
RedHat_Rocky_10 |
Full OS bootstrap: Ansible venv, packages, hostname | In Progress |
RedHat_Rocky_9 |
Rocky Linux 9 bootstrap | Planned |
RedHat_Rocky_8 |
Rocky Linux 8 bootstrap | Planned |
- Ansible >= 2.17
- Python >= 3.12
pre-commit(for local hook enforcement)
# Install pre-commit hooks (run once after cloning)
pip install pre-commit
pre-commit install
pre-commit install --hook-type commit-msg
# Lint all files
pre-commit run --all-files
ansible-lint
yamllint --config-file .yamllint.yml .- hosts: all
vars:
ENV: prod
roles:
- python3_pipAll role defaults live under a namespaced key in defaults/main.yml. Override specific settings without replacing the entire structure:
# group_vars/prod.yml
python3_pip:
self_upgrade:
version: '24.3.1'
templates:
'/etc/pip.conf':
file:
mode: '0640'This project uses Conventional Commits, enforced by pre-commit. Merging to PROD triggers release-please, which opens a Release PR and eventually creates a tagged GitHub Release.
<type>(<scope>): <description>
Types: feat | fix | docs | refactor | test | chore | perf | ci | build | revert
Scope: role name or 'framework'
feat(python3_pip): add Debian apt task file
fix(RedHat_Rocky_10): correct Python venv version comparison
chore(ci): pin ansible-lint to 25.2.0
MIT — see LICENSE.