Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ansible: How do I avoid registering a variable when a "when" condition is *not* met?

Tags:

I have the following Ansible Playbook code:

- name: Users | Generate password for user (Debian/Ubuntu)
  shell: makepasswd --chars=20
  register: make_password
  when: ansible_distribution in ['Debian', 'Ubuntu']

- name: Users | Generate password for user (Fedora)
  shell: makepasswd -m 20 -M 20
  register: make_password
  when: ansible_distribution in ['Fedora', 'Amazon']

- name: Users | Generate password for user (CentOS)
  shell: mkpasswd -l 20
  register: make_password
  when: ansible_distribution in ['CentOS']

- name: debug
  debug: var=make_password

Which outputs:

TASK: [users | debug] 
ok: [127.0.0.1] => {
                     "var": {
                       "make_password": {
                         "changed": false,
                         "skipped": true
                       }
                     }
                   }

... Because every register block gets executed regardless of the when condition.

How would I fix this so make_password doesn't get overwritten when the when condition isn't met?

Or if this is the wrong approach for what you can see that I'm trying to accomplish, let me know of a better one.

like image 384
Neil Avatar asked Jan 05 '16 21:01

Neil


Video Answer


2 Answers

Unfortunately, this is the expected behavior. From Ansible Variables

Note If a task fails or is skipped, the variable still is registered with a failure or skipped status, the only way to avoid registering a variable is using tags.

I do not know how to use tags to solve your issue.

EDIT: I found a way albeit a crude solution. Store the results so that it is not overwritten

  - set_fact: mypwd="{{make_password}}"
    when: make_password.changed

So your code will look like:

- name: Users | Generate password for user (Debian/Ubuntu)
  shell: makepasswd --chars=20
  register: make_password
  when: ansible_distribution in ['Debian', 'Ubuntu']

- set_fact: mypwd="{{make_password}}"
  when: make_password.changed

- name: Users | Generate password for user (Fedora)
  shell: makepasswd -m 20 -M 20
  register: make_password
  when: ansible_distribution in ['Fedora', 'Amazon']

- set_fact: mypwd="{{make_password}}"
  when: make_password.changed

- name: Users | Generate password for user (CentOS)
  shell: mkpasswd -l 20
  register: make_password
  when: ansible_distribution in ['CentOS']

- set_fact: mypwd="{{make_password}}"
  when: make_password.changed

- name: debug
  debug: var=mypwd
like image 185
helloV Avatar answered Sep 18 '22 14:09

helloV


Typically for tasks that run differently on different distros I tend to include a distro specific playbook that is then conditionally included into main.yml.

So an example might look something like this:

main.yml:

- include: tasks/Debian.yml
  when: ansible_distribution in ['Debian', 'Ubuntu']

- include: tasks/Fedora.yml
  when: ansible_distribution in ['Fedora', 'Amazon']

- include: tasks/Centos.yml
  when: ansible_distribution in ['CentOS']

- name: debug
  debug: var=make_password

Debian.yml

- name: Users | Generate password for user (Debian/Ubuntu)
  shell: makepasswd --chars=20
  register: make_password

And obviously repeat for the other 2 distros.

This way you keep main.yml to be only running all the generic tasks for the role that can be run on any distro but then anything that needs to be different can be in a distro specific playbook. Because the include is conditional it won't even load the task if the condition isn't met so the variable should not be registered.

like image 37
ydaetskcoR Avatar answered Sep 20 '22 14:09

ydaetskcoR



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!