Saltar a contenido

Ansible Galaxy: Colecciones y roles

En este capítulo aprenderá a utilizar, instalar y gestionar los roles y colecciones de Ansible.


Objetivos : En este capítulo aprenderá a:

✔ instalar y gestionar colecciones;
✔ instalar y gestionar roles;.

🏁 ansible, ansible-galaxy, roles, colecciones

Conocimiento: ⭐ ⭐
Complejidad: ⭐ ⭐ ⭐

Tiempo de lectura: 40 minutos


Ansible Galaxy proporciona roles y colecciones de Ansible desde la comunidad Ansible.

Los elementos proporcionados se pueden referenciar en los playbooks y ser utilizados tal y como están

Comando ansible-galaxy

El comando ansible-galaxy gestiona los roles y las colecciones utilizando galaxy.ansible.com.

  • Para gestionar los roles:
ansible-galaxy role [import|init|install|login|remove|...]
Sub-comandos Observaciones
install instalar un rol.
remove elimina uno o más roles.
lista muestra el nombre y la versión de los roles instalados.
info muestra la información sobre un rol.
init genera la estructura básica de un nuevo rol.
import importa un rol desde el sitio web de Ansible Galaxy. Requiere inicio de sesión.
  • Para gestionar las colecciones:
ansible-galaxy collection [import|init|install|login|remove|...]
Sub-comandos Observaciones
init genera la estructura básica de una nueva colección.
install instala una colección.
list muestra el nombre y la versión de las colecciones instaladas.

Roles de Ansible

Un rol de Ansible es una unidad que promueve la reutilización de los playbooks.

Note

Puede encontrar más información aquí

Instalación de roles útiles

Para resaltar el interés del uso de roles, le sugiero que utilice el rol alemorvan/patchmanagement, que le permitirá realizar un montón de tareas (preactualización o postactualización, por ejemplo) durante su proceso de actualización, en sólo unas pocas líneas de código.

Puedes consultar el código en el repo de github del rol [aquí](https://github. com/alemorvan/patchmanagement).

  • Instalar el rol. Para ello, sólo es necesario un comando:
ansible-galaxy role install alemorvan.patchmanagement
  • Cree un playbook para incluir el rol:
- name: Start a Patch Management
  hosts: ansible_clients
  vars:
    pm_before_update_tasks_file: custom_tasks/pm_before_update_tasks_file.yml
    pm_after_update_tasks_file: custom_tasks/pm_after_update_tasks_file.yml

  tasks:
    - name: "Include patchmanagement"
      include_role:
        name: "alemorvan.patchmanagement"

Con este rol, puede añadir sus propias tareas para todo su inventario o sólo para su nodo objetivo.

Vamos a crear tareas que se ejecutarán antes y después del proceso de actualización:

  • Cree la carpeta custom_tasks:
mkdir custom_tasks
  • Cree el archivo custom_tasks/pm_before_update_tasks_file.yml (siéntase libre de cambiar el nombre y el contenido de este archivo)
---
- name: sample task before the update process
  debug:
    msg: "This is a sample tasks, feel free to add your own test task"
  • Cree el archivo custom_tasks/pm_after_update_tasks_file.yml (siéntase libre de cambiar el nombre y el contenido de este archivo)
---
- name: sample task after the update process
  debug:
    msg: "This is a sample tasks, feel free to add your own test task"

Y lance su primera gestión de parches:

ansible-playbook patchmanagement.yml

PLAY [Start a Patch Management] *************************************************************************

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

TASK [Include patchmanagement] **************************************************************************

TASK [alemorvan.patchmanagement : MAIN | Linux Patch Management Job] ************************************
ok: [192.168.1.11] => {
    "msg": "Start 192 patch management"
}

...

TASK [alemorvan.patchmanagement : sample task before the update process] ********************************
ok: [192.168.1.11] => {
    "msg": "This is a sample tasks, feel free to add your own test task"
}

...

TASK [alemorvan.patchmanagement : MAIN | We can now patch] **********************************************
included: /home/ansible/.ansible/roles/alemorvan.patchmanagement/tasks/patch.yml for 192.168.1.11

TASK [alemorvan.patchmanagement : PATCH | Tasks depends on distribution] ********************************
ok: [192.168.1.11] => {
    "ansible_distribution": "Rocky"
}

TASK [alemorvan.patchmanagement : PATCH | Include tasks for CentOS & RedHat tasks] **********************
included: /home/ansible/.ansible/roles/alemorvan.patchmanagement/tasks/linux_tasks/redhat_centos.yml for 192.168.1.11

TASK [alemorvan.patchmanagement : RHEL CENTOS | yum clean all] ******************************************
changed: [192.168.1.11]

TASK [alemorvan.patchmanagement : RHEL CENTOS | Ensure yum-utils is installed] **************************
ok: [192.168.1.11]

TASK [alemorvan.patchmanagement : RHEL CENTOS | Remove old kernels] *************************************
skipping: [192.168.1.11]

TASK [alemorvan.patchmanagement : RHEL CENTOS | Update rpm package with yum] ****************************
ok: [192.168.1.11]

TASK [alemorvan.patchmanagement : PATCH | Inlude tasks for Debian & Ubuntu tasks] ***********************
skipping: [192.168.1.11]

TASK [alemorvan.patchmanagement : MAIN | We can now reboot] *********************************************
included: /home/ansible/.ansible/roles/alemorvan.patchmanagement/tasks/reboot.yml for 192.168.1.11

TASK [alemorvan.patchmanagement : REBOOT | Reboot triggered] ********************************************
ok: [192.168.1.11]

TASK [alemorvan.patchmanagement : REBOOT | Ensure we are not in rescue mode] ****************************
ok: [192.168.1.11]

...

TASK [alemorvan.patchmanagement : FACTS | Insert fact file] *********************************************
ok: [192.168.1.11]

TASK [alemorvan.patchmanagement : FACTS | Save date of last PM] *****************************************
ok: [192.168.1.11]

...

TASK [alemorvan.patchmanagement : sample task after the update process] *********************************
ok: [192.168.1.11] => {
    "msg": "This is a sample tasks, feel free to add your own test task"
}

PLAY RECAP **********************************************************************************************
192.168.1.11               : ok=31   changed=1    unreachable=0    failed=0    skipped=4    rescued=0    ignored=0  

Bastante fácil para un proceso tan complejo, ¿no?

Este es sólo un ejemplo de lo que se puede hacer utilizando los roles puestos a disposición por la comunidad. Eche un vistazo a galaxy.ansible.com para descubrir las funciones que podrían serle útiles.

También puede crear sus propios roles para cubrir sus propias necesidades y publicarlos en Internet si le apetece. Lo que trataremos brevemente en el próximo capítulo.

Introducción al desarrollo de roles

La estructura básica de un rol, sirve como punto de partida para el desarrollo de roles personalizados, puede ser generada mediante el comando ansible-galaxy:

$ ansible-galaxy role init rocky8
- Role rocky8 was created successfully

El comando generará la siguiente estructura de árbol para contener el rol rocky8:

tree rocky8/
rocky8/
├── defaults
│   └── main.yml
├── files
├── handlers
│   └── main.yml
├── meta
│   └── main.yml
├── README.md
├── tasks
│   └── main.yml
├── templates
├── tests
│   ├── inventory
│   └── test.yml
└── vars
    └── main.yml

8 directories, 8 files

Los roles le permiten prescindir de la necesidad de incluir archivos. No es necesario especificar rutas de archivos o directivas include en los playbooks. Sólo tiene que especificar una tarea, y Ansible se encarga de las inclusiones.

La estructura de un rol es bastante obvia de entender.

Simplemente las variables se almacenan en vars/main.yml si las variables no van a ser sobreescribir, o en default/main.yml si quiere dejar la posibilidad de sobreescribir el contenido de las variables desde fuera de su rol.

Los handlers, archivos y plantillas necesarios para su código se almacenan en handlers/main.yml, files y templates respectivamente.

Sólo queda definir el código de las tareas de su rol en tasks/main.yml.

Una vez que todo esto funciona correctamente, puede utilizar este rol en sus playbooks. Podrá utilizar su rol sin preocuparse por el aspecto técnico de sus tareas, mientras personaliza su funcionamiento con variables.

Trabajo práctico: crear un primer rol sencillo

Implementemos esto con un rol que creará un usuario por defecto e instalará paquetes de software. Este rol puede aplicarse sistemáticamente a todos sus servidores.

Variables

Crearemos un usuario rockstar en todos nuestros servidores. Como no queremos que este usuario sea reemplazado, vamos a definirlo en el vars/main.yml:

---
rocky8_default_group:
  name: rockstar
  gid: 1100
rocky8_default_user:
  name: rockstar
  uid: 1100
  group: rockstar

Ahora podemos usar esas variables dentro de nuestro archivo tasks/main.yml sin ninguna inclusión.

---
- name: Create default group
  group:
    name: "{{ rocky8_default_group.name }}"
    gid: "{{ rocky8_default_group.gid }}"

- name: Create default user
  user:
    name: "{{ rocky8_default_user.name }}"
    uid: "{{ rocky8_default_user.uid }}"
    group: "{{ rocky8_default_user.group }}"

Para probar su nuevo rol, vamos a crear un playbook test-role.yml en el mismo directorio que su rol:

---
- name: Test my role
  hosts: localhost

  roles:

    - role: rocky8
      become: true
      become_user: root

y ejecútelo:

ansible-playbook test-role.yml

PLAY [Test my role] ************************************************************************************

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

TASK [rocky8 : Create default group] *******************************************************************
changed: [localhost]

TASK [rocky8 : Create default user] ********************************************************************
changed: [localhost]

PLAY RECAP *********************************************************************************************
localhost                  : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

¡Felicidades! Ahora es capaz de hacer grandes cosas con un playbook de unas pocas líneas.

Veamos el uso de las variables por defecto.

Cree una lista de paquetes para instalar por defecto en sus servidores y una lista vacía de paquetes para desinstalar. Edite los archivos defaults/main.yml y añada esas dos listas:

rocky8_default_packages:
  - tree
  - vim
rocky8_remove_packages: []

y utilícelos en tu archivo tasks/main.yml:

- name: Install default packages (can be overridden)
  package:
    name: "{{ rocky8_default_packages }}"
    state: present

- name: "Uninstall default packages (can be overridden) {{ rocky8_remove_packages }}"
  package:
    name: "{{ rocky8_remove_packages }}"
    state: absent

Pruebe su rol con la ayuda del playbook creado anteriormente:

ansible-playbook test-role.yml

PLAY [Test my role] ************************************************************************************

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

TASK [rocky8 : Create default group] *******************************************************************
ok: [localhost]

TASK [rocky8 : Create default user] ********************************************************************
ok: [localhost]

TASK [rocky8 : Install default packages (can be overridden)] ********************************************
ok: [localhost]

TASK [rocky8 : Uninstall default packages (can be overridden) []] ***************************************
ok: [localhost]

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

Ahora puede anular el valor de la variable rocky8_remove_packages en su playbook y desinstalar por ejemplo cockpit:

---
- name: Test my role
  hosts: localhost
  vars:
    rocky8_remove_packages:
      - cockpit

  roles:

    - role: rocky8
      become: true
      become_user: root
ansible-playbook test-role.yml

PLAY [Test my role] ************************************************************************************

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

TASK [rocky8 : Create default group] *******************************************************************
ok: [localhost]

TASK [rocky8 : Create default user] ********************************************************************
ok: [localhost]

TASK [rocky8 : Install default packages (can be overridden)] ********************************************
ok: [localhost]

TASK [rocky8 : Uninstall default packages (can be overridden) ['cockpit']] ******************************
changed: [localhost]

PLAY RECAP *********************************************************************************************
localhost                  : ok=5    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

Evidentemente, no hay límite a la hora de mejorar su rol. Imagine que para uno de sus servidores, necesita un paquete que está en la lista de los que hay que desinstalar. A continuación, podría, por ejemplo, crear una nueva lista que puede ser anulada y luego eliminar de la lista de paquetes a desinstalar los de la lista de paquetes específicos a instalar mediante el filtro de jinja difference().

- name: "Uninstall default packages (can be overridden) {{ rocky8_remove_packages }}"
  package:
    name: "{{ rocky8_remove_packages | difference(rocky8_specifics_packages) }}"
    state: absent

Colecciones de Ansible

Las colecciones son un formato de distribución para contenido de Ansible que puede incluir playbooks, roles, módulos y plugins.

Note

Puede encontrar más información aquí

Para instalar o actualizar una colección:

ansible-galaxy collection install namespace.collection [--upgrade]

A continuación, puede utilizar la colección recién instalada utilizando su espacio de nombres y su nombre antes del nombre del módulo o del rol:

- import_role:
    name: namespace.collection.rolename

- namespace.collection.modulename:
    option1: value

Puede encontrar un índice de la colección aquí.

Vamos a instalar la colección community.general:

ansible-galaxy collection install community.general
Starting galaxy collection install process
Process install dependency map
Starting collection install process
Downloading https://galaxy.ansible.com/download/community-general-3.3.2.tar.gz to /home/ansible/.ansible/tmp/ansible-local-51384hsuhf3t5/tmpr_c9qrt1/community-general-3.3.2-f4q9u4dg
Installing 'community.general:3.3.2' to '/home/ansible/.ansible/collections/ansible_collections/community/general'
community.general:3.3.2 was installed successfully

Ahora podemos utilizar el nuevo módulo disponible yum_versionlock:

- name: Start a Patch Management
  hosts: ansible_clients
  become: true
  become_user: root
  tasks:

    - name: Ensure yum-versionlock is installed
      package:
        name: python3-dnf-plugin-versionlock
        state: present

    - name: Prevent kernel from being updated
      community.general.yum_versionlock:
        state: present
        name: kernel
      register: locks

    - name: Display locks
      debug:
        var: locks.meta.packages                            
ansible-playbook versionlock.yml

PLAY [Start a Patch Management] *************************************************************************

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

TASK [Ensure yum-versionlock is installed] **************************************************************
changed: [192.168.1.11]

TASK [Prevent kernel from being updated] ****************************************************************
changed: [192.168.1.11]

TASK [Display locks] ************************************************************************************
ok: [192.168.1.11] => {
    "locks.meta.packages": [
        "kernel"
    ]
}

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

Crea su propia colección

Al igual que con los roles, puede crear su propia colección con la ayuda del comando ansible-galaxy:

ansible-galaxy collection init rocky8.rockstarcollection
- Collection rocky8.rockstarcollection was created successfully
tree rocky8/rockstarcollection/
rocky8/rockstarcollection/
├── docs
├── galaxy.yml
├── plugins
│ └── README.md
├── README.md
└── roles

A continuación, puede almacenar sus propios plugins o roles dentro de esta nueva colección.