Ansible: How to inherit variables?

I want to get variable inheritance in Ansible. Let's say I have:

group_vars / all

---
ifaces:
   -   name: eth0
       adress: 10.107.13.236
       netmask: 255.255.255.192
       routes:
           - {from: 10.108.100.34/31, via: 10.107.13.193}
           - {from: 10.108.105.128/31, via: 10.107.13.193}
   -   name: eth1
       adress: 10.112.13.236
       netmask: 255.255.255.192
       gateway: 10.112.13.193
       routes:
           - {from: 10.2.1.0/26, via: 10.112.13.254}

      

Now I want to extend eth0 routes like:

group_vars / webserver

--- ifaces:
   -   name: eth0
       routes:
           - {from: 1.2.3.34, via: 5.6.7.8}
           - {from: 9.9.9.9/9, via: 5.6.7.8}

      

My desired output:

---
ifaces:
   -   name: eth0
       adress: 10.107.13.236
       netmask: 255.255.255.192
       routes:
           - {from: 10.108.100.34/31, via: 10.107.13.193}
           - {from: 10.108.105.128/31, via: 10.107.13.193}
           - {from: 1.2.3.34, via: 5.6.7.8}
           - {from: 9.9.9.9/9, via: 5.6.7.8}
   -   name: eth1
       adress: 10.112.13.236
       netmask: 255.255.255.192
       gateway: 10.112.13.193
       routes:
           - {from: 10.2.1.0/26, via: 10.112.13.254}

      

Thus, routes must be extended and not overwritten. I know about setting hash_behaviour: merge

in ansible.cfg

, but it doesn't suit my needs because I want to add values ​​to the list stored in routes.

The background is that I need to be able to define some standard routes (note: this is not limited to routes, this is just an example) and improve those standards for certain groups instead of overriding them.

Is this possible in Ansible?

+3


source to share


1 answer


I would suggest creating lookup_plugin

one that will do all the heavy ligation of merge / append variables.

eg:

lookup_plugins / myvars.py

import yaml
class LookupModule(object):
    def __init__(self, basedir=None, **kwargs):
        self.basedir = basedir
        self.plugin_name = 'myvars'
    def run(self, vars_file, variable=None, **kwargs):
        all_routes = yaml.load(file('group_vars/all'))['ifaces'][0]['routes']
        all_routes.extend(
            yaml.load(file('group_vars/%s' % vars_file[0]))['ifaces'][0]['routes'])
        return [all_routes]

      

playbook.yml



---
- hosts: webservers
  gather_facts: no
  connection: local
  tasks:
    - debug: msg=" Hey {{ item }}"
      with_myvars:
        - webservers

      

Of course, this doesn't completely solve your problem, and you still need to tweak it for it to work. But you should get an idea of ​​how to achieve this from this example.

The result should look like this:

PLAY [webservers] ************************************************************* 

TASK: [debug msg=" Hey {{ item }}"] ******************************************* 
ok: [localhost] => (item=[{'via': '10.107.13.193', 'from': '10.108.100.34/31'}, {'via': '10.107.13.193', 'from': '10.108.105.128/31'}, {'via': '5.6.7.8', 'from': '1.2.3.34'}, {'via': '5.6.7.8', 'from': '9.9.9.9/9'}]) => {
    "item": [
        {
            "from": "10.108.100.34/31",
            "via": "10.107.13.193"
        },
        {
            "from": "10.108.105.128/31",
            "via": "10.107.13.193"
        },
        {
            "from": "1.2.3.34",
            "via": "5.6.7.8"
        },
        {
            "from": "9.9.9.9/9",
            "via": "5.6.7.8"
        }
    ],
    "msg": " Hey [{'via': '10.107.13.193', 'from': '10.108.100.34/31'}, {'via': '10.107.13.193', 'from': '10.108.105.128/31'}, {'via': '5.6.7.8', 'from': '1.2.3.34'}, {'via': '5.6.7.8', 'from': '9.9.9.9/9'}]"
}

PLAY RECAP ******************************************************************** 
localhost                  : ok=1    changed=0    unreachable=0    failed=0   

      

So, you can see that it returns a list of routes, so you can easily fit {{ item }}

in whatever you need.

+2


source







All Articles