ansible-lockdown/UBUNTU22-CIS

Tasks are not being skipped based on defaults/main.yml or passing '-e taskname=false'

mboeker opened this issue · 8 comments

Describe the Issue
I am trying to run the playbook with certain components skipped. For example NetworkManager, I don't want that installed. I tried both of these options:
ubtu22cis_install_network_manager: false
in defaults/main.yml, and
ansible-playbook -e ubtu22cis_install_network_manager=false site.yml
but it is still installing it. Same with rule 5.3.4, sudo password. Even when I set ubtu22cis_rule_5_3_4: false and pass -e ubtu22cis_rule_5_3_4=false it sets a sudo password.

Expected Behavior
Tasks get skipped if defaults/main.yml or -e args are set to false.

Actual Behavior
Tasks are still processed.

Control(s) Affected
Hardening process

Environment (please complete the following information):

  • branch being used: main
  • Ansible Version: ansible 9.5.1 from pip3
  • Host Python Version: 3.10.12
  • Ansible Server Python Version: 3.10.12
  • Additional Details: Ubuntu 22.04 from Jan 2024.

Additional Notes
When I change the playbooks to explicitly check for bool they work as expected.
So this task, in prelim.yml:

- name: "PRELIM | PATCH | Install Network-Manager"
  ansible.builtin.package:
      name: network-manager
      state: present
  when:
      - ubtu22cis_rule_3_1_2
      - ubtu22cis_install_network_manager
      - not system_is_container
      - "'network-manager' not in ansible_facts.packages"
  tags:
      - always

That will install network manager no matter what is set in defaults/main.yml or passed as an arg. HOWEVER, if I change the task to this, appending | bool to ubtu22cis_install_network_manager:

- name: "PRELIM | PATCH | Install Network-Manager"
  ansible.builtin.package:
      name: network-manager
      state: present
  when:
      - ubtu22cis_rule_3_1_2
      - ubtu22cis_install_network_manager | bool  # force checking if true/false
      - not system_is_container
      - "'network-manager' not in ansible_facts.packages"
  tags:
      - always

then it will skip the task if I set the variable in defaults/main.yml or pass the argument.

Possible Solution
See notes.

hi @mboeker

Thank you for raising this issue, this is one of those things that has been going on for some time. Historically using the ini format on the command line has been inconsistent as it sets it as a string (depending how conditionals etc have been written), ansible have been trying stating it for some time although it was (a little hidden) in documentation to use json instead.
This seems to be clearer now in the latest documentation, calling out that booleans variables when set on the command line should be in json format.

[key=value format]
Values passed in using the key=value syntax are interpreted as strings. Use the JSON format if you need to pass non-string values such as Booleans, integers, floats, lists, and so on.

taken from
https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_variables.html#defining-variables-at-runtime

Generally for more consistency when running playbooks any changes that are expected such as your examples, i would add to the inventory file (in yaml) or other variable location thats loaded, ensuring that nothing gets missed on subsequent runs. Being set as a default variable (the lowest type) these are easily overridden by alternative variables.

I hope that helps you and others.

uk-bolly

Interesting, I've never tried passing JSON args. But that wouldn't explain why it's still running tasks when they are only defined in defaults/main.yml as false. I'll give the JSON args a shot.

Interesting, I've never tried passing JSON args. But that wouldn't explain why it's still running tasks when they are only defined in defaults/main.yml as false. I'll give the JSON args a shot.

Strange you are having the problem with the defaults main also, thank you for highlighting. Have you tested devel at all, see if the issues exists there also? We skip/change a number of these during testing and they all appear to work. Will try and replicate as soon as able.
uk-bolly

Hi uk-bolly,

I've been digging some more. Per https://stackoverflow.com/questions/39640654/using-true-false-with-ansible-when-clause as of ansible 2.8 if a variable is given as a parameter (which I assume also applies to defaults/main.yml), the condition has to be converted to | bool explicitly.

I have not tested with devel as the playbook works once I've modified it to have | bool after the conditions that I care about. I just looked though and devel does not have | bool set.

The same info from the official source :)
https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_conditionals.html#conditionals-based-on-variables

You can also create conditionals based on variables defined in the playbooks or inventory. Because conditionals require boolean input (a test must evaluate as True to trigger the condition), you must apply the | bool filter to non-boolean variables, such as string variables with content like ‘yes’, ‘on’, ‘1’, or ‘true’.

hi @mboeker
Thank you for the feedback, The last comment the values are set to a string so are 'true' in quotes is not seen the same as true without quotes which is why you force the value to be validated as a boolean.
Ours are set without quotes thereby not requiring the | bool to be set.

I would be happy to see what happening with your setup to be causing this. We have in excess of 70 repos setup without the | bool requirement and we've not had the feedback from others experiencing this issue.
So if we can get to the bottom of this is would be great to add to the readthedocs so we are able to point others in the right direction.

Many thanks

uk-bolly