ansible

How can I define changed_when based on file content?


I have a few installations on our servers and workstations, which are executed via proprietary setup scripts, for example MATLAB.

Do keep the idempotency I would like to analyze the log file, which is created in the process. How can I define the changed_when based on the content of those log files?

So for example the command task would look like the following at the moment:

- name: Run MATLAB installer
  ansible.builtin.command:
    argv:
      - /mnt/matlabiso/install
      - -inputFile
      - /mnt/downloads/Software/MATLAB/R2024a/installer_input_linux.txt
  changed_when: false

So this command creates a log file at /tmp/ML2024.log, which has the line "Succesful installed" as the last line or "Installation failed" if it was not succesfull. The command itself if remember correctly mostly never fails.

If I understand my linter correctly, changed_when: false and than reading the content of the log file and printing via debug is not a real idempotent way of calling a command, since the changes are already done with the command.

So the actual Question: Did I miss a way how command is able to treat file content, without creating a custom script, which is executing and setup and reading the content afterwards.


Solution

  • Q: "To keep the idempotency I would like to analyze the log file, which is created in the process."

    Still, this looks like a job for Custom facts for me.

    Q: "How command is able to treat file content, without creating a custom script, which is executing and setup and reading the content afterwards?"

    It isn't and it wasn't made for that. See command module – Execute commands on targets - Notes and at least "Use the ansible.builtin.shell module if you need these features."

    Q: "This command creates a log file at /tmp/ML2024.log, which has the line Succesful installed as the last line or Installation failed if it was not succesfull."

    That sounds more like Define failure and the status of failed_when, because it doesn't tells if it was already installed before or not. See a minimal example playbook

    ---
    - hosts: localhost
      become: false
      gather_facts: false
    
      tasks:
    
        - shell:
            cmd: echo 'Installation failed' > /tmp/ML2024.log | grep 'Succesful installed' /tmp/ML2024.log
          register: result
    
        - debug:
            var: result
    

    resulting into an output of

    TASK [shell] *******************************************************************
    fatal: [localhost]: FAILED! => changed=true
      cmd: echo 'Installation failed' > /tmp/ML2024.log | grep 'Succesful installed' /tmp/ML2024.log
      delta: '0:00:00.007761'
      end: '2024-11-12 09:30:00.347773'
      msg: non-zero return code
      rc: 1
      start: '2024-11-12 09:30:00.340012'
      stderr: ''
      stderr_lines: <omitted>
      stdout: ''
      stdout_lines: <omitted>
    

    Just Registering result and check on Common Return Values will already provide some of the capabilities in question.