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.
