[PYTHON] [Ansible] How to call variables when creating your own module

Introduction

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.

environment

・ CentOS 7.2 -Python 2.7.5

Preparation

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.

Create defaults / main.yml

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"

Create tasks / main.yml

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

Create your own 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()

Run

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.

Afterword

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

[Ansible] How to call variables when creating your own module
How to create your own Transform
(Note) How to pass the path of your own module
To import your own module with jupyter
How to install your own (root) CA
How to define your own target in Sage
[Ansible] I want to call my own function from the template module (macro)
How to run the Ansible module added in Ansible Tower
[Introduction to Udemy Python 3 + Application] 66. Creating your own exceptions
[Ansible] How to use SSH password authentication when executing ansible
Call your own python module from the ROS package
How to call a function
How to use pyenv and pyenv-virtualenv in your own way
How to define Go variables
Try HeloWorld in your own language (with How to & code)
How to output additional information when logging with python's logging module
How to put the string JSON passed as a parameter into the dictionary when writing Ansible module
Make the theme of Pythonista 3 like Monokai (how to make your own theme)
How to make your own domain site with heroku (free plan)
[Tips] How to do template extends when creating HTML with django
How to use the optparse module
[Python] logging in your own module
How to use Python's logging module
[Ansible] How to prevent forced change
How to add sudo when debugging
Bridge ROS to your own protocol
How to use the ConfigParser module
How to call PyTorch in Julia
When using the zap library in your own Logger with Golang, how to put the hierarchy above Logger in Caller
How to call when using double underscore (Private attribute) for class function
[python] How to add RDF triples to your own Fuseki server using rdflib
[Introduction to pytorch-lightning] How to use torchvision.transforms and how to freely create your own dataset ♬
How to access data with object ['key'] for your own Python class
How to build my own Linux server
Add your own content view to mitmproxy
How to access environment variables in Python
[Python] Use and and or when creating variables
[Python] How to display random numbers (random module)
How to dynamically define variables in Python
python3 How to install an external module
How to get IP when Tornado + nginx
Migrate your own CMS data to WordPress
How to add python module to anaconda environment
[Python] How to deal with module errors
How to use TouchDesigner Python's external module
[For recording] Keras image system Part 1: How to create your own data set?
[Linux] [kernel module] How to pass parameters as arguments when loading a loadable kernel module