"Old" variables vs. "new" variables.

So, I’ve read in other posts here that the ${var} syntax is being deprecated in favor of the {{ var }} syntax. I’m in the process of replacing the old syntax with the new in my roles, but I’m seeing YAML syntax errors as a result:

dan at work in ~/src/ansible-base-osx on default at default/default, tip! on master!
± ansible-playbook -i inventory site.yml
ERROR: Syntax Error while loading YAML script, /Users/dan/src/ansible-base-osx/roles/base-osx/tasks/common.yml
Note: The error may actually appear before this position: line 12, column 33

  • name: base-osx | common | brew linkapps
    shell: {{ executables.brew }} linkapps --system executable={{ executables.zsh }}
    ^

Always quote {{ after : ,check yaml gotchas in docs

Brian Coca

If the line starts with a “{”, you need to wrap the entire line in quotes. This is unfortunately a YAML parsing issue, for which we are looking to add a parsing check for in the future. So your line would look like this (single quotes also work):

  • name: base-osx | common | brew linkapps
    shell: “{{ executables.brew }} linkapps --system executable={{ executables.zsh }}”

Alternatively, you can use the line continuation syntax as follows:

  • name: base-osx | common | brew linkapps
    shell: >
    {{ executables.brew }} linkapps --system executable={{ executables.zsh }}

OK, I’ve gone through and quoted all lines that start with a “{”; however, now I’ve run into a different error:

Here is the reason: dan.home depends on dan.user, in the same level of nesting. This is an example of something which works fine with dollar variables and not with jinja2. I did point this out before on the list, I don’t recall anyone actually commenting on it, so it probably got lost in the mounting traffic. Probably I need to ticket them. Surely a valid use-case? Please do implement a solution to this before deprecating dollar variables! Currently it is something I work around by continuing to use dollar variables in certain cases. If they went away I would have no easy solution except to restructure all my playbooks. Cheers N ps. Related points I’ve personally run into: a) Referencing datastructures isn’t possible with {{ }}, the data gets stringified: As Michael says elsewhere, this is known and there will be new syntax for this - in the mean time it’s another case when dollar variables are necessary. b) Certain unfortunate choices of variable names that worked with ${} stop working with {{ }}. Ansible does not (or did not) warn about these, the variable may simply appear to be undefined. For example, leading numerals like “foo.4bar” is one such unfortunate choice. Hyphens are another. Presumably this will generate warnings in the future; I need to read the new docs to see if this is mentioned

FYI, 1.4 already reports some helpful YAML tips should you start a string with a {{ and a few others.

Check it out and we’ll be adding more.

We’ve mentioned that before we fully remove $x refering data is going to be fixed up :slight_smile:

“Certain unfortunate choices of variable names that worked with ${} stop working with”

Yes, you have to name variables in valid ways. This is documented in the current variables chapter. Usually it’s people using dots or hypens instead of underscores.

I’m not positive that will ever generate warnings, but it’s best to know what the convention has always been.

This has always been true of Jinja2 templates for the template module, for instance.

repo: git://github.com/robbyrussell/oh-my-zsh.git

this will be an error due to the : (another yaml gotcha), needs to be:

repo: “git://github.com/robbyrussell/oh-my-zsh.git

Just to mention, I got around to filing an issue on this:

     https://github.com/ansible/ansible/issues/4450

N

I’m having this same problem after upgrading from version 1.3 to version 1.4.1 of Ansible using the EPEL packages.I see that this issue got fixed but it’s unclear whether this issue was fixed in 1.4.1 as no commit is specified. Can’t see whether that was added in or not. I’m guessing not since I’m getting errors but just want to verify.

I started to cut over from the ${foo} variables to the now preferred {{foo}} variables because of the deprecation warnings I saw but doesn’t look like I’ll really be able to do that until this gets fixed. Here is an example of one of the vars files I’m having a problem with.

Before:

In the above I’m not seeing where you are defining bar.

Can you please supply the complete example?

Oops, correction on my last post. Things should be {{foo.dir}} or ${foo.dir} in my examples but hopefully you get the idea. Sorry about that.

Here are the fixed complete examples. Sorry about that.

Before:

Don’t define foo so it self references.

foo_dir

Etc

– Michael

I’m not sure if I understand what you mean or how to do this differently/better. Can you provide an example of how you would do it?

Maybe I wasn’t clear so let me start over. Below is a quote from Nick in another post (https://groups.google.com/forum/#!msg/ansible-project/EAerV9UZ0KI/gVIP6WUK5UQJ) where he is having the exact same problem I am having. I think he does a good job describing the problem. Unfortunately, it doesn’t seem to get answered in that post either. It also seems like the exact same problem that this github issue (https://github.com/ansible/ansible/issues/4450) is describing which was apparently fixed. However, I’m still having this same issue in the 1.4.1 version of Ansible from EPEL. So my questions are this:

  • Was this fixed?
  • If not is going to get fixed?
  • If so when can we expect the fix?
  • If not what should the work around look like when converting from ${foo} to {{foo}}?

Here is the example from Nick I spoke of earlier. Surely this is a valid thing for someone to want to do and I’m not seeing a better way to do it.

For example, assuming a simple role with a tasks/main.yml like this:

You were being clear.

Hashes can’t self reference their own values.

That’s the only limitation now.

So just to be clear to do the example I used earlier using the {{foo}} variables I’d need to do what is below? If so I’d have to say that kind of sucks. I really preferred the other method unless there is something I’m missing to make things work just as easily.

— # some task

  • name: test
    action: debug msg=“got {{foo.path1}}”
    action: debug msg=“got {{foo.path2}}”

— # some var
foo:
path1: ‘/some/path//filename’
path2: ‘/some/path//filename’

Absolutely not.

— # some var
basedir: ‘/some/path’
foo:
path1: ‘{{ basedir }}/filename’
path2: ‘{{ basedir }}/filename’

What you were doing was reference a structure that somehow ‘knew’ it’s variable name before it was even created, so I think it’s quite fine if that isn’t a thing.

It working before was a side effect of the legacy template engine being rather … special.

Okay. I understand now. Thank you for your patience and explanation.

It's even more general than that. This doesn't work:

--- # some var

foo:
   dir: '/some/path'

foo:
   path1: '{{foo.dir}}/filename'
   path2: '{{foo.dir}}/filename2'

Any kind of self-reference gets quashed in 1.4.1. Bummer. I work with Andrew Widdersheim and we've been using this motif often in our playbooks and roles.

I dislike having to use top-level variables in this way. Keeping it all in the hash feels cleaner to me.

--[Lance]