include ignores when statement when var inside inlcuded yml not defined #18346

Closed
sbrueseke opened this Issue Nov 3, 2016 · 8 comments

Projects

None yet

6 participants

@sbrueseke
ISSUE TYPE
  • Bug Report
COMPONENT NAME

include

ANSIBLE VERSION
ansible 2.2.0.0 (stable-2.2 b229898f80) last updated 2016/11/03 17:59:27 (GMT +200)
  lib/ansible/modules/core: (detached HEAD 164225aa43) last updated 2016/11/03 17:59:32 (GMT +200)
  lib/ansible/modules/extras: (detached HEAD 18bb736cc2) last updated 2016/11/03 17:59:36 (GMT +200)
CONFIGURATION

none

OS / ENVIRONMENT

Debian 8 64bit

SUMMARY

when using include with when statement and inside the included yml is a var used which is not defined the task fails even if when statement of the include did not match.
This was working in ansible 2.0.0.2

STEPS TO REPRODUCE

playbook.yml

- name: testing    
  hosts: all
  become: True
  tasks:
    #
    - name: testing include with when statement
      include: "testing-include-file.yml"
      when: _var is defined

testing-include-file.yml

- name: task inside testing-include-file.yml
  debug: msg="include"
  with_items: "{{ _itemvar }}"
EXPECTED RESULTS
TASK [testing include with when statement] *************************************
task path: /home/s.brueseke/repositories/testing/debian/testing_include.yml:6
skipping: [ansible-debian] => {"changed": false, "skip_reason": "Conditional check failed", "skipped": true}
ACTUAL RESULTS
TASK [task inside testing-include-file.yml] ************************************
task path: /home/s.brueseke/repositories/testing/debian/testing-include-file.yml:2
fatal: [ansible-debian]: FAILED! => {
    "failed": true,
    "msg": "'_itemvar' is undefined"
}

@agaffney
Contributor
agaffney commented Nov 3, 2016

This might be a result of the change in 2.1 to make the default include behavior "static" like it was in 1.9. Does adding static: no to the include task prevent the error?

Additionally, you should probably just add a | default([]) after the _itemvar in the failing item. That will prevent the undefined variable error either way.

@agaffney
Contributor
agaffney commented Nov 3, 2016

This (using an undefined var in a with_items) generated a deprecation warning starting in 2.0 and is now a fatal error starting in 2.2. Add the | default([]), and you should be fine.

@dene14
dene14 commented Nov 4, 2016

@agaffney confirm that | default([]) helps. However don't you agree that if task file conditionally SHOULD NOT be included into play ansible SHOULD NOT evaluate anything from that task file?

@naslanidis
Contributor

@agaffney

You might be on to something here. I was having a similar issues with includes conditional on a variable that should've been skipped and changing them to static: no explicitly seems to have restored the previous behaviour:

e.g.


  • { include: setup_instances.yml, static: no, when: stage != "delete"}
  • { include: terminate_instances.yml, static: no, when: stage == "delete" }
@sbrueseke
sbrueseke commented Nov 4, 2016 edited

static: no fixed it. Is this documented anywhere?
But my understanding of include with when statement is different than the default behavior in ansibble 2.2. I am with @dene14 here, if something is not matching why evaluate it in the first place.

We have the following use case for our role mysql-server:
main.yml

- name: include install-mysql.yml
  include: "install-mysql.yml"

- name: include config-mysql.yml
  include: "config-mysql.yml"
  when: mysql_config is defined

- name: include setup-mysql.yml
  include: "setup-mysql.yml"

config-mysql.yml

# get mysql version and save it to _mysql_version_query
- name: get output of mysql --version
  shell: mysql --version
  changed_when: false
  always_run: yes
  register: _mysql_version_query

- name: fix mysql 5.6 bugs
  include: "fix-mysql56.yml"
  when: _mysql_version_query.stdout.split()[4].split('.')[0] == "5" and _mysql_version_query.stdout.split()[4].split('.')[1] == "6"

ansible is failing because "_mysql_version_query" is not defined, but it is not needed if config-mysql.yml is skipped.

@bcoca
Member
bcoca commented Nov 4, 2016

Possible Misunderstanding

Hi!

Thanks very much for your submission to Ansible. It sincerely means a lot to us.

We believe the ticket you have filed is being somewhat misunderstood, as one thing works a little differently than stated.

As explained above, this is an issue with static vs dynamic includes, inheritance and that when executes inside the with loops.

In the future, this might be a topic more well suited for the user list, which you can also post here if you'd like some more help with the above.

Thank you once again for this and your interest in Ansible!

@bcoca bcoca closed this Nov 4, 2016
@sbrueseke

Hi,

can you please explain why ansible is validating something which will be skipped because of conditional false? Can you please refer to documentation about static and dynamic inlcudes? I want to understand this. Thank you very much!

@bcoca
Member
bcoca commented Nov 4, 2016 edited

http://docs.ansible.com/ansible/playbooks_conditionals.html#loops-and-conditionals
http://docs.ansible.com/ansible/include_module.html

The issue is that with both static includes and when/with interactions Ansible does NOT know if it will skip the task.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment