diff --git a/.gitignore b/.gitignore index 50541cf..6f1dd02 100644 --- a/.gitignore +++ b/.gitignore @@ -6,4 +6,8 @@ env *.json .lock docs/dev-environment.md -collections/ \ No newline at end of file +collections/ + +# ansible-navigator artifacts +ansible-navigator.log +playbook-artifacts/ \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index d668a43..1ecc929 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,18 @@ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). ## Unreleased +### Added +- `ansible-navigator.yml` — navigator configuration for Red Hat EE ee-supported-rhel9 with volume mounts for ~/.ansible/ and environment variable passthrough (closes #167) +- `scripts/bootstrap.sh` — bootstrap wrapper script with inventory validation, env var checks, and automatic Automation Hub token extraction +- `.gitignore` — exclude ansible-navigator.log and playbook-artifacts/ from version control + +### Changed +- `ansible.cfg` — removed collections_path (collections pre-installed in EE image), moved Automation Hub token to env var lookup, removed hardcoded token value (closes #167) +- `CLAUDE.md` — updated Prerequisites section to use ansible-navigator + podman pull instead of ansible-galaxy collection install; updated bootstrap commands to use ansible-navigator run; added ansible-navigator.yml and scripts/bootstrap.sh to Key Files table; added navigator convention (closes #167) +- Workflow migrated from ansible-galaxy + ansible-playbook to ansible-navigator with Red Hat supported Execution Environment (closes #167) + +### Previous Unreleased + ### Added - `inventories/rhdp-acme-cac/` — inventory for acme CaC demo environment diff --git a/CLAUDE.md b/CLAUDE.md index 791d5d8..a29d125 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -22,16 +22,29 @@ Run `playbooks/bootstrap_dev.yml` first — it creates the prerequisites automat Run `/aap-first-time` inside Claude Code to set these up interactively, or configure manually: -- `~/.ansible/ansible.cfg` with a valid Automation Hub token under `[galaxy_server.rh_certified]` +- Red Hat Container Registry authentication: + ```bash + podman login registry.redhat.io + # Username: your Red Hat account + # Password: your Red Hat password or registry token + ``` + +- Pull the AAP 2.6 Execution Environment image: + ```bash + podman pull registry.redhat.io/ansible-automation-platform-26/ee-supported-rhel9:latest + ``` + +- `~/.ansible/ansible.cfg` with a valid Automation Hub token under `[galaxy_server.automation_hub]` - Get it from: `console.redhat.com → Automation Hub → Connect to Hub → API token` + - `~/.ansible/secrets2` containing your vault password (single line) -- Collections installed locally: -```bash -ANSIBLE_CONFIG=~/.ansible/ansible.cfg \ - ansible-galaxy collection install ansible.platform ansible.controller \ - -p ./collections -``` +- ansible-navigator installed: + ```bash + python3 -m pip install ansible-navigator + ``` + +**Note**: Collections are NOT installed locally — they are pre-installed in the EE container image. ### Running the Bootstrap @@ -39,15 +52,26 @@ Each environment gets its own named inventory. Copy the sample and set env vars: ```bash cp -r inventories/rhdp-sample-demo/ inventories/rhdp--/ + export CONTROLLER_HOST= export CONTROLLER_USERNAME=admin export CONTROLLER_PASSWORD= -ansible-playbook -i inventories/rhdp--/ playbooks/bootstrap_dev.yml + +# Run with ansible-navigator +ansible-navigator run playbooks/bootstrap_dev.yml \ + -i inventories/rhdp--/ \ + --mode stdout + +# Or use the helper script +./scripts/bootstrap.sh rhdp-- ``` The inventory `group_vars/all.yml` resolves all sensitive values at runtime via env var and file lookups — no secrets are stored in the inventory. +The bootstrap runs inside the Red Hat supported Execution Environment container, +ensuring identical behavior between local development and AAP production execution. + The playbook creates: - Automation Hub certified and validated credentials - Galaxy credentials associated with the Default Organization @@ -90,9 +114,12 @@ claude plugins update aap-skills@aap-skills | File | Purpose | |------|---------| -| `playbooks/bootstrap_dev.yml` | Inventory-driven bootstrap playbook — run with `-i inventories/rhdp--/` | +| `ansible-navigator.yml` | Navigator configuration — EE image, volume mounts, environment variables | +| `playbooks/bootstrap_dev.yml` | Inventory-driven bootstrap playbook — run with ansible-navigator | | `playbooks/main.yml` | Main CaC setup playbook (runs inside AAP) | | `inventories/rhdp-sample-demo/` | Sample inventory template — copy for each new environment | +| `scripts/bootstrap.sh` | Bootstrap wrapper script with validation and token extraction | +| `collections/requirements.yml` | Collection dependencies (reference only — pre-installed in EE) | | `docs/dev-environment.md` | Local dev credentials — gitignored, never commit | | `ROADMAP.md` | DC1 strategic roadmap and migration status | | `CHANGELOG.md` | Record of all changes — always update before committing | @@ -104,4 +131,6 @@ claude plugins update aap-skills@aap-skills - One fix per branch and PR - Use `ansible.platform` modules where available; fall back to `ansible.controller` only when no platform equivalent exists +- Run playbooks with `ansible-navigator` to ensure execution environment consistency +- Collections are managed via the EE container image, not local installation - Any playbook that creates a token must delete it in an `always:` block diff --git a/ansible-navigator.yml b/ansible-navigator.yml new file mode 100644 index 0000000..994ef7a --- /dev/null +++ b/ansible-navigator.yml @@ -0,0 +1,43 @@ +--- +ansible-navigator: + ansible: + config: + path: ./ansible.cfg + + execution-environment: + container-engine: podman + enabled: true + image: registry.redhat.io/ansible-automation-platform-26/ee-supported-rhel9:latest + pull: + policy: missing + + # Volume mounts for local development + volume-mounts: + - src: ~/.ansible/ + dest: /home/runner/.ansible/ + options: Z + - src: ./ + dest: /runner/project/ + options: Z + + # Environment variables passed from host + environment-variables: + pass: + - CONTROLLER_HOST + - CONTROLLER_USERNAME + - CONTROLLER_PASSWORD + - ANSIBLE_GALAXY_TOKEN + + logging: + level: warning + append: true + file: ./ansible-navigator.log + + playbook-artifact: + enable: true + save-as: ./playbook-artifacts/{playbook_name}-{time_stamp}.json + + mode: stdout + + # Set timezone inside container + time-zone: America/Phoenix diff --git a/ansible.cfg b/ansible.cfg index 47cd7d2..12f4bb3 100644 --- a/ansible.cfg +++ b/ansible.cfg @@ -7,8 +7,7 @@ deprecation_warnings = false forks = 10 gathering = explicit roles_path = ./roles/ -collections_path = ./collections/ -inventory = /home/eames/git-repos/aap.as.code/my_inventory +# collections_path removed - collections pre-installed in EE image [privilege_escalation] become = false @@ -17,3 +16,15 @@ become_user = root [persistent_connection] command_timeout = 30 + +[galaxy] +server_list = automation_hub, release_galaxy + +[galaxy_server.automation_hub] +url=https://console.redhat.com/api/automation-hub/content/published/ +auth_url=https://sso.redhat.com/auth/realms/redhat-external/protocol/openid-connect/token +token={{ lookup('ansible.builtin.env', 'ANSIBLE_GALAXY_TOKEN') }} + +[galaxy_server.release_galaxy] +url=https://galaxy.ansible.com/ +token= diff --git a/scripts/bootstrap.sh b/scripts/bootstrap.sh new file mode 100755 index 0000000..f3d5704 --- /dev/null +++ b/scripts/bootstrap.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash +set -euo pipefail + +INVENTORY="${1:-}" +if [[ -z "$INVENTORY" ]]; then + echo "Usage: $0 " + echo "Example: $0 rhdp-customer-demo" + exit 1 +fi + +INVENTORY_PATH="inventories/${INVENTORY}/" +if [[ ! -d "$INVENTORY_PATH" ]]; then + echo "ERROR: Inventory not found: $INVENTORY_PATH" + exit 1 +fi + +# Verify required environment variables +: "${CONTROLLER_HOST:?ERROR: CONTROLLER_HOST not set}" +: "${CONTROLLER_USERNAME:?ERROR: CONTROLLER_USERNAME not set}" +: "${CONTROLLER_PASSWORD:?ERROR: CONTROLLER_PASSWORD not set}" + +# Extract Automation Hub token from ansible.cfg if not already set +if [[ -z "${ANSIBLE_GALAXY_TOKEN:-}" ]]; then + if [[ -f ~/.ansible/ansible.cfg ]]; then + export ANSIBLE_GALAXY_TOKEN=$(grep -A3 '\[galaxy_server.automation_hub\]' ~/.ansible/ansible.cfg | grep token | cut -d'=' -f2 | tr -d ' ') + fi +fi + +echo "Running bootstrap for inventory: $INVENTORY" +ansible-navigator run playbooks/bootstrap_dev.yml \ + -i "$INVENTORY_PATH" \ + --mode stdout \ + --pull-policy missing