Cómo Usar vars_files de Ansible para la Gestión de la Configuración

AnsibleBeginner
Practicar Ahora

Introducción

Este tutorial le guiará a través del uso de vars_files de Ansible para una gestión de configuración eficiente. Ansible es una poderosa herramienta de automatización que ayuda a gestionar la infraestructura a través de archivos YAML simples y legibles por humanos. La función vars_files le permite mantener sus datos de configuración separados de su lógica de automatización, haciendo que sus proyectos de Ansible sean más organizados y mantenibles.

Al final de este tutorial, aprenderá a crear y organizar vars_files, incorporarlos en playbooks y aprovecharlos para gestionar diferentes entornos de manera efectiva. Este conocimiento le ayudará a construir una automatización de infraestructura más escalable y mantenible.

Instalación de Ansible y Creación de su Primer vars_file

En este primer paso, instalaremos Ansible en nuestro sistema y crearemos nuestro primer vars_file para almacenar datos de configuración.

Instalación de Ansible

Comencemos instalando Ansible en nuestro sistema Ubuntu:

sudo apt update
sudo apt install -y ansible

Después de que la instalación se complete, verifique que Ansible esté instalado correctamente:

ansible --version

Debería ver una salida similar a esta, que muestra la versión y la configuración de Ansible:

ansible [core 2.12.x]
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/home/labex/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3/dist-packages/ansible
  ansible collection location = /home/labex/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/bin/ansible
  python version = 3.10.x (default, Mar 14 2023, 14:21:35) [GCC 11.3.0]
  jinja version = 3.0.3
  libyaml = True

Creación de una Estructura de Directorios del Proyecto

Creemos una estructura de directorios para nuestro proyecto Ansible:

mkdir -p ~/project/ansible-vars-demo/vars
cd ~/project/ansible-vars-demo

Entendiendo los vars_files de Ansible

Los vars_files de Ansible son archivos YAML que almacenan definiciones de variables que se pueden importar en los playbooks. Estos archivos le permiten:

  1. Separar los datos de configuración de la lógica de automatización
  2. Reutilizar las mismas variables en múltiples playbooks
  3. Mantener diferentes configuraciones para diferentes entornos

Creación de su Primer vars_file

Creemos nuestro primer vars_file para almacenar la configuración del servidor web. Usando el WebIDE, cree un nuevo archivo en ~/project/ansible-vars-demo/vars/webserver.yml con el siguiente contenido:

---
## Web Server Configuration
http_port: 80
server_name: example.com
document_root: /var/www/html
max_clients: 200

Este vars_file define cuatro variables que podrían usarse para configurar un servidor web:

  • http_port: El puerto en el que el servidor web escuchará
  • server_name: El nombre de dominio para el servidor web
  • document_root: El directorio donde se almacenarán los archivos del sitio web
  • max_clients: El número máximo de conexiones de clientes simultáneas

Para ayudar a entender cómo se ve esto en el WebIDE, navegue al explorador de archivos en el lado izquierdo, expanda la carpeta project, luego ansible-vars-demo, luego vars, y debería ver su archivo webserver.yml. Haga clic en él para ver o editar su contenido.

Creación de un Archivo de Inventario

A continuación, necesitamos crear un archivo de inventario para decirle a Ansible qué hosts administrar. En un entorno real, esto contendría direcciones de servidor reales, pero para este tutorial, usaremos localhost.

Cree un nuevo archivo en ~/project/ansible-vars-demo/inventory.ini con el siguiente contenido:

[webservers]
localhost ansible_connection=local

Este simple inventario define un grupo llamado webservers que incluye solo nuestra máquina local.

Entendiendo la Estructura del Proyecto

En este punto, la estructura de su proyecto debería verse así:

ansible-vars-demo/
├── inventory.ini
└── vars/
    └── webserver.yml

Esta estructura básica separa nuestro inventario (qué hosts administrar) de nuestras definiciones de variables (cómo configurar esos hosts).

Creación de un Playbook Básico con vars_files

Ahora que hemos creado nuestro vars_file, construyamos un playbook de Ansible simple que use estas variables. Esto demostrará cómo importar y usar datos de configuración de vars_files.

Entendiendo los Playbooks de Ansible

Los playbooks de Ansible son archivos YAML que definen un conjunto de tareas a ejecutar en los hosts gestionados. Los playbooks son el núcleo de la funcionalidad de Ansible, lo que le permite automatizar procesos de configuración complejos.

Creación de un Playbook Simple

Creemos un playbook que simule la configuración de un servidor web utilizando las variables que definimos en nuestro vars_file. Cree un nuevo archivo en ~/project/ansible-vars-demo/webserver_setup.yml con el siguiente contenido:

---
- name: Configure Web Server
  hosts: webservers
  vars_files:
    - vars/webserver.yml

  tasks:
    - name: Display web server configuration
      debug:
        msg: "Web server will be configured with: Port={{ http_port }}, ServerName={{ server_name }}, DocumentRoot={{ document_root }}"

    - name: Create a directory for document root
      file:
        path: "/tmp/{{ document_root }}"
        state: directory
        mode: "0755"

    - name: Create a sample index.html file
      copy:
        content: |
          <html>
            <head>
              <title>Welcome to {{ server_name }}</title>
            </head>
            <body>
              <h1>Welcome to {{ server_name }}</h1>
              <p>This server is configured to handle {{ max_clients }} simultaneous connections.</p>
            </body>
          </html>
        dest: "/tmp/{{ document_root }}/index.html"
        mode: "0644"

Entendamos qué hace este playbook:

  1. hosts: webservers - Especifica que este playbook debe ejecutarse en todos los hosts del grupo "webservers" de nuestro inventario.
  2. vars_files: - vars/webserver.yml - Importa variables de nuestro vars_file.
  3. La primera tarea usa el módulo debug para mostrar un mensaje que muestra las variables.
  4. La segunda tarea crea una estructura de directorio que se usaría para la raíz del documento del servidor web.
  5. La tercera tarea crea un archivo HTML de muestra que incluye las variables de nuestro vars_file.

Ejecutando el Playbook

Ahora, ejecutemos el playbook para verlo en acción:

cd ~/project/ansible-vars-demo
ansible-playbook -i inventory.ini webserver_setup.yml

Debería ver una salida similar a esta:

PLAY [Configure Web Server] ****************************************************

TASK [Gathering Facts] *********************************************************
ok: [localhost]

TASK [Display web server configuration] ****************************************
ok: [localhost] => {
    "msg": "Web server will be configured with: Port=80, ServerName=example.com, DocumentRoot=/var/www/html"
}

TASK [Create a directory for document root] ************************************
changed: [localhost]

TASK [Create a sample index.html file] *****************************************
changed: [localhost]

PLAY RECAP *********************************************************************
localhost                  : ok=4    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Verificando los Resultados

Verifiquemos que nuestro playbook ha creado los archivos esperados:

ls -la /tmp/var/www/html/
cat /tmp/var/www/html/index.html

Debería ver la estructura del directorio y el contenido del archivo index.html, que debería incluir los valores de nuestro vars_file:

<html>
  <head>
    <title>Welcome to example.com</title>
  </head>
  <body>
    <h1>Welcome to example.com</h1>
    <p>This server is configured to handle 200 simultaneous connections.</p>
  </body>
</html>

Entendiendo el Flujo de Trabajo

Repasemos lo que hemos logrado:

  1. Almacenamos datos de configuración en un vars_file separado (vars/webserver.yml).
  2. Creamos un playbook que importa y usa estos datos de configuración.
  3. Ejecutamos el playbook para ejecutar tareas que usan las variables.

Esta separación de los datos de configuración (vars_files) de la lógica de automatización (playbooks) hace que nuestro código Ansible sea más mantenible y reutilizable. Ahora podemos actualizar la configuración editando solo el vars_file, sin cambiar el playbook en sí.

Trabajando con Múltiples vars_files

Ahora que entendemos los conceptos básicos de los vars_files, exploremos cómo usar múltiples vars_files para administrar diferentes entornos. Esta es una práctica común en escenarios del mundo real donde podría tener diferentes configuraciones para entornos de desarrollo, staging y producción.

Creación de vars_files Específicos del Entorno

Creemos vars_files para diferentes entornos. Primero, creemos una configuración de entorno de desarrollo:

Cree un nuevo archivo en ~/project/ansible-vars-demo/vars/dev_environment.yml con el siguiente contenido:

---
## Development Environment Configuration
environment_name: development
debug_mode: true
log_level: debug
backup_frequency: weekly
max_memory: 512MB

A continuación, creemos una configuración de entorno de producción:

Cree un nuevo archivo en ~/project/ansible-vars-demo/vars/prod_environment.yml con el siguiente contenido:

---
## Production Environment Configuration
environment_name: production
debug_mode: false
log_level: error
backup_frequency: daily
max_memory: 2048MB

Creación de un Playbook con Múltiples vars_files

Ahora, creemos un playbook que use tanto nuestra configuración del servidor web como las configuraciones específicas del entorno. Cree un nuevo archivo en ~/project/ansible-vars-demo/environment_setup.yml con el siguiente contenido:

---
- name: Configure Environment
  hosts: webservers
  vars:
    env: dev
  vars_files:
    - vars/webserver.yml
    - "vars/{{ env }}_environment.yml"

  tasks:
    - name: Display environment details
      debug:
        msg: >
          Setting up {{ environment_name }} environment with the following parameters:
          - Web Server: {{ server_name }} on port {{ http_port }}
          - Debug Mode: {{ debug_mode }}
          - Log Level: {{ log_level }}
          - Backup Frequency: {{ backup_frequency }}
          - Max Memory: {{ max_memory }}
          - Max Clients: {{ max_clients }}

    - name: Create environment config file
      copy:
        content: |
          ## Environment Configuration for {{ server_name }}
          ENVIRONMENT={{ environment_name }}
          DEBUG={{ debug_mode }}
          LOG_LEVEL={{ log_level }}
          BACKUP_FREQUENCY={{ backup_frequency }}
          MAX_MEMORY={{ max_memory }}
          HTTP_PORT={{ http_port }}
          MAX_CLIENTS={{ max_clients }}
        dest: "/tmp/{{ environment_name }}_config.env"
        mode: "0644"

Este playbook introduce varios conceptos nuevos:

  1. Establecemos una variable env: dev dentro del propio playbook.
  2. Incluimos tanto nuestro vars_file del servidor web como un vars_file específico del entorno.
  3. La ruta del vars_file del entorno incluye una variable: "vars/{{ env }}_environment.yml", que se evalúa como vars/dev_environment.yml.
  4. Las tareas usan variables de ambos vars_files.

Ejecutando el Playbook con Diferentes Entornos

Ejecutemos el playbook primero con el entorno de desarrollo (que ya es el predeterminado):

cd ~/project/ansible-vars-demo
ansible-playbook -i inventory.ini environment_setup.yml

Debería ver una salida que incluye la configuración del entorno de desarrollo:

TASK [Display environment details] ********************************************
ok: [localhost] => {
    "msg": "Setting up development environment with the following parameters:\n- Web Server: example.com on port 80\n- Debug Mode: True\n- Log Level: debug\n- Backup Frequency: weekly\n- Max Memory: 512MB\n- Max Clients: 200"
}

Ahora, ejecutemos el mismo playbook pero anulemos la variable env para usar el entorno de producción:

ansible-playbook -i inventory.ini environment_setup.yml -e "env=prod"

Debería ver una salida que incluye la configuración del entorno de producción:

TASK [Display environment details] ********************************************
ok: [localhost] => {
    "msg": "Setting up production environment with the following parameters:\n- Web Server: example.com on port 80\n- Debug Mode: False\n- Log Level: error\n- Backup Frequency: daily\n- Max Memory: 2048MB\n- Max Clients: 200"
}

Verificando los Archivos de Configuración

Verifiquemos que nuestro playbook creó los archivos de configuración del entorno:

cat /tmp/development_config.env
cat /tmp/production_config.env

Debería ver dos archivos de configuración diferentes, cada uno con la configuración del respectivo vars_file del entorno.

Entendiendo la Precedencia de Variables

Es importante entender que al usar múltiples vars_files, Ansible sigue un orden específico de precedencia para las variables. Si el mismo nombre de variable aparece en múltiples lugares, el valor definido más tarde anulará las definiciones anteriores.

En nuestro ejemplo, si hubiéramos definido http_port tanto en los archivos webserver.yml como en dev_environment.yml, el valor de dev_environment.yml tendría precedencia porque se incluye más tarde en la lista vars_files.

Este comportamiento le permite definir valores predeterminados comunes en un archivo y luego anular valores específicos para diferentes entornos.

Técnicas Avanzadas de vars_files

En este paso final, exploraremos algunas técnicas avanzadas para trabajar con vars_files en Ansible, incluida la organización jerárquica de variables y la implementación de la organización de variables basada en roles.

Organización Jerárquica de Variables

En proyectos complejos, a menudo es útil organizar las variables jerárquicamente. Creemos una estructura donde tengamos:

  1. Variables comunes que se aplican a todos los entornos
  2. Variables específicas del entorno
  3. Variables específicas de la aplicación

Primero, creemos un archivo de variables comunes:

Cree un nuevo archivo en ~/project/ansible-vars-demo/vars/common.yml con el siguiente contenido:

---
## Common variables for all environments
organization: "Example Corp"
admin_email: "admin@example.com"
timezone: "UTC"

A continuación, creemos variables específicas de la aplicación:

Cree un nuevo archivo en ~/project/ansible-vars-demo/vars/database.yml con el siguiente contenido:

---
## Database application variables
db_port: 3306
db_user: "dbuser"
db_name: "appdb"
db_max_connections: 100

Creación de un Playbook Jerárquico

Ahora, creemos un playbook que demuestre el uso de estas variables jerárquicas. Cree un nuevo archivo en ~/project/ansible-vars-demo/hierarchical_setup.yml con el siguiente contenido:

---
- name: Hierarchical Variable Demo
  hosts: webservers
  vars:
    env: dev
    app: database
  vars_files:
    - "vars/common.yml"
    - "vars/{{ env }}_environment.yml"
    - "vars/{{ app }}.yml"

  tasks:
    - name: Display hierarchical configuration
      debug:
        msg: >
          Configuration for {{ app }} in {{ environment_name }} environment:
          - Organization: {{ organization }}
          - Admin Email: {{ admin_email }}
          - Timezone: {{ timezone }}
          - Debug Mode: {{ debug_mode }}
          - Log Level: {{ log_level }}
          - DB Port: {{ db_port }}
          - DB User: {{ db_user }}
          - DB Max Connections: {{ db_max_connections }}

    - name: Create hierarchical config file
      copy:
        content: |
          ## {{ organization }} Configuration
          ## {{ environment_name }} Environment

          ## Common Settings
          ADMIN_EMAIL={{ admin_email }}
          TIMEZONE={{ timezone }}

          ## Environment Settings
          DEBUG={{ debug_mode }}
          LOG_LEVEL={{ log_level }}
          BACKUP_FREQUENCY={{ backup_frequency }}

          ## {{ app | capitalize }} Settings
          DB_PORT={{ db_port }}
          DB_USER={{ db_user }}
          DB_NAME={{ db_name }}
          DB_MAX_CONNECTIONS={{ db_max_connections }}
        dest: "/tmp/{{ environment_name }}_{{ app }}_config.conf"
        mode: "0644"

Entendiendo las Variables de Grupo y Host

Además de vars_files, Ansible también admite el almacenamiento de variables en directorios especiales llamados group_vars y host_vars. Veamos cómo funcionan:

Cree una estructura de directorio para las variables de grupo y host:

mkdir -p ~/project/ansible-vars-demo/group_vars
mkdir -p ~/project/ansible-vars-demo/host_vars

Ahora, cree un archivo de variables de grupo para el grupo 'webservers':

Cree un nuevo archivo en ~/project/ansible-vars-demo/group_vars/webservers.yml con el siguiente contenido:

---
## Variables for all webservers
firewall_enabled: true
ssh_port: 22
monitoring_enabled: true

Y cree un archivo de variables de host para 'localhost':

Cree un nuevo archivo en ~/project/ansible-vars-demo/host_vars/localhost.yml con el siguiente contenido:

---
## Variables specific to localhost
local_backup_path: "/tmp/backups"
is_development_machine: true

Creación de un Playbook con Todos los Tipos de Variables

Creemos un playbook final que demuestre el uso de todos los tipos de variables juntos. Cree un nuevo archivo en ~/project/ansible-vars-demo/complete_setup.yml con el siguiente contenido:

---
- name: Complete Variable Demo
  hosts: webservers
  vars:
    env: prod
    app: database
  vars_files:
    - "vars/common.yml"
    - "vars/{{ env }}_environment.yml"
    - "vars/{{ app }}.yml"

  tasks:
    - name: Display complete configuration
      debug:
        msg: >
          Complete configuration for {{ inventory_hostname }}:
          - Organization: {{ organization }}
          - Environment: {{ environment_name }}
          - Debug Mode: {{ debug_mode }}
          - Firewall Enabled: {{ firewall_enabled }}
          - SSH Port: {{ ssh_port }}
          - Monitoring Enabled: {{ monitoring_enabled }}
          - Local Backup Path: {{ local_backup_path }}
          - Is Development Machine: {{ is_development_machine }}

    - name: Create complete config file
      copy:
        content: |
          ## {{ organization }} - {{ environment_name }} Environment
          ## Host: {{ inventory_hostname }}

          ## Common Settings
          ADMIN_EMAIL={{ admin_email }}
          TIMEZONE={{ timezone }}

          ## Environment Settings
          DEBUG={{ debug_mode }}
          LOG_LEVEL={{ log_level }}

          ## Server Settings
          FIREWALL_ENABLED={{ firewall_enabled }}
          SSH_PORT={{ ssh_port }}
          MONITORING_ENABLED={{ monitoring_enabled }}

          ## Host-specific Settings
          LOCAL_BACKUP_PATH={{ local_backup_path }}
          IS_DEVELOPMENT_MACHINE={{ is_development_machine }}

          ## {{ app | capitalize }} Settings
          DB_PORT={{ db_port }}
          DB_USER={{ db_user }}
          DB_NAME={{ db_name }}
        dest: "/tmp/complete_config.conf"
        mode: "0644"

Ejecutando los Playbooks Avanzados

Ejecutemos nuestro playbook jerárquico:

cd ~/project/ansible-vars-demo
ansible-playbook -i inventory.ini hierarchical_setup.yml

Debería ver una salida que incluye variables de los tres vars_files.

Ahora, ejecutemos nuestro playbook completo:

ansible-playbook -i inventory.ini complete_setup.yml

Esta vez, debería ver una salida que incluye variables de vars_files, group_vars y host_vars.

Verificando los Archivos de Configuración

Verifiquemos los archivos de configuración creados por nuestros playbooks avanzados:

cat /tmp/dev_database_config.conf
cat /tmp/complete_config.conf

Entendiendo la Precedencia de Variables en Ansible

Al usar múltiples fuentes de variables, Ansible sigue un orden específico de precedencia:

  1. Variables de la línea de comandos (-e o --extra-vars)
  2. Variables definidas en el play
  3. Variables de archivos y roles incluidos
  4. Hechos del host (Host facts)
  5. Variables del host (Host vars)
  6. Variables del grupo (Group vars)
  7. Variables del inventario (Inventory vars)
  8. Variables predeterminadas del rol (Role default vars)

Esto significa que las variables definidas en host_vars anularán las mismas variables definidas en group_vars, que a su vez anularán las mismas variables definidas en vars_files.

Esta estructura jerárquica le brinda una forma poderosa de administrar la configuración en diferentes entornos, hosts y aplicaciones.

Resumen

En este tutorial, ha aprendido a usar eficazmente los vars_files de Ansible para la gestión de la configuración. Ha:

  1. Instalado Ansible y creado su primer vars_file para almacenar datos de configuración
  2. Creado y ejecutado un playbook básico que usa vars_files para separar la configuración de la lógica de automatización
  3. Trabajado con múltiples vars_files para administrar diferentes entornos
  4. Explorado técnicas avanzadas, incluida la organización jerárquica de variables y el uso de group_vars y host_vars

Estas habilidades proporcionan una base sólida para construir automatización de Ansible escalable y mantenible. Al separar sus datos de configuración de su lógica de automatización, puede:

  • Hacer que sus playbooks sean más reutilizables en diferentes entornos
  • Simplificar el proceso de actualización de los valores de configuración
  • Administrar configuraciones complejas de manera estructurada
  • Mejorar la colaboración al organizar claramente los datos de configuración

A medida que continúe trabajando con Ansible, recuerde que la gestión eficaz de variables es clave para construir una automatización mantenible. Las técnicas que ha aprendido en este tutorial le ayudarán a organizar sus proyectos de Ansible a medida que crecen en complejidad.