====== Ansible: Conceptos fundamentales ======
Sección perteneciente al [[informatica:ciberseguridad:cursos:curso_ansible_automatizacion_it|curso Ansible Automatización IT]]
https://player.vimeo.com/video/786197388
===== Ansible en entornos virtuales de Python =====
- Instalar pip3
- Instalar python3 virtualenv
- Crear un entorno virtual
- Activar el entorno virtual
- Lanzar una nueva terminal
- Instalar Ansible
Si estamos en una Debian, para instalar el módulo de Python que nos permite crear entornos virtuales:
apt install python3-venv
Crearemos un directorio para crear nuestro entorno virtual, por ejemplo:
mkdir /home/pepito/test_venv
Ahora creamos el entorno virtual en ese directorio:
python3 -m venv /home/pepito/test_venv
Si ahora miramos el contenido del directorio ''/home/pepito/test_venv'' veremos algo como:
bin include lib lib64 pyvenv.cfg
Lo que nos falta es activar este nuevo entorno virtual:
source /home/pepito/test_venv/bin/activate
Sabremos que estamos en el nuevo entorno si en el prompt aparece primero el nombre de dicho entorno:
(test_venv) pepito@box:/home/pepito/test_venv$
Para instalar Ansible solo para este entorno virtual:
pip3 install ansible
Si miramos dónde está este nuevo binario:
which ansible
Cuando ejecutemos ''ansible'', se ejecutará dentro del entorno virtual.
Para salir del entorno virtual, ejecutamos ''exit''.
Si no quisiésemos usar más ese entorno virtual, podemos borrarlo. Al fin y al cabo no es más que un directorio en el sistema:
rm -rf /home/pepito/test_venv
===== Introducción a los módulos en Ansible =====
Los módulos son trozos de código escrito en Python que realizan una determinada tarea.
* [[https://docs.ansible.com/ansible/2.9/modules/modules_by_category.html|Documentación oficial de los módulos]]
Si no existe ningún módulo que cumpla nuestras necesidades, existen los //run commands//:
* ''command'': ejecuta el comando introducido por el usuario en el equipo destino. Es el más seguro y predecible.
* ''shell'': ejecuta los comandos en una shell (por ejemplo, ''/bin/sh'') y permite utilizar pipes, etc. Debe usarse con cuidado.
* ''script'': transfiere un script y lo ejecuta en el equipo destino.
* ''raw'': ejecuta el comando sin pasar por el control de Ansible
Los módulos ofrecen //idempotencia//, es decir, da igual las veces que lo ejecutemos, el resultado será el mismo, llegaríamos siempre al estado deseado. Esto con los //run commands// es más difícil y hay que ser cuidadosos.
===== Ejecutando módulos de forma standalone =====
Empezamos con el módulo ''[[https://docs.ansible.com/ansible/latest/collections/ansible/builtin/ping_module.html|ping]]'':
ansible localhost -m ping
Podemos ver información sobre un módulo desde línea de comandos: ''ansible-doc ''
ansible localhost -m ping -a "data='correcto'"
Poner la salida de los comandos anteriores
Ejemplo con el módulo ''[[https://docs.ansible.com/ansible/latest/collections/ansible/builtin/script_module.html#ansible-collections-ansible-builtin-script-module|script]]'':
ansible localhost -m script -a "/home/pepito/miscript.sh"
Contenido de ''miscript.sh'':
#!/bin/bash
echo "Hola, mundo!"
Poner ejemplo de salida
Si queremos cambiar la //shell// a usar:
ansible localhost -m script -a "/home/pepito/miscript.sh executable=/bin/sh"
===== Preparando las máquinas a gestionar con usuario y contraseña =====
En la realidad lo que queremos en configurar una o varias máquinas remotas.
==== Equipo a gestionar ====
* Crear un usuario para Ansible
* Verificar que el servicio SSH está funcionando
Para crear usuario desde línea de comandos:
adduser ansible
Verificamos si el servicio SSH está corriendo:
systemctl status sshd
Podríamos verificar también si tenemos conectividad a nivel de red entre los equipos a gestionar y el equipo que hace de nodo de gestión:
ping ip.equipo.destino.1
ping ip.equipo.destino.2
ping ip.equipo.destino.X
==== Nodo de gestión ====
* Confiar en la clave SSH del equipo destino
* Especificar el usuario y contraseña a utilizar para realizar la gestión
Para usar ansible desde el nodo de gestión:
ansible dir.ip.maquina.destino --user=ansible -k -m ping
* ''-k'' nos pedirá la contraseña en lugar de tener que indicarla como argumento.
De esta manera habríamos validado que Ansible puede conectarse al equipo remoto y recuperar información (en este caso usando el módulo ''ping'').
===== Preparando las máquinas a gestionar con clave pública =====
Para evitar dejar las credenciales en algún sitio accesible, usaremos la criptografía de clave pública. La privada nos la quedamos y la pública se la pasamos a los sistemas que queremos gestionar con Ansible.
Esta es la manera recomendable de realizar las conexiones a otros equipos
==== Equipo a gestionar ====
* Disponer de un usuario para Ansible
* Verificar que el servicio SSH está funcionando.
* Configurar las claves SSH autorizadas.
==== Nodo de gestión ====
* Generar clave SSH para la autenticación
* Configuar en la clave SSH del equipo destino
* Indicar a Ansible la ubicación de la clave
* Especificar el usuario a utilizar para realizar la conexión.
Creamos el par de claves pública y privada:
ssh-keygen -N "" -C "Ansible"
Por defecto, las claves se generan en ''/home/usuario/.ssh/id_rsa'' (privada) y ''/home/usuario/.ssh/id_rsa.pub'' (pública)
Ahora tendríamos que llevar la clave pública a los equipos a gestionar. Para ello, se puede copiar y pegar el contenido del fichero ''id_rsa.pub'' en ''/home/pepito/.ssh/authorized_keys'' o realizarlo mediante el comando ''ssh-copy-id'':
ssh-copy-id usuarioremoto@equiporemoto
Finalmente, para probar a conectarnos con claves:
ansible dir.ip.equipo.remoto --user=ansible --key-file /home/pepito/.ssh/id_rsa -m ping
* ''%%--%%key-file'': permite indicar dónde está la clave privada del nodo de gestión.
===== Inventarios estáticos =====
Fichero con la lista de los sistemas que queremos configurar. En los estáticos no son más que un fichero de texto con información de los equipos.
Ejemplo:
10.0.65.40
10.0.65.42
10.0.65.50
host.example.com
También son válidos:
[control]
control ansible_host=10.0.42.10
[web]
node-[1:3] ansible_host=10.0.42.[5:8]
ansible ip.dir.equipo.remoto -u ansible --key-file /home/pepito/.ssh/id_rsa -m ping
Ansible crea por defecto un inventario estático en ''/etc/ansible/hosts''. Ahí tendríamos que añadir los equipos que queremos gestionar.
Añadir ejemplos de lo anterior.
Para crear nuestro propio inventario estático, creamos un fichero de texto con el siguiente contenido:
10.0.40.10
10.0.40.20
Para ejecutar Ansible sobre ese inventario:
ansible all -i /home/pepito/inventario -u ansible --key-file /home/pepito/.ssh/id_rsa -m ping
Podríamos "complicar" un poco el fichero de inventario:
[servidor_web]
10.0.40.10
[bbdd]
10.0.40.20
ansible all -i /home/pepito/inventario -l servidor_web -u ansible --key-file /home/pepito/.ssh/id_rsa -m ping
De esa manera, solo se ejecutará el módulo ''ping'' sobre la máquina etiquetada como ''servidor_web''.
Si queremos agrupar máquinas:
[servidor_web]
10.0.40.10
[bbdd]
10.0.40.20
[aplicacion:children]
servidor_web
bbdd
ansible all -i /home/pepito/inventario -l aplicacion -u ansible --key-file /home/pepito/.ssh/id_rsa -m ping
Más cosas, añadiendo alias:
[servidor_web]
10.0.40.10
[bbdd]
bbdd1 ansible_host=10.0.40.20
Y llamamos a Ansible sobre el equipo con la etiqueta que creamos anteriormente:
ansible bbdd1 -i /home/pepito/inventario -u ansible --key-file /home/pepito/.ssh/id_rsa -m ping
===== Qué son los facts en Ansible =====
Los //facts// permiten recoger información sobre los sistemas objetivo y realizar así ciertas modificaciones en función de esa información recogida.
ansible servidor_web -i /home/pepito/inventario -u ansible --key-file /home/pepito/.ssh/id_rsa -m setup
* El módulo ''setup'' permite recoger los //facts//
Poner salida del comando anterior
Podríamos filtrar (mirar documentación oficial del módulo ''setup''):
ansible servidor_web -i /home/pepito/inventario -u ansible --key-file /home/pepito/.ssh/id_rsa -m setup -a "filter=ansible_processor"
Cuando usemos Playbooks, por defecto Ansible recoge todos los //facts//.
===== Recursos =====
* [[https://docs.ansible.com/ansible/latest/inventory_guide/intro_inventory.html|How to build your inventory]]
* [[https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_vars_facts.html|Discovering variables: facts and magic variables]]