Ansible開発簡明チュートリアル
AnsibleはPython言語を使用していますが、コードの質はかなり高いので、Pythonを使って二次開発を行うのが最も便利で、自分が提供するモジュールや機能は基本的に日常の使用シーンをすべてカバーすることができますが、複雑で業務に密着している場合は、このような複雑な機能をカプセル化し、効率をさらに向上させたいと思っています.これらのカスタマイズのニーズを満たすためにAnsibleを二次開発する必要がある
かいはつモード
python API
Ansibleは実はansibleというpythonモジュールにカプセル化されており、インストールが完了するとpipでこのpythonモジュールが表示されます.したがって、pythonコードの中でimportというモジュールを使用してAnsibleが外部に提供するAPIを呼び出すことができます.典型的にはansibleとansible-playbookの2つのコマンドです.これらは2つのpythonスクリプトで、ansibleモジュールを呼び出すことですべての機能を実現します.
理論的には、スクリプトimportというansibleモジュールを自分で作成することで、すべてのAnsibleの機能を実現することができます.
以下は公式のドキュメントの中の1つの古いバージョンの呼び出しの例で、2.6と以上のバージョンはすでにAPIを大きく変更して、この方面のドキュメントは少なくて、ソースコードを見て理解するしかないようで、もちろんみんなは何か良いドキュメントとリンクがあれば伝言を残すことができます
import ansible.runner
runner = ansible.runner.Runner(
module_name='ping',
module_args='',
pattern='web*',
forks=10
)
datastructure = runner.run()
modules
Ansibleが提供する基礎機能ユニットをモジュールと呼び、playbookを実行する過程は、playbookに記録されているモジュール呼び出しロジックを読み出し、各モジュールを順次呼び出して機能全体を完了することである.
そのため、カスタムモジュールでAnsibleの機能を拡張することができます.
最も便利なカスタムモジュールを拡張する方法は、Ansibleの1級ディレクトリの下にlibraryディレクトリを作成し、カスタムpythonファイルを中に入れることで、playbookで直接この拡張モジュールを使用することができます.もちろん、各roleのディレクトリの下でこのlibraryディレクトリを作成することもできます.この拡張モジュールはこのroleだけで使用できます.もちろん、Ansibleプロファイルを変更してlibraryのパスを指定することもできます.詳細は公式ドキュメントを参照してください.
以下は最も簡単なモジュールの例で、公式の例のtomcat-standaloneに基づいてカスタムモジュールを追加します:hdz_test1
[root@10-10-20-194 tomcat-standalone]# tree
.
├── group_vars
│ └── tomcat-servers
├── hosts
├── library # library
│ ├── hdz_test1.py # python
│ └── __init__.py
├── LICENSE.md
├── README.md
├── roles
│ ├── hdz
│ │ └── tasks
│ │ └── main.yml # playbook
│ ├── selinux
│ │ └── tasks
│ │ └── main.yml
│ └── tomcat
│ ├── files
│ │ └── tomcat-initscript.sh
│ ├── handlers
│ │ └── main.yml
│ ├── tasks
│ │ └── main.yml
│ └── templates
│ ├── iptables-save
│ ├── server.xml
│ └── tomcat-users.xml
├── site.retry
└── site.yml
12 directories, 16 files
#!/usr/bin/env python
# -*- coding:UTF-8
"""
Created on 2018/8/9
Author: hdzhang
Description:
"""
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {
'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'
}
DOCUMENTATION = '''
---
module: hdz_test1
author: hdzhang
short_description: test
version_added: "0.0.1"
description:
- test create file
options:
name:
description:
- name of the create file
required: true
context:
description:
- context of the create file
required: false
default: ""
'''
EXAMPLES = '''
- name: create a file
hdz_test1:
name: "hdz1.txt"
context: "qnmlgb"
'''
RETURN = '''# '''
from ansible.module_utils.basic import AnsibleModule
import datetime
def run_module():
module_args = dict(
name=dict(type='str', required=True),
context=dict(type='str', required=False),
)
module = AnsibleModule(
argument_spec=module_args,
supports_check_mode=True,
add_file_common_args=True,
)
# Gather module parameters in variables
name = module.params.get('name')
context = module.params['context']
result = dict(
changed=False,
stdout='',
stderr='',
rc='',
start='',
end='',
delta='',
)
if module.check_mode:
return result
startd = datetime.datetime.now()
cmd = "echo %s > /root/%s" % (context, name)
rc, out, err = module.run_command(cmd, use_unsafe_shell=True)
endd = datetime.datetime.now()
delta = endd - startd
result = dict(
cmd=cmd,
start=str(startd),
end=str(endd),
delta=str(delta),
rc=rc,
stdout=out.rstrip(b"\r
"),
stderr=err.rstrip(b"\r
"),
changed=True,
)
if rc != 0:
module.fail_json(msg='non-zero return code', **result)
module.exit_json(**result)
def main():
run_module()
if __name__ == '__main__':
main()
---
- name: create a file
hdz_test1:
name: "test.txt"
context: "qnmlgb"
plugins
補足対象
詳細
公式開発文書
Ansibleクラシックの例