How to loop dict with nested lists?
Ansible allows deeply nested dicts, but then doesn't actually allow you to get much use out of them! Here is my story.
I'm trying to configure a number of ini files with Ansible. To this end, I am using the ini_file
module. This module requires at a minimum, four pieces of information:
- File path
- Section
- Option
- Value of that option
So, I've defined a dict:
vars:
conf:
"/etc/conf1.ini":
- section: main
option: foo
val: bar
- section: main
option: baz
val: qux
"/etc/otherconf.ini":
- section: options
option: flower
val: bird
And so on. So, I can use:
- name: Write ini files
ini_file:
path: "{{ item.0.key }}"
section: "{{ item.1.section }}"
option: "{{ item.1.option }}"
value: "{{ item.1.val }}"
loop: "{{ conf | dict2items | subelements('value') }}"
This... works. I can continue to use this. Example output of /etc/conf1.ini
:
[main]
foo = bar
baz = qux
Question: Is there a better way? How can I organize my data to work better with (the new style of) Ansible loops? (i.e. nothing that starts with with_
)
Note: I also really don't like having to use a fully qualified path as a dict key; I'd rather it be e.g. path: "/etc/conf1.ini"
somehow.
Note 2: I don't have to have this all in one single variable, conf
, but if I have one variable per ini file, how do I loop that?
ansible yaml ini
|
show 3 more comments
Ansible allows deeply nested dicts, but then doesn't actually allow you to get much use out of them! Here is my story.
I'm trying to configure a number of ini files with Ansible. To this end, I am using the ini_file
module. This module requires at a minimum, four pieces of information:
- File path
- Section
- Option
- Value of that option
So, I've defined a dict:
vars:
conf:
"/etc/conf1.ini":
- section: main
option: foo
val: bar
- section: main
option: baz
val: qux
"/etc/otherconf.ini":
- section: options
option: flower
val: bird
And so on. So, I can use:
- name: Write ini files
ini_file:
path: "{{ item.0.key }}"
section: "{{ item.1.section }}"
option: "{{ item.1.option }}"
value: "{{ item.1.val }}"
loop: "{{ conf | dict2items | subelements('value') }}"
This... works. I can continue to use this. Example output of /etc/conf1.ini
:
[main]
foo = bar
baz = qux
Question: Is there a better way? How can I organize my data to work better with (the new style of) Ansible loops? (i.e. nothing that starts with with_
)
Note: I also really don't like having to use a fully qualified path as a dict key; I'd rather it be e.g. path: "/etc/conf1.ini"
somehow.
Note 2: I don't have to have this all in one single variable, conf
, but if I have one variable per ini file, how do I loop that?
ansible yaml ini
1
I'm no ansible expert, but two things jump out at me. Issubelements('value')
what you are really using or is that a typo forsubelements('val')
? Secondly, you can clearly usepath
as another entry in your dictionary and make the key be some label just for humans. (Then you could check for apath
subelement...)
– Cupcake Protocol
Nov 14 '18 at 0:46
If the syntax and looping become too complex, I would suggest just using the template module instead.
– M_dk
Nov 14 '18 at 11:11
Also remember that while you can do something thats complex, it might be a better idea to keep it simpler even though it means adding more tasks. At least, thats how I read the best practice guidelines: ansible.com/blog/ansible-best-practices-essentials
– M_dk
Nov 14 '18 at 11:26
1
@CupcakeProtocol - Yes, it's super intentional. Subelements is looking at the list of tuples that dict2items provides. Each tuple is key, value. That's why I can't name any keys in my variable as "value". Learned this trick from: stackoverflow.com/a/50711744/3201683
– courtlandj
Nov 14 '18 at 15:47
@M_dk I don't see how templating is going to help me edit values in existing ini files. And, I don't really think what I am doing is all that "complex", either. I'm just sequentially setting values in some ini files, but I can't use a nice hierarchical data structure to do all the work for me -- I have to duplicate the "section" value unnecessarily all over the place. To me, that is more complex, not less. I cannot imagine writing it this way in any other language.
– courtlandj
Nov 14 '18 at 15:48
|
show 3 more comments
Ansible allows deeply nested dicts, but then doesn't actually allow you to get much use out of them! Here is my story.
I'm trying to configure a number of ini files with Ansible. To this end, I am using the ini_file
module. This module requires at a minimum, four pieces of information:
- File path
- Section
- Option
- Value of that option
So, I've defined a dict:
vars:
conf:
"/etc/conf1.ini":
- section: main
option: foo
val: bar
- section: main
option: baz
val: qux
"/etc/otherconf.ini":
- section: options
option: flower
val: bird
And so on. So, I can use:
- name: Write ini files
ini_file:
path: "{{ item.0.key }}"
section: "{{ item.1.section }}"
option: "{{ item.1.option }}"
value: "{{ item.1.val }}"
loop: "{{ conf | dict2items | subelements('value') }}"
This... works. I can continue to use this. Example output of /etc/conf1.ini
:
[main]
foo = bar
baz = qux
Question: Is there a better way? How can I organize my data to work better with (the new style of) Ansible loops? (i.e. nothing that starts with with_
)
Note: I also really don't like having to use a fully qualified path as a dict key; I'd rather it be e.g. path: "/etc/conf1.ini"
somehow.
Note 2: I don't have to have this all in one single variable, conf
, but if I have one variable per ini file, how do I loop that?
ansible yaml ini
Ansible allows deeply nested dicts, but then doesn't actually allow you to get much use out of them! Here is my story.
I'm trying to configure a number of ini files with Ansible. To this end, I am using the ini_file
module. This module requires at a minimum, four pieces of information:
- File path
- Section
- Option
- Value of that option
So, I've defined a dict:
vars:
conf:
"/etc/conf1.ini":
- section: main
option: foo
val: bar
- section: main
option: baz
val: qux
"/etc/otherconf.ini":
- section: options
option: flower
val: bird
And so on. So, I can use:
- name: Write ini files
ini_file:
path: "{{ item.0.key }}"
section: "{{ item.1.section }}"
option: "{{ item.1.option }}"
value: "{{ item.1.val }}"
loop: "{{ conf | dict2items | subelements('value') }}"
This... works. I can continue to use this. Example output of /etc/conf1.ini
:
[main]
foo = bar
baz = qux
Question: Is there a better way? How can I organize my data to work better with (the new style of) Ansible loops? (i.e. nothing that starts with with_
)
Note: I also really don't like having to use a fully qualified path as a dict key; I'd rather it be e.g. path: "/etc/conf1.ini"
somehow.
Note 2: I don't have to have this all in one single variable, conf
, but if I have one variable per ini file, how do I loop that?
ansible yaml ini
ansible yaml ini
asked Nov 13 '18 at 22:04
courtlandjcourtlandj
340616
340616
1
I'm no ansible expert, but two things jump out at me. Issubelements('value')
what you are really using or is that a typo forsubelements('val')
? Secondly, you can clearly usepath
as another entry in your dictionary and make the key be some label just for humans. (Then you could check for apath
subelement...)
– Cupcake Protocol
Nov 14 '18 at 0:46
If the syntax and looping become too complex, I would suggest just using the template module instead.
– M_dk
Nov 14 '18 at 11:11
Also remember that while you can do something thats complex, it might be a better idea to keep it simpler even though it means adding more tasks. At least, thats how I read the best practice guidelines: ansible.com/blog/ansible-best-practices-essentials
– M_dk
Nov 14 '18 at 11:26
1
@CupcakeProtocol - Yes, it's super intentional. Subelements is looking at the list of tuples that dict2items provides. Each tuple is key, value. That's why I can't name any keys in my variable as "value". Learned this trick from: stackoverflow.com/a/50711744/3201683
– courtlandj
Nov 14 '18 at 15:47
@M_dk I don't see how templating is going to help me edit values in existing ini files. And, I don't really think what I am doing is all that "complex", either. I'm just sequentially setting values in some ini files, but I can't use a nice hierarchical data structure to do all the work for me -- I have to duplicate the "section" value unnecessarily all over the place. To me, that is more complex, not less. I cannot imagine writing it this way in any other language.
– courtlandj
Nov 14 '18 at 15:48
|
show 3 more comments
1
I'm no ansible expert, but two things jump out at me. Issubelements('value')
what you are really using or is that a typo forsubelements('val')
? Secondly, you can clearly usepath
as another entry in your dictionary and make the key be some label just for humans. (Then you could check for apath
subelement...)
– Cupcake Protocol
Nov 14 '18 at 0:46
If the syntax and looping become too complex, I would suggest just using the template module instead.
– M_dk
Nov 14 '18 at 11:11
Also remember that while you can do something thats complex, it might be a better idea to keep it simpler even though it means adding more tasks. At least, thats how I read the best practice guidelines: ansible.com/blog/ansible-best-practices-essentials
– M_dk
Nov 14 '18 at 11:26
1
@CupcakeProtocol - Yes, it's super intentional. Subelements is looking at the list of tuples that dict2items provides. Each tuple is key, value. That's why I can't name any keys in my variable as "value". Learned this trick from: stackoverflow.com/a/50711744/3201683
– courtlandj
Nov 14 '18 at 15:47
@M_dk I don't see how templating is going to help me edit values in existing ini files. And, I don't really think what I am doing is all that "complex", either. I'm just sequentially setting values in some ini files, but I can't use a nice hierarchical data structure to do all the work for me -- I have to duplicate the "section" value unnecessarily all over the place. To me, that is more complex, not less. I cannot imagine writing it this way in any other language.
– courtlandj
Nov 14 '18 at 15:48
1
1
I'm no ansible expert, but two things jump out at me. Is
subelements('value')
what you are really using or is that a typo for subelements('val')
? Secondly, you can clearly use path
as another entry in your dictionary and make the key be some label just for humans. (Then you could check for a path
subelement...)– Cupcake Protocol
Nov 14 '18 at 0:46
I'm no ansible expert, but two things jump out at me. Is
subelements('value')
what you are really using or is that a typo for subelements('val')
? Secondly, you can clearly use path
as another entry in your dictionary and make the key be some label just for humans. (Then you could check for a path
subelement...)– Cupcake Protocol
Nov 14 '18 at 0:46
If the syntax and looping become too complex, I would suggest just using the template module instead.
– M_dk
Nov 14 '18 at 11:11
If the syntax and looping become too complex, I would suggest just using the template module instead.
– M_dk
Nov 14 '18 at 11:11
Also remember that while you can do something thats complex, it might be a better idea to keep it simpler even though it means adding more tasks. At least, thats how I read the best practice guidelines: ansible.com/blog/ansible-best-practices-essentials
– M_dk
Nov 14 '18 at 11:26
Also remember that while you can do something thats complex, it might be a better idea to keep it simpler even though it means adding more tasks. At least, thats how I read the best practice guidelines: ansible.com/blog/ansible-best-practices-essentials
– M_dk
Nov 14 '18 at 11:26
1
1
@CupcakeProtocol - Yes, it's super intentional. Subelements is looking at the list of tuples that dict2items provides. Each tuple is key, value. That's why I can't name any keys in my variable as "value". Learned this trick from: stackoverflow.com/a/50711744/3201683
– courtlandj
Nov 14 '18 at 15:47
@CupcakeProtocol - Yes, it's super intentional. Subelements is looking at the list of tuples that dict2items provides. Each tuple is key, value. That's why I can't name any keys in my variable as "value". Learned this trick from: stackoverflow.com/a/50711744/3201683
– courtlandj
Nov 14 '18 at 15:47
@M_dk I don't see how templating is going to help me edit values in existing ini files. And, I don't really think what I am doing is all that "complex", either. I'm just sequentially setting values in some ini files, but I can't use a nice hierarchical data structure to do all the work for me -- I have to duplicate the "section" value unnecessarily all over the place. To me, that is more complex, not less. I cannot imagine writing it this way in any other language.
– courtlandj
Nov 14 '18 at 15:48
@M_dk I don't see how templating is going to help me edit values in existing ini files. And, I don't really think what I am doing is all that "complex", either. I'm just sequentially setting values in some ini files, but I can't use a nice hierarchical data structure to do all the work for me -- I have to duplicate the "section" value unnecessarily all over the place. To me, that is more complex, not less. I cannot imagine writing it this way in any other language.
– courtlandj
Nov 14 '18 at 15:48
|
show 3 more comments
0
active
oldest
votes
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%2f53290199%2fhow-to-loop-dict-with-nested-lists%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
0
active
oldest
votes
0
active
oldest
votes
active
oldest
votes
active
oldest
votes
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%2f53290199%2fhow-to-loop-dict-with-nested-lists%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
1
I'm no ansible expert, but two things jump out at me. Is
subelements('value')
what you are really using or is that a typo forsubelements('val')
? Secondly, you can clearly usepath
as another entry in your dictionary and make the key be some label just for humans. (Then you could check for apath
subelement...)– Cupcake Protocol
Nov 14 '18 at 0:46
If the syntax and looping become too complex, I would suggest just using the template module instead.
– M_dk
Nov 14 '18 at 11:11
Also remember that while you can do something thats complex, it might be a better idea to keep it simpler even though it means adding more tasks. At least, thats how I read the best practice guidelines: ansible.com/blog/ansible-best-practices-essentials
– M_dk
Nov 14 '18 at 11:26
1
@CupcakeProtocol - Yes, it's super intentional. Subelements is looking at the list of tuples that dict2items provides. Each tuple is key, value. That's why I can't name any keys in my variable as "value". Learned this trick from: stackoverflow.com/a/50711744/3201683
– courtlandj
Nov 14 '18 at 15:47
@M_dk I don't see how templating is going to help me edit values in existing ini files. And, I don't really think what I am doing is all that "complex", either. I'm just sequentially setting values in some ini files, but I can't use a nice hierarchical data structure to do all the work for me -- I have to duplicate the "section" value unnecessarily all over the place. To me, that is more complex, not less. I cannot imagine writing it this way in any other language.
– courtlandj
Nov 14 '18 at 15:48