Just trying to figure out how to fix the deprecation warnings (recently updated to 2.1.1.0 from 1.7). I used to have the 4 individual tasks in the block below (I left the commented out when statements from the original 1.7 tasks). I tried refactoring a couple of times, but with the current setup, I still get “Skipping task due to undefined Error, in the future this will be a fatal error.: ‘project_config’ is undefined.” on all 4 tasks when project_config is undefined. Shouldn’t the block just skip the tasks? Is there something I’m missing about how blocks are executed? Is there a better way to rewrite this set of tasks?
block:
name: Install system dependencies for project
become: True
apt: pkg={{ item }} state=installed
with_items: " {{ project_config.apt|default() }}"
when: project_config is defined and ‘apt’ in project_config
Just trying to figure out how to fix the deprecation warnings (recently
updated to 2.1.1.0 from 1.7). I used to have the 4 individual tasks in the
block below (I left the commented out when statements from the original 1.7
tasks). I tried refactoring a couple of times, but with the current setup,
I still get "Skipping task due to undefined Error, in the future this will
be a fatal error.: 'project_config' is undefined." on all 4 tasks when
project_config is undefined. Shouldn't the block just skip the tasks?
You would think so, since the documentation says
"...tasks will be executed after appending the when condition from the block and evaluating it in the task’s context."
Is
there something I'm missing about how blocks are executed? Is there a
better way to rewrite this set of tasks?
- block:
- name: Install system dependencies for project
become: True
apt: pkg={{ item }} state=installed
with_items: " {{ project_config.apt|default() }}"
# when: project_config is defined and 'apt' in project_config
If project_config is not defined this will work
with_items: "{{ project_config | default() }}"
but thees two will give a deprecation warning
with_items: "{{ project_config.apt | default() }}"
with_items: "{{ project_config['apt'] | default() }}"
Is
there something I'm missing about how blocks are executed? Is there a
better way to rewrite this set of tasks?
- block:
- name: Install system dependencies for project
become: True
apt: pkg={{ item }} state=installed
with_items: " {{ project_config.apt|default() }}"
# when: project_config is defined and 'apt' in project_config
This will work.
First project_config need to be filtered through default, and then project_config.apt.
It seems like using a “is-defined” check as a conditional is pointless if we have to send everything through default anyway. I understand the change for loops (since it checks each item now), but this behavior seems really counter-intuitive for blocks. What’s even the point of grouping it into a block if I have to set those default filters on each task? It’s just going back to being 4 separate tasks.
blocks let you do 2 things, handle errors and ‘share settings’, the conditional does not affect the block itself, it is a way to allow all tasks to inherit it, instead of writing it N times.
TASK [customer_sftp : Create plain FTP groups] *********************************
[DEPRECATION WARNING]: Skipping task due to undefined Error, in the future this will be a fatal error.: ‘dict object’ has no attribute u’internal’.
This feature will be removed in a future release. Deprecation warnings can be disabled by setting
deprecation_warnings=False in ansible.cfg.
skipping: [myserver]
It threw me off because it’s purple and says “DEPRECATION WARNING”, but it’s just a regular error really. It does what I want, in so much as it skips hosts not in a particular list, but I could do without the error. It’s of course fixed like this:
I’ve put a comment in the file which describes it like this:
If using “with_items”, the “when” is evaluated on each iteration of the loop, and not when looking at the task as a whole. As such, trying to ‘lock out’ the task with a “when” won’t work, and instead we have to default the “with_items” with an empty list if we don’t want to run the loop at all.
Taking a ‘step back’ from this, it makes sense for Ansible to work this way, but it can easily catch you out as a single task (with no “with_items”) works in a way you may mentally extrapolate out to loops.
note the change, only the last one is an empty list , if
project_config is undefined it should be an empty hash/dictionary, as
.apt can only be part of that and not a list. Default will need to
return what is expected of the 'next step'