ansible-lockdown / UBUNTU22-CIS

Ansible role for Ubuntu22 CIS Baseline
https://ansible-lockdown.readthedocs.io/en/latest/
MIT License
155 stars 68 forks source link

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

Open mboeker opened 2 months ago

mboeker commented 2 months ago

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):

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.

uk-bolly commented 2 months ago

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

mboeker commented 2 months ago

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.

uk-bolly commented 2 months ago

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

mboeker commented 2 months ago

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.

mboeker commented 2 months ago

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.

mboeker commented 2 months ago

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’.