I tried to find out how to make a module that works with ansible. I referred to Developing Modules on docs.ansible.com. I actually ran the python sample code posted and checked the behavior of the module. The execution environment is CentOS 7 + ansible 1.9.1.
Describe the path where the module is placed in /etc/ansible/ansible.cfg. Add a line for "library = destination directory".
[Description example]
[defaults]
inventory = /etc/ansible/hosts
library = / root / ansible / modules / # Add
Create the sample code (time.py) described in Developing Modules in the module location described in ansible.cfg.
$ vi /root/ansible/modules/time.py
The contents of the sample code are as follows. You can call the datetime module to set or get the current time. Basic procedures such as importing required classes, parsing methods for parameters passed to modules, and output methods for processing results are described with comments.
#!/usr/bin/python
# import some python modules that we'll use. These are all
# available in Python's core
import datetime
import sys
import son
import os
import shlex
# read the argument string from the arguments file
args_file = sys.argv[1]
args_data = file(args_file).read()
# for this module, we're going to do key=value style arguments
# this is up to each module to decide what it wants, but all
# core modules besides 'command' and 'shell' take key=value
# so this is highly recommended
arguments = shlex.split(args_data)
for arg in arguments:
# ignore any arguments without an equals in it
if "=" in arg:
(key, value) = arg.split("=")
# if setting the time, the key 'time'
# will contain the value we want to set the time to
if key == "time":
# now we'll affect the change. Many modules
# will strive to be 'idempotent', meaning they
# will only make changes when the desired state
# expressed to the module does not match
# the current state. Look at 'service'
# or 'yum' in the main git tree for an example
# of how that might look.
rc = os.system("date -s \"%s\"" % value)
# always handle all possible errors
#
# when returning a failure, include 'failed'
# in the return data, and explain the failure
# in 'msg'. Both of these conventions are
# required however additional keys and values
# can be added.
if rc != 0:
print json.dumps({
"failed" : True,
"msg" : "failed setting the time"
})
sys.exit(1)
# when things do not fail, we do not
# have any restrictions on what kinds of
# data are returned, but it's always a
# good idea to include whether or not
# a change was made, as that will allow
# notifiers to be used in playbooks.
date = str(datetime.datetime.now())
print json.dumps({
"time" : date,
"changed" : True
})
sys.exit(0)
# if no parameters are sent, the module may or
# may not error out, this one will just
# return the time
date = str(datetime.datetime.now())
print json.dumps({
"time" : date
})
The module is transferred to the server to be processed, then executed, and the result is returned in json format.
・ Acquisition of current time
If you execute the module without specifying any parameters, the current time will be output in json format.
[Execution example]
$ ansible localhost -m time -k
SSH password:
localhost | success >> {
"time": "2015-05-23 21:50:50.921787"
}
·Currently set of
If you specify the time with the -a option as a parameter and execute it, the "date -s" command is executed in the module, then the datetime module gets the changed time and the result is output in json format. ..
[Execution example]
$ ansible localhost -m time -k -a "time=21:50:50"
SSH password:
localhost | success >> {
"changed": true,
"time": "2015-05-23 21:50:50.006286"
}
In this case, "changed": true is displayed in the execution result, which indicates that the time has been changed.
・ Operation when an error occurs
If you execute an invalid value (a character string that is not the time) with the -a option as a parameter, the execution of the "date -s" command in the module will fail, and the following error information will be output as the execution result. I will.
[Execution example]
# ansible localhost -m time -k -a "time=hoge"
SSH password:
localhost | FAILED >> {
"failed": true,
"msg": "failed setting the time"
}
In this case, "failed": true is displayed in the execution result, which indicates that the process failed. Also, the reason why the process failed is output to "msg" :.
When executing the sample module from the playbook, write the playbook as follows.
[Description example]
---
- hosts: "{{ target }}"
tasks:
- name: set time
time: time="{{ time }}"
In the tasks: section, describe the module name "time" to be executed and the parameter "time =" {{time}} "to be passed to the module.
When running the playbook, specify the node (target) to run the module and the time (time) to set with the -e option.
[Execution example]
$ ansible-playbook time.yml -k -e "target=localhost time=23:27:00"
SSH password:
PLAY [localhost] **************************************************************
GATHERING FACTS ***************************************************************
ok: [localhost]
TASK: [set time] **************************************************************
changed: [localhost]
PLAY RECAP ********************************************************************
localhost : ok=2 changed=1 unreachable=0 failed=0
A summary of module execution results is output in the playbook execution results.
After testing the sample module, it is highly recommended to set the time back to the correct value with NTP: sweat_smile:
$ ntpdate time.asia.apple.com
Recommended Posts