Define var if not defined

Hi,

Does anyone have any suggestions on how this problem could be solved:

I have a playbook that I would like to invoke with the var ‘foo’ set to ‘bar’, using --extra-vars. So far fine. But in the playbook I want to set ‘foo’ to ‘baz’ if I don’t give it a value in --extra-vars.

Any ideas?

you could in Jinja2 templates but there is not otherwise a way to do it in a playbook, especially now that we execute Jinja2 only in actual templates for the template module.

--Michael

Hmm… any ideas on how to do this. Would a patch be accepted?

I’d say propose a syntax first?

Perhaps similar to the vars_prompt: let vars values be a dictionary, like so:

vars:
foo: {value: “bar”, when: “‘${foo}’ == ‘’”}

The only thing here is that ${foo} would currently evaluate to the string “${foo}” if it’s not already defined.

Thoughts?

I don’t particularly care for that.

While that seems logically more elegant if like this:

foo: { unless_already_set: 5 }

However that still bothers me in terms of syntax that is weird. It doesn’t fit well in my brain and feels like the exceptions and rules you have to remember are building up way too much.

I think this is one of those features that, because it is difficult to explain and unwieldy (and a bit of a corner case), it won’t exist in Ansible.

The current order of priorities is:

extra vars
inventory overrides extra vars
playbook vars override inventory

In which case my advice would be to make sure the script using extra vars sets the variable every time.

Yeah, I ended up using a bash script wrapper that has the logic there.

I’m not clear on how all this is supposed to work out, so there are probably some goals of this design that I’m missing. But to me, it seems like I’d want playbooks to be generic – you download one from a contrib repo on the Internet, and it has generic definitions you can use without modification. You tailor it to your site with the inventory, and you tailor to a specific run with extra vars.

For example: a playbook to install hadoop uses a group called “workers” to refer to all your cluster worker nodes. Your local cluster is probably not called “workers,” but its easy to add one to your inventory (and it would be really easy with group aliases ;). Now say worker17 is acting up again, and you just want to run on one host, so you pass --extra-vars=“hosts=worker17”.

This matches the way most Unix tools work: defaults (try to) make sense for everyone, config files customize for the way you usually work, command line overrides config file for this invocation. It would also fix mgw’s problem.

So if this breakdown makes sense:

playbook → everybody on the Interwebs
inventory → my site
extra vars → this run

I’d think precedence would go like this:

playbook is lowest
inventory overrides playbook
extra vars (cmdline in general) overrides inventory

Thoughts?

-John

I'm not clear on how all this is supposed to work out, so there are probably
some goals of this design that I'm missing. But to me, it seems like I'd
want playbooks to be generic -- you download one from a contrib repo on the
Internet, and it has generic definitions you can use without modification.
You tailor it to your site with the inventory, and you tailor to a specific
run with extra vars.

yeah, but this never works out in practice. Very true of Puppet and
Chef "books" that they are almost
never reusable without tweaks. That being said, we're not any worse
in this regard.

There are at best examples you use, but everyone has different
management requirements, and distributions, and
application versions. It never works out as advertised.

For example: a playbook to install hadoop uses a group called "workers" to
refer to all your cluster worker nodes. Your local cluster is probably not
called "workers," but its easy to add one to your inventory (and it would be
*really* easy with group aliases ;). Now say worker17 is acting up again,
and you just want to run on one host, so you pass
--extra-vars="hosts=worker17".

You can already pass in things to "hosts" via a variable in 0.4

hosts: $foo

--extra-vars="foo=groupname" etc

playbook -> everybody on the Interwebs
inventory -> my site
extra vars -> this run

I'd think precedence would go like this:

playbook is lowest
inventory overrides playbook
extra vars (cmdline in general) overrides inventory

Thoughts?

We shouldn't be changing this seeing we're already well established.

Inventory is for geographic and hardware specific setup. You
shouldn't have the same variables in both places, it's a sign things
have gotten too complicated if so.