There are moments when you want Ansible to stop printing anything own and just to show output of the remote command.
Like ssh user@server command
, but with all Ansible bells and whistles, with custom ssh arguments, transports, etc, etc.
I'm talking about the ansibile
binary, not the ansible-playbook
, although, with some tinkering, it's possible to use this trick with ansible-playbook
too.
Foundation for tricks:
- Use raw module (disaANSIBLE_LOAD_CALLBACK_PLUGINS=1 ANSIBLE_STDOUT_CALLBACK=json ansible -i localhost, -m raw -a 'cat /etc/passwd' all -c local | jq -r '.plays[].tasks[].hosts | to_entries[] | "(.key):\n(.value.stdout)\n"'bles AnsiballZ mechanism)
- Use json output (which allow to extract stdout without using unsound grep expressions).
- Process it with jq.
- Ask jq not to print quotes for string value.
Here it is:
ANSIBLE_LOAD_CALLBACK_PLUGINS=1 \
ANSIBLE_STDOUT_CALLBACK=json \
ansible -i localhost, -m raw -a 'cat /etc/passwd' all -c local \
| jq -r '.plays[].tasks[].hosts[]?.stdout'
Disection:
- Env variables says ansible to load callback plugins and to use json callback plugin (output).
-
-i localhost,
and-c local
are not important. Use a proper inventory here if you need. localhost here just for an example. -
-m raw -a command
is usual ansible invocation -
-r
for jq removes quotes from a string. - Expression
.plays[].tasks[].hosts[]?.stdout
scans all hosts in all tasks for all plays and prints stdout.
Why do you need it?
Well, the thing I wanted to do was to get a secret file from a remote server and encrypt it locally on the host using sops. I can use community.sops.sops_encrypt
module, but it require multiple steps to do, and secrets are nasty to debug, so I don't want to do those steps.
A 'simple' ansible call with | sops -e
is require less attention.
But, it requires this 'pristine output' from ansible to avoid mangling the content, so, I had to invent this quirk.
Top comments (0)