Ansible es una herramienta de software libre para configurar y administrar hosts. Combina instalación multi-nodo, ejecuciones de tareas ad-hoc y administración de configuraciones. Adicionalmente, Ansible es categorizado como una herramienta de orquestación. Maneja nodos a través de SSH y no requiere ningún software remoto adicional, excepto Python. Utiliza un sistema llamado playbooks para lanzar las instrucciones definidas en ficheros escritos en YAML y gestiona los hosts mediante un inventariado.
En esta práctica, vamos a instalar ansible en un sistema CentOS7
Instalación
Instalar los repositorios Epel
yum -y install epel-release
Instalar ansible
yum -y install ansible
Primeros pasos
Configurar el archivo de inventariado
Ansible, por defecto utiliza un fichero llamado hosts para almacenar todo el inventario de máquinas que se va a gestionar
vim /etc/ansible/hosts
Hay diferentes formas de declarar los hosts
[Nombre_Grupo] alias_host1 alias_host2 alias_host3 [Nombre_Grupo] IP_host1 IP_host2 IP_host3 [Nombre_Grupo] alias_host[1:3]
Crear la key ssh
Para poder utilizar ansible con los clientes, hay que pasarles la ssh-key publica a cada uno. Para ello, primero hay que generar la key
ssh-keygen Generating public/private rsa key pair. Enter file in which to save the key (/root/.ssh/id_rsa): Created directory '/root/.ssh'. Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /root/.ssh/id_rsa. Your public key has been saved in /root/.ssh/id_rsa.pub. The key fingerprint is: 68:3d:60:26:38:f4:15:73:cd:8e:76:8f:9f:6b:1c:4b root@ansible The key's randomart image is: +--[ RSA 2048]----+ | . +..o | | . o . o o | | o o + o | | . + +o o | | o.S. o | | . .. E | | + + | | * | | ... | +-----------------+
Propagar la ssh key pública
Para que ansible se pueda conectar con los clientes, estos tienen que tener la key pública. La manera tradicional de hacerlo es:
ssh-copy-id root@host
Pero si se hace de ese modo, hay que hacerlo de uno en uno. Para ser mas eficientes, vamos a crear un script que automatice el proceso
vim ssh-massive.sh
for ip in `cat /etc/ansible/hosts`; do sshpass -p "<contraseña>" ssh-copy-id -o "StrictHostKeyChecking no" -i ~/.ssh/id_rsa.pub root@$ip; done
Darle permisos de ejecución
# chmod +x ssh-massive.sh
Una vez añadidos todos los servidores ejecutar el script
# ./ssh.massive.sh
/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed /bin/ssh-copy-id: ERROR: ssh: Could not resolve hostname [nodes]: Name or service not known /bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed /bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys Number of key(s) added: 1 Now try logging into the machine, with: "ssh -o 'StrictHostKeyChecking no' 'root@10.0.0.102'" and check to make sure that only the key(s) you wanted were added. /bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed /bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys Number of key(s) added: 1 Now try logging into the machine, with: "ssh -o 'StrictHostKeyChecking no' 'root@10.0.0.113'" and check to make sure that only the key(s) you wanted were added.
Nota: En los clientes hay que tener habilitadas ciertos parámetros en el archivo de configuración ssh
vim /etc/ssh/sshd_config
PermitRootLogin yes PasswordAuthentication yes
systemctl restart sshd
Una vez distribuidas las claves, se puede deshabilitar esto para mayor seguridad.
Comprobación
Para comprobar que todo esté bien, ejecutar el siguiente comando en el master
ansible -m ping all
10.0.0.113 | SUCCESS => { "changed": false, "ping": "pong" } 10.0.0.102 | SUCCESS => { "changed": false, "ping": "pong" }
En el caso de que se quiera lanzar comandos específicos, hay que lanzarlos de la siguiente manera
ansible -m shell -a 'uname -a' all
10.0.0.113 | SUCCESS | rc=0 >> Linux node2 3.10.0-514.21.2.el7.x86_64 #1 SMP Tue Jun 20 12:24:47 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux 10.0.0.102 | SUCCESS | rc=0 >> Linux node1 3.10.0-514.21.2.el7.x86_64 #1 SMP Tue Jun 20 12:24:47 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
Playbook
Los playbooks son las instrucciones que se ejecutarán en los hosts. Algo así como un manifiesto en puppet. Están escritos en YAML y son bastante intuitivos.
Vamos a empezar con un playbook muy sencillo que sea instalar vim en los hosts
vim /etc/ansible/vim.yml
--- - hosts: all tasks: - name: asegurarse que vim esta en la ultima version yum: name=vim state=latest
Ahora para lanzarlo
ansible-playbook /etc/ansible/vim.yml
PLAY [all] ******************************************************************************************************************************************************************************************************** TASK [Gathering Facts] ******************************************************************************************************************************************************************************************** ok: [10.0.0.102] ok: [10.0.0.113] TASK [asegurarse que vim esta en la ultima version] *************************************************************************************************************************************************************** ok: [10.0.0.113] changed: [10.0.0.102] PLAY RECAP ******************************************************************************************************************************************************************************************************** 10.0.0.102 : ok=2 changed=1 unreachable=0 failed=0 10.0.0.113 : ok=2 changed=0 unreachable=0 failed=0
Como se puede apreciar, solo se han generado cambios en el 10.0.0.102. Esto es porque en el otro ya estaba instalado vim y lo único que hace es asegurarse de que esté la última versión.
Variables
Para el uso de variables, sería del siguiente modo
vim /etc/ansible/paquetes.yml
--- - hosts: all vars: paquete: vim tasks: - name: Instalacion de Paquete yum: name={{ paquete }} state=latest
Pero si se quieren instalar varios paquetes, hay que hacerlo de la siguiente manera
--- - hosts: all tasks: - name: Instalacion de Paquetes yum: name={{ item }} state=latest with_items: - git - curl
O utilizar un array con los paquetes
--- - hosts: all vars: paquetes: [ 'git', 'curl' ] tasks: - name: Instalacion de paquetes yum: name={{ item }} state=latest with_items: paquetes
Roles
Ansible, recomienda el uso de roles para tener todo mas organizado. Los roles no son mas que playbooks que son llamados modularmente pero divididos en vez de en secciones en carpetas. Para hacerse una idea es similar a un modulo de puppet
La estructura de los roles, es la siguiente:
roles/ common/ files/ templates/ tasks/ handlers/ vars/ defaults/ meta/
Como se puede apreciar, el nombre del rol es common y luego de el cuelgan todas las carpetas donde habrá que meter los playbooks que queramos
Para hacer un PoC de esto, vamos a instalar apache. Para comenzar, hay que generar la estructura de rol
mkdir /etc/ansible/roles/apache && cd /etc/ansible/roles/apache && mkdir files handlers meta templates tasks vars
Ahora empezaremos a definir los playbooks. Cuando se trabaja con roles, los nombres de los playbooks principales tiene que ser main.yml
tasks
vim tasks/main.yml
--- - name: Instalacion de Apache yum: name=httpd state=latest notify: - start httpd - name: Eliminar el index.html command: rm /var/www/html/index.html register: html_old ignore_errors: True - name: Subir el index.html que queramos copy: src=index.html dest=/var/www/html mode=0644 when: html_old|success
handlers
vim handlers/main.yml
--- - name: start httpd service: name=httpd state=started
files
echo "esto es una prueba > files/index.html
En este caso, con esto es suficiente. Pero si se quisiese añadir variables o plantillas, habría que hacerlo en sus respectivas carpetas.
Ahora vamos a crear el playbook que llame a este
vim /etc/ansible/master.yml
--- - hosts: all roles: - apache
Lanzar el playbook
ansible-playbook /etc/ansible/master.yml
PLAY [all] ******************************************************************************************************************************************************************************************************** TASK [Gathering Facts] ******************************************************************************************************************************************************************************************** ok: [10.0.0.102] ok: [10.0.0.113] TASK [apache : Instalacion de Apache] ***************************************************************************************************************************************************************************** ok: [10.0.0.102] ok: [10.0.0.113] TASK [apache : Eliminar el index.html] **************************************************************************************************************************************************************************** [WARNING]: Consider using file module with state=absent rather than running rm changed: [10.0.0.113] changed: [10.0.0.102] TASK [apache : Subir el index.html que queramos] ****************************************************************************************************************************************************************** changed: [10.0.0.113] changed: [10.0.0.102] PLAY RECAP ******************************************************************************************************************************************************************************************************** 10.0.0.102 : ok=4 changed=2 unreachable=0 failed=0 10.0.0.113 : ok=4 changed=2 unreachable=0 failed=0
Y con esto ya estaría preparado para desplegar apaches.
Fuentes
http://blog.deiser.com/primeros-pasos-con-ansible/
https://www.digitalocean.com/community/tutorials/how-to-install-and-configure-ansible-on-centos-7