Group variables conditional based on OS distribution release

1,624 views
Skip to first unread message

Darren S.

unread,
Feb 27, 2016, 1:01:27 AM2/27/16
to ansible...@googlegroups.com
Hi,

After various docs and some trial and error, I can't figure out how to handle setting a variable differently when the target operating system version is newer than a certain release. OpenBSD 5.8 and newer have replaced sudo(8) with doas(1), so I'd like to set ansible_become_method correctly based on the OS version. The only idea I could come up with was this template logic in /etc/ansible/group_vars/openbsd, which is clearly incorrect:

{% if {{ ansible_distribution_release | version_compare('5.8', '>=') }} %}
    ansible_become_method: doas
{% else %}
    ansible_become_method: sudo
{% endif %}

What is the correct/cleanest way to ansible_become_method conditionally for a given OS family based on the value of ansible_distribution_release?

Ansible manager: ansible 2.0.1.0 on OpenBSD 5.7

Managed nodes: OpenBSD 5.7, OpenBSD 5.8, various Linux

Thanks,

--
Darren Spruell
phatb...@gmail.com

Brian Coca

unread,
Feb 27, 2016, 1:10:48 AM2/27/16
to ansible...@googlegroups.com
​Y​
ou cannot use jinja2 commands in vars file, the templates are not used in the vars file, they are just assigned as strings that later get recognized as templates and templated. But you can do this:

ansible_become_method: "{{ (ansible_distribution_release|version_compare('5.8', '>='))|ternary('doas', 'sudo') }}"


---
------------
Brian Coca

Josh Smift

unread,
Feb 27, 2016, 9:48:32 AM2/27/16
to ansible...@googlegroups.com
We do stuff with inventory variales and dicts, like

become_method:
5.7: doas
5.8: doas
6.0: sudo

ansible_become_method: become_method[ansible_distribution_release]

You can't do the >= thing this way, you have to enumerate all the options.
(Or you could have a default and only enumerate the ones that are
different from the defaults.) You might have to quote the numbers if
ansible_distribution_release is a string, I've gotten tripped up by stuff
like that once in a while but don't remember if this is one of them. :^)

-Josh (j...@care.com)








This email is intended for the person(s) to whom it is addressed and may contain information that is PRIVILEGED or CONFIDENTIAL. Any unauthorized use, distribution, copying, or disclosure by any person other than the addressee(s) is strictly prohibited. If you have received this email in error, please notify the sender immediately by return email and delete the message and any attachments from your system.

Darren S.

unread,
Feb 28, 2016, 12:08:12 AM2/28/16
to ansible...@googlegroups.com
This looks elegant, thanks. In my environment when I run the playbook using this configuration, it fails with the variable showing undefined:

$ ansible-playbook site.yml --limit sinoptik --tags snmpd

PLAY ***************************************************************************

TASK [setup] *******************************************************************
fatal: [sinoptik]: FAILED! => {"failed": true, "msg": "Version comparison: 'ansible_distribution_release' is undefined"}

NO MORE HOSTS LEFT *************************************************************

PLAY RECAP *********************************************************************
sinoptik                   : ok=0    changed=0    unreachable=0    failed=1


With the suggested test in place in the group_vars file, it also prevents running the setup module from running with same error:

$ ansible sinoptik -m setup      
sinoptik | FAILED! => {
    "failed": true,
    "msg": "Version comparison: 'ansible_distribution_release' is undefined"
}

I thought this might have something to do with gather_facts or similar, but I guess I'm stumped at this point.



## ansible.cfg                                                                          
[privilege_escalation]
become=True


## group_vars/openbsd
---
# OpenBSD group variables

gather_facts: True
ansible_python_interpreter: /usr/local/bin/python
sudoers_supergroup: wheel
snmpd_service_name: snmpd
# OpenBSD 5.8 and newer use doas(1) in place of sudo(8)

ansible_become_method: "{{ (ansible_distribution_release|version_compare('5.8', '>='))|ternary('doas', 'sudo') }}"


## hosts
[openbsd]
sinoptik ansible_ssh_host=sinoptik.sancho2k.net


## roles/snmpd/tasks/main.yml     
---
# SNMP daemon setup tasks

- name: install snmpd config file
  template: src=snmpd.conf.j2 dest=/etc/snmpd.conf owner=root group=wheel
    mode=0640 backup=yes validate='snmpd -nf %s'
  notify: restart snmpd
  tags: snmpd

- name: enable snmpd service
  service: name=snmpd enabled=yes
  tags: snmpd


--
Darren Spruell
phatb...@gmail.com
 



Brian Coca

unread,
Mar 1, 2016, 12:29:59 AM3/1/16
to ansible...@googlegroups.com
yes, you need to gather facts before that variable is available, you might want to use |default filter to avoid the error 


--
----------
Brian Coca

Darren S.

unread,
Mar 7, 2016, 12:58:27 AM3/7/16
to ansible...@googlegroups.com
I'm still finding myself stumped on this.

On Mon, Feb 29, 2016 at 10:29 PM, Brian Coca <bc...@ansible.com> wrote:
>
> yes, you need to gather facts before that variable is available, you might want to use |default filter to avoid the error

If the variable ansible_distribution_release is used in a vars file:


## group_vars/openbsd
---
# OpenBSD group variables

ansible_python_interpreter: /usr/local/bin/python
sudoers_supergroup: wheel
snmpd_service_name: snmpd
# OpenBSD 5.8 and newer use doas(1) in place of sudo(8)
ansible_become_method: "{{
(ansible_distribution_release|version_compare('5.8',
'>='))|ternary('doas', 'sudo') }}"


...and facts are not gathered to supply it by default, how should
(can?) facts be gathered at a point prior to ansible_become_method
requiring the variable? The only way I think I know from the docs is
to call the setup module, but it seems like a chicken-and-egg problem
to me.

Confident I don't understand something simple but important. :-|

--
Darren Spruell
phatb...@gmail.com

Johannes Kastl

unread,
Mar 7, 2016, 1:18:12 PM3/7/16
to ansible...@googlegroups.com
Hi Darren,

Am 07.03.16 schrieb Darren S.:
> I'm still finding myself stumped on this.

See my answer below.

> On Mon, Feb 29, 2016 at 10:29 PM, Brian Coca <bc...@ansible.com> wrote:
>>
>> yes, you need to gather facts before that variable is available, you might want to use |default filter to avoid the error

> ansible_become_method: "{{
> (ansible_distribution_release|version_compare('5.8',
> '>='))|ternary('doas', 'sudo') }}"

I think Brian meant something like this:

ansible_become_method: "{{
(ansible_distribution_release|version_compare('5.8',
> '>='))|ternary('doas', 'sudo')|default(sudo) }}"

This way, when ansible_distribution_release is undefined, the
default(sudo) strikes and sets a default. Once
ansible_distribution_release is defined, default does nothing anymore.

Johannes

signature.asc
Reply all
Reply to author
Forward
0 new messages