Fase 0 — Preparación¶
Objetivo¶
Tener el repo clonado, Ansible operativo, inventario validado y (opcional) un informe de hardware medido antes de tocar red o clústeres.
Qué aprendes¶
Cómo Ansible usa un inventario como fuente de verdad de hosts, y por qué un discovery opcional evita suposiciones sobre RAM, disco y arquitectura al elegir roles (control-plane, Longhorn, etc.).
Stack de esta fase¶
flowchart LR
Op[Operador] --> Repo[Repo_homelab]
Op --> Ansible[Ansible]
Ansible --> Inv[inventory.ini]
Ansible --> Disc[playbook_discovery]
Disc --> Reports[reports_md]
Profundización: Discovery de hardware · Inventario
Antes de empezar¶
- Tres nodos accesibles por SSH (aunque aún con DHCP está bien).
- Python 3.11+ en tu estación.
- Clave SSH (Secure Shell) configurada hacia los nodos.
- GitHub: la organización
symintelcreada, con un teamdevops(sus miembros son quienes pueden entrar a ArgoCD) y una cuenta que sea owner de la organización para crear las Apps. Detalle en Plataforma symintel — GitHub. - 1Password: la app de escritorio instalada, con una bóveda llamada
HomeLaby Settings → Developer → Integrate with other apps activado. Ahí se guardan las credenciales que usan los playbooks (qué items y campos).
Ejecutar¶
Clonar repo y entorno Ansible¶
git clone https://github.com/symintel/homelab.git
cd homelab
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt # Ansible, mkdocs, ansible-lint, etc.
ansible-galaxy collection install -r ansible/requirements.yml
Ruta del requirements.txt
requirements.txt vive en la raíz del repo, no en ansible/ — es un
error común confundirlo con ansible/requirements.yml (ese es el
manifiesto de collections de Galaxy, un archivo YAML distinto, no algo
que pip install -r pueda instalar).
Día 0 — nodos recién instalados (solo la primera vez por nodo)¶
Un nodo recién flasheado (Debian netinst) todavía no tiene python3 ni
sudo listos, y el usuario admin no está en el grupo sudo — el ping
de más abajo (usa el módulo ansible.builtin.ping, que sí necesita Python
en el destino) va a fallar sin este paso primero:
Detalle completo (por qué conecta como root y dónde encaja en el resto
del bootstrap) en
ansible/bootstrap/README.md.
Si tus 3 nodos ya tienen un usuario admin con sudo funcionando, salteá
este paso.
Validar inventario¶
Revisa ansible/inventory.ini: ansible_host, static_ip,
bridge_iface por nodo.
Discovery opcional (recomendado la primera vez)¶
Salida en ansible/reports/ (gitignored): ficha por nodo + summary.md.
Recopila CPU, RAM, disco y red con lscpu, free -h, lsblk, ip -br link
y compara con Inventario de hardware.
GitHub y 1Password — org symintel (manual, una sola vez)¶
Aquí se preparan, una sola vez, las cuentas y credenciales de GitHub que el
HomeLab necesita: las Apps con las que el clúster habla con GitHub (entre
ellas la que usa ArgoCD para leer el repo privado symintel/gitops) y los
repos base (gitops, core-pipelines e infra). Todo se crea a mano, y las credenciales se
guardan en 1Password para que después los playbooks las lean desde ahí. El
detalle de cada una (permisos, dónde encontrar cada dato en GitHub y cómo
cargarlo en 1Password) está en
Plataforma symintel — GitHub.
Los items de 1Password van en la bóveda HomeLab, casi todos como
Nota segura con campos propios. El título del item y el nombre de cada
campo tienen que ser exactos, porque el playbook los busca por nombre:
cómo crear el item.
Con una cuenta owner de la organización symintel:
- GitHub App
symintel-terraform→ itemsymintel-terraform(Nota segura) con los camposapp_id(Texto),installation_id(Texto) yprivate_key(Contraseña, el.pemcompleto). Permisos y dónde está cada dato. - GitHub App
symintel-arc-runners→ itemsymintel-arc-runners, con los mismos tres campos pero con los datos de esta App. Permisos y pasos. - OAuth App
Symintel Dex→ camposGITHUB_CLIENT_ID(Texto) yGITHUB_CLIENT_SECRET(Contraseña) en el itemsymintel-dex(Nota segura). Pasos. - Repos privados, con su contenido subido con git:
gitops.core-pipelines: en Settings → Actions → General → Access, elige "Accessible from repositories in the 'symintel' organization". No hace falta crear tags: mientras pruebas, los demás repos lo usan con@main.infra.
- GitHub App
symintel-argocd(solo lectura, instalada solo engitops) → itemsymintel-argocdcon los mismos tres campos. Va después de los repos porque se instala engitops. Permisos y pasos. - Llave de Sealed Secrets (opcional hasta la Fase 6): un par de llaves
generado con
openssl, en el itemsealed-secrets(certificateyprivate_key), para que sobreviva si reinstalas K3s. Comando y pasos. - Credenciales FTP (File Transfer Protocol) del repo
api:apies el primer proyecto del mapa de repos y despliega por FTP, así que necesita su itemftp-api(Nota segura) desde el primer pipeline. Cada repo que agregues después sigue el procedimiento de rutina — Agregar un repo. El item lleva 8 campos:dev_host,dev_user,dev_password,dev_remote_diry los mismos cuatro conprod_. Los*_passwordvan como Contraseña y el resto como Texto. Tabla con ejemplos.
Comprueba que todas las credenciales se pueden leer de 1Password. Son dos comandos, y ninguno toca un clúster ni muestra valores secretos:
--check: revisa cada item esperado y marca con ✓ los campos que están bien y con ✗ los que faltan, tienen otro nombre o están dentro de una sección. Córrelo primero: si algo está mal, dice exactamente qué.--dry-run: lee todos los valores y lista los Secrets que se van a crear en el clúster, con los valores ocultos (<redacted>). Confirma que las llaves se pueden interpretar.
El script lee 1Password a través de la app de escritorio, así que la app
tiene que estar desbloqueada y con Settings → Developer → Integrate with
other apps activado. Además hay que decirle qué cuenta usar con la
variable ONEPASSWORD_ACCOUNT_NAME: es el nombre de tu cuenta tal como
aparece arriba a la izquierda en la barra lateral de la app (por ejemplo
MCO Family). Si no la defines, usa Personal.
export ONEPASSWORD_ACCOUNT_NAME="MCO Family" # tu cuenta
.venv/bin/python ansible/scripts/apply_platform_secrets.py --check
.venv/bin/python ansible/scripts/apply_platform_secrets.py --dry-run
--check termina bien cuando todos los items tienen ✓ (el aviso de que no
hay items ftp-<repo> es solo informativo si ningún repo despliega).
Opciones¶
| Opción | Cuándo |
|---|---|
| Saltar discovery | Re-despliegue y hardware ya conocido |
| Actualizar inventario | Tras cambiar IPs en Fase 1 |
reports/Verificar¶
ansible -i ansible/inventory.ini incus_cluster -m ping
# todos → SUCCESS
export ONEPASSWORD_ACCOUNT_NAME="MCO Family" # tu cuenta
.venv/bin/python ansible/scripts/apply_platform_secrets.py --check
# todos los items con ✓
.venv/bin/python ansible/scripts/apply_platform_secrets.py --dry-run
# lista los Secrets de plataforma (valores <redacted>), sin errores de 1Password
Si falla¶
| Síntoma | Revisar |
|---|---|
UNREACHABLE |
ansible_host, firewall, clave SSH |
ping falla por Python ausente |
Nodo recién instalado — correr setup_sudo.yml (paso "Día 0" arriba) |
| Discovery sin reports | Ejecutar desde ansible/; permisos de escritura |
--check o --dry-run no leen 1Password |
App desbloqueada con Integrate with other apps y ONEPASSWORD_ACCOUNT_NAME con el nombre de tu cuenta. Si dice field cannot be found o Bóveda no encontrada, mira la salida de --check: marca qué item o campo no coincide (nombres esperados) |