En este módulo, aprenderás cómo crear tus propios módulos personalizados en Ansible. Los módulos personalizados te permiten extender la funcionalidad de Ansible para satisfacer necesidades específicas que no están cubiertas por los módulos integrados.

Objetivos del Módulo

  • Comprender la estructura básica de un módulo personalizado.
  • Aprender a escribir y ejecutar un módulo personalizado.
  • Conocer las mejores prácticas para desarrollar módulos personalizados.

  1. Introducción a los Módulos Personalizados

¿Qué es un Módulo Personalizado?

Un módulo personalizado en Ansible es un script que puedes escribir para realizar tareas específicas que no están cubiertas por los módulos integrados. Estos módulos pueden ser escritos en cualquier lenguaje de programación, aunque Python es el más común debido a su integración nativa con Ansible.

¿Por qué Crear Módulos Personalizados?

  • Flexibilidad: Permiten realizar tareas específicas que no están cubiertas por los módulos existentes.
  • Reusabilidad: Pueden ser reutilizados en múltiples playbooks y proyectos.
  • Mantenibilidad: Facilitan la organización y mantenimiento del código.

  1. Estructura de un Módulo Personalizado

Componentes Básicos

Un módulo personalizado generalmente consta de los siguientes componentes:

  • Documentación: Describe el propósito del módulo, sus parámetros y ejemplos de uso.
  • Argument Spec: Define los argumentos que el módulo acepta.
  • Main Function: Contiene la lógica principal del módulo.
  • Exit JSON: Devuelve el resultado de la ejecución del módulo.

Ejemplo de Estructura

#!/usr/bin/python

from ansible.module_utils.basic import AnsibleModule

def run_module():
    # Definir los argumentos que el módulo acepta
    module_args = dict(
        name=dict(type='str', required=True),
        state=dict(type='str', required=True, choices=['present', 'absent'])
    )

    # Crear el objeto AnsibleModule
    module = AnsibleModule(
        argument_spec=module_args,
        supports_check_mode=True
    )

    # Obtener los parámetros
    name = module.params['name']
    state = module.params['state']

    # Lógica del módulo
    result = dict(
        changed=False,
        original_message='',
        message=''
    )

    if state == 'present':
        result['changed'] = True
        result['message'] = f'{name} is now present'
    elif state == 'absent':
        result['changed'] = True
        result['message'] = f'{name} is now absent'

    # Salida del módulo
    module.exit_json(**result)

def main():
    run_module()

if __name__ == '__main__':
    main()

  1. Escribiendo tu Primer Módulo Personalizado

Paso a Paso

  1. Crear el Archivo del Módulo: Crea un archivo Python, por ejemplo, my_custom_module.py.

  2. Importar AnsibleModule:

    from ansible.module_utils.basic import AnsibleModule
    
  3. Definir Argumentos:

    module_args = dict(
        name=dict(type='str', required=True),
        state=dict(type='str', required=True, choices=['present', 'absent'])
    )
    
  4. Crear el Objeto AnsibleModule:

    module = AnsibleModule(
        argument_spec=module_args,
        supports_check_mode=True
    )
    
  5. Obtener Parámetros:

    name = module.params['name']
    state = module.params['state']
    
  6. Implementar la Lógica del Módulo:

    result = dict(
        changed=False,
        original_message='',
        message=''
    )
    
    if state == 'present':
        result['changed'] = True
        result['message'] = f'{name} is now present'
    elif state == 'absent':
        result['changed'] = True
        result['message'] = f'{name} is now absent'
    
  7. Devolver el Resultado:

    module.exit_json(**result)
    
  8. Definir la Función Principal:

    def main():
        run_module()
    
    if __name__ == '__main__':
        main()
    

Ejemplo Completo

#!/usr/bin/python

from ansible.module_utils.basic import AnsibleModule

def run_module():
    module_args = dict(
        name=dict(type='str', required=True),
        state=dict(type='str', required=True, choices=['present', 'absent'])
    )

    module = AnsibleModule(
        argument_spec=module_args,
        supports_check_mode=True
    )

    name = module.params['name']
    state = module.params['state']

    result = dict(
        changed=False,
        original_message='',
        message=''
    )

    if state == 'present':
        result['changed'] = True
        result['message'] = f'{name} is now present'
    elif state == 'absent':
        result['changed'] = True
        result['message'] = f'{name} is now absent'

    module.exit_json(**result)

def main():
    run_module()

if __name__ == '__main__':
    main()

  1. Ejecutando el Módulo Personalizado

Incluir el Módulo en un Playbook

Para ejecutar tu módulo personalizado, inclúyelo en un playbook de la siguiente manera:

---
- name: Test custom module
  hosts: localhost
  tasks:
    - name: Ensure my_custom_module works
      my_custom_module:
        name: "example"
        state: "present"

Ejecutar el Playbook

ansible-playbook test_custom_module.yml

  1. Mejores Prácticas

  • Documentación: Asegúrate de documentar bien tu módulo para que otros usuarios puedan entender su propósito y cómo usarlo.
  • Pruebas: Realiza pruebas exhaustivas para asegurarte de que tu módulo funciona correctamente en diferentes escenarios.
  • Manejo de Errores: Implementa un manejo de errores adecuado para que el módulo pueda manejar situaciones inesperadas de manera elegante.

  1. Ejercicio Práctico

Ejercicio

Crea un módulo personalizado que gestione archivos en el sistema. El módulo debe aceptar los siguientes parámetros:

  • path: Ruta del archivo.
  • state: Estado del archivo (present para crear, absent para eliminar).

Solución

#!/usr/bin/python

from ansible.module_utils.basic import AnsibleModule
import os

def run_module():
    module_args = dict(
        path=dict(type='str', required=True),
        state=dict(type='str', required=True, choices=['present', 'absent'])
    )

    module = AnsibleModule(
        argument_spec=module_args,
        supports_check_mode=True
    )

    path = module.params['path']
    state = module.params['state']

    result = dict(
        changed=False,
        original_message='',
        message=''
    )

    if state == 'present':
        if not os.path.exists(path):
            open(path, 'w').close()
            result['changed'] = True
            result['message'] = f'File {path} created'
        else:
            result['message'] = f'File {path} already exists'
    elif state == 'absent':
        if os.path.exists(path):
            os.remove(path)
            result['changed'] = True
            result['message'] = f'File {path} deleted'
        else:
            result['message'] = f'File {path} does not exist'

    module.exit_json(**result)

def main():
    run_module()

if __name__ == '__main__':
    main()

Conclusión

En este módulo, has aprendido cómo crear y ejecutar módulos personalizados en Ansible. Los módulos personalizados te permiten extender la funcionalidad de Ansible para satisfacer necesidades específicas, proporcionando flexibilidad y reusabilidad en tus playbooks. Asegúrate de seguir las mejores prácticas para documentar, probar y manejar errores en tus módulos personalizados. En el próximo módulo, exploraremos el uso de inventarios dinámicos en Ansible.

© Copyright 2024. Todos los derechos reservados