override non-defaults role variables

82 views
Skip to first unread message

Antoine Jacoutot

unread,
Jan 22, 2015, 11:46:30 AM1/22/15
to ansible...@googlegroups.com
Hi.

After a lot of reading about variable inheritance in ansible, there's still something I cannot properly grasp...
I hope some folks in here could enlighten me :-)

So. I have a "foobar" role with some default variables set under defaults/main.yml.
So far, so good.
But I would like some of these default variables to be for e.g. OS-dependant.
I can easily achieve that using vars or with_first_found along with ansible_os_family.
But if I do that, then I am not able to override these variables using group_vars (/etc/ansible/group_vars/mygroup (like I am able to override the variables set in defaults/main.yml). I do not want to have to pass variables directly in the inventory file.

I am sure I am missing something stupid...
Thanks in advance.

-- 
Antoine

James Martin

unread,
Jan 22, 2015, 1:59:18 PM1/22/15
to ansible...@googlegroups.com
Antoine,

Let's say for example you have your foobar role, and 

#defaults/main.yml
foobar_port
: 42


And let's say you have an inventory group called "foobar" which is a list of all your foobar hosts.

By using the group_by module (http://docs.ansible.com/group_by_module.html)  in a previous play, you can dynamic create a group based on the OS (or any other fact)

Enter code here...
- group_by: key=machine_{{ ansible_distribution }}


You would also have a 

#group_vars/machine_Ubuntu
foobar_port
: 43

and a

#group_vars/machine_CentOS
foobar_port
: 44


That would render the 43 or 44, overriding the default role value and be dependent on the OS.


- James

Antoine Jacoutot

unread,
Jan 23, 2015, 4:59:48 AM1/23/15
to ansible...@googlegroups.com
On Thu, Jan 22, 2015 at 10:59:18AM -0800, James Martin wrote:
> Antoine,
> Let's say for example you have your foobar role, and
> #defaults/main.yml
> foobar_port: 42
> And let's say you have an inventory group called "foobar" which is a
> list of all your foobar hosts.
> By using the group_by module
> (http://docs.ansible.com/group_by_module.html) in a previous play, you
> can dynamic create a group based on the OS (or any other fact)
> Enter code here...
> - group_by: key=machine_{{ ansible_distribution }}
> You would also have a
> #group_vars/machine_Ubuntu
> foobar_port: 43
> and a
> #group_vars/machine_CentOS
> foobar_port: 44
> That would render the 43 or 44, overriding the default role value and
> be dependent on the OS.

Hi James and thanks for the quick answer.

I already tried what you proposed but my issue is that the role ended not being self-contained.
i.e. I had to put the default os values under /etc/ansible/group_vars/machine_* instead of within the role hierarchy.

Or is there a way that I missed?
Thanks.

--
Antoine

Tomasz Kontusz

unread,
Jan 23, 2015, 5:42:46 AM1/23/15
to ansible...@googlegroups.com
There is another way: you can put "foo: '{{ default_foo }}' in defaults, and only set default_foo in the per-OS variables

Antoine Jacoutot <ajac...@bsdfrog.org> napisał:

--
Wysłane za pomocą K-9 Mail.

Antoine Jacoutot

unread,
Jan 23, 2015, 8:13:53 AM1/23/15
to ansible...@googlegroups.com
On Fri, Jan 23, 2015 at 11:42:11AM +0100, Tomasz Kontusz wrote:
> There is another way: you can put "foo: '{{ default_foo }}' in
> defaults, and only set default_foo in the per-OS variables

Ok, It took me a little while to understand what you meant with "only set default_foo in the per-OS variables"
but I think I got it. Thanks Tomasz, that's clever :-)

For the record, this is what I ended up with and it seems to work fine (I can override one or more vars using the inventory hierarchy under /etc/ansible):
(of course I have to duplicate all vars from defaults.yml into the OS-specific vars files, not just the ones that need overriding, but I can leave with that)

# tasks/main.yml
- name: OS-specific vars
include_vars: "{{ item }}"
with_first_found:
- "defaults_{{ ansible_distribution }}.yml"
- "defaults_{{ ansible_os_family }}.yml"
- "defaults.yml"


# defaults/main.yml
foobar: '{{ def_foobar }}'


# vars/defaults.yml
def_foobar: blahblah

# vars/defaults_CentOS.yml
def_foobar: blahblah-for-centos

# var/defaults_Debian.yml
def_foobar: blahblah-for-debian-family


Thank you again Tomasz.
Unless someone has a better idea...

--
Antoine
Reply all
Reply to author
Forward
0 new messages