ansible-lint icon indicating copy to clipboard operation
ansible-lint copied to clipboard

Add rule warning about use of run_once with strategy: free

Open cboylan opened this issue 5 years ago • 3 comments

Summary

It would be useful for ansible-lint to have a rule that warns against the use of run_once with strategy: free. Ansible ignores run_once with the free strategy which means your tasks are run many times, once for each valid inventory host. Ansible itself does warn against this as well but doesn't fail directly. Being able to catch this early would be great.

Issue Type
  • Feature Idea

cboylan avatar Sep 02 '20 16:09 cboylan

ansible 2.10 does produce runtime warning about use of run_once when used with strategy: free but it does not produce any warnings when doing syntax check or when running without free strategy.

This behavior makes the run_once a potential production bomb, as users may change strategy when deploying in production, in some cases when they use tower/awx this can also be changed by the operator.

I am inclined to consider run_once an unpredictable option to use and always warn about its presences, regardless the strategy (especially as it cannot reliably be inferred during linting). I would suggest manually whitelisting each usage, unless someone comes with a better recommendation.

ssbarnea avatar Sep 02 '20 16:09 ssbarnea

Just for info, providing what ansible 2.9.x shows as far as the warning message:

playbook:

---
- hosts: all
  strategy: free
  gather_facts: false

  tasks:

  - debug:
      msg: "Test"
    run_once: True

output from ansible-playbook -i localhost, test.yml:

PLAY [all] ***********************************************************************************************************************
[WARNING]: Using run_once with the free strategy is not currently supported. This task will still be executed for every host in
the inventory list.

TASK [debug] *********************************************************************************************************************
ok: [localhost] => {
    "msg": "Test"
}

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

Perhaps the rule should make the following recommendation to the user... this is in the following docs where it states:

When used together with “serial”, tasks marked as “run_once” will be run on one host in each serial batch. If it’s crucial that the task is run only once regardless of “serial” mode, use when: inventory_hostname == ansible_play_hosts_all[0] construct.

I would be ok with a rule that gives a warning and leaving it up to the individual to make it an error or leave it as warning. However this does not feel like a deprecation issue, but rather just not supported in the specific situation with strategy=free.

Btw, this is another rule where it would be beneficial for lint rules to know a bit more about the context (in this case if the task is within a Play where strategy=free). However, that's a separate enhancement.

ansiblejunky avatar Sep 02 '20 21:09 ansiblejunky

use when: inventory_hostname == ansible_play_hosts_all[0] construct

If the rule proposed in the OP will be added, I for one would not want see the above construct as a remedy recommendation. It may work in some cases but in many cases (especially with the free strategy, where some similar construct is the only option) it is not equivalent at all and is a bad advise.

bluikko avatar Jan 02 '22 06:01 bluikko