In Ansible, how to combine variables from separate files into one array?
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}
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.
ansible
add a comment |
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.
ansible
add a comment |
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.
ansible
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.
ansible
ansible
asked Feb 22 '16 at 13:01
Phil GyfordPhil Gyford
4,36363478
4,36363478
add a comment |
add a comment |
5 Answers
5
active
oldest
votes
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.
2
In Ansible 2 you can use thecombine
Jinja filter but it does require that you know the hashes you want to combine up front
– ydaetskcoR
Feb 22 '16 at 14:07
2
I had so much hope in this filter but unfortunately you can not use it to extend a hash and store the result with the same name.some_hash: "{{ some_hash | combine({foo: bar}) }}"
This would have been useful.
– udondan
Feb 22 '16 at 14:16
Thanks both. I feared there was no simple answer - I'll find some other, less nice, way to handle these vars. I'd come acrosshash_behaviour=merge
but was wary given it changes Ansible's behaviour so much. Alsocombine
raised my hopes too, only to swiftly dash them. So close…
– Phil Gyford
Feb 22 '16 at 14:27
In case you start from a clean playbook, you could load one set of variables and then load them into your target dictionary from thehostvars
dictionary, filtering out any keys that start withansible_
,group
,inventory_
,module_
,omit
, andplaybook_
. On the second step, filter out your target dictionary, as well.
– Andreas
Aug 8 '17 at 22:47
add a comment |
Starting with Ansible v2.0 you can do it:
- name: merging hash_a and hash_b into hash_c
set_fact: hash_c="{{ hash_a|combine(hash_b) }}"
Check more under Ansible filters - Combining hashes/dictionaries (coming from Jinja2)
Can you show how to do this with to vars files? Do I have to do it with every single array within the vars file? Can I somehow do it for the entire vars file?
– Jonathan
Feb 6 at 21:07
add a comment |
Well, you cannot directly build an array, but you can achieve the same effort with a dict.
Suppose you want to construct an array:
[{
name: 'bob',
age: 30
}, {
name: 'alice',
age: 35
}]
You can put each element in a file like:
bob.yml
bob:
name: bob
age: 30
alice.yml
alice:
name: alice
age: 35
Place these files in the same dir (e.g. user
), then use include_vars
to load the whole dir:
- name: Include vars
include_vars:
name: users
dir: user
This will give you a dict users
:
users:
alice:
name: alice
age: 35
bob:
name: bob
age: 30
User the dict2items
filter in ansible, you get the array you want
add a comment |
Wanted to post a possible alternate solution by getting a list of variables that match a pattern, then you can just process all those variables, sorta manual merge.
The following code block gives an example of pulling all variables that match a specific pattern and looping. you could set a new fact with them merged, or simply process them all individually.
- name: "debug2" debug:
msg: "value is: {{ lookup('vars', item) }} "
loop: "{{ hostvars[inventory_hostname] | select('match', '^linux_hosts_entries') |list }}"
see the following post for further details.
Please provide the core details of the post in your answer, thank you.
– Jonathan
Feb 6 at 21:10
@Jonathan updated
– abe
Feb 6 at 23:23
add a comment |
Since Ansible 2.2
, the include_vars
(link) module has been expanded quite a bit.
It's now possible to do something like:
- include_vars:
name: 'apps'
dir: '../vars'
extensions:
- 'yaml'
- 'yml'
name
is the key there. From the module page:
The name of a variable into which assign the included vars. If omitted (null) they will be made top level vars.
This allows you to convert:
vars/
app1.yml
app2.yml
...
app1.yml:
name: app1
git_repo: https://github.com/philgyford/app1.git
# ...
app2.yml:
name: app2
git_repo: https://github.com/philgyford/app2.git
# ...
Into...
apps:
- name: app1
git_repo: https://github.com/philgyford/app1.git
# ...
- name: app2
git_repo: https://github.com/philgyford/app2.git
# ...
Have you tried the solution you posted? Because Ansible will not accept vars file being a list, it must be a dictionary. It will throw an error../vars/app1.yml must be stored as a dictionary/hash
.
– techraf
Sep 8 '18 at 17:38
What if you want to merge two child arrays? Such as a having twoapps
vars merged?
– Jonathan
Feb 6 at 21:09
@techraf - you're correct. The hyphens need removing from theappX.yml
files so that they're dictionaries. They're unnecessary anyway, as the list is exactly what this method is looking to breakdown in to separate files. I've updated my answer to have a functioning example. Sorry about that.
– Jack_Hu
Feb 15 at 17:53
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f35554415%2fin-ansible-how-to-combine-variables-from-separate-files-into-one-array%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
5 Answers
5
active
oldest
votes
5 Answers
5
active
oldest
votes
active
oldest
votes
active
oldest
votes
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.
2
In Ansible 2 you can use thecombine
Jinja filter but it does require that you know the hashes you want to combine up front
– ydaetskcoR
Feb 22 '16 at 14:07
2
I had so much hope in this filter but unfortunately you can not use it to extend a hash and store the result with the same name.some_hash: "{{ some_hash | combine({foo: bar}) }}"
This would have been useful.
– udondan
Feb 22 '16 at 14:16
Thanks both. I feared there was no simple answer - I'll find some other, less nice, way to handle these vars. I'd come acrosshash_behaviour=merge
but was wary given it changes Ansible's behaviour so much. Alsocombine
raised my hopes too, only to swiftly dash them. So close…
– Phil Gyford
Feb 22 '16 at 14:27
In case you start from a clean playbook, you could load one set of variables and then load them into your target dictionary from thehostvars
dictionary, filtering out any keys that start withansible_
,group
,inventory_
,module_
,omit
, andplaybook_
. On the second step, filter out your target dictionary, as well.
– Andreas
Aug 8 '17 at 22:47
add a comment |
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.
2
In Ansible 2 you can use thecombine
Jinja filter but it does require that you know the hashes you want to combine up front
– ydaetskcoR
Feb 22 '16 at 14:07
2
I had so much hope in this filter but unfortunately you can not use it to extend a hash and store the result with the same name.some_hash: "{{ some_hash | combine({foo: bar}) }}"
This would have been useful.
– udondan
Feb 22 '16 at 14:16
Thanks both. I feared there was no simple answer - I'll find some other, less nice, way to handle these vars. I'd come acrosshash_behaviour=merge
but was wary given it changes Ansible's behaviour so much. Alsocombine
raised my hopes too, only to swiftly dash them. So close…
– Phil Gyford
Feb 22 '16 at 14:27
In case you start from a clean playbook, you could load one set of variables and then load them into your target dictionary from thehostvars
dictionary, filtering out any keys that start withansible_
,group
,inventory_
,module_
,omit
, andplaybook_
. On the second step, filter out your target dictionary, as well.
– Andreas
Aug 8 '17 at 22:47
add a comment |
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.
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.
edited Jan 2 at 13:13
Richlv
2,79311015
2,79311015
answered Feb 22 '16 at 13:31
udondanudondan
35k10123131
35k10123131
2
In Ansible 2 you can use thecombine
Jinja filter but it does require that you know the hashes you want to combine up front
– ydaetskcoR
Feb 22 '16 at 14:07
2
I had so much hope in this filter but unfortunately you can not use it to extend a hash and store the result with the same name.some_hash: "{{ some_hash | combine({foo: bar}) }}"
This would have been useful.
– udondan
Feb 22 '16 at 14:16
Thanks both. I feared there was no simple answer - I'll find some other, less nice, way to handle these vars. I'd come acrosshash_behaviour=merge
but was wary given it changes Ansible's behaviour so much. Alsocombine
raised my hopes too, only to swiftly dash them. So close…
– Phil Gyford
Feb 22 '16 at 14:27
In case you start from a clean playbook, you could load one set of variables and then load them into your target dictionary from thehostvars
dictionary, filtering out any keys that start withansible_
,group
,inventory_
,module_
,omit
, andplaybook_
. On the second step, filter out your target dictionary, as well.
– Andreas
Aug 8 '17 at 22:47
add a comment |
2
In Ansible 2 you can use thecombine
Jinja filter but it does require that you know the hashes you want to combine up front
– ydaetskcoR
Feb 22 '16 at 14:07
2
I had so much hope in this filter but unfortunately you can not use it to extend a hash and store the result with the same name.some_hash: "{{ some_hash | combine({foo: bar}) }}"
This would have been useful.
– udondan
Feb 22 '16 at 14:16
Thanks both. I feared there was no simple answer - I'll find some other, less nice, way to handle these vars. I'd come acrosshash_behaviour=merge
but was wary given it changes Ansible's behaviour so much. Alsocombine
raised my hopes too, only to swiftly dash them. So close…
– Phil Gyford
Feb 22 '16 at 14:27
In case you start from a clean playbook, you could load one set of variables and then load them into your target dictionary from thehostvars
dictionary, filtering out any keys that start withansible_
,group
,inventory_
,module_
,omit
, andplaybook_
. On the second step, filter out your target dictionary, as well.
– Andreas
Aug 8 '17 at 22:47
2
2
In Ansible 2 you can use the
combine
Jinja filter but it does require that you know the hashes you want to combine up front– ydaetskcoR
Feb 22 '16 at 14:07
In Ansible 2 you can use the
combine
Jinja filter but it does require that you know the hashes you want to combine up front– ydaetskcoR
Feb 22 '16 at 14:07
2
2
I had so much hope in this filter but unfortunately you can not use it to extend a hash and store the result with the same name.
some_hash: "{{ some_hash | combine({foo: bar}) }}"
This would have been useful.– udondan
Feb 22 '16 at 14:16
I had so much hope in this filter but unfortunately you can not use it to extend a hash and store the result with the same name.
some_hash: "{{ some_hash | combine({foo: bar}) }}"
This would have been useful.– udondan
Feb 22 '16 at 14:16
Thanks both. I feared there was no simple answer - I'll find some other, less nice, way to handle these vars. I'd come across
hash_behaviour=merge
but was wary given it changes Ansible's behaviour so much. Also combine
raised my hopes too, only to swiftly dash them. So close…– Phil Gyford
Feb 22 '16 at 14:27
Thanks both. I feared there was no simple answer - I'll find some other, less nice, way to handle these vars. I'd come across
hash_behaviour=merge
but was wary given it changes Ansible's behaviour so much. Also combine
raised my hopes too, only to swiftly dash them. So close…– Phil Gyford
Feb 22 '16 at 14:27
In case you start from a clean playbook, you could load one set of variables and then load them into your target dictionary from the
hostvars
dictionary, filtering out any keys that start with ansible_
, group
, inventory_
, module_
, omit
, and playbook_
. On the second step, filter out your target dictionary, as well.– Andreas
Aug 8 '17 at 22:47
In case you start from a clean playbook, you could load one set of variables and then load them into your target dictionary from the
hostvars
dictionary, filtering out any keys that start with ansible_
, group
, inventory_
, module_
, omit
, and playbook_
. On the second step, filter out your target dictionary, as well.– Andreas
Aug 8 '17 at 22:47
add a comment |
Starting with Ansible v2.0 you can do it:
- name: merging hash_a and hash_b into hash_c
set_fact: hash_c="{{ hash_a|combine(hash_b) }}"
Check more under Ansible filters - Combining hashes/dictionaries (coming from Jinja2)
Can you show how to do this with to vars files? Do I have to do it with every single array within the vars file? Can I somehow do it for the entire vars file?
– Jonathan
Feb 6 at 21:07
add a comment |
Starting with Ansible v2.0 you can do it:
- name: merging hash_a and hash_b into hash_c
set_fact: hash_c="{{ hash_a|combine(hash_b) }}"
Check more under Ansible filters - Combining hashes/dictionaries (coming from Jinja2)
Can you show how to do this with to vars files? Do I have to do it with every single array within the vars file? Can I somehow do it for the entire vars file?
– Jonathan
Feb 6 at 21:07
add a comment |
Starting with Ansible v2.0 you can do it:
- name: merging hash_a and hash_b into hash_c
set_fact: hash_c="{{ hash_a|combine(hash_b) }}"
Check more under Ansible filters - Combining hashes/dictionaries (coming from Jinja2)
Starting with Ansible v2.0 you can do it:
- name: merging hash_a and hash_b into hash_c
set_fact: hash_c="{{ hash_a|combine(hash_b) }}"
Check more under Ansible filters - Combining hashes/dictionaries (coming from Jinja2)
answered Oct 15 '18 at 21:59
mPrinCmPrinC
1,3751220
1,3751220
Can you show how to do this with to vars files? Do I have to do it with every single array within the vars file? Can I somehow do it for the entire vars file?
– Jonathan
Feb 6 at 21:07
add a comment |
Can you show how to do this with to vars files? Do I have to do it with every single array within the vars file? Can I somehow do it for the entire vars file?
– Jonathan
Feb 6 at 21:07
Can you show how to do this with to vars files? Do I have to do it with every single array within the vars file? Can I somehow do it for the entire vars file?
– Jonathan
Feb 6 at 21:07
Can you show how to do this with to vars files? Do I have to do it with every single array within the vars file? Can I somehow do it for the entire vars file?
– Jonathan
Feb 6 at 21:07
add a comment |
Well, you cannot directly build an array, but you can achieve the same effort with a dict.
Suppose you want to construct an array:
[{
name: 'bob',
age: 30
}, {
name: 'alice',
age: 35
}]
You can put each element in a file like:
bob.yml
bob:
name: bob
age: 30
alice.yml
alice:
name: alice
age: 35
Place these files in the same dir (e.g. user
), then use include_vars
to load the whole dir:
- name: Include vars
include_vars:
name: users
dir: user
This will give you a dict users
:
users:
alice:
name: alice
age: 35
bob:
name: bob
age: 30
User the dict2items
filter in ansible, you get the array you want
add a comment |
Well, you cannot directly build an array, but you can achieve the same effort with a dict.
Suppose you want to construct an array:
[{
name: 'bob',
age: 30
}, {
name: 'alice',
age: 35
}]
You can put each element in a file like:
bob.yml
bob:
name: bob
age: 30
alice.yml
alice:
name: alice
age: 35
Place these files in the same dir (e.g. user
), then use include_vars
to load the whole dir:
- name: Include vars
include_vars:
name: users
dir: user
This will give you a dict users
:
users:
alice:
name: alice
age: 35
bob:
name: bob
age: 30
User the dict2items
filter in ansible, you get the array you want
add a comment |
Well, you cannot directly build an array, but you can achieve the same effort with a dict.
Suppose you want to construct an array:
[{
name: 'bob',
age: 30
}, {
name: 'alice',
age: 35
}]
You can put each element in a file like:
bob.yml
bob:
name: bob
age: 30
alice.yml
alice:
name: alice
age: 35
Place these files in the same dir (e.g. user
), then use include_vars
to load the whole dir:
- name: Include vars
include_vars:
name: users
dir: user
This will give you a dict users
:
users:
alice:
name: alice
age: 35
bob:
name: bob
age: 30
User the dict2items
filter in ansible, you get the array you want
Well, you cannot directly build an array, but you can achieve the same effort with a dict.
Suppose you want to construct an array:
[{
name: 'bob',
age: 30
}, {
name: 'alice',
age: 35
}]
You can put each element in a file like:
bob.yml
bob:
name: bob
age: 30
alice.yml
alice:
name: alice
age: 35
Place these files in the same dir (e.g. user
), then use include_vars
to load the whole dir:
- name: Include vars
include_vars:
name: users
dir: user
This will give you a dict users
:
users:
alice:
name: alice
age: 35
bob:
name: bob
age: 30
User the dict2items
filter in ansible, you get the array you want
answered Jan 3 at 2:33
fifmanfifman
213
213
add a comment |
add a comment |
Wanted to post a possible alternate solution by getting a list of variables that match a pattern, then you can just process all those variables, sorta manual merge.
The following code block gives an example of pulling all variables that match a specific pattern and looping. you could set a new fact with them merged, or simply process them all individually.
- name: "debug2" debug:
msg: "value is: {{ lookup('vars', item) }} "
loop: "{{ hostvars[inventory_hostname] | select('match', '^linux_hosts_entries') |list }}"
see the following post for further details.
Please provide the core details of the post in your answer, thank you.
– Jonathan
Feb 6 at 21:10
@Jonathan updated
– abe
Feb 6 at 23:23
add a comment |
Wanted to post a possible alternate solution by getting a list of variables that match a pattern, then you can just process all those variables, sorta manual merge.
The following code block gives an example of pulling all variables that match a specific pattern and looping. you could set a new fact with them merged, or simply process them all individually.
- name: "debug2" debug:
msg: "value is: {{ lookup('vars', item) }} "
loop: "{{ hostvars[inventory_hostname] | select('match', '^linux_hosts_entries') |list }}"
see the following post for further details.
Please provide the core details of the post in your answer, thank you.
– Jonathan
Feb 6 at 21:10
@Jonathan updated
– abe
Feb 6 at 23:23
add a comment |
Wanted to post a possible alternate solution by getting a list of variables that match a pattern, then you can just process all those variables, sorta manual merge.
The following code block gives an example of pulling all variables that match a specific pattern and looping. you could set a new fact with them merged, or simply process them all individually.
- name: "debug2" debug:
msg: "value is: {{ lookup('vars', item) }} "
loop: "{{ hostvars[inventory_hostname] | select('match', '^linux_hosts_entries') |list }}"
see the following post for further details.
Wanted to post a possible alternate solution by getting a list of variables that match a pattern, then you can just process all those variables, sorta manual merge.
The following code block gives an example of pulling all variables that match a specific pattern and looping. you could set a new fact with them merged, or simply process them all individually.
- name: "debug2" debug:
msg: "value is: {{ lookup('vars', item) }} "
loop: "{{ hostvars[inventory_hostname] | select('match', '^linux_hosts_entries') |list }}"
see the following post for further details.
edited Feb 6 at 23:23
answered Jan 30 at 1:42
abeabe
1364
1364
Please provide the core details of the post in your answer, thank you.
– Jonathan
Feb 6 at 21:10
@Jonathan updated
– abe
Feb 6 at 23:23
add a comment |
Please provide the core details of the post in your answer, thank you.
– Jonathan
Feb 6 at 21:10
@Jonathan updated
– abe
Feb 6 at 23:23
Please provide the core details of the post in your answer, thank you.
– Jonathan
Feb 6 at 21:10
Please provide the core details of the post in your answer, thank you.
– Jonathan
Feb 6 at 21:10
@Jonathan updated
– abe
Feb 6 at 23:23
@Jonathan updated
– abe
Feb 6 at 23:23
add a comment |
Since Ansible 2.2
, the include_vars
(link) module has been expanded quite a bit.
It's now possible to do something like:
- include_vars:
name: 'apps'
dir: '../vars'
extensions:
- 'yaml'
- 'yml'
name
is the key there. From the module page:
The name of a variable into which assign the included vars. If omitted (null) they will be made top level vars.
This allows you to convert:
vars/
app1.yml
app2.yml
...
app1.yml:
name: app1
git_repo: https://github.com/philgyford/app1.git
# ...
app2.yml:
name: app2
git_repo: https://github.com/philgyford/app2.git
# ...
Into...
apps:
- name: app1
git_repo: https://github.com/philgyford/app1.git
# ...
- name: app2
git_repo: https://github.com/philgyford/app2.git
# ...
Have you tried the solution you posted? Because Ansible will not accept vars file being a list, it must be a dictionary. It will throw an error../vars/app1.yml must be stored as a dictionary/hash
.
– techraf
Sep 8 '18 at 17:38
What if you want to merge two child arrays? Such as a having twoapps
vars merged?
– Jonathan
Feb 6 at 21:09
@techraf - you're correct. The hyphens need removing from theappX.yml
files so that they're dictionaries. They're unnecessary anyway, as the list is exactly what this method is looking to breakdown in to separate files. I've updated my answer to have a functioning example. Sorry about that.
– Jack_Hu
Feb 15 at 17:53
add a comment |
Since Ansible 2.2
, the include_vars
(link) module has been expanded quite a bit.
It's now possible to do something like:
- include_vars:
name: 'apps'
dir: '../vars'
extensions:
- 'yaml'
- 'yml'
name
is the key there. From the module page:
The name of a variable into which assign the included vars. If omitted (null) they will be made top level vars.
This allows you to convert:
vars/
app1.yml
app2.yml
...
app1.yml:
name: app1
git_repo: https://github.com/philgyford/app1.git
# ...
app2.yml:
name: app2
git_repo: https://github.com/philgyford/app2.git
# ...
Into...
apps:
- name: app1
git_repo: https://github.com/philgyford/app1.git
# ...
- name: app2
git_repo: https://github.com/philgyford/app2.git
# ...
Have you tried the solution you posted? Because Ansible will not accept vars file being a list, it must be a dictionary. It will throw an error../vars/app1.yml must be stored as a dictionary/hash
.
– techraf
Sep 8 '18 at 17:38
What if you want to merge two child arrays? Such as a having twoapps
vars merged?
– Jonathan
Feb 6 at 21:09
@techraf - you're correct. The hyphens need removing from theappX.yml
files so that they're dictionaries. They're unnecessary anyway, as the list is exactly what this method is looking to breakdown in to separate files. I've updated my answer to have a functioning example. Sorry about that.
– Jack_Hu
Feb 15 at 17:53
add a comment |
Since Ansible 2.2
, the include_vars
(link) module has been expanded quite a bit.
It's now possible to do something like:
- include_vars:
name: 'apps'
dir: '../vars'
extensions:
- 'yaml'
- 'yml'
name
is the key there. From the module page:
The name of a variable into which assign the included vars. If omitted (null) they will be made top level vars.
This allows you to convert:
vars/
app1.yml
app2.yml
...
app1.yml:
name: app1
git_repo: https://github.com/philgyford/app1.git
# ...
app2.yml:
name: app2
git_repo: https://github.com/philgyford/app2.git
# ...
Into...
apps:
- name: app1
git_repo: https://github.com/philgyford/app1.git
# ...
- name: app2
git_repo: https://github.com/philgyford/app2.git
# ...
Since Ansible 2.2
, the include_vars
(link) module has been expanded quite a bit.
It's now possible to do something like:
- include_vars:
name: 'apps'
dir: '../vars'
extensions:
- 'yaml'
- 'yml'
name
is the key there. From the module page:
The name of a variable into which assign the included vars. If omitted (null) they will be made top level vars.
This allows you to convert:
vars/
app1.yml
app2.yml
...
app1.yml:
name: app1
git_repo: https://github.com/philgyford/app1.git
# ...
app2.yml:
name: app2
git_repo: https://github.com/philgyford/app2.git
# ...
Into...
apps:
- name: app1
git_repo: https://github.com/philgyford/app1.git
# ...
- name: app2
git_repo: https://github.com/philgyford/app2.git
# ...
edited Feb 15 at 17:55
answered Sep 8 '18 at 17:22
Jack_HuJack_Hu
957
957
Have you tried the solution you posted? Because Ansible will not accept vars file being a list, it must be a dictionary. It will throw an error../vars/app1.yml must be stored as a dictionary/hash
.
– techraf
Sep 8 '18 at 17:38
What if you want to merge two child arrays? Such as a having twoapps
vars merged?
– Jonathan
Feb 6 at 21:09
@techraf - you're correct. The hyphens need removing from theappX.yml
files so that they're dictionaries. They're unnecessary anyway, as the list is exactly what this method is looking to breakdown in to separate files. I've updated my answer to have a functioning example. Sorry about that.
– Jack_Hu
Feb 15 at 17:53
add a comment |
Have you tried the solution you posted? Because Ansible will not accept vars file being a list, it must be a dictionary. It will throw an error../vars/app1.yml must be stored as a dictionary/hash
.
– techraf
Sep 8 '18 at 17:38
What if you want to merge two child arrays? Such as a having twoapps
vars merged?
– Jonathan
Feb 6 at 21:09
@techraf - you're correct. The hyphens need removing from theappX.yml
files so that they're dictionaries. They're unnecessary anyway, as the list is exactly what this method is looking to breakdown in to separate files. I've updated my answer to have a functioning example. Sorry about that.
– Jack_Hu
Feb 15 at 17:53
Have you tried the solution you posted? Because Ansible will not accept vars file being a list, it must be a dictionary. It will throw an error
../vars/app1.yml must be stored as a dictionary/hash
.– techraf
Sep 8 '18 at 17:38
Have you tried the solution you posted? Because Ansible will not accept vars file being a list, it must be a dictionary. It will throw an error
../vars/app1.yml must be stored as a dictionary/hash
.– techraf
Sep 8 '18 at 17:38
What if you want to merge two child arrays? Such as a having two
apps
vars merged?– Jonathan
Feb 6 at 21:09
What if you want to merge two child arrays? Such as a having two
apps
vars merged?– Jonathan
Feb 6 at 21:09
@techraf - you're correct. The hyphens need removing from the
appX.yml
files so that they're dictionaries. They're unnecessary anyway, as the list is exactly what this method is looking to breakdown in to separate files. I've updated my answer to have a functioning example. Sorry about that.– Jack_Hu
Feb 15 at 17:53
@techraf - you're correct. The hyphens need removing from the
appX.yml
files so that they're dictionaries. They're unnecessary anyway, as the list is exactly what this method is looking to breakdown in to separate files. I've updated my answer to have a functioning example. Sorry about that.– Jack_Hu
Feb 15 at 17:53
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f35554415%2fin-ansible-how-to-combine-variables-from-separate-files-into-one-array%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown