I understand writing the module in Python and using Python > 2.6 is the best way forward, but I have a lot of older Linux/Unix servers and have restriction on installing any new packages on them. In addition, the environment also have a few network devices that only support SSH and basic shell. I had been using the “raw” module, but I would like to write/reuse some of my current shell script (in BASH), and convert them into ansible module. Is that possible?
To help with more fancy JSON operations in bash, the most impressive
thing I've found is this: https://github.com/kristopolous/TickTick
However, it does some kind of on-the-fly rewriting of the script as it
is run, so you need to use it from a script file. It won't work in an
interactive shell, and it might not work for Ansible.
I am not sure whether there is any document on writing BASH/SH module in
ansible, but I did found a few example. But I would like to know what is
return value for JSON
You should be able to get by, either by printing JSON to stdout, or
doing something like this:
Hi JP,
Yes, I know about these few variables from your sample shell script module
But I am actually looking for a complete list of JSON returned variable, and the meaning of them.
Hi Andreas,
Thanks. I had used the sample shell script module from JP to do some testing and experiment, and I would like to findout whether there is something documented on the JSON variables which I can use to “echo” or “print” from the shell script module.
I got a number of shell scripts, which I usually use to update the remote hosts via ssh, and I am trying to make them ansible-module so that it can be reuse and I can also contribute back to the project.
Hi JP,
Yes, I know about these few variables from your sample shell script module
But I am actually looking for a complete list of JSON returned variable,
and the meaning of them.
You can return whatever data you want. There are really very few that have
any special meaning, everything else is up to the module to define and the
user to use. The special ones are:
- failed=True, indicating that the action failed
- skipped=True, indicating a pre-condition for running the task was already
met
- changed=True/False, indicating the task changed/didn't change something,
used to trigger notifiers and coloring of the output.
- ansible_facts=<dict>, containing custom facts that will be usable as
variables in following tasks
- stdout=<str>, containing text output. Will be split into lines that can be
used if register'd
- msg, used for e.g. failure messages
An additional tip -- If you want to read the arguments to a module,
they are in key=value format, and can be read by parsing the file
given as the first argument ($1) to the module script
Also also -- there is no reason to return changed if nothing has
changed, or failed if nothing has failed, ansible assumes the value of
these variables is no unless otherwise specified.
the JSON here document is a pretty good idea for bash.
Python modules have a slight leg up in they can use the common core
(and are faster, due to some clever tricks), but things like Ruby and
Perl can at least use available JSON libraries to help them along.
The arguments are still key=value though, and not JSON, as they are
passed from the playbook or CLI across relatively raw.
* Michael DeHaan <michael.dehaan at gmail.com> [2012/12/18 20:37]:
An additional tip -- If you want to read the arguments to a
module, they are in key=value format, and can be read by parsing
the file given as the first argument ($1) to the module script
Actually, you don't even need to parse the args; the key=value
format they use is valid sh variable syntax. All you need to do is
source $1, and the variables become available in your env.
Michael DeHaan <michael.dehaan at gmail.com> [2012/12/18 20:37]:
An additional tip – If you want to read the arguments to a
module, they are in key=value format, and can be read by parsing
the file given as the first argument ($1) to the module script
Actually, you don’t even need to parse the args; the key=value
format they use is valid sh variable syntax. All you need to do is
source $1, and the variables become available in your env.
Sweet! Killer feature I didn’t even plan for
Sorry if I jump into this old discussion, but I’m a new user and I am as well starting to develop some ansible modules, so I would like to contribute.
I’ve noticed that the module acts a bit differently if you call it from ansible or from ansible-playbook: in the first case the module script is called with all the arguments on the command line, while in the latter it’s called with just one argument which is a file containing the module arguments.
In my module script I’ve therefore added the following at the beginning:
[ -f $1 ] && source $1 || eval $*
in order to make it work with both ansible and ansible-playbook.
Moreover, I usually use the following syntax to print json structures:
does ansible gives a special meaning to the exit status of the script? If I exit with 0 or 1 is it the same for ansible as long as the output is json-ized and meaningful?
is the standard error ignored by ansible?
does ansible set any environment variable the module can access, like variables or group names?
is there a way to show the module documentation using ansible-doc.
.a.
P.S. I know the preferred way to develop modules is using Python, but sometimes a shell script is a lot easier and faster to write, and since ansible is so wonderful to allow you to do it…
"I've noticed that the module acts a bit differently if you call it
from `ansible` or from `ansible-playbook`: in the first case the
module script is called with all the arguments on the command line,
while in the latter it's called with just one argument which is a file
containing the module arguments."
This actually isn't the case, it is true when you write non-python
modules you get the arguments file.
To answer other questions, modules do not see any variables -- this is
a basically a security feature, only arguments you pass to modules get
sent to modules, there is a principle of 'least data exchange'. (Same
reason we don't have a fileserver).
exit codes are not important, but a script should always return 0 and
returned failed=1 (or True) in the JSON on failure.
Ansible also supports "baby JSON" which is just a list of key=value
pairs, so you don't technically have to output JSON.
non-Python modules won't work with ansible-doc currently.