Saltar a contenido

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

  • No aplica.

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.