Having variables in task names

1,749 views
Skip to first unread message

Stephen Aylward

unread,
Sep 15, 2014, 10:32:51 PM9/15/14
to ansible...@googlegroups.com
When running my playbook, on tasks that I have tried to name with variables, the variable name is there rather than the value.
Eg:
TASK: [weblogic | Create {{ tmp_dir }}] **************************

What do I need to change to get the tmp dir value output?
Thanks

Matt Martz

unread,
Sep 16, 2014, 8:33:07 AM9/16/14
to ansible...@googlegroups.com
In order for this to work the variable cannot be a host var or by extension not a group_var.  It must be a variable that is defined globally such as from:

1. vars
2. vars_files
3. --extra-vars/-e
4. role invocation ( - { role: foo, some_var: bar } )

There are others, but the important thing is that vars from inventory, host_vars and group_vars will not work.  The reason for this is that the var could be different for each host and it would make sense, as well as name being printed before the hosts are inspected.

--
You received this message because you are subscribed to the Google Groups "Ansible Project" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ansible-proje...@googlegroups.com.
To post to this group, send email to ansible...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ansible-project/952d8dbc-c468-4bcf-9696-e6e5bfeb51db%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
Matt Martz
ma...@sivel.net
http://sivel.net/

Michael DeHaan

unread,
Sep 16, 2014, 8:47:58 AM9/16/14
to ansible...@googlegroups.com
To expand on Matt's answer, it's because they aren't really in scope yet.

If you can imagine having 500 different hosts, each with a different value of "x", what would be printed for:

"TASK: {{ x }}"

in the header?

Well, we don't know what the value of x is yet at this point in time, but we do in the tasks below it.   But we can't show 500 values in the header.

So that's why it is the way is there.



Chip Selden

unread,
Dec 15, 2014, 12:02:06 PM12/15/14
to ansible...@googlegroups.com
To expand on this, I have a task with 3 variable references in its name. 

- name: Send messages, count {{msgcount}}, size {{msgsize}}, port {{msgport}}
  shell: some_command

I've noticed a couple behaviors with evaluating these:
1. The variable is not evaluated if only defined in the role's "defaults/main.yml" variables file
2. None of the variables are evaluated if one of them wouldn't be evaluated

Are these behaviors purposeful or just the result of how and when variables are put in scope? None of these variables are related to hosts (i.e. they are global).
I know that there is a hierarchy of variables and that they are looked for in a certain order, but where does Ansible look for variables before deciding how to display task names?
 
Thanks,
Chip

Brian Coca

unread,
Dec 15, 2014, 12:44:28 PM12/15/14
to ansible...@googlegroups.com
short answer: yes, this is expected behaviour

long one:
#1 happens because of main/defaults.yml has the lowest precedence
possible and vars there don't get merged in until task execution,
name: gets set during task definition, this is because host vars are
allowed to override them. You can use vars/main.yml for 'non
overridable' higher precedence vars.

#2 happens because jinja2 is given the full name: string to evaluate,
and it throws a 'variable undefined error' (with default settings)
which we capture, ignore and return the original string, this is done
in some cases (like name:) as it should not play/task execution.

Using vars, extra vars or role vars (but not defaults) should give you
what you need for task names.

--
Brian Coca

Michael DeHaan

unread,
Dec 15, 2014, 1:14:17 PM12/15/14
to ansible...@googlegroups.com
Basically think of it as each variable (for a large infrastructure) basically having 500 different values

Ansible can't tell the variable has only *one* value, since the variable is "inventory scope" as such, it can't plug it in, because the task header (that preceeds the next 500 task results) would not apply equally to all hosts.

So it's a cosmetic thing, but done for a very good (if not slightly confusing!) reason.



--
You received this message because you are subscribed to the Google Groups "Ansible Project" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ansible-proje...@googlegroups.com.
To post to this group, send email to ansible...@googlegroups.com.
Message has been deleted

Rick Kasten

unread,
Mar 12, 2015, 1:20:48 PM3/12/15
to ansible...@googlegroups.com
These answers don't make sense to me. Here's what I've got:

# inventory/dse/group_vars/dse/
package_versions.yml
package_versions:
  app:
    oraclejre_version: jdk1.7.0_75

# roles/oraclejre/tasks/main.yml
- name: OracleJRE | Make OracleJRE {{ version }} home directory
  file: path=/usr/local/java-{{ version }} state=directory
  sudo: yes

# roles/oraclejre/vars/main.yml
oraclejre_versions:
  jdk1.7.0_75:
    download_filename: jdk-7u75-linux-x64.tar.gz
    download_url: "http://download.oracle.com/otn-pub/java/jdk/7u75-b13/jdk-7u75-linux-x64.tar.gz"

# roles/app/meta/main.yml
dependencies:
  - { role: oraclejre, version: "{{ package_versions.app.oraclejre_version }}" }

and my output looks like this:

TASK: [oraclejre | OracleJRE | Make OracleJRE {{ package_versions.app.oraclejre_version }} home directory] ***
changed: [dse02] => {"changed": true, "gid": 0, "group": "root", "mode": "0755", "owner": "root", "path": "/usr/local/java-jdk1.7.0_75", "secontext": "unconfined_u:object_r:usr_t:s0", "size": 4096, "state": "directory", "uid": 0}

Now it would seem to me that if everyone's explanations were correct that my task should have failed, because "{{ package_versions.app.oraclejre_version }}" should not resolve properly AT ALL for the reasons that everyone has stated. But you can see that it IS resolving properly :  "path": "/usr/local/java-jdk1.7.0_75". So why would it resolve properly in the file: field but not the name: field?

Krishna

unread,
Mar 12, 2015, 4:04:09 PM3/12/15
to ansible...@googlegroups.com
Except this fails to work even with global vars on 1.8.4 (but used to print the value with 1.7.x).

    ---
    - hosts: 127.0.0.1
      gather_facts: no
      vars:
        vhost: "foo"
      tasks:
        - name: create a virtual host file for {{ vhost }}
          debug: msg="{{ vhost }}"

Why would that be the case?

Toshio Kuratomi

unread,
Mar 13, 2015, 1:00:05 AM3/13/15
to ansible...@googlegroups.com
This is a bug: https://github.com/ansible/ansible/issues/10347

The variable handling changed and the callback isn't getting the
variables it needs anymore. Defered to v2 because one of the goals of
v2 is to simplify variable handling which should make this easier to
fix. (and any fix that was to hit v1 wouldn't be applicable to v2).

-Toshio
> --
> You received this message because you are subscribed to the Google Groups
> "Ansible Project" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to ansible-proje...@googlegroups.com.
> To post to this group, send email to ansible...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/ansible-project/865d3913-1321-4bac-9e5b-83be046936b5%40googlegroups.com.

Toshio Kuratomi

unread,
Mar 13, 2015, 1:08:17 AM3/13/15
to ansible...@googlegroups.com
I'm not sure I see the reason you have for thinking it won't resolve at all...

In general the difference between the name field of a task resolving
and the same variable within a task is that the name field is
templated once per task whereas the parts that make up what is
executed in the task are templated once per host. So something that
is at the host/group level can't be known at the time that we template
and print out the name field. But it will be known by the time we
loop over the task body.

You could think of it sort of like this pseudo code:

global_vars = resolve_globals()
print (template(name_field, global_vars))
for host in hosts:
host_and_group_vars = resolve_host_and_group(host)
execute(template(task, global_vars, host_and_group_vars))


( Any of these specific cases could be because of the bug I linked to
later in the thread: https://github.com/ansible/ansible/issues/10347
but I can't guarantee it... there are certain variables that simply
aren't available at the time the name field is printed but are
available once we start looping over the task itself.)

-Toshio
Reply all
Reply to author
Forward
0 new messages