I ran across one of Ansible's modules that take free_form arguments along with named arguments - win_command
. A specific example is given, where a powershell script is provided on stdin
:
- name: Run an executable and send data to the stdin for the executable
win_command: powershell.exe -
args:
stdin: Write-Host test
I want to use this as a one-off task, so I want to use ad-hoc execution in the style of
ansible <host> -m <module> -a <args...>
Unfortunately, I see no info in the documentation on how to deal with a module that requires specifying both free_form and named arguments. Does anyone know?
Putting the named arguments after the free_form argument puts everything in the free_form argument, resulting in powershell complaining about extraneous arguments
... -m win_command -a 'powershell - stdin=C:\some\script.ps1 -arg1 value_1 -arg2 value_2'
PS: I'm aware I could probably stuff both the script path and arguments in the free_form argument, but I am more interested in learning whether this is possible with ad-hoc, as the docs don't say either way.
I can't test the win_command
module directly, but with the command
module, which is syntactically very similar, you can reproduce this:
- command: some_command
args:
chdir: /tmp
creates: flagfile
Like this:
ansible -m command -a 'chdir=/tmp creates=flagfile some_command'
Update
Upon investigation...the problem you've encountered with stdin
isn't a quoting issue;
it's that when using the k1=v1 k2=v2 somecommand
format of passing parameters to e.g. the command
module, Ansible only handles specific keys. In lib/ansible/parsing/splitter.py we see:
if check_raw and k not in ('creates', 'removes', 'chdir', 'executable', 'warn'):
raw_params.append(orig_x)
else:
options[k.strip()] = unquote(v.strip())
That is, it only recognizes creates
, removes
, chdir
, executable
, and warn
as module arguments. I would argue that this is a bug in Ansible. Adding support for the stdin
argument is trivial, of course:
if check_raw and k not in ('stdin', 'creates', 'removes', 'chdir', 'executable', 'warn'):
With this change, we can include stdin
with spaces as expected:
$ ansible localhost -m command -a 'chdir=/tmp stdin="Hello world" sed s/Hello/Goodbye/'
[WARNING]: Unable to parse /home/lars/.ansible_hosts as an inventory source
[WARNING]: No inventory was parsed, only implicit localhost is available
localhost | CHANGED | rc=0 >>
Goodbye world