user8295576
user8295576

Reputation: 29

Weird Ansible issue

When I use two consecutive shell tasks with When condition "when: ansible_distribution == 'Amazon' and when: ansible_distribution == 'CentOS'" its fails to register variable(attributes) of first tasks If I disable task with "when: ansible_distribution == 'CentOS'" it works perfectly. here I am using local Centos VM but this is true for CentOS EC2 instance.

Playbook

- hosts: "{{ target }}"

  tasks:

    - name: uptime al2
      shell: uname -r
      changed_when: true
      ignore_errors: true
      register: ucheck
      when: ansible_distribution == 'Amazon'


    - name: uptime centos
      shell: uname -r
      changed_when: true
      ignore_errors: true
      register: ucheck
      when: ansible_distribution == 'CentOS' or ansible_distribution == 'RedHat'

    - debug:
        msg: "RC is {{ ucheck.rc }}"

Running on CentOS

[root@server1 ~]# ansible-playbook -i localhost, vagrant-ansible/playbooks/al2-test.yml -e target=localhost

PLAY [localhost] *********************************************************************************************************************

TASK [Gathering Facts] ***************************************************************************************************************
ok: [localhost]

TASK [uptime al2] ********************************************************************************************************************
skipping: [localhost]

TASK [uptime centos] *****************************************************************************************************************
changed: [localhost]

TASK [debug] *************************************************************************************************************************
ok: [localhost] => {
    "msg": "RC is 0"
}

PLAY RECAP ***************************************************************************************************************************
localhost                  : ok=3    changed=1    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0

Runing on AL2

[root@server1 ~]# ansible-playbook -i 3.238.194.98, vagrant-ansible/playbooks/al2-test.yml -e target=3.238.194.98 -u ec2-user --private-key=<keypair>

PLAY [3.238.194.98] ******************************************************************************************************************

TASK [Gathering Facts] ***************************************************************************************************************
[WARNING]: Platform linux on host 3.238.194.98 is using the discovered Python interpreter at /usr/bin/python, but future installation
of another Python interpreter could change this. See
https://docs.ansible.com/ansible/2.9/reference_appendices/interpreter_discovery.html for more information.
ok: [3.238.194.98]

TASK [uptime al2] ********************************************************************************************************************
changed: [3.238.194.98]

TASK [uptime centos] *****************************************************************************************************************
skipping: [3.238.194.98]

TASK [debug] *************************************************************************************************************************
fatal: [3.238.194.98]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'dict object' has no attribute 'rc'\n\nThe error appears to be in '/root/vagrant-ansible/playbooks/al2-test.yml': line 20, column 7, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n    - debug:\n      ^ here\n"}

PLAY RECAP ***************************************************************************************************************************
3.238.194.98               : ok=2    changed=1    unreachable=0    failed=1    skipped=1    rescued=0    ignored=0

Runing after disabling Second Task

[root@server1 ~]# ansible-playbook -i 3.238.194.98, vagrant-ansible/playbooks/al2-test.yml -e target=3.238.194.98 -u ec2-user --private-key=<keypair>

PLAY [3.238.194.98] ******************************************************************************************************************

TASK [Gathering Facts] ***************************************************************************************************************
[WARNING]: Platform linux on host 3.238.194.98 is using the discovered Python interpreter at /usr/bin/python, but future installation
of another Python interpreter could change this. See
https://docs.ansible.com/ansible/2.9/reference_appendices/interpreter_discovery.html for more information.
ok: [3.238.194.98]

TASK [uptime al2] ********************************************************************************************************************
changed: [3.238.194.98]

TASK [debug] *************************************************************************************************************************
ok: [3.238.194.98] => {
    "msg": "RC is 0"
}

PLAY RECAP ***************************************************************************************************************************
3.238.194.98               : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Upvotes: 1

Views: 254

Answers (2)

Zeitounator
Zeitounator

Reputation: 44808

This is not an issue and is absolutely expected. register tells ansible to feed whatever task result inside a variable. In your second example:

  • The first task runs fine on "Amazon" and registers its successful result in ucheck (including an rc field from the shell module).
  • Then the next task is skipped for "Centos or Redhat" and overrides ucheck with a skipped task result. Since this second result only contains info about the skipped task (debug for yourself to see the exact full content), it does not contain any info about running the shell module hence not any rc attribute.

This definitely explains your error message. You need to debug in each situation or use different variables. Here is a possible solution:

- hosts: "{{ target }}"

  tasks:

    - name: uptime al2
      shell: uname -r
      changed_when: true
      ignore_errors: true
      register: ucheck
      when: ansible_distribution == 'Amazon'

    - debug:
        msg: "RC is {{ ucheck.rc }}"
      when: ucheck is not skipped

    - name: uptime centos
      shell: uname -r
      changed_when: true
      ignore_errors: true
      register: ucheck
      when: ansible_distribution == 'CentOS' or ansible_distribution == 'RedHat'

    - debug:
        msg: "RC is {{ ucheck.rc }}"
      when: ucheck is not skipped

Upvotes: 2

mdaniel
mdaniel

Reputation: 33231

Ansible always processes the register: task keyword, even if skipped, because it allows one to later test when: my_var is skipped which wouldn't be possible without registration

So, you'll need a unique variable for each one of those cases. But, thankfully you don't need thing1 is not skipped and thing1.rc == 0 because there is the more helpful is failed (or is succeeded) jinja2 tests that do the right thing

Upvotes: 2

Related Questions