Ansible Module in Bash

Create custom Ansible modules using BASH & Linux shell.

Overview

Normally Ansible modules are built using its native python. However, using its JSON API it's possible to make just about any programming language, or even in this case shell that can create JSON to work as an ansible module.

Environment

For developing shared resources like this it can be helpful to have a library directory. Go to your working directory where most code is stored, and create a library directory.

mkdir $PROJECTS_DIRECTORY/lib

Create Module File

Next create the script file using coreutil touch. It will be called os_type.sh because its purpose is to check the Ansible controlled host for what type of OS it is.

touch $PROJECT_DIRECTORY/lib/os_type.sh

Edit the Module Script

#!/bin/bash 

OS="$(uname)"

echo "{ \"changed\": false, \"operating_system\": \"$OS\" }"

The code is pretty simple. It gets the OS from the coreutil command uname. Then the magic to make it work with Ansible, it has to spit out properly formatted JSON when ansible calls it to stdout.

The JSON that Ansible expects can be of any magic variable that ansible uses. Particularly changed is important because it determines how Ansible informs the state of the task running this module. Next is the ansible variable that will be output from this task, operating_system. This is custom for this module and any desired output variable can be defined for the module to be accessed by tasks later.

Using the Module in Ansible

For the sake of practice, create a module_test.yml play to test out the module.

touch module_test.yml

Then edit the play to use the os_type module just created.

---
- hosts: localhost
tasks:
- name: Testing our bash-based module
os_type:
register: result
- name: Debug the var created from the bash-based module
var: result

The Expected Output of an Ansible Module

Running the above play, should return something like this:

ansible-playbook -i hosts module_test.yml
PLAY [127.0.0.1] ***************************************
TASK [Gathering Facts] *********************************
ok: [127.0.0.1]
TASK [testing our new module] **************************
ok: [127.0.0.1]
TASK [debug] *******************************************
ok: [127.0.0.1] => {
"result": {
"changed": false,
"failed": false,
"meta": {
"operating_system": "Linux"
}
}
}
PLAY RECAP **********************************************
127.0.0.1: ok=3 changed=0 unreachable=0 failed=0

References