How to loop dict with nested lists?












0















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:




  1. File path

  2. Section

  3. Option

  4. 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?










share|improve this question


















  • 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











  • 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


















0















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:




  1. File path

  2. Section

  3. Option

  4. 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?










share|improve this question


















  • 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











  • 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
















0












0








0








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:




  1. File path

  2. Section

  3. Option

  4. 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?










share|improve this question














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:




  1. File path

  2. Section

  3. Option

  4. 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






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 13 '18 at 22:04









courtlandjcourtlandj

340616




340616








  • 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











  • 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





    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











  • 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














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
});


}
});














draft saved

draft discarded


















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
















draft saved

draft discarded




















































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.




draft saved


draft discarded














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





















































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







Popular posts from this blog

Xamarin.iOS Cant Deploy on Iphone

Glorious Revolution

Dulmage-Mendelsohn matrix decomposition in Python