例子1:
#!/usr/bin/python
import json
from collections import namedtuple
from ansible.parsing.dataloader import DataLoader
from ansible.vars.manager import VariableManager
from ansible.inventory.manager import InventoryManager
from ansible.playbook.play import Play
from ansible.executor.task_queue_manager import TaskQueueManager
from ansible.executor.task_result import TaskResult
from ansible.plugins.callback import CallbackBase

class ResultCallback(CallbackBase):
	def v2_runner_on_ok(self, result, **kwargs):
		host = result._host
		print(json.dumps({host.name: result._result}, indent=4))

Options = namedtuple('Options', ['connection', 'module_path', 'forks', 'become', 'become_method', 'become_user', 'check', 'diff'])
loader = DataLoader()
options = Options(connection='smart', module_path=None, forks=2, become=None, become_method=None, become_user=None, check=False, diff=False)
#connection参数,如果执行本地节点用'local', 远端节点用'smart'
#passwords = dict(vault_pass='xxxxx')    #密钥方式取消这步
results_callback = ResultCallback()

inventory = InventoryManager(loader=loader, sources=['hosts'])
variable_manager = VariableManager(loader=loader, inventory=inventory)
#variable_manager.set_inventory(inventory)

play_source = dict(
	name = "Ansible Play",
	hosts = 'webserver',
	gather_facts = 'no',
	tasks = [
		dict(action=dict(module='shell', args='df -Th'), register='shell_out'),
	]
)

play = Play().load(play_source, variable_manager=variable_manager, loader=loader)

tqm = None
try:
	tqm = TaskQueueManager(
		inventory=inventory,
		variable_manager=variable_manager,
		loader=loader,
		options=options,
		passwords=None,
		stdout_callback=results_callback,
		)
	result = tqm.run(play)
	print(result)
finally:
	if tqm is not None:
		tqm.cleanup()
		
		
自定义模块	
例子2:
play.yml
---
- hosts: webserver
  tasks:
    - name: Test that my module works
      github_repo:
      register: result
    - debug: var=result
    
 模块github_repo.py   放在/usr/local/lib/python3.6/site-packages/ansible/modules, 
 ansible模块路径
 #!/usr/bin/python
from ansible.module_utils.basic import *
def main():
	module = AnsibleModule(argument_spec={})
	response = {"hello": "world"}
	module.exit_json(changed=False, meta=response)

if __name__ == '__main__':
	main()
	
注:
main() 是你的程序入口
#!/usr/bin/python is 这个是必须的,就和些shell脚本一样
AnsibleModule 是从 ansible.module_utils.basic 总导入的,import * 必须是导入全部的 *
AnsibleModule 有一些已经写好的方法让我们调用,例如exit_json


使用模块
# ansible-playbook play.yml

注:
  在使用ansible-playbook 执行yml文件时,handlers只有在前面动作触发的情况下才能执行
  例如,当copy文件时,只有copy后的文件和copy之前不一样才会触发handlers
  tasks/main.yml
  # copy配置文件到节点服务器    当copy到远程服务器的文件和远程服务器自身的文件相同时,并不会触发notify
  - name: copy file
  copy: src=/data/docker_conf/{{ service_dir }}/ dest=/data/docker_conf/{{ service_dir }}/ backup=no owner=root group=root mode=0644
  notify:
    - exec script    # 修改文件并启动服务
    
  handlers/main.yml
  - name: exec script
  shell: /bin/bash /data/scripts/startup.sh  # 执行远程脚本