Access a variable defined in a playbook - within a role

Hello,

I have this playbook running a role. The role runs a script that runs with the role-parameter: “whentorun”
I reuse the role with different arguments bun I need to run the second command (/scripts/nonReg/expoNonRegTest.sh diff) when “whentorun” has a certain value.
For example:

  • name: bla bla
    hosts: ALL
    remote_user: root
    roles:
  • role: nonreg
    whentorun:
  • post

This may not directly answer your question, but this how I am handling that same issue. We have definitions of packages and rpms defined in group_vars and host_vars:

inventory/dse/group_vars/dse/package_versions.yml

package_versions:
app:
app: 4.6.1
jre: jre-1.7.0_75-fcs.x86_64

Then as part of the role of “app” we check if the packages are already installed:

roles/datastax_enterprise/tasks/main.yml

  • name: Lookup installed jre version
    shell: rpm -q jre || true
    register: installed_jre_version
    ignore_errors: true
    changed_when: installed_jre_version.stdout != package_versions.app.jre

  • name: Install jre rpm
    yum: pkg={{ path_to_rpm }}/{{ package_versions.app.jre }} state=present
    sudo: yes
    when: installed_jre_version | changed

So “installed_jre_version | changed” is True only when jre doesn’t match our version (not installed or earlier version). You can take the same action as my “Lookup installed jre version” to register a variable based on the output of “1” or of a different play that double-checks “1” and then run “2” based on that variable.

Thanks for the reply but if I run a role 10 times in a playbook and only on the 5th run of that role I want it to run the second shell cmd from within that role. How can I address that ? If I can insert some variable within the playbook (outside the role) in the beggining something like:
vars:
some_variable: 0

and on each run of the role within the playbook increment the variable: some_variable:

some_variable = some_variable + 1 … or some_variable ++ ? :slight_smile:

and at the 5th run I can have a

shell: the 5th run cmd
when: “{{ some_variable }}” == 5

How can I do that ?
How can I declare a variable and assign a value to it (during the run o a role/playbook)? What is the syntax ? In the ansible documentation, at variables, there isn’t a simple example of how can you assign a value to a variable (not with register :P)

Adrian,

Interesting idea. Ansible is tricky when it comes to assigning values to variables and having them persist through roles, plays, or between hosts. I don’t know about how you could manipulate variable values, but one way I’ve found to keep track of things between plays and hosts is by working with inventory groups.

Using this, you can add a fake host to a fake group on every iteration of a role. The later roles will be able to access this group and see it’s contents/length so that the role knows how many iterations have passed. Here’s an example:

#site.yml

  • name: play1
    hosts: all
    role:
  • { role: myrole, myvar: foo }
  • { role: myrole, myvar: bar }
  • { role: myrole, myvar: foobar }

#myrole/tasks/main.yml

  • name: run script
    shell: /path/to/script.sh {{myvar}}

  • name: run other script on 5th run
    shell: /path/to/otherscript.sh {{myvar}}
    when: groups.counter_group_{{inventory_hostname}}|d(“”)|length == 4

  • name: add host to counter group
    add_host:
    group=counter_group_{{inventory_hostname}}
    name=fakehost{{groups.counter_group|d(“”)|length}}

Running this role multiple times lets you keep track of the number of runs so far and lets you use a makeshift counter for a conditional statement. If you’ve never used some of these things, here’s a little background:
– The d(“”) in the when statement and the name parameter of the add_host module is short for default(“”) and is for setting a default value for that variable so that it doesn’t error out when undefined.
– In this case, using {{inventory_hostname}} in the group name lets each host manage its own counter group so that multiple hosts are not adding to the same group on a single run of the role.

Good luck!
\Chip

That’s a very big workaround for a simple var++ stuff :slight_smile:

It weird to say “Ansible’s human-readable IT automation language” and you can’t even do a basic value to variable assignment

I found the solution:

You can use the set_fact module to increment your variable:

- set_fact: some_variable={{ some_variable | int + 1 }}

Your condition for running the extra task then should look like this:

  when: some_variable | int == 5

Make sure you always cast the value to and int with | int or it will be handled as a string.

Awesome, I had forgotten that those variables survive between plays