ansible을 사용하다보면, 여러가지 제약 사항을 맞닥들이게 되는데 그러다 보면 custom module을 만들 때가 생기는데, 이에 대한 간단한 가이드를 만든다.

Ansible custom module 만들기

Ansible을 통해 배포를 진행할 때, roles를 구성해서 만든다.
이때 roles 하위에 component를 생성하는데, "library" 디렉토리를 생성하고 custom module을 만들면 된다.

이번에 예제로 만든 것은 Dictionary 데이터와 key(string) 데이터를 받아서 key가 존재하면 데이터를 반환하면 모듈이다.

디렉토리 구조는 아래와 같다.

# tree
.
├── custom-playbook.yml
├── inventory
└── roles
    └── custom_module
        ├── library
        │   └── findkeyindicts.py
        ├── tasks
        │   └── main.yml
        └── vars
            └── main.yml

 

Custom module 이름은 "findkeyindicts"이며, "roles/custom_module/library/findkeyindicts.py" 위치에 파일을 생성한다.

library/findkeyindicts.py 

#!/usr/bin/python
from ansible.module_utils.basic import AnsibleModule
import json

def main():
    module = AnsibleModule(
        argument_spec=dict(
            data=dict(type='dict', required=True),
            key=dict(type='str', required=True),
        ),
        supports_check_mode=True
    )

    result_dict = dict(checking=False)

    input_dict = module.params['data']
    checked_key = module.params['key']

    if checked_key in input_dict:
        result_dict['checking'] = True
        result_dict['data'] = input_dict[checked_key]

    module.exit_json(changed=False, meta=result_dict)

if __name__ == '__main__':
    main()

 

tasks에서 사용할 변수를 "roles/custom_module/vars/main.yml"에 아래와 같이 정의한다.

vars/main.yml 

address:
  "192.168.122.91":
    hostname: "gitlab-test"
    installpkg:
      - "nmon"
      - "htop"
  "192.168.122.92":
    hostname: "gitlab-new"
    installpkg:
      - "nmon"
      - "htop"

 

아래와 같이 "roles/custom_module/tasks/main.yml" 파일을 생성한다.

tasks/main.yml 

- name: Execute custom Ansible module with dictionary
  findkeyindicts:
    data: '{{ address }}'
    key: '{{ ansible_default_ipv4.address }}'
  register: result_out

- name: full data of result_out
  debug:
    var: result_out

- name: debug 2 use when
  debug:
    msg: "result_out is {{ result_out.meta }}"

 

ansible-playbook을 실행하기 위해 아래와 같이 간단하게 inventory, playbook을 작성한다.

inventory

192.168.122.91 ansible_connection=ssh ansible_ssh_user=root ansible_ssh_private_key_file=~./ssh/id_rsa

playbook

---
- name: custom module tets
  gather_facts: true
  hosts: all
  become: true
  roles:
    - role: custom_module

 

ansible을 실행한 결과 화면은 아래와 같다.

# ansible-playbook -i inventory custom-playbook.yml

PLAY [custom module tets] *********************************************************************************************************************

TASK [Gathering Facts] ************************************************************************************************************************
ok: [192.168.122.91]

TASK [custom_module : Execute custom Ansible module with dictionary] **************************************************************************
ok: [192.168.122.91]

TASK [custom_module : full data of result_out] ************************************************************************************************
ok: [192.168.122.91] => {
    "result_out": {
        "changed": false,
        "failed": false,
        "meta": {
            "checking": true,
            "data": {
                "hostname": "gitlab-test",
                "installpkg": [
                    "nmon",
                    "htop"
                ]
            }
        }
    }
}

TASK [custom_module : debug 2 use when] *******************************************************************************************************
ok: [192.168.122.91] => {
    "msg": "result_out is {'checking': True, 'data': {'hostname': 'gitlab-test', 'installpkg': ['nmon', 'htop']}}"
}

PLAY RECAP ************************************************************************************************************************************
192.168.122.91             : ok=4    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

 

이를 통해 ansible의 제약사항을 어느 정도 피해가도록 해보는 방안도 좋을 것 같다.