Ansible – Merging Lists from Multiple Group Vars

ansiblelinux

We have many servers groups, for example :

  • MTL (servers located in Montreal)
  • OTA (servers located in Ottawa)
  • DMZ (reverse proxies exposed to internet)
  • APP (applicative servers)
  • CUSTOMER_X (server that contains customer X)
  • CUSTOMER_Y (server that contains customer Y)

Each server group have their own cron jobs, and a server can belong to many matched and unmatched groups (a server can be in all groups MTL, DMZ, APP, CUSTOMER_Y and CUSTOMER_X).

What we want to do is to merge all "cron_jobs" list of matching group_vars of a given server.

Is that possible ? Else, is there a way to achieve equivalent ?

We could of course do :

crons: "{{ all_crons + dmz_crons + mtl_crons }}" # etc ..

But that would be redneck as hell considering we have hundreds of groups

Thank you very much for your help

Best Answer

Create a role for each function (OTA, MTL, DMZ, APP, CUSTOMER_X, CUSTOMER_Y)

- hosts: dmz
  roles:
    - { role: dmz}   
- hosts: ota
  become: yes
  roles:
    - { role: ota}       
- hosts: app
  become: yes
  roles:
    - { role: app}   

Each role does specific configuration for the function (i.e. dmz configures a dmz) and it also adds the needed cron jobs.

You can optimize the roles, avoiding repeating code, by using a common role that is added as a dependency on the meta folder.

Example, in role app folder meta, create a file main.yml with the following content:

dependencies:
  - { role: common,
      common_cron_job: "{{app_common_cron_job}}"
    }

The value of app_common_cron_job can be set in each ansible group, for example group_vars\app

The common role will have the needed task to create the cron job using the provided value in common_cron_job. If you need more than a single job for each group, modify the code to pass a struct of jobs.

See my tutorial Creating a Kubernetes Cluster with Vagrant and Ansible for a full example of how to use meta folders and dependencies. See my tutorial Using Ansible for Terraform Managed AWS Infrastructure for an example on how to use group vars.

A host that is present in many groups will end up executing a role for each of its groups and the value of common_cron_job will change to be whatever the groupvars define for that group. At the end all the needed cron jobs will be created.

Be aware that you will also need a way to clear created cron jobs that are not needed anymore (tip: use a common_cron_job_delete var and its corresponding task).