Inventarios: nociones avanzadas
Objetivos del capítulo y requisitos
1. Contexto y requisitos
En este capítulo se tratarán distintos temas concernientes a los inventarios. Verá, especialmente, cómo almacenar datos sensibles (nombres de usuario y contraseñas) en un archivo, así como la noción de inventario dinámico de Ansible.
Con respecto a los inventarios dinámicos, verá algunas aplicaciones sobre productos del mercado con las que podría encontrarse. No tendrá, seguramente, ganas de volver a escribir un inventario para Ansible y de mantenerlo ya que esta información está disponible en algún lugar (y que ya ha pasado, además, mucho tiempo trabajando en este tema).
Los ejemplos que se tratarán en este capítulo partirán de la base de que usted dispone de permisos de administración en sus máquinas.
Para la parte de la escritura dinámica del inventario, necesitará tener algunas nociones básicas de programación en Python.
2. Archivos descargables
Puede encontrar los ejemplos de los directorios inventarios y variables en el archivo comprimido capitulo-04.tar.gz que se encuentra en la página del libro en el sitio de Ediciones ENI.
Cifrado de archivos
1. Contexto
En el capítulo del descubrimiento del inventario, vio cómo administrar este último y cómo almacenar nombres de usuarios o contraseñas. Esto supone un problema ya que estos datos están almacenados en archivos de texto plano. Cualquier persona que tenga acceso a sus inventarios podría extraer este tipo de información y utilizarla.
En este capítulo verá un mecanismo que permite cifrar sus archivos con el objetivo de evitar que las contraseñas estén accesibles directamente.
Todos los ejemplos de ahora en adelante utilizarán la contraseña «ansible».
2. Almacenamiento de los nombres de usuario para las conexiones
La primera etapa consistirá en crear un archivo en el que almacenará la información necesaria para conectarse a una base de datos MySQL.
Para ello, usará dos campos: intranet_mysql_db_user y intranet_mysql_db_password.
Esos dos nombres de usuario le serán útiles para una hipotética aplicación en una intranet.
He aquí la declaración que usará como ejemplo:
intranet_mysql_db_user: "intranet"
intranet_mysql_db_password: "1ntran3t!"
3. Cifrado de un archivo entero
El cifrado de elementos en Ansible se hace gracias a la herramienta ansible-vault. Esta puede funcionar con una contraseña o utilizando archivos como argumento.
En los dos casos, para el cifrado de un archivo entero, hay que ejecutar ansible-vault con la opción encrypt (cifrar en inglés) seguida del nombre del archivo.
En todos los casos en que Ansible utilice archivos, estos pueden estar cifrados. Usted puede, por ejemplo, cifrar todos los archivos en local antes de copiarlos remotamente.
a. Usando una contraseña
Aquí encontrará el comando que habría que ejecutar para cifrar el archivo intranet-pass.yml:
$ ansible-vault encrypt intranet-pass.yml
Ansible le pedirá introducir una contraseña que tendrá que volver a confirmar una segunda vez. Aquí encontrará el resultado del comando cuando el cifrado se desarrolla correctamente:
New Vault password: ...
Los inventarios dinámicos
1. Contexto
Usted es el administrador del sistema y/o de red y tiene un parque informático de algunos centenares de máquinas. Seguramente, ya debe disponer de alguna solución para gestionar sus máquinas.
Como primer reflejo, podría hacer una extracción regular de su parque informático usando sus propios scripts (shell, Python u otros). Verá que no es necesario y que, generalmente, se puede obtener este tipo de información directamente de las máquinas. He aquí algunos ejemplos que podría utilizar:
-
Podría supervisar su parque usando Nagios, Shinken u otra solución como, por ejemplo, Zabbix.
-
Podría virtualizar su infraestructura usando VMware.
-
Podría utilizar máquinas en la nube (AWS, Azure u otra solución).
-
Podría administrar contenedores de tipo Docker (Kubernetes o Docker Swarm).
Si usted está en alguno de esos casos, tiene muchas probabilidades de poder reutilizar esa información directamente a través de algún plugin que ya exista. Si no es el caso, este libro le indicará cómo obtener toda esa información usando un script de inventario específico.
Tenga en cuenta que oficialmente esos mecanismos ya no son compatibles. El método recomendado por Ansible se presentará en la sección Funcionamiento de los plugins de inventarios genéricos.
2. Máquinas AWS
a. Requisitos
Antes de empezar, necesitará claves de acceso (Access Key) para poder gestionar AWS en consola. Si no las tiene, pídalas a su administrador AWS o siga el procedimiento del capítulo Ansible: virtualización y nube de la sección Gestión de la nube AWS.
Cuando haya obtenido estas claves, exporte los valores en las variables de entorno AWS_SECRET_ACCESS_KEY y AWS_ACCESS_KEY_ID.
He aquí un ejemplo de ejecución:
$ export AWS_ACCESS_KEY_ID=XXXXXXXXXXXXXX
$ export AWS_SECRET_ACCESS_KEY=XXXXXXXXXXXXXXXXXXXXX
Además de exportar las variables, va a tener que instalar las bibliotecas boto y boto3.
He aquí el comando que le permitirá realizar estas instalaciones:
$ pip3 install boto boto3
b. Obtención del script ec2.py
La comunicación con AWS se hace a través del script ec2.py. Tiene que descargarlo en esta URL: https://github.com/ansible/ansible/tree/stable-2.9/contrib/inventory...
Funcionamento de los plugins de inventarios genéricos
1. Contexto
Anteriormente, el lector estudió las diferentes maneras de dar a Ansible una lista de máquinas con las que quiere trabajar:
-
Mediante el intermediario de los archivos de texto (INI o YAML)
-
Mediante el intermediario de los scripts generadores de inventarios en formato YAML
En realidad, todos los mecanismos utilizan la misma mecánica interna de Ansible: los plugins de inventario.
A partir de ahora, el lector se familiarizará con este funcionamiento. Estudiará también la creación de un script de inventario en el caso que el existente no le conviniera.
Tenga en cuenta que, por defecto, Ansible soporta cierto número de scripts (por orden de prioridad):
-
host_list: máquinas utilizadas como parámetros en línea de comando separadas por comas (ejemplo: -i host1,host2,host3).
-
script: script de inventario ejecutable (ejemplo visto con anterioridad).
-
auto: formato de inventario basado en archivos con formato YAML que contienen una clave plugin (disponible desde la versión 2.5 de Ansible).
-
yaml: formato de inventario en formato YAML (visto con anterioridad).
-
ini: formato de inventario histórico en formato INI (visto con anterioridad).
-
toml: formato de inventario en formato TOML.
El formato TOML es una mezcla entre el formato INI y JSON/YAML. No se estudiará en este libro.
La lista de formatos soportados se configura con la variable de entorno ANSIBLE_INVENTORY_ENABLED o modificando la clave enable_plugins en la sección inventory del archivo de configuración de Ansible.
2. Conector soportado por el formato auto
El formato auto espera un archivo YAML de entrada. Este último no tiene una estructura particular, solamente debe contener el campo plugin que corresponde al conector que se quiera utilizar. Este conector puede tomar distintos valores, como por ejemplo:
-
aws_ec2: lista de las instancias EC2 del servicio Amazon.
-
docker_swarm: lista de los nodos de un clúster Docker Swarm.
-
k8s: lista las cápsulas presentes en un clúster Kubernetes.
La lista es larga y harían falta algunos capítulos para estudiar todas las posibilidades. El usuario...
Escribir su propio inventario dinámico
1. Contexto
Ha visto los plugins que existen, pero ninguno corresponde a nuestro caso. Hay otra posibilidad, ha encontrado un plugin interesante, pero necesita adaptar algunos aspectos.
Este capítulo tratará de la escritura de un plugin de inventario. El antiguo mecanismo se apoyaba sobre el resultado de una estructura en formato JSON. Aunque no haya ninguna contraindicación para usar esta solución, el ejemplo que será estudiado en adelante se apoyará en el nuevo mecanismo de inventario. Dicho ejemplo tratará los elementos que tienen que encontrarse en este mecanismo y la aplicación que se hará en un caso concreto.
2. Formato de entrada
En el ejemplo que tratará, usted empezará con un archivo properties Java que analizará antes de enviarlo de nuevo a Ansible con el objetivo de que Ansible pueda utilizarlo como inventario.
La estructura de ese archivo de properties es conocida. Allí encontrará las claves siguientes:
-
db.host: nombre de la máquina de la base de datos;
-
db.user: usuario de la base de datos;
-
db.password: contraseña del usuario de la base de datos;
-
apache.hosts: lista de las máquinas apache separadas por comas (,).
Aquí encontrará el archivo prop2inv.properties que se utilizará en adelante:
db.host=mysql1
db.user=test
db.password=password_test
apache.hosts=apache1,apache2
3. Estructura del programa
Anteriormente, el mismo programa se podía escribir en cualquier lenguaje de programación. A partir de ahora, con el mecanismo genérico de inventario (tipo auto), el script se tiene que escribir en Python.
a. Encabezado del programa
Se trata de un programa en Python, tiene que tener un encabezado (sheebang) correspondiente al intérprete de Python. Tendrá también que añadir el formato de codificación de caracteres UTF-8 para evitar problemas de codificación (Python es bastante quisquilloso en ese aspecto).
Un plugin de inventario Ansible debe implementar una clase InventoryModule que se apoya en la clase BaseInventoryPlugin (paquete ansible.plugins.inventory).
He aquí una proposición de implementación que respondería a estos criterios:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Read a properties a give...