# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## What This Repo Does Ansible automation for the BAB (Borrow a Boat) project backend. Manages the full lifecycle of an Appwrite-based backend running on a single RHEL 9 host (`bab1.mgmt.toal.ca`) via Ansible Automation Platform. Do not refer to AWX. Also contains Ansible EDA rulebooks for event-driven automation triggered by Gitea webhooks and Alertmanager alerts. ## Common Commands Run a playbook via ansible-navigator (preferred — uses execution environment): ```bash ansible-navigator run playbooks/.yml --mode stdout ``` Run with extra vars (required by several playbooks): ```bash ansible-navigator run playbooks/deploy_application.yml --mode stdout -e artifact_url= ``` Lint all playbooks: ```bash ansible-navigator lint playbooks/ --mode stdout ``` Install required collections: ```bash ansible-galaxy collection install -r requirements.yml ``` ## Architecture ### Inventory and Credentials There is no inventory file in this repo. For development, a static inventory is located in ~/Dev/inventories/bab-inventory/. In production, inventory and credentials (Appwrite API keys, ServiceNow instance, vault password) are managed externally in AAP. Sensitive files are gitignored: `ansible.cfg`, `secrets.yml`, `.vault_password`. ### Playbook Roles | Playbook | Purpose | Notable vars | |---|---|---| | `install_appwrite.yml` | Full RHEL 9 host setup: Docker, Appwrite container via compose | — | | `install_nginx.yml` | Nginx via `nginxinc.nginx_core` role + firewalld | — | | `configure_act_runner.yml` | Gitea Act Runner as systemd user unit (rootless) | `runner_user` | | `deploy_application.yml` | Downloads a release tarball and extracts to nginx webroot | `artifact_url` | | `provision_database.yml` | Creates Appwrite database, collections, and attributes via REST API | Appwrite vars | | `provision_users.yml` | Creates users in Appwrite via REST API (Argon2 hashed) | `bab_users` list | | `load_data.yml` | Loads seed data from `playbooks/files/database/*.json` into Appwrite | Appwrite vars | | `read_database.yml` | Dumps Appwrite collection data to `playbooks/files/database/` | Appwrite vars, targets `appwrite:&dev` | | `clean_logs.yml` | Removes large test log files from `/var/log` | — | | `investigate_high_cpu.yml` | Captures process data and opens ServiceNow incident + problem | `snow_instance`, EDA event vars | | `update_certificates.yml` | Requests and installs TLS certs from Red Hat IdM (IPA) | `ipa_admin_password`, cert path vars | ### Event-Driven Ansible (EDA) Rulebooks `rulebooks/gitea_webhook.yml` — listens for Gitea push webhooks carrying an `artifact_url` and triggers the `bab-deploy-application` AAP job template. `rulebooks/alertmanager_listener.yml` — listens on port 9101 for Prometheus Alertmanager events; routes to AAP job templates for log cleanup (`root filesystem over 80% full`) and CPU investigation (`ProcessCPUHog`). Scoped to `org == "OYS"`. ### Appwrite API Pattern Playbooks that talk to Appwrite use `ansible.builtin.uri` delegated to `localhost`, with `module_defaults` at the play level to set shared headers (`X-Appwrite-Project`, `X-Appwrite-Key`, `X-Appwrite-Response-Format`). All mutating calls use `status_code: [201, 409]` to tolerate re-runs — but true idempotency is incomplete (noted in `provision_database.yml`). ### Templates and Static Files - `playbooks/templates/` — Jinja2 templates: `act_runner.service` (systemd unit for Gitea runner), `appwrite_attribute_template.json.j2` (Appwrite schema helper), `cpuhog_ticket.j2` (ServiceNow ticket body) - `playbooks/files/database/` — JSON seed data files used by `load_data.yml` and written by `read_database.yml` ### Collections Used - `community.docker` — Docker image pulls and container management - `community.general` — RHSM repo management - `ansible.posix` — firewalld - `nginxinc.nginx_core` — Nginx install and config roles - `servicenow.itsm` — Incident and problem creation - `redhat.rhel_idm` — IPA certificate requests - `community.crypto` — TLS key/CSR generation - `ansible.utils` — `remove_keys` filter used in `load_data.yml` - `ansible.eda` — webhook and alertmanager sources