# ansible-runner Centralized Ansible runner repository for the homelab. Contains the inventory, vault configuration, SSH credentials, and two reusable Gitea Actions workflows: one that builds the custom runner image, and one that executes Ansible playbooks from any role repository. --- ## Repository Structure ``` ansible-runner/ ├── docker/ │ └── Dockerfile # Custom ansible-act-runner image ├── inventory/ │ └── raspberries.yaml # Ansible inventory ├── .gitea/ │ └── workflows/ │ ├── build-image.yaml # Builds and pushes the runner image │ └── ansible-runner.yaml # Reusable workflow for all role repos └── example-caller-workflow.yaml # Example: how to call from another repo ``` --- ## Workflows ### `build-image.yaml` — Build the Ansible Act Runner Image Triggers automatically when `docker/Dockerfile` changes on `main`, or manually via `workflow_dispatch` with an optional force-rebuild flag. Runs on the `docker` label (directly on the runner host) to access the DinD sidecar that is configured in the OKD runner pod. Builds and pushes two tags: - `gitea.mod.home/ansible/ansible-act-runner:latest` - `gitea.mod.home/ansible/ansible-act-runner:` ### `ansible-runner.yaml` — Reusable Ansible Playbook Runner A `workflow_call` workflow that can be called from any role repository. Runs on the `ansible` label using the custom image, which has Node.js, Python, Ansible, and all required collections pre-installed. **Inputs:** | Input | Required | Default | Description | |-------|----------|---------|-------------| | `role_repo` | ✅ | — | Gitea repo of the role, e.g. `ansible/role-samba` | | `playbook_path` | ✅ | — | Path to playbook inside the role repo | | `inventory` | ❌ | `inventory/raspberries.yaml` | Inventory file relative to this repo | | `ansible_extra_args` | ❌ | `''` | Additional Ansible CLI arguments | **Secrets passed through:** | Secret | Description | |--------|-------------| | `TOKEN` | Gitea access token for checking out private repos | --- ## Calling from a Role Repository Place a workflow file in `.gitea/workflows/` of your role repository: ```yaml name: 🚀 Deploy on: push: branches: - main workflow_dispatch: jobs: deploy: uses: ansible/ansible-runner/.gitea/workflows/ansible-runner.yaml@main with: role_repo: ansible/role-samba playbook_path: playbooks/deploy.yml ansible_extra_args: '--tags install' # optional secrets: TOKEN: ${{ secrets.TOKEN }} ``` --- ## Required Secrets All secrets are configured at the **Organization level** in Gitea (`ansible` org → Settings → Secrets) so they are available to all role repositories without duplication. | Secret | Used in | Description | |--------|---------|-------------| | `SSHKEY_B64` | `ansible-runner.yaml` | Base64-encoded ED25519 private key for SSH access to managed hosts | | `ANSIBLE_VAULT_KEY` | `ansible-runner.yaml` | Ansible Vault password | | `TOKEN` | `ansible-runner.yaml` | Gitea access token (`repo` scope) for checking out role repos | | `REGISTRY_USER` | `build-image.yaml` | Gitea username for container registry login | | `REGISTRY_PASSWORD` | `build-image.yaml` | Gitea access token with `package:write` scope | | `TELEGRAM_BOT_TOKEN` | both | Telegram bot token for notifications | | `TELEGRAM_CHAT_ID` | both | Telegram chat ID for notifications | ### Creating the Gitea Access Token In Gitea → User Settings → Applications → Generate Token: - For `TOKEN`: scopes `repo` (read/write) - For `GITEA_REGISTRY_PASSWORD`: scope `package` (read/write) --- ## OKD Runner Configuration The act runner pod in the OKD cluster (`gitea-act-runner` namespace) runs with a DinD sidecar. The `build-image.yaml` workflow uses `runs-on: docker` to execute directly on the runner host where `DOCKER_HOST=tcp://localhost:2376` is available via the sidecar. The `ansible-runner.yaml` workflow uses `runs-on: ansible` and spawns a container from the custom image. Node.js, Python, Ansible, and all collections are pre-installed — no runtime installation required. ### Runner Labels (configured in OKD ConfigMap) The runner ConfigMap (`gitea-act-runner-config`) must have the following labels registered. Without the `docker` label, `build-image.yaml` will not be picked up by the runner. ```yaml # configmap.yaml — labels section runner: labels: - "docker:host" # required for build-image.yaml (runs-on: docker) - "ansible:host" # required for ansible-runner.yaml (runs-on: ansible) - "ubuntu-latest:docker://..." ``` | Label | `runs-on` value | Purpose | |-------|----------------|---------| | `docker:host` | `docker` | Direct host execution with DinD sidecar — used for Docker builds | | `ansible:host` | `ansible` | Direct host execution — Ansible jobs via container image | | `ubuntu-latest` | `ubuntu-latest` | Container execution via DinD | > **Note:** After changing the ConfigMap labels, the runner pod must re-register. > Delete the pod to force a restart: `kubectl delete pod -n gitea-act-runner -l app=gitea-act-runner` --- ## Bootstrap: First Image Build No manual build from a laptop is required. The existing `gitea/act_runner:latest` pod already has a DinD sidecar and the `docker:host` label registered, so it can build and push the custom image itself. **Steps:** 1. Create the repository in Gitea and push all files 2. Set the required secrets in the `ansible` org (see above) 3. Trigger the build manually via `workflow_dispatch` in Gitea Actions UI The runner will build the image and push it to `gitea.mod.home/ansible/ansible-act-runner:latest`. All subsequent builds are triggered automatically when `docker/Dockerfile` changes on `main`. --- ## Roadmap - [ ] TLS for Gitea registry via cert-manager (remove insecure flag) - [ ] Samba AD DC deployment playbook - [ ] Bind9 DNS backend playbook - [ ] Windows domain join playbook - [ ] Fluentbit → VictoriaLogs for Samba log shipping