3

NB: I am using Ansible 1.9.4 and can't upgrade at this time

I am trying to conditionally include a task file based on whether or not a nested dictionary exists.

I have 4 hosts, 1 of which has a type of virtual machine I'm calling heavy_nvme but the others don't. I am trying to run this playbook on all 4 hosts simultaneously. I am using group_vars to set all of the variables for all of the servers, then a single host file to overwrite the relevant dict for the server with different requirements.

My group vars look like this:

virtual_machines:
  type:
    druid:
      os: amazon_linux_2
      count: 0
      memory: 16
      vcpus: 4
      disk: {}
    heavy_nvme:
      active: false

My include command looks like this:

- name: destroy virtual machines
  include: destroy-virtual-machines.yml types={{ virtual_machines.type }} name='heavy_nvme'
  when: '"heavy_nvme" in virtual_machines.type and virtual_machines.type.heavy_nvme.count > 0'

When I try to run this, I get a failure related to a task in the included file:

fatal: [hostname.local] => unknown error parsing with_sequence arguments: u'start=1 end={{ num_machines }}'

This refers to the following line from destroy-virtual-machines.yml:

- name: destroy virt pools
  command: "virsh pool-destroy {{ vm_name_prefix }}-{{ item }}"
  with_sequence: start=1 end={{ num_machines }}
  ignore_errors: True

The error occurs because the num_machines variable is a fact set by performing a calculation on the count variable from each of the virtual machine types. The druid type runs fine because count exists, but obviously it doesn't in the heavy_nvme dict.

I have tried a few different approaches, including adding a count: 0 to the heavy_nvme dict. I have also tried removing the heavy_nvme dict entirely, or setting it as a blank dict - neither give me the outcome I require.

I'm pretty sure this error occurs because when you run a conditional include, the condition is simply added to every task in the included file. That won't work for me because then I'll be missing a load of variables that the included file requires.

Is there a way that I can stop these tasks from being run at all if the heavy_nvme dict doesn't exist, or if it has a count 0, or if it has a specified key/var set (e.g. active: false)?

turbonerd
  • 1,234
  • 4
  • 27
  • 63
  • 2
    Did you consider using the [`default` filter](https://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html#defaulting-undefined-variables) to give default values to unexisting vars ? This should fix your undefined vars and you tasks should still be skipped. – Zeitounator Jul 03 '20 at 21:52
  • Thanks @Zeitounator. Would I use this in the included task files, for each variable set? Or in the conditional? – turbonerd Jul 04 '20 at 08:55
  • In any task where you anticipate a barrable might not be set. – Zeitounator Jul 04 '20 at 14:23

0 Answers0