I need to run a few lines of shell on a remote system, and I find YAML more than awkward to use for this and would prefer to put this into a foo.sh.j2 file instead.
Now I could do the dance:
stat to test if a remote directory exists
create a remote temporary path if said directory does not exist
run the template module with foo.sh.j2 into the remote temporary path if said directory does not exist
run sh path/foo.sh with the command module if said directory does not exist, creating said directory
remove the remote temporary path if said directory did not exist
This is quite the overhead for something that ideally does get executed only once.
You can use the template lookup to build a string from a template using the template lookup:
- name: run shell command from template
ansible.builtin.shell:
cmd: '{{ lookup("template", "foo.sh.j2") }}'
creates: /path/to/said/directory
Please keep in mind this could be dangerous if the template is from an untrusted source, that may be a moot point if it’s stored in the same way as the playbook but if sourced elsewhere this could lead to an injection attack.
The template module evaluates on the control node but using inventory context of the target node, generates the result and transfers it to the remote node for storage which also lets you specify permissions and file attributes. You can then call the “shell” or “command” module as necessary to execute your generated script. It’s two tasks in this fashion, but it depends on what level of detail you want to achieve.
Regardless of which method, you still need the additional “file” module task to delete the file on the target node.
I also assume you’re using the ssh connection type for all this. If you’re using something else, then this may not apply.