I've got the same issue (in various roles) and still cannot foresee a good 
enough fix exists (or planned)

- An earlier post with the same question:
https://groups.google.com/d/msg/ansible-project/jFf1KfoWxBA/KXmcsQZqAQAJ

- Please upvote your favorite solution, in the proposals I gathered in 
following post:
https://github.com/ansible/proposals/pull/21#issuecomment-470048538 

On Tuesday, March 28, 2017 at 6:33:29 PM UTC+2, Mike Ray wrote:
>
> In the current Ansible setup, you can have 1 file in defaults (i.e. 
> defaults/main.yml) and it is used for all hosts that run that task, no 
> matter what the host.
>
> In our use case, we have found it would be highly advantageous to be able 
> to have os-specific and release-specific defaults files. For instance, some 
> applications change directives between releases -- using a directive in a 
> release that doesn't support it, in the best case just issues a warning 
> (which is not ideal), but in the far more likely case, breaks something.
>
> We cannot use include_vars as this completely ruins precedence: 
> http://docs.ansible.com/ansible/playbooks_variables.html#variable-precedence-where-should-i-put-a-variable
>
> To illustrate, here is an example/outline of our setup:
>
>     file structure:
>         - inventory/production/host_vars/mail-server-1
>         - inventory/production/group_vars/mail-servers
>         - roles/servers/mail-server
>         - roles/postfix
>         - mail-server.yml
>
>     mail-server.yml:
>         roles:
>             - roles/servers/mail-server
>
>     roles/servers/mail-server/meta/main.yml:
>         dependencies:
>             - { role: postfix }
>
>
>     summary: What the above is trying to illustrate, is that we have our 
> re-usable building blocks in "roles" and server-specific setups in 
> "roles/servers", e.g. the "mail-server" role runs through postfix as meta, 
> and then runs through its own tasks. This gives us the flexibility to:
>     - set host-specific vars in the inventory host_vars variables (e.g. 
> relayhost="")
>     - set vars common to particular groupings of mail servers in inventory 
> group_vars variables (e.g. relay_domains=domain.foo)
>     - set vars common to mail-servers in general in 
> roles/servers/mail-server/vars (e.g. 
> content-filter=smtp-amavis:[127.0.0.1]:10024)
>     - set vars for everything that runs the postfix role (e.g. 
> heloname="{{ ansible_hostname }}")
>
> If for example, we were to use include_vars to try to include variables 
> specific to CentOS, it would be the highest precedence and override host 
> specific settings with generic CentOS stuff.
>
>
>
> Our current working solution is to do a large amount of "union-ing" in the 
> defaults file based on variables, i.e. to get the proper postfix 
> configuration options trusty v. xenial:
>     postfix_configuration_options: "{{ 
> postfix_common_configuration_options | union( 
> (ansible_distribution_release=='xenial') | 
> ternary(postfix_xenial_configuration_options,[]) ) | union( 
> (ansible_distribution_release=='trusty') | 
> ternary(postfix_trusty_configuration_options,[]) ) }}"
>
> This is not ideal for a number of reasons:
>     - unless you already know what it does, it can take some time to 
> figure out
>     - it gets messier and messier the more distributions you support
>     - it'll get slower to run the more distributions are supported
>
> But is still useful as you can have a common template for everything then:
> main.cf.j2:
>     # {{ ansible_managed }}
>     {% for item in postfix_configuration_options %}
>     {% if item.option is defined and item.value is defined %}
>     {% if item.comment is defined %}
>     {{ item.comment }}
>     {% endif %}
>     {{ item.option }} = {{ item.value }}
>     {% endif %}
>     {% endfor %}
>
>
>
>
> What we had planned on doing was using the meta structure to include 
> specific roles with particular defaults based on os and release, e.g.:
>
>     - mail-server.yml:
>         roles:
>             - meta/postfix
>
>     - meta/postfix/meta/main.yml:
>         dependencies:
>           - { role: os/CentOS/postfix, when: ansible_distribution == 
> 'CentOS' }
>           - { role: releases/trusty/postfix, when: 
> ansible_distribution_release == 'trusty' }
>           - { role: releases/xenial/postfix, when: 
> ansible_distribution_release == 'xenial' }
>           - { role: postfix }
>
>     - release/trusty/postfix/defaults/main.yml:
>         postfix_configuration_options:
>             postscreen_dnsbl_ttl
>
>     - release/trusty
>         postfix_configuration_options:
>             address_verify_pending_request_limit
>         
> And then in the aforementioned main.cf.j2, xenial hosts would define 
> "address_verify_pending_request_limit" (which is not a thing available in 
> the postfix release for trusty) and trusty hosts would define 
> "postscreen_dnsbl_ttl" (which is not a thing available in the postfix 
> release for xenial).
>
> While it works for that case, I've found that even when a meta role is 
> skipped, the defaults file is still read, so for situations where you had 
> the same directive, but wanted different values based on os/release, it 
> would not work (i.e. in the following example, "biff" would always be set 
> to "yes"):
>
>     - release/trusty/postfix/defaults/main.yml:
>         postfix_configuration_options:
>             biff = no
>
>     - release/trusty
>         postfix_configuration_options:
>             biff = yes
>
>
>
> Does anyone have any ideas for how to have a defaults file per os/release 
> like I want? Does anyone have alternative suggestions on setups such that I 
> would not need/want this anymore?
>

-- 
You received this message because you are subscribed to the Google Groups 
"Ansible Project" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/ansible-project/188121b2-963a-4840-a65b-f05d1a97bcf1%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to