Ansible CI (plan/apply)
CI/CD del bootstrap de k3s (k3s/ansible/): valida los cambios en cada PR y los
aplica automáticamente al mergear a main, en el runner self-hosted ARC.
Resumen
El bootstrap de k3s se define en k3s/ansible/ (roles, playbooks e inventario).
La Ansible CI automatiza su ciclo de vida con dos workflows de GitHub Actions que
corren en el runner self-hosted homelab (ARC, dentro de la LAN): un plan en
cada PR (lint + syntax-check + --check --diff + diff de Helm) y un apply
idempotente al mergear a main. Cierra el hueco de GitOps del bootstrap layer,
en espejo de terraform-plan.yml / terraform-apply.yml.
Estado
| Campo |
Valor |
| Estado |
Operativo |
| Argo CD Application |
— (GitHub Actions; no vive en el cluster) |
| Namespace |
— |
Despliegue
| Campo |
Valor |
| Método |
Workflows de GitHub Actions |
| Runner |
ARC self-hosted runs-on: homelab (ver ARC) |
| Imagen del job |
python:3.12-slim (instala ansible-core, kubectl y helm en el job) |
| Origen |
.github/workflows/ansible-plan.yml, .github/workflows/ansible-apply.yml |
| Objetivo |
k3s/ansible/playbooks/site.yml sobre los 3 nodos |
Red
| Campo |
Valor |
| Service |
— (job en el runner; SSH saliente a los nodos 192.168.20.10–12) |
| URL |
— |
Acceso y usuarios
- Clave SSH de CI dedicada (ed25519), distinta de la personal: la pública en
ci_ssh_keys (terraform/variables.tf) y en ~/.ssh/authorized_keys de
ubuntu en los 3 nodos; la privada solo como GitHub secret
ANSIBLE_SSH_PRIVATE_KEY.
- Secrets de GitHub:
ANSIBLE_SSH_PRIVATE_KEY (plan y apply) y
ARGOCD_REPO_TOKEN (apply; PAT read-only para registrar el repo en Argo CD).
No vienen de Vaultwarden/VKS: los consume GitHub Actions al lanzar el job.
Seguridad
- El runner self-hosted corre dentro de la LAN con SSH a los nodos y la clave CI
cargada. Riesgo acotado: el repo es privado (solo el propietario abre
PRs), el
apply nunca se dispara desde un PR (solo push a main; el
workflow_dispatch permite re-ejecutar a mano y debe usarse únicamente sobre
main), los runners son efímeros y --check omite las tareas
command/shell. El modelo de amenaza completo está en
docs/specs/2026-09-07-ansible-ci-design.md (Riesgos y mitigaciones).
Configuración
ansible-plan.yml (pull_request en k3s/ansible/** + el propio workflow):
ansible-lint + --syntax-check + --check --diff + diff offline de
helm template (traefik/argocd) comentado en la PR.
ansible-apply.yml (push a main en k3s/ansible/** +
workflow_dispatch): reejecución idempotente de site.yml, serializada con
concurrency (igual que terraform-apply.yml).
- Versiones pinneadas en
env (ansible-core, kubectl, helm).
host_key_checking = False vía ansible.cfg.
.ansible-lint con skip_list para el shell-out deliberado
(command/shell a helm/kubectl/curl).
Almacenamiento
Dependencias
- Depende de: ARC (runner
homelab en la LAN), clave SSH de CI.
- Usado por: el bootstrap layer (
k3s/ansible/**); despliega k3s, Traefik,
Argo CD, MetalLB, cert-manager y el resto de la plataforma bootstrap.
Backup y recuperación
- Re-ejecutable:
gh workflow run ansible-apply.yml --repo gorkarevilla/homelab.
El estado vive en Git; no hay datos propios.
Monitorización
- No expone métricas (es CI, no un servicio del cluster). El runner subyacente
sí se monitoriza vía ARC.
Referencias
- Runbook:
docs/runbooks/ansible-ci.md (clave CI, secrets, rotación, límites).
- Diseño:
docs/specs/2026-09-07-ansible-ci-design.md.
Notas / TODO
--check salta las tareas command/shell (vista parcial); se complementa
con lint + syntax-check + diff de helm template.
- El plan no valida que existan los secrets/certs referenciados (no tiene
kubeconfig); es responsabilidad del flujo VKS/cert-manager antes del merge.
- El apply no actualiza la versión de k3s: el
creates: /usr/local/bin/k3s
omite silenciosamente un bump de k3s_version; los charts (Traefik/Argo CD)
sí reconcilian.
helm template replica a mano las flags de helm de los roles; si cambian,
hay que actualizar el paso del workflow en el mismo PR.