Cómo instalar y configurar Ansible en Ubuntu 22.04

Ansible es una herramienta de gestión de la configuración muy popular, diseñada para agilizar el proceso de control de un gran número de servidores. Puede automatizar el proceso de configuración de nuevos servidores y de instalación de aplicaciones con un solo comando o archivo. Puedes controlar tantos servidores y ejecutar procesos en ellos simultáneamente desde un único nodo. Ansible no requiere la instalación de ningún software especial en los nodos del servidor y puede controlarlos a través de SSH.

En esta guía, aprenderemos a instalar y configurar Ansible en un servidor Ubuntu 22.04.

Requisitos previos

  • Dos o más sistemas de servidor que ejecuten Ubuntu 22.04 con el servidor OpenSSH instalado.
  • Tanto el servidor como los nodos son accesibles a través de direcciones IP públicas.
  • Se ha configurado un usuario no root con privilegios sudo en el servidor de Ansible y un usuario root con contraseña en los clientes de Ansible.

Paso 1 – Instalar Ansible

Utilizaremos el repositorio oficial de Ansible para instalar su última versión. Añade el repositorio oficial de Ansible al servidor.

$ sudo add-apt-repository ppa:ansible/ansible

Afortunadamente, Ubuntu incluye la versión 2.9 de Ansible, que es la que vamos a instalar. Ejecuta el siguiente comando para instalar Ansible.

$ sudo apt install ansible -y

Prueba la instalación ejecutando el siguiente comando.

$ ansible --version
ansible [core 2.13.3rc1]
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/home/navjot/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3/dist-packages/ansible
  ansible collection location = /home/navjot/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/bin/ansible
  python version = 3.10.4 (main, Jun 29 2022, 12:14:53) [GCC 11.2.0]
  jinja version = 3.0.3
  libyaml = True

Instala y activa el paquete python3-argcomplete para configurar el soporte de finalización de bash de Ansible.

$ sudo apt install python3-argcomplete
$ sudo activate-global-python-argcomplete3

Ahora puedes pulsar la tecla Tab para obtener una lista de opciones para el shell bash.

Paso 2 – Configurar el archivo de inventario

Para poder conectarte a varios hosts, necesitas un archivo que registre los detalles de los nodos. Este archivo se llama archivo de inventario.

Dependiendo del número de servidores que quieras controlar, el archivo de Inventario de Ansible también te permite organizarlos en grupos y subgrupos. También puedes establecer variables personalizadas aplicables a determinados hosts o grupos, que pueden utilizarse posteriormente al transmitir las instrucciones.

Ansible incluye un archivo de Inventario por defecto disponible en /etc/ansible/hosts. Ábrelo con el editor Nano.

$ sudo nano /etc/ansible/hosts

Pega el siguiente código en la parte inferior del archivo.

[servers]
server1 ansible_host=203.0.113.111
server2 ansible_host=203.0.113.112
server3 ansible_host=203.0.113.113

[all:vars]
ansible_python_interpreter=/usr/bin/python3

La sección servers define la lista de nodos a los que quieres conectarte. Puedes crear tantos grupos para organizar los servidores en varios grupos.

El grupo all:vars establece el parámetro ansible_python_interpreter en todos los hosts del inventario. Asegura que Ansible utiliza el ejecutable Python 3 en lugar de Python 2, que se ha eliminado de las últimas versiones de Ubuntu.

Cuando hayas terminado, guarda el archivo pulsando Ctrl + X e introduciendo Y cuando se te pida que confirmes los cambios.

Nota: También puedes crear tu archivo de inventario en cualquier ubicación de tu elección, que luego puedes pasar utilizando el parámetro -i al ejecutar los comandos de Ansible.

Puedes comprobar tu lista de inventario mediante el siguiente comando.

$ ansible-inventory --list -y
all:
  children:
    servers:
      hosts:
        server1:
          ansible_host: 203.0.113.111
          ansible_python_interpreter: /usr/bin/python3
        server2:
          ansible_host: 203.0.113.112
          ansible_python_interpreter: /usr/bin/python3
        server3:
          ansible_host: 203.0.113.113
          ansible_python_interpreter: /usr/bin/python3
    ungrouped: {}

Organizar los servidores en grupos y subgrupos

Este es un consejo útil si tienes muchos servidores con algunos que realizan funciones específicas. Por ejemplo, puedes utilizar este método para agrupar servidores web y servidores de bases de datos por separado. Incluso puedes hacer que un host forme parte de varios grupos. Para ello, tu archivo de inventario debería tener un aspecto similar al siguiente.

[webservers]
203.0.113.111
203.0.113.112

[dbservers]
203.0.113.113
server_hostname

[development]
203.0.113.111
203.0.113.113

[production]
203.0.113.112
server_hostname

Paso 3 – Configurar las claves SSH

Para que Ansible pueda conectarse a los servidores, debes configurar las claves SSH entre tu servidor Ansible y los hosts especificados en el archivo de inventario. Esto sólo funcionará si los clientes de Ansible no tienen una clave pública habilitada y tienen una cuenta de root habilitada con una contraseña.

Sigue los siguientes pasos para crear y configurar una clave SSH para Ansible y sus nodos.

Crea la clave para Ansible.

$ ssh-keygen -t rsa -b 4096 -C "Ansible key"

Copia la clave pública a tus cuentas en los servidores remotos. Para ello, utilizaremos el comando ssh-copy-id.

$ ssh-copy-id -i $HOME/.ssh/id_rsa.pub [email protected]
$ ssh-copy-id -i $HOME/.ssh/id_rsa.pub [email protected]
$ ssh-copy-id -i $HOME/.ssh/id_rsa.pub [email protected]

Eso es todo. Ahora Ansible debería poder hablar con tus servidores.

Configurar claves SSH en nodos con clave pública existente

Si los clientes ya tienen habilitadas las claves públicas, tendrás que seguir algunos pasos adicionales. Para ello, tienes que crear un nuevo usuario accesible sólo por Ansible en cada nodo servidor. Ese usuario tendrá privilegios sudo accesibles sin contraseña y sólo se podrá acceder a él desde tu servidor ansible.

Para crear un usuario ansible, ejecuta el siguiente comando.

$ sudo adduser ansible

Elige una contraseña fuerte y deja los demás campos vacíos.

Ahora, configura el acceso sudo sin contraseña para este usuario mediante el siguiente comando.

$ echo "ansible ALL=(ALL) NOPASSWD:ALL" | sudo tee /etc/sudoers.d/ansible

Ahora que tienes el nuevo usuario añadido y configurado, puedes copiar la clave SSH de tu servidor ansible al servidor del nodo mediante el siguiente comando.

$ ssh-copy-id [email protected]

Se te pedirá una contraseña para el usuario ansible. Introdúcela y se copiará la clave SSH.

A continuación, desactiva el inicio de sesión con contraseña para el usuario ansible en el servidor de nodos.

$ sudo usermod -L ansible

Ahora, tu servidor de nodos sólo es accesible desde el servidor de Ansible, ya que sólo ese servidor tiene la clave pública para él y no puedes utilizarlo con privilegios sudo en el servidor de nodos directamente, ya que el inicio de sesión con contraseña está desactivado.

Tendrás que repetir estos pasos para cada servidor de nodos. Además, sustituye el usuario root por el usuario ansible en este tutorial.

Paso 4 – Prueba de conexión

Después de configurar el archivo de inventario y las claves SSH, debemos comprobar si Ansible puede conectarse a los servidores.

Escribe el siguiente comando para comprobar la conexión. Este comando probará la conexión con todos los servidores del archivo de inventario.

$ ansible all -m ping -u root

Este comando utiliza el módulo ping de Ansible para ejecutar una prueba de conectividad en todos los servidores. Deberías obtener una salida como la siguiente.

server1 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}
server2 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}
server3 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}

Si es la primera vez que utilizas Ansible, se te pedirá que confirmes la autenticidad de todos los servidores. Cuando se te pida, escribe yes y pulsa ENTER para confirmar.

Paso 5 – Ejecuta algunos comandos básicos

Vamos a ejecutar algunos comandos básicos en los servidores utilizando Ansible. Para ejecutar cualquier comando en el servidor, se utiliza el siguiente formato.

$ ansible all -a "command" -u <username>

Comprobar el uso del disco

En primer lugar, vamos a comprobar el uso del disco en todos nuestros servidores.

$ ansible all -a "df -h" -u root
server1 | CHANGED | rc=0 >>
Filesystem      Size  Used Avail Use% Mounted on
tmpfs           198M  972K  197M   1% /run
/dev/sda2        50G  3.9G   44G   9% /
tmpfs           989M     0  989M   0% /dev/shm
tmpfs           5.0M     0  5.0M   0% /run/lock
tmpfs           198M  4.0K  198M   1% /run/user/1000

server2 | CHANGED | rc=0 >>
Filesystem      Size  Used Avail Use% Mounted on
tmpfs           198M  922K  197M   1% /run
/dev/sda2        50G  4.9G   43G  10% /
tmpfs           989M     0  989M   0% /dev/shm
tmpfs           5.0M     0  5.0M   0% /run/lock
tmpfs           198M  4.0K  198M   1% /run/user/1000

Dirigirnos a hosts y grupos individuales

Hasta ahora, ejecutábamos los comandos en todos los servidores remotos a la vez. Pero no siempre es así. Para ejecutar un comando en un solo servidor, debes utilizar el siguiente formato.

$ ansible server1 -a "uptime" -u root
server1 | CHANGED | rc=0 >>
 21:38:26 up 11 min,  2 users,  load average: 0.00, 0.20, 0.19

El comando anterior comprueba el tiempo de actividad en el servidor1 del grupo de inventario.

También puedes dirigirte a varios servidores utilizando el siguiente formato.

$ ansible server1:server2 -m ping -u root

También puedes dirigirte a grupos o subgrupos desde el archivo de inventario directamente.

$ ansible groupname -m ping -u <username>

Actualizar todos los servidores

Para este tutorial, suponemos que todos los servidores remotos ejecutan el sistema operativo Debian o Ubuntu.

Ejecuta el siguiente comando para actualizar el software en todos tus servidores.

$ ansible all -m apt -a "update_cache=yes upgrade=yes" -u root

El parámetro -m define el módulo para que Ansible lo ejecute. El parámetro -a se refiere a los argumentos o comandos del módulo asociado. Aquí, estamos utilizando el módulo apt de Ansible para actualizar los servidores, al igual que utilizamos el módulo ping en nuestro último ejemplo. El update_cache actualiza la caché de APT en el servidor y el upgrade=yes indica a Ansible que ejecute el comando apt upgrade.

Si utilizas el usuario ansible como se ha documentado anteriormente, tienes que modificar el comando ansible para que se ejecute con privilegios elevados de sudo.

$ ansible server2 -m apt -a "update_cache=yes upgrade=yes" -K -b -u ansible

Aquí, -K pide una contraseña de elevación de privilegios. -b ejecuta la operación de ansible con become, lo que te permite ser otro usuario. Ambas variables combinadas permiten que ansible se ejecute con privilegios sudo elevados. Tendrás que usar esto para todos los comandos que requieran privilegios sudo.

A veces, algunos de estos comandos de actualización pueden requerir un reinicio, así que ejecuta el siguiente comando para reiniciar todos tus servidores.

$ ansible all -a "reboot" -u root

Estos son sólo algunos de los comandos básicos que puedes ejecutar con Ansible.

Paso 6 – Introducción a los Playbooks

Los comandos anteriores te permiten ejecutar tareas puntuales, pero si quieres configurar varios servidores o ejecutar la misma secuencia de comandos en varios servidores, necesitas configurar libros de jugadas. Los playbooks son archivos escritos en YAML y contienen instrucciones para automatizar una secuencia de tareas para configurar aplicaciones y servicios.

Ahora crearemos un playbook para instalar Nginx y configurar una página HTML en el nodo Ansible. Crea un directorio para Ansible en tu directorio principal.

$ mkdir ~/ansible

Crea y abre el archivo del playbook para editarlo.

$ cd ~/ansible
$ nano testplaybook.yml

Los playbooks utilizan el formato YAML para definir una o varias jugadas. Una obra es un conjunto de tareas ordenadas para automatizar un proceso. Las jugadas se definen como una lista YAML.

El primer paso para definir una jugada es determinar qué hosts son el objetivo utilizando la directiva hosts: all. La directiva become se utiliza para indicar que las siguientes tareas deben ser ejecutadas por un superusuario.

Definiremos tres tareas: una para añadir un usuario, otra para actualizar todos los paquetes y la última para instalar el servidor Nginx. La sección vars del libro de jugadas se utiliza para definir variables personalizadas. Definimos dos variables, una para el usuario que tenemos que añadir, y la segunda para definir el estado del paquete que tenemos que instalar. Para utilizar la variable, tenemos que encerrar el nombre de la variable entre dobles llaves.

El módulo ansible.builtin.user se utiliza para añadir un nuevo usuario con privilegios sudo. Para añadir el usuario, utilizamos las variables name, password y group. La variable group se establece en sudo para dar permisos de superusuario al usuario. No puedes poner la contraseña en texto plano en el archivo del libro de jugadas, por lo tanto, añadiremos un secreto con hash SHA. Para ello utilizaremos la utilidad mkpasswd. Para instalarla, ejecuta el siguiente comando para instalar el paquete whois.

$ sudo apt install whois

Genera la contraseña cifrada. Se te pedirá la contraseña habitual y se te dará una cadena con hash para ella. Anota la clave hashed que se utilizará en el archivo playbook.

$ mkpasswd --method=sha-512
Password:
$6$dGbprm2oVqClDDDh$Epk6r5eXYkYBaQpQpP.H7VCdz0g9Aj0aO8hjy/WXq4WmfQ7GvQP2/cl/cNhd7.LRFuCKix9uCF2t8X5/Pv0Lk1

La directiva update_cache sirve para actualizar la lista de repositorios del sistema al igual que el comando apt update y la directiva upgrade: dist indica a Ansible que realice la actualización del sistema. La tercera tarea se explica por sí misma y consiste en instalar la última versión del servidor Nginx.

Basándote en la información que hemos discutido, pega el siguiente código en el archivo. Pega la clave hash que has obtenido como valor de la variable password.

---
- name: Test playbook
  hosts: all
  become: true
  vars:
      state: latest
      user: navjot
  tasks:
  - name: Add the user {{ user }}
    ansible.builtin.user:
      name: "{{ user }}"
      password: '$6$dGbprm2oVqClDDDh$Epk6r5eXYkYBaQpQpP.H7VCdz0g9Aj0aO8hjy/WXq4WmfQ7GvQP2/cl/cNhd7.LRFuCKix9uCF2t8X5/Pv0Lk1'
      group: sudo
  - name: Upgrade all apt packages
    apt:
      update_cache: yes
      upgrade: dist
  - name: Install the {{ state }} of package "nginx"
    apt:
      name: "nginx"
      state: "{{ state }}"

Guarda el archivo pulsando Ctrl + X e introduciendo Y cuando se te pida que confirmes los cambios.

Para ejecutar el libro de jugadas, ejecuta el siguiente comando. La bandera --ask-become-pass te pedirá tu contraseña de root para realizar una operación elevada.

$ ansible-playbook testplaybook.yml --ask-become-pass

Obtendrás la siguiente salida.

BECOME password:

PLAY [Test playbook] ***************************************************************************************************

TASK [Gathering Facts] *************************************************************************************************
ok: [server1]
ok: [server2]
ok: [server3]

TASK [Add the user casablanca] *****************************************************************************************
changed: [server3]
changed: [server2]
changed: [server1]

TASK [Upgrade all apt packages] ****************************************************************************************
changed: [server1]
changed: [server2]
changed: [server3]

TASK [Install the latest of package "nginx"] ***************************************************************************
changed: [server3]
changed: [server2]
changed: [server1]

PLAY RECAP *************************************************************************************************************
server1                    : ok=4    changed=3    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
server2                    : ok=4    changed=3    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
server3                    : ok=4    changed=3    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Esto confirma que tu libro de jugadas se ha ejecutado con éxito.

Si utilizas un archivo de inventario personalizado, deberás incluir la ubicación del archivo en el comando como se indica a continuación.

$ ansible-playbook -i /etc/ansible/custominventory testplaybook.yml --ask-become-pass 

Conclusión

Con esto terminamos nuestro tutorial sobre la instalación y configuración de Ansible en un servidor Ubuntu 22.04. Si tienes alguna pregunta, publícala en los comentarios de abajo.

También te podría gustar...