1

I am currently trying to work out a way to use modules like general.ini_file or general.lineinfile in order to address volatile settings such as file system drivers or paths to data locations. Such settings should certainly be managed by Ansible, but if in an existing system found to be different, I do not want them to automatically change due to the possibly catastrophic data loss that could cause.

Instead, I think the go to would be for the play to fail, and for an experienced system administrator to look at the concrete situation to decide how to handle it, assuming one isn't writing a play for a fleet of thousands that expects specific situations like this regularly where it might make sense to write complicated plays to fix such issues - but even then, something would have to trigger such plays, and before the change was actually carried out and the damage might already be done.

TL;DR: Looking for a way to make a play or task that checks if general.ini_file or general.lineinfile would cause a change and fail instead.

Torque
  • 3,319
  • 2
  • 27
  • 39
  • It might be helpful https://www.middlewareinventory.com/blog/ansible-changed_when-and-failed_when-examples/ – k0chan Apr 20 '23 at 09:38
  • @k0chan that suffers the problem I described - it can trigger after the change was carried out, but if the change is to, say, the data dir of a running application, that could have terrible consequences depending on how often the config is read – Torque Apr 20 '23 at 09:54
  • 1
    You might want to audit the systems first. See [Check if a file has certain strings](https://stackoverflow.com/questions/75451639/check-if-a-file-has-certain-strings). – Vladimir Botka Apr 20 '23 at 10:56

1 Answers1

1

To achieve your goal you could use an apporach with Enforcing or preventing check mode on tasks together with Defining failure.

---
- hosts: localhost
  become: false
  gather_facts: false

  tasks:

  - name: Check a service file for changes
    ini_file:
      path: "/home/{{ ansible_user }}/test/test.service"
      section: Service
      option: ExecStart
      value: "service.sh"
    check_mode: true
    register: result

  - name: Report if there would be changes
    debug:
      msg: "{{ result.changed }}"

Looking for a way to make a play or task that checks if general.ini_file or general.lineinfile would cause a change and fail instead.

  - name: Check a service file for changes and fail if
    ini_file:
      path: "/home/{{ ansible_user }}/test/test.service"
      section: Service
      option: ExecStart
      value: "service.sh"
    check_mode: true
    register: result
    failed_when: result.changed

Please take note that this is not an "exact science" and will probably under certain circumstances provide false positives. This can be caused by different syntax and coding styles. See in example "Note that ini_file adds whitespace around = as in ...".

... the go to would be for the play to fail, and for an experienced system administrator to look at the concrete situation to decide how to handle it ...

Right, in that way it could be addressed than.

Similar Q&A

U880D
  • 8,601
  • 6
  • 24
  • 40
  • 1
    Thanks, that worked perfectly for my use case. Two additions that I came across that I ended up implementing: `diff: true` on the `ini_file` task will print the potential changes to the console (with the obvious caveat of possibly leaking secrets), and instead of the `failed_when` flag, an `ansible.builtin.fail`-task with the same condition can be used to provide a more descriptive error message – Torque Apr 20 '23 at 11:45