Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Ansible, how to combine variables from separate files into one array?

Tags:

In Ansible, in a role, I have vars files like this:

vars/     app1.yml     app2.yml 

Each file contains vars specific to an app/website like this:

name: app1 git_repo: https://github.com/philgyford/app1.git # ... 

Ideally, without the task knowing in advance which apps have variable files, I'd like to end up with an array called apps like this:

apps:   - name: app1     git_repo: https://github.com/philgyford/app1.git     # ...   - name: app2     git_repo: https://github.com/philgyford/app2.git     # ... 

ie, that combines the variables from the files into one.

I know I can load all the variable files like this:

- name: Load var files   with_fileglob:     - ../vars/*.yml   include_vars: '{{ item }}' 

But given each file has identical variable names, it will overwrite each previous set of variables. I can't see a way to load the variables and put them into an apps array.

I'm open to rearranging things slightly if it's the only way to make something like this possible.

like image 853
Phil Gyford Avatar asked Feb 22 '16 13:02

Phil Gyford


People also ask

How do you pass multiple variables in Ansible?

Ansible treats values of the extra variables as strings. To pass values that are not strings, we need to use JSON format. To pass extra vars in JSON format we need to enclose JSON in quotation marks: ansible-playbook extra_var_json.

How do I use dynamic variables in Ansible?

Create an Ansible Playbook which will dynamically load the variable file named the same as OS_name and just by using the variable names we can Configure our target node. (Note: No need to use when keyword here.)


1 Answers

You can not do that. Variables will always override variables with the same name. The only thing you could do with this exact setup is to write your own vars plugin which reads those files and merges them into an array.

If you are open to change the structure of your apps definition you can use a hash and set your hash_behavior=merge. In each vars file then you'd have a definition like:

apps:   app1:     git_repo: https://github.com/philgyford/app1.git 

apps:   app2:     git_repo: https://github.com/philgyford/app2.git 

When Ansible loads both files it will merge it automatically together into:

apps:   app1:     git_repo: https://github.com/philgyford/app1.git   app2:     git_repo: https://github.com/philgyford/app2.git</pre> 

But be advised that hash_behavior=merge fundamentally changes the default behavior of Ansible on a global level. Make sure all your roles do not have issues with this setting. The documentation mentions:

We generally recommend not using this setting unless you think you have an absolute need for it

If you still use Ansible 1 you could use one of my old plugins instead: include_vars_merged. Basically this adds the behavior of hash_behavior=merge to only a single task.

I have not yet looked into migrating this to Ansible 2 though and currently it looks like I won't have the need for it any longer.

like image 57
udondan Avatar answered Oct 13 '22 22:10

udondan