variables in "--check" mode

Variables that are brought into scope through the “register: var” when a task is executed are not available when a playbook is run with the --check mode.

The work-around I have been using is to put defaults (for all those variables that will eventually be brought into scope using register) using set_fact or group_vars/all or an included var file.

I suggest changing the ansible --check mode to not evaluate those variables, in the when clause, normally brought into scope using register.

Does anyone else have this problem? Did you use another work around? Do you like my idea of selectively evaluating variables that are “registered”?

I believe you’d want to check whether the registered variable (or member of the variable) is defined, as follows (assuming you registered a variable named result):

when: ‘“foo” in result and result.foo != “something”’

This way, you can prevent undefined errors and the task would just be skipped.

Variables that are brought into scope through the "register: var" when a
task is executed are not available when a playbook is run with the --check
mode.

That depends on the task - if a given module supports check-mode (most of the ones bundled with Ansible do) it will give you *some* information.
Tasks using modules that do not support check mode are skipped by default, so you'd need a workaround

The work-around I have been using is to put defaults (for all those
variables that will eventually be brought into scope using register) using
set_fact or group_vars/all or an included var file.

One way to work around it for modules that don't support check mode (like command/shell, which can't do it for obvious reasons :-)) is to have a data-gathering command with "always_run: yes", and then use that to decide if the target command should be run.

For example:
- name: Get Jenkins's plugins
   shell: jenkins-cli -s {{ jenkins.url }} list-plugins | cut -f 1 -d ' '
   register: installed_plugins
   changed_when: False
   always_run: yes # This gets run even in check mode, as it's safe to read a list of plugins

- name: Install missing plugins
   shell: jenkins-cli -s {{ jenkins.url }} install-plugin -deploy {{ item }}
   with_items: jenkins.plugins
   when: item not in installed_plugins.stdout_lines

I suggest changing the ansible --check mode to not evaluate those
variables, in the when clause, normally brought into scope using register.

That sounds like a pretty confusing behavior, and it would break a lot of existing plays.

Does anyone else have this problem? Did you use another work around? Do
you like my idea of selectively evaluating variables that are "registered"?

I did have this problem, and I still would sometimes like to have a variable telling me if I'm in check mode (I know I can create one with set_fact and always_run, but it's an ugly hack).
The only real workaround that won't make your --check runs useless is splitting tasks into probing the system part, and changing the system part (or writing modules that do this :-)).

always_run is there, yes, but ultimately, check mode (dry run) is kind of a configuration management thing, and can get difficult in more step-wise application deployment or orchestration tasks.

I agree we’re not going to make a behavior change to variable evaluation in check mode.

I’m unclear on why we need a variable to indicate whether we are in check mode when always_run can be used for data gathering commands.
It’s not a workaround, it’s a feature :slight_smile:

Thanks for all the replies. I was not aware of the always_run feature (http://docs.ansible.com/playbooks_checkmode.html) so that answers my question. Thank you.

Also, @laserllama nice meeting you at AnsibleFest this week

I'm unclear on why we need a variable to indicate whether we are in check
mode when always_run can be used for data gathering commands.
It's not a workaround, it's a feature :slight_smile:

Right, a variable like that wouldn't make anything new possible, it's just that I recall I wanted it for something.
I'll note any use-cases if I run into them again (my memory is not too good with things I had gotten around anyway...).