Task using with_fileglob shows warnigs when skipped

I’m running into a somewhat irritating issue and would like to ask for feedback or help on this.

We have to install / update a helm chart on kubernetes that includes some CRDs. But helm doesn’t update CRDs. And we want to keep them up-to-date. Actually, we recently ran into some problems because they weren’t.

So my solution is to “install” / “update” the chart with kubernetes.core.helm and check_mode: true. If, and only if, this would install or update the chart I run a block of tasks that:

  1. unpack the chart to temp_directory/chart
  2. apply all CRD YAML files with kubernetes.core.k8s using with_fileglob: temp_directory/chart/crds/*.yaml
  3. install / update the chart

If not, the block is skipped.

But when there’s no installation or update needed, I get a warning that there are no temp_directory/chart/crds/*.yaml files. Of course there aren’t, because we didn’t unpack the chart. But since this task is skipped, anyway, why the warning?

What’s the reason for this? And, if there’s a reason for this, is there a way to suppress this warning for a task that is skipped and only then? I’d still like to see warnings if the task isn’t skipped.

BTW: I think this has to do with ansible-core and not the kubernetes.core collection. I’ve tagged this with kubernetes, anyway, because maybe someone using ansible to manage helm charts with CRDs might have a better solution than the one that I thought up.

Having not provided any output or reproducer, I can only imagine it is the common “gotcha” that when conditionals run for each iteration of a loop, and not before the loop.

I will note that I don’t know what warning you are getting. with_fileglob doesn’t produce any warnings itself when nothing exists, unless the directory where the *.yaml files are suppose to exist doesn’t.

If that is the case, a few ideas:

  1. Use the file module to ensure the parent dir exists
  2. Use include_tasks with a when instead of when statements on individual subsequent tasks.

Run them as a task file? As was mentioned, `when` runs for all cycle iterations.

- name: Check if installation is required
  ....
  register: installation_required

- name: Run the installation (if required)
  ansible.builtin.include_tasks:
     file: "{{ installation_required | ternary('install.yml', 'noop.yml') }}"

Where noop.yaml is an empty but existing file. Noop - no operation.

Well it’s basically:

- name: Check installed
  kubernetes.core.helm:
    host: https://{{ inventory_hostname }}.{{ dns_zone }}:8443
    context: "{{ inventory_hostname }}"
    kubeconfig: "{{ playbook_dir }}/tmp/config-{{ inventory_hostname }}"
    validate_certs: true
    name: myapp
    chart_ref: "oci://{{ my_registry }}/myapp/mychart"
    release_namespace: myapp
    chart_version: "{{ chart_version }}"
  check_mode: true
  register: install_result

- name: Install / update myapp
  when: install_result.changed
  block:
    - name: Get chart
      kubernetes.core.helm_pull:
        chart_ref: "oci://{{ my_registry }}/myapp/mychart"
        chart_version: "{{ chart_version }}"
        destination: "{{ playbook_dir }}/tmp/{{ inventory_hostname }}"
        untar_chart: true
      check_mode: false

    - name: Install / update myapp CRDs
      kubernetes.core.k8s:
        state: present
        src: "{{ item }}"
      with_fileglob:
        - "{{ playbook_dir }}/tmp/{{ inventory_hostname }}/mychart/crds/*.yaml"
        - "{{ playbook_dir }}/tmp/{{ inventory_hostname }}/mychart/crds/*.yml"

If the chart is up to date, the block is skipped. But nevertheless I get this warning:

TASK [Install / update myapp CRDs] *******************************************************************************************
[WARNING]: Unable to find '/home/mariolenz/playbook/tmp/test-cluster-001/mychart/crds' in expected paths (use -vvvvv to see paths)
skipping: [test-cluster-001]

BTW this is unsecure. As soon as there are predictable path patterns for temp data - this temp data can be changed after you’ve created it and before you read it.

I wounder how output with -vvvvv looks like.

A common and not at all unreasonable misconception. Blocks are never skipped.

A block is a convenient way to apply things — in this case, a when: condition — to each iteration of tasks in a set of tasks.

So your block’s when: condition is evaluated for each iteration of your with_fileglob: list, each of which would generate the warning you see. You only see the warning once because of Ansible’s “suppress identical warnings” functionality.

Well, I guess you’re right… but it doesn’t explain why I see a warning on a skipped task. I don’t care for any warnings, it’s skipped anyway.

It’s not really a big issue, just somewhat annoying.

As I mentioned above, when conditions are applied for each iteration of a loop, not before the loop is evaluated. So with_fileglob is evaluated before the when.

I appreciate your perspective, but the warning is generated before Ansible can determine whether the task should be skipped.

You don’t care about the warning because you already know that path doesn’t exist.
But consider the case of a user running a similar task except for a typo in the with_fileglob path which results in the task being skipped. That user would (rightly) be here on the forum asking why the task is being skipped with no hint that something is amiss!

Far better to emit a warning that some users won’t care about than to omit a warning that costs other users days of hair-pulling frustration.

You bring up and interesting point, though. Deciding what to include in a job log is a delicate balancing act. Job logs need to contain all anomalous behavior relative to a given verbosity level - like your warning - while not overwhelming users with (details×repetition) - hence Ansible’s “suppress identical warnings” functionality for instance.

Thanks for the explanation @sivel! As I’ve said it’s not really a big deal, just somehow annoying and irritating. We’ll just just ignore this warning. I just wasn’t able to find anything about this behavior and wanted to satisfy my curiosity.

I think “delicate” is the right word. In my case, this warning doesn’t make sense. But I can think up use cases where showing warnings even if a task is skipped makes perfect sense. As I’ve said, we’ll simply ignore this since we know it’s now an issue for us.

Thanks all!