====== 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]]