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