I want to achieve variable inheritance in Ansible. Lets 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 the routes of eth0, like this:
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 result is:
---
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}
So the routes should be extendend and not overwritten. I know about setting hash_behaviour: merge
in ansible.cfg
but that does not satisfy my needs, because I want to append 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, it is just an example) and enhance these standards for specific groups instead of overriding them.
Is this possible in Ansible?
The easiest way to pass Pass Variables value to Ansible Playbook in the command line is using the extra variables parameter of the “ansible-playbook” command. This is very useful to combine your Ansible Playbook with some pre-existent automation or script.
You can use the environment keyword at the play, block, or task level to set an environment variable for an action on a remote host. With this keyword, you can enable using a proxy for a task that does http requests, set the required environment variables for language-specific version managers, and more.
Ansible defines the precedence order as follows: Extra vars (from command-line) always win. Task vars (only for the specific task). Block vars (only for the tasks within the block).
Ansible registers are used when you want to capture the output of a task to a variable. You can then use the value of these registers for different scenarios like a conditional statement, logging etc. The variables will contain the value returned by the task. The common return values are documented in Ansible docs.
I would suggest creating lookup_plugin
that will do all the heavy-ligting of the merging/appending variables.
for example:
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]
---
- hosts: webservers
gather_facts: no
connection: local
tasks:
- debug: msg=" Hey {{ item }}"
with_myvars:
- webservers
Of cource it doesn't fully solve your plroblem and you still need to tweak it to make it work. But you should get an idea on how to achive this from this example.
An output of this 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 as you can see it's returning a list of routes, so you can easily place {{ item }}
in what ever spot you need.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With