create a file based on grep result

I want to create a file based on a grep result of another file on the host
It can be achieved with a shell TASK I believe …

  • name: create 10-ssl.conf based on old postgresql.conf
    ansible.builtin.shell:
    cmd: grep ssh /var/lib/pgsql/13/data/postgresql.conf > /var/lib/pgsql/14/data/conf.d/10-ssl.conf

… but am wondering whether there was a more anible-ish way to approach this

From memory and untested:

  • name: “do grep to get a name”command:
    cmd=“grep ssh {{pgconfiguration}}”
    register: grep

  • name: “set the filename”
    setfact:
    filename=grep.stdout

There should be a book on making shell scripts more Ansible-ish. My take on it, below, handles the cases of missing postgresql.conf, missing or pre-existing 10-ssl.conf, and whether your grep pattern is or isn’t found. It also properly sets “changed” and “failed” for the task. The tmp file is removed by the trapped EXIT handler. Note the intentional use of “cat” instead of “cp”; that’s because the tmp file is created with more restrictive permissions than you’ll get with a redirection. If you need more control, add the necessary chmod and chown commands. Also, I moved the pattern and two file names to task variables to facilitate my own testing.

Having said all that, I’d be surprised if there aren’t some corner cases that will still mess things up.

Here ya go:

  - name: Create 10-ssl.conf based on old postgresql.conf
    ansible.builtin.shell: |
      set -e
      [ -f {{ src }} ] || (echo "{{ src }} is missing" >&2 && exit 1)
      function finish {
        [ -z "$tmp" ] ||  rm -f $tmp
      }
      trap finish EXIT
      tmp=$(mktemp)
      grep {{ pat }} {{ src }} > $tmp || (echo "{{ pat }} not found in {{ src }}" >&2 && exit 2)
      set +e
      cmp --silent $tmp {{ tgt }}
      rc=$?
      case $rc in
        0)   echo no-change
             ;;
        1|2) cat $tmp > {{ tgt }}
             echo changed
             ;;
        *)   exit 3
             ;;
      esac
    args:
      executable: /bin/bash
    register: ssl_conf
    changed_when: ssl_conf.stdout_lines is search('changed')
    vars:
      pat: ssh
      src: /var/lib/pgsql/13/data/postgresql.conf  
      tgt: /var/lib/pgsql/14/data/conf.d/10-ssl.conf