Ansible: introduccion e inventarios
Ansible automatiza configuracion de sistemas y despliegues por SSH (o WinRM) sin agente permanente en el nodo. Describes el estado deseado en YAML; el control node empuja cambios a los hosts del inventario.
Capitulos
- Introduccion e inventarios
- Playbooks tasks y handlers
- Variables facts y templates
- Roles
- Vault y secretos
- Idempotencia
- Testing y buenas practicas
Que problema resuelve
Sin automatizacion:
- SSH manual a cada servidor, checklist en Notion.
- "En staging esta bien" porque alguien aplico un fix a mano.
- Drift entre nodos del mismo rol (nginx distinto, paquetes distintos).
Con Ansible:
inventario + playbook -> ansible-playbook -> hosts en el estado declaradoNo necesitas demonio en el target: solo Python (Linux) o PowerShell (Windows) y acceso remoto.
Conceptos clave
| Concepto | Descripcion |
|---|---|
| Control node | Maquina donde ejecutas ansible / ansible-playbook |
| Managed node | Host destino (SSH, puerto 22 por defecto) |
| Inventario | Lista de hosts y grupos (hosts.ini o YAML) |
| Modulo | Unidad de trabajo (ping, apt, copy, template) |
| Playbook | YAML con plays: hosts + tasks |
| Ad-hoc | Un modulo suelto sin playbook (ansible all -m ping) |
Instalacion
Linux (pipx / pip)
# Recomendado: entorno aislado
python3 -m pip install --user pipx
pipx install ansible
# O en venv de proyecto
python3 -m venv .venv
source .venv/bin/activate
pip install "ansible-core>=2.16,<2.18"ansible (paquete meta) incluye colecciones; ansible-core es el motor minimo.
Windows (WSL2)
Usa WSL2 con Ubuntu; el control node oficial en Windows nativo es limitado. Dentro de WSL:
sudo apt update
sudo apt install -y python3-pip python3-venv
python3 -m venv ~/.venvs/ansible
source ~/.venvs/ansible/bin/activate
pip install ansible-coremacOS
brew install ansible
# o pipx install ansibleVerifica:
ansible --version
ansible-playbook --versionFija version en CI (requirements.txt o image con tag concreto).
Inventario INI
inventory/hosts.ini:
[web]
web1.example.com
web2.example.com ansible_host=10.0.1.12
[db]
db1.example.com ansible_port=2222
[app:children]
web
db
[web:vars]
ansible_user=deploy
app_env=stagingansible_host— IP si el nombre DNS no resuelve desde el control node.ansible_port— SSH no estandar.:children— grupo padre (agrupa otros grupos).:vars— variables a nivel de grupo.
Inventario YAML
inventory/hosts.yml:
all:
children:
web:
hosts:
web1.example.com:
web2.example.com:
ansible_host: 10.0.1.12
vars:
ansible_user: deploy
app_env: staging
db:
hosts:
db1.example.com:
ansible_port: 2222
app:
children:
web:
db:YAML escala mejor con muchos hosts y variables anidadas.
ansible.cfg minimo
En la raiz del proyecto:
[defaults]
inventory = inventory/hosts.ini
remote_user = deploy
host_key_checking = True
retry_files_enabled = False
interpreter_python = auto_silent
[privilege_escalation]
become = True
become_method = sudo
become_user = rootPrioridad de config: ANSIBLE_CONFIG > ./ansible.cfg > ~/.ansible.cfg > /etc/ansible/ansible.cfg.
Primer contacto: modulo ping
ping no es ICMP: comprueba que Ansible puede conectar, autenticar y ejecutar Python en el remoto.
# Clave SSH cargada (ssh-agent) o IdentityFile en inventory
ansible all -i inventory/hosts.ini -m pingSalida esperada:
web1.example.com | SUCCESS => {
"changed": false,
"ping": "pong"
}Ad-hoc utiles:
ansible web -m setup -a "filter=ansible_distribution*"
ansible web -m command -a "uptime" --become
ansible db -m shell -a "systemctl is-active postgresql" --becomePrefiere modulos dedicados (apt, systemd, copy) frente a shell/command cuando existan.
Inventario dinamico (idea)
En cloud, genera hosts desde la API:
# Ejemplo conceptual: plugin aws_ec2 (coleccion amazon.aws)
# inventory/aws_ec2.yml
plugin: amazon.aws.aws_ec2
regions:
- eu-west-1
filters:
tag:Role: web
keyed_groups:
- key: tags.Env
prefix: envansible-inventory -i inventory/aws_ec2.yml --graphEl inventario estatico basta para lab y muchos on-prem; dinamico evita listas obsoletas.
Estructura de proyecto tipica
ansible-demo/
ansible.cfg
inventory/
hosts.ini
group_vars/
web.yml
host_vars/
web1.example.com.yml
playbooks/
site.yml
roles/
nginx/
requirements.ymlFlujo de trabajo
editar inventario/playbook -> ansible-playbook --check -> apply -> commitComandos base:
ansible-inventory -i inventory/hosts.ini --list
ansible-playbook -i inventory/hosts.ini playbooks/site.yml --check --diff
ansible-playbook -i inventory/hosts.ini playbooks/site.yml--check simula (limitado por modulos); --diff muestra cambios en ficheros.
Ansible vs alternativas
| Herramienta | Enfoque |
|---|---|
| Ansible | Push por SSH, YAML, sin agente |
| Terraform | Provisionar infra (APIs cloud); complementa Ansible |
| Puppet / Chef | Agente + pull, mas ops tradicionales |
| Salt | Agente o SSH; mas orientado a eventos |
Patron habitual: Terraform crea VMs; Ansible instala paquetes, configs y apps.
Buenas practicas iniciales
- Un repo por producto o plataforma; inventario versionado (sin secretos).
- Grupos por rol (
web,db) y por entorno (staging,prod) si hace falta. - SSH por clave; usuario dedicado (
deploy) con sudo acotado. - No desactives
host_key_checkingen produccion salvo bootstrap controlado. - Documenta en README como obtener acceso al inventario (VPN, bastion).
Errores comunes
- Inventario con hostname que no resuelve y sin
ansible_host. ansible all -m pingfalla por Python ausente en el target (instalapython3).- Mezclar
becomeglobal sin necesidad (rompe hosts sin sudo). - Commitear
ansible.cfgconhost_key_checking = Falsecomo default de equipo. - Usar
localhosten inventario pensando que es remoto (es el control node).
Ejercicios
- Instala
ansible-core, creainventory/hosts.inicon un host real o un contenedor SSH, y obtenpongcon-m ping. - Anade grupos
webydb, un grupo hijoapp, y lista el grafo conansible-inventory --graph. - Ejecuta
ansible web -m setupy localizaansible_os_familyyansible_memtotal_mb. - Escribe un
ansible.cfgde proyecto que apunte a tu inventario y usuario SSH.
Siguiente paso
El capitulo 2 introduce plays, tasks y handlers (reinicios solo cuando hace falta).
