I am a person who works every day as an infrastructure engineer at a certain company to create ansible roles and playbooks. I've only been ansible for half a year, but nowadays I'm finally getting used to development and operation. He said that he wanted the work that came in during that time to create an "original module."
Many modules are implemented in ansible. (Refer to the official website: http://docs.ansible.com/ansible/list_of_all_modules.html) However, this request is a requirement that the existing modules as described above do not support. Programming experience is a newcomer who just started python from a month ago. At first, I was worried whether I could really do a cool job of creating my own module.
I was worried, but!
Ansible modules were surprisingly easy to create. The hurdle is not high if you just make it. However, since the original module is separate from ansible If you don't know how to call the variables defined on the ansible side, You may suffer from uncallable stress.
It's been a long time, but the main subject is from here.
On this page, to counter such stress Here's how to call variables that beginners will stumble upon.
・ CentOS 7.2 -Python 2.7.5
First, prepare your own module storage area. Create a "library" directory in your playbook.
ansible-test-playbook
|_test-server.yml
|_group_vars
|_host_vars
|_vars
|_inventory
|_roles
|_role_test
|_defaults
|_main.yml
|_tasks
|_main.yml
|_templates
|_library ⬅︎new!
|_test.py ⬅︎new!
Now that we're ready, let's create our own module. A simple shell script will work, but This time, I will mainly write the method of "reading and executing the variable declared on the ansible side on the module side".
In ansible, variables once described can be used freely by calling them. However, if you try to call it as it is on the original module side, it will not work. Therefore, it is necessary to specify the variable you want to call with task and bring it to your own module. In the following, we will describe how to bring the variable to the original module and return the execution result to the ansible side.
Declare the variable you want to call this time with defaults as follows. (How to write variables is omitted on this page)
main.yml
un: "Hello"
deux: "World"
Next, prepare the task. In task, write as follows.
main.yml
- name: get hello world
test: # .Original module name to be executed excluding py
un: "{{ un }}" #Variables you want to use in your own module
deux: "{{ deux }}"
register: cinq #Variable name to store the execution result of the original module
Now let's create a module. Create a file called "test.py" in the library directory.
test.py
#!/usr/bin/env python
# coding: utf-8
#Import what you need
import json, urllib2
from ansible.module_utils.basic import *
def main():
#It's like a spell to get information from vars
#At this time, write the variable name so that it matches the one declared in task.
module = AnsibleModule(
argument_spec=dict(
un=dict(required=True, type='str'),
deux=dict(required=True, type='str')
),
# no skip
supports_check_mode=True,
)
#Store the information obtained above and make it available in the module
un = module.params['un']
deux = module.params['deux']
#What to do with this module
trois = un + deux
#Store execution results in dictionary type
#Ansible described later_This form is mandatory as facts are made in a dictionary format
quatre = {"quatre": trois}
#Pass the execution result to the ansible side
module.exit_json(changed=True, ansible_facts=quatre)
if __name__ == '__main__':
main()
Now that you're ready, let's do the above.
PLAYBOOK: test-server.yml ********************************************************
1 plays in test-server.yml
PLAY [all] *********************************************************************
TASK [setup] *******************************************************************
ok: [localhost]
TASK [role-test : get hello world] *******************************************
changed: [localhost] => {
"ansible_facts": {
"quatre": "HelloWorld"⬅︎ Execution result
},
"changed": true,
"invocation": {
"module_args": {
"deux": "World",
"un": "Hello"
},
"module_name": "test"
}
}
You can see that the execution result of the original module is stored in ansible_facts. Then, how should I write to call the execution result on the ansible side this time?
"{{ cinq.ansible_facts.quatre }}"
"Variable name specified by register in task. Ansible_facts. Dictionary type key declared in original module" If you write this way, you can use the execution result in ansible.
This is the end of the work.
How was that? We hope that it will be useful to those who have fallen into such troubles.
I will continue to touch on ansible and python, so I would like to post if there is new learning.
Thank you for visiting.
Recommended Posts