I'm using programatically generated Ansible playbooks. In general, because playbooks are just YAML, this is straightforward. However, when using the "simple" key=value
form, playbooks aren't pure YAML -- they include content embedded a shlex
-parsable form.
To avoid the ambiguity in this form (is that key=value
pair an argument to the command or an argument for ansible?), and have only a single format to parse and generate, I'm unconditionally using the complex args mechanism demonstrated by example in the ansible-examples repository.
This uses a syntax of the following kind:
action: module-name
args:
key1: value1
key2: value2
...which is well and good. However, when trying to use this form for the shell
or command
modules (whose documentation describes the actual command as being passed in an argument named free_form
), this doesn't work so well:
action: shell
args:
free_form: echo hello_world >/tmp/something
creates: /tmp/something
When invoked, this runs the following:
/bin/sh -c " free_form='echo hello_world >/tmp/something' "
...which is very much not what I'm trying to accomplish.
What's the right way to use Ansible modules taking "free-form" commands using pure YAML syntax?
Short answer: Don't use the
command
,raw
,script
, orshell
modules. Write your own module that accepts the command as a "normal" argument.Long answer:
In most cases, you can do this:
However, this fails in some edge cases:
I don't know of a general way to handle this, but a bash-specific solution is:
This is addressed in the Ansible documentation now.
Note that there is no parameter named 'free_form'.