Cómo crear jugadas y libros de jugadas de Ansible - Parte 5
En esta Parte 5 de la serie Ansible, explicaremos cómo crear Ansible Plays y Playbooks utilizando módulos de Ansible.
Ansible se entrega con scripts independientes llamados módulos que se utilizan en playbooks para la ejecución de tareas especializadas en nodos remotos.
Los módulos son útiles para automatizar tareas como la administración de paquetes, el archivado y la copia de archivos, por mencionar solo algunas. Le permiten realizar ajustes en los archivos de configuración y administrar dispositivos como enrutadores, conmutadores, equilibradores de carga, firewalls y una gran cantidad de otros dispositivos.
El objetivo de este subtema es brindarle una descripción general de varias tareas que pueden realizarse mediante módulos de Ansible:
Gestión de paquetes en Linux
La gestión de paquetes es una de las tareas más esenciales y frecuentes que realizan los administradores de sistemas. Ansible se entrega con módulos que lo ayudan a ejecutar tareas de administración de paquetes tanto en sistemas basados en RedHat como en Debian.
Son relativamente fáciles de adivinar. Existe el módulo apt para la gestión de paquetes APT para Debian, el antiguo módulo yum para la gestión de paquetes YUM y el módulo dnf asociado con distribuciones RHEL más nuevas. .
A continuación se muestran algunos ejemplos de cómo se pueden utilizar los módulos en un playbook:
Ejemplo 1: instalación del servidor web Apache en RHEL 8
---
- name: install Apache webserver
hosts: webservers
tasks:
- name: install httpd
dnf:
name: httpd
State: latest
Ejemplo 2: instalación del servidor web Apache en Debian 10
---
- name: install Apache webserver
hosts: databases
tasks:
- name: install Apache webserver
apt:
name: apache2
State: latest
Módulo de servicio
El módulo de servicio permite a los administradores del sistema iniciar, detener, actualizar y recargar servicios en el sistema.
Ejemplo 1: iniciar el servidor web Apache
---
- name: Start service httpd, if not started
service:
name: httpd
state: started
Ejemplo 2: detener el servidor web Apache
---
- name: Stop service httpd
service:
name: httpd
state: stopped
Ejemplo 3: Reiniciar una interfaz de red enp2s0
---
- name: Restart network service for interface eth0
service:
name: network
state: restarted
args: enp2s0
Copiar módulo
Como sugiere el nombre, el módulo de copia copia archivos desde una ubicación en la máquina remota a una ubicación diferente en la misma máquina.
Ejemplo 1: Copiar archivos de Linux local a remoto
---
- name: Copy file with owner and permissions
copy:
src: /etc/files/tecmint.conf
dest: /srv/tecmint.conf
owner: tecmint
group: tecmint
mode: '0644'
El libro de estrategias copia el archivo de configuración tecmint.conf del directorio /etc/files/ al directorio /srv/ como tecmint . usuario con permisos 0644.
Los permisos también se pueden representar mediante representación simbólica como se muestra en la última línea.
Ejemplo 2: Copiar archivos de Linux local a remoto
---
- name: Copy file with owner and permissions
copy:
src: /etc/files/tecmint.conf
dest: /srv/tecmint.conf
owner: tecmint
group: tecmint
mode: u=rw, g=r, o=r
Los permisos del ejemplo anterior se pueden representar como se muestra en la última línea: al usuario se le asignan permisos de lectura y escritura, al grupo se le asignan permisos de escritura y el resto de al mundo se le asignan permisos de lectura.
Módulo de archivos
El módulo de archivos se utiliza para realizar muchas operaciones con archivos, incluida la creación de archivos y directorios, la asignación de permisos de archivos y la configuración de enlaces simbólicos.
Ejemplo 1: realizar permisos de archivos de Linux
---
- name: Change file ownership, group, and permissions
file:
path: /etc/tecmint.conf
owner: tecmint
group: tecmint
mode: '0644'
La reproducción anterior crea un archivo llamado tecmint.conf en el directorio /etc estableciendo permisos en 0644.
Ejemplo 2: eliminar archivo de Linux
---
- name: Remove file (delete file)
file:
path: /etc/tecmint.conf
state: absent
Esto elimina o elimina el archivo tecmint.conf.
Ejemplo 3: crear un directorio
---
- name: create a directory if it doesn’t exist
file:
path: /etc/mydirectory
State: directory
mode: '0777'
Esto creará un directorio en el directorio /etc estableciendo permisos en 0777.
Ejemplo 4: eliminar un directorio de forma recursiva
---
- name: Recursively deleting a directory
file:
path: /etc/tecmint.conf
state: absent
La jugada anterior elimina recursivamente un directorio.
Módulo de archivo de línea
El módulo lineinfile es útil cuando desea cambiar una sola línea en un archivo. Puede reemplazar una línea existente.
Ejemplo 1: manipular archivos en Linux
---
- name: Ensure SELinux is set to enforcing mode
lineinfile:
path: /etc/selinux/config
regexp: '^SELINUX='
line: SELINUX=disabled
La jugada anterior establece el valor de SELINUX en deshabilitado.
SELINUX=disabled
Ejemplo 2: modificar archivos en Linux
---
- name: Add a line to a file if the file does not exist, without passing regexp
lineinfile:
path: /etc/hosts
line: 10.200.50.51 linux-console.net
create: yes
Esto agrega la entrada 10.200.50.51 linux-console.net al archivo /etc/hosts.
Módulo de archivo
Un módulo Archivo se utiliza para la creación de un archivo comprimido de uno o varios archivos. Se supone que la fuente de compresión existe y está presente en el destino de destino. Después del archivado, el archivo fuente se puede eliminar o eliminar utilizando la declaración remove=True
.
Ejemplo 1: crear un archivo de almacenamiento
- name: Compress directory /path/to/tecmint_dir/ into /path/to/tecmint.tgz
archive:
path: /path/to/tecmint_dir
dest: /path/to/tecmint.tgz
This compresses the /path/to/tecmint_dir directory to /path/to/tecmint.tgz
Ejemplo 2: crear un archivo de almacenamiento y eliminarlo
- name: Compress regular file /path/to/tecmint into /path/to/foo.gz and remove it
archive:
path: /path/to/tecmint
dest: /path/to/tecmint.tgz
remove: yes
En la reproducción anterior, el archivo fuente /path/to/tecmint se elimina una vez que se completa el archivo.
Ejemplo 3: crear un archivo de almacenamiento
- name: Create a bz2 archive of /path/to/tecmint
archive:
path: /path/to/tecmint
format: bz2
Esto crea un archivo comprimido en formato bz2 a partir del archivo /path/to/tecmint.
Módulo Git
El módulo gestiona las salidas de git de los repositorios de software.
Ejemplo 1: comprobar los repositorios de Git
- git:
repo: 'https://foosball.example.org/path/to/repo.git'
dest: /srv/checkout
version: release-0.22
Módulo de mando
Uno de los módulos más utilizados, el módulo comando toma el nombre del comando y luego le sigue una lista de argumentos. El comando se pasa de la misma manera que lo escribiría en un shell de Linux.
Ejemplo 1: ejecutar un comando
- name: Executing a command using the command module
command: cat helloworld.txt
Ejemplo 2: comprobar el tiempo de actividad de Linux remoto
---
- name: Check the remote host uptime
hosts: servers
tasks:
- name: Execute the Uptime command over Command module
register: uptimeoutput
command: "uptime"
- debug:
var: uptimeoutput.stdout_lines
El módulo de comando recupera el tiempo de actividad de los servidores remotos.
Variables para recuperar los resultados de la ejecución de comandos
Por lo general, los playbooks de Ansible se utilizan para ejecutar tareas en hosts administrados sin mostrar el resultado en la línea de comando. Sin embargo, hay casos en los que es posible que se le solicite capturar el resultado o los resultados. En esta sección, le explicamos cómo puede capturar el resultado de un libro de jugadas en una variable y luego mostrarlo.
Un registro ansible se utiliza para capturar el resultado de una tarea y guardarlo como variable. A partir de entonces, la variable contendrá la salida estándar de la tarea.
Por ejemplo, supongamos que desea verificar el uso del disco de los nodos administrados en los respectivos directorios raíz usando el comando df -Th /
. Utilizará el módulo 'command'
para definir el comando y 'register'
para guardar la salida estándar en una variable.
Para mostrar el comando, utilizará el módulo ‘debug’
junto con el valor de retorno estándar.
---
- hosts: all
become: yes
tasks:
- name: Execute /boot usage on Hosts
command: 'df -Th /'
register: df
- debug: var=df.stdout
Ahora, ejecutemos el libro de jugadas. En este caso, hemos nombrado nuestro libro de estrategias check_disk_space.yml.
ansible-playbook check_disk_space.yml
Como ha visto, el resultado está todo confuso y dificulta su seguimiento.
Para alinear la salida y hacerla más fácil de leer, reemplace el valor de retorno stdout con stdout_lines.
---
- hosts: all
become: yes
tasks:
- name: Execute /boot usage on Hosts
command: 'df -Th /'
register: df
- debug: var=df.stdout_lines
Utilice condicionales para controlar la ejecución del juego
Al igual que en los lenguajes de programación, las declaraciones condicionales se utilizan cuando es posible más de un resultado. Echemos un vistazo a algunas de las declaraciones condicionales comúnmente utilizadas en los manuales de Ansible.
cuando declaración
A veces, es posible que desee realizar tareas en nodos específicos y no en otros. La declaración condicional 'when'
es bastante fácil de usar e implementar en un libro de estrategias. Cuando utilice la cláusula 'when'
, simplemente declare la condición adyacente a la cláusula como se muestra:
when: condition
Cuando se cumple la condición, la tarea se realiza en el sistema remoto.
Veamos algunos ejemplos:
Ejemplo 1: uso del operador When
---
- hosts: all
tasks:
- name: Install Nginx on Debian
apt: name=nginx state=present
when: ansible_os_family == “Debian”
El juego anterior instala el servidor web Nginx en hosts que ejecutan la familia de distribuciones Debian.
También puede utilizar el operador OR
y AND
junto con cuando la declaración condicional.
Ejemplo 2: uso del operador AND con When
---
- hosts: all
tasks:
- name: Install Nginx on Debian
apt: name=nginx state=present
when: ansible_os_family == “Debian” and
ansible_distribution_version == “18.04”
Cuando se utiliza el operador AND
, se deben cumplir ambas declaraciones para que se ejecute la tarea.
La obra anterior instala Nginx en nodos que ejecutan una familia de sistemas operativos Debian, que es la versión 18.04. Obviamente, este será Ubuntu 18.04.
Ejemplo 3: uso del operador OR con When
Con el operador OR
, la tarea se ejecuta si se cumple alguna de las condiciones.
---
- hosts: all
tasks:
- name: Install Nginx on Debian
apt: name=nginx state=present
when: ansible_os_family == “Debian” or
Ansible_os_family == “SUSE”
El juego anterior instala servidores web Nginx en la familia de sistemas operativos Debian o SUSE o en ambos.
NOTA: asegúrese siempre de utilizar el signo de doble igualdad ==
al probar una condición.
Condicionales en bucles
Los condicionales también se pueden utilizar en un bucle. Digamos, por ejemplo, que tiene una lista de varios paquetes que deben instalarse en nodos remotos.
En el siguiente manual, tenemos una matriz llamada paquetes que contiene una lista de paquetes que deben instalarse. Estas tareas se llevarán a cabo una tras otra si la cláusula required está establecida en True.
---
- name: Install Software packages
hosts: all
vars:
packages:
• name: nginx
required: True
• name: mysql
required: True
• name: apache
required: False
tasks:
• name: Install “{{ item.name }}”on Debian
apt:
name: “{{ item.name }}”
state: present
When: item.required == True
loop: “{{ packages }}”
Configurar el manejo de errores
A veces, las tareas fallan al ejecutar los manuales. Supongamos que está ejecutando 5 tareas en 3 servidores como se muestra en el siguiente manual. Si se produce un error en la tarea 3 (Iniciando MySQL) en el servidor 2, Ansible dejará de ejecutar las tareas restantes en el servidor 2 e intentará completar las tareas restantes en el resto de los servidores.
---
- name: Install Software packages
hosts: server1, server2, server3
tasks:
- name: Install dependencies
<< some code >>
- name: Install MySQL database
<< some code >>
- name: Start MySQL
<< some code >>
- name: Install Nginx
<< some code >>
- name: Start Nginx
<< some code >>
Si desea coherencia en la ejecución del libro de jugadas, por ejemplo, detenga la ejecución de un libro de jugadas; si uno de los servidores falla, agregue la opción.
---
- name: Install Software packages
hosts: server1, server2, server3
any_errors_fatal: true
tasks:
De esta manera, si una tarea falla en un servidor, Ansible detendrá la ejecución de todo el libro de estrategias en todos los servidores y saldrá.
Si desea que el libro de estrategias ignore los errores y proceda a ejecutar el conjunto restante de tareas, utilice la opción ignore_errors: True.
---
- name: Install Software packages
hosts: server1, server2, server3
tasks:
- name: Install dependencies
<< some code >>
ignore_errors: True
Cree guías para configurar sistemas en un estado específico
En esta sección, analizamos algunas opciones adicionales que están disponibles al ejecutar un libro de estrategias.
Comencemos con el modo Comprobar o la opción Ejecución en seco. La opción del modo de ejecución en seco o de verificación se utiliza cuando se ejecuta un libro de jugadas para verificar si se encontrará algún error y si se realizará algún cambio en los hosts administrados. Sin embargo, no realiza ningún cambio en los nodos remotos.
Por ejemplo, para ejecutar en seco un libro de estrategias llamado httpd.yml
que instala e inicia el servidor web Apache, ejecute:
ansible-playbook httpd.yml --check
La otra opción que debemos considerar es la opción --start-at-task
. Esto se utiliza al especificar el nombre de la tarea en la que debe comenzar o comenzar el libro de jugadas.
Tomemos un ejemplo: el siguiente manual detalla 2 tareas: la primera instala el servidor web Apache y la segunda instala la utilidad htop.
---
- name: Install httpd
hosts: all
tasks:
yum:
name: httpd
state: Installed
- name: Install htop
yum:
name: htop
state: started
Si desea omitir la instalación del servidor web Apache y en su lugar instalar la utilidad htop, ejecute:
ansible-playbook playbook.yml --start-at-task “Install htop”
Por último, puedes etiquetar tus tareas o jugadas agregando la opción etiquetas a tu libro de jugadas como se muestra. Esto resulta útil cuando tienes un libro de jugadas bastante grande y quieres ejecutar tareas específicas de todo el libro de jugadas.
---
- name: Install httpd
tags: Install and start
hosts: all
tasks:
yum:
name: httpd
state: Installed
tags: Install
• service:
name: httpd
state: started
ansible-playbook playbook.yml -tags "Install"
Para omitir las etiquetas utilice las opciones --skip-tags
como se muestra.
ansible-playbook playbook.yml --skip-tags "Install"
Conclusión
En este tema, lo guiamos a través de los módulos utilizados comúnmente en Ansible, cómo recuperar la salida estándar de la ejecución de un libro de jugadas para su análisis, cómo usar condicionales en el libro de jugadas y cómo administrar los errores que pueden ocurrir al ejecutar tareas. Por último, recapitulamos la configuración de los libros de estrategias y cómo puede usar opciones adicionales para decidir qué tareas ejecutar si no tiene intención de ejecutar todo el libro de estrategias.