I just realized for the thousandth time or thereabouts that utils.template silently lets undefined vars pass through playbooks. I’m not sure what the best solution would be, but I see a couple possible solutions:
GIven the following action without ${foo} being defined:
action: copy src=${foo} dest=/some/path
Currently this tries to copy the literal file ${foo}, which of course fails.
I think utils.template could do one of the following to make what’s happening a little more obvious:
- Throw an error and exit if it encounters an undefined var
- Substitute something like this: <undefined var: $foo>
Personally, I like things to fail early, so #1 would be my preference. An undefined var is almost certainly going to prevent the task from completing anyway.
This is actually desired behavior.
Suppose you are templating a Perl script with “$foo” in it, you don’t want $foo replaced unless it matches a variable.
In a jinja2 template, I agree (and it deals with this by using {{ }} for jinja vars). But It’s unlikely that we will be feeding in a perl script to utils.template (e.g., as part of a path name or an arg to a module). Maybe I’m just off though.
You would be surprised what people ask for. Got one request for turning off varReplace for exactly that reason. I said no.
That being said, I can see this causing a fair amount of problems.
And generally I find whenever I hear a voice in my head saying “you could make that an option”, that makes things extra confusing.
So I think we pick our current behavior.
It’s what staging environments are for anyway. Or that vagrant-ansible plugin!
–Michael