Ansible与Python API
Ansible
https://www.ansible.com/
自动化运维的最流行的工具。
Automation for everyone
Simplify work. Break down silos. Speed transformation.
All with an enterprise automation platform.
Simple, agentless IT automation that anyone can use
Ansible is a universal language, unraveling the mystery of how work gets done. Turn tough tasks into repeatable playbooks. Roll out enterprise-wide protocols with the push of a button.
中文:
https://ansible-tran.readthedocs.io/en/latest/index.html
原理
https://www.ansible.com/overview/how-ansible-works
以SSH作为传输通道,推送模块到远程机器, 然后执行此模块,反馈执行结果。
无任何代理agent。
EFFICIENT ARCHITECTURE
Ansible works by connecting to your nodes and pushing out small programs, called "Ansible modules" to them. These programs are written to be resource models of the desired state of the system. Ansible then executes these modules (over SSH by default), and removes them when finished.
Your library of modules can reside on any machine, and there are no servers, daemons, or databases required. Typically you'll work with your favorite terminal program, a text editor, and probably a version control system to keep track of changes to your content.
运行
https://www.ansible.com/overview/how-ansible-works
THE BASICS: USING ANSIBLE FOR AD HOC PARALLEL TASK EXECUTION
Once you have an instance available, you can talk to it right away, without any additional setup:
PLAYBOOKS: A SIMPLE+POWERFUL AUTOMATION LANGUAGE
Playbooks can finely orchestrate multiple slices of your infrastructure topology, with very detailed control over how many machines to tackle at a time. This is where Ansible starts to get most interesting.
---
- yum: name={{contact.item}} state=installed
with_items:
- app_server
- acme_software
- service: name=app_server state=running enabled=yes
- template: src=/opt/code/templates/foo.j2 dest=/etc/foo.conf
notify:
- restart app server
使用如下命令运行 ansible-playbook yaml/httpd.yaml
更多playbook例子
https://github.com/ansible/ansible-examples
模块
https://docs.ansible.com/ansible/latest/modules/modules_by_category.html?extIdCarryOver=true&sc_cid=701f2000001OH7YAAW
- All modules
- Cloud modules
- Clustering modules
- Commands modules
- Crypto modules
- Database modules
- Files modules
- Identity modules
- Inventory modules
- Messaging modules
- Monitoring modules
- Net Tools modules
- Network modules
- Notification modules
- Packaging modules
- Remote Management modules
- Source Control modules
- Storage modules
- System modules
- Utilities modules
- Web Infrastructure modules
- Windows modules
命令行模块
https://docs.ansible.com/ansible/latest/modules/list_of_commands_modules.html
- command – Execute commands on targets
- expect – Executes a command and responds to prompts
- psexec – Runs commands on a remote Windows host based on the PsExec model
- raw – Executes a low-down and dirty command
- script – Runs a local script on a remote node after transferring it
- shell – Execute shell commands on targets
- telnet – Executes a low-down and dirty telnet command
Python API
此API不是正规的API,仅仅是内部的API,可随版本不做兼容性考虑的改变。官方更加推荐 ansible tower,使用 rest api调用。
Ad-hoc
https://docs.ansible.com/ansible/latest/dev_guide/developing_api.html#python-api-2-0
#!/usr/bin/env python import json import shutil from ansible.module_utils.common.collections import ImmutableDict 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.plugins.callback import CallbackBase from ansible import context import ansible.constants as C class ResultCallback(CallbackBase): """A sample callback plugin used for performing an action as results come in If you want to collect all results into a single object for processing at the end of the execution, look into utilizing the ``json`` callback plugin or writing your own custom callback plugin """ def v2_runner_on_ok(self, result, **kwargs): """Print a json representation of the result This method could store the result in an instance attribute for retrieval later """ host = result._host print(json.dumps({host.name: result._result}, indent=4)) # since the API is constructed for CLI it expects certain options to always be set in the context object context.CLIARGS = ImmutableDict(connection='local', module_path=['/to/mymodules'], forks=10, become=None, become_method=None, become_user=None, check=False, diff=False) # initialize needed objects loader = DataLoader() # Takes care of finding and reading yaml, json and ini files passwords = dict(vault_pass='secret') # Instantiate our ResultCallback for handling results as they come in. Ansible expects this to be one of its main display outlets results_callback = ResultCallback() # create inventory, use path to host config file as source or hosts in a comma separated string inventory = InventoryManager(loader=loader, sources='localhost,') # variable manager takes care of merging all the different sources to give you a unified view of variables available in each context variable_manager = VariableManager(loader=loader, inventory=inventory) # create data structure that represents our play, including tasks, this is basically what our YAML loader does internally. play_source = dict( name = "Ansible Play", hosts = 'localhost', gather_facts = 'no', tasks = [ dict(action=dict(module='shell', args='ls'), register='shell_out'), dict(action=dict(module='debug', args=dict(msg='{{shell_out.stdout}}'))) ] ) # Create play object, playbook objects use .load instead of init or new methods, # this will also automatically create the task objects from the info provided in play_source play = Play().load(play_source, variable_manager=variable_manager, loader=loader) # Run it - instantiate task queue manager, which takes care of forking and setting up all objects to iterate over host list and tasks tqm = None try: tqm = TaskQueueManager( inventory=inventory, variable_manager=variable_manager, loader=loader, passwords=passwords, stdout_callback=results_callback, # Use our custom callback instead of the ``default`` callback plugin, which prints to stdout ) result = tqm.run(play) # most interesting data for a play is actually sent to the callback's methods finally: # we always need to cleanup child procs and the structures we use to communicate with them if tqm is not None: tqm.cleanup() # Remove ansible tmpdir shutil.rmtree(C.DEFAULT_LOCAL_TMP, True)
https://ansible-docs.readthedocs.io/zh/stable-2.0/rst/developing_api.html
playbook API
https://gist.github.com/viper233/69dfe7943b076f0d79db
#!/usr/bin/env python # stolen from http://stackoverflow.com/questions/27590039/running-ansible-playbook-using-python-api import os import sys from collections import namedtuple from ansible.parsing.dataloader import DataLoader from ansible.vars import VariableManager from ansible.inventory import Inventory from ansible.executor.playbook_executor import PlaybookExecutor variable_manager = VariableManager() loader = DataLoader() inventory = Inventory(loader=loader, variable_manager=variable_manager, host_list='/tmp/hosts') playbook_path = '/tmp/ls.yml' if not os.path.exists(playbook_path): print '[INFO] The playbook does not exist' sys.exit() Options = namedtuple('Options', ['listtags', 'listtasks', 'listhosts', 'syntax', 'connection','module_path', 'forks', 'remote_user', 'private_key_file', 'ssh_common_args', 'ssh_extra_args', 'sftp_extra_args', 'scp_extra_args', 'become', 'become_method', 'become_user', 'verbosity', 'check']) options = Options(listtags=False, listtasks=False, listhosts=False, syntax=False, connection='local', module_path=None, forks=100, remote_user='stephen', private_key_file=None, ssh_common_args=None, ssh_extra_args=None, sftp_extra_args=None, scp_extra_args=None, become=False, become_method=None, become_user='root', verbosity=None, check=False) variable_manager.extra_vars = {'hosts': 'localhost'} # This can accomodate various other command line arguments.` passwords = {} pbex = PlaybookExecutor(playbooks=[playbook_path], inventory=inventory, variable_manager=variable_manager, loader=loader, options=options, passwords=passwords) results = pbex.run()
中文参考:
https://www.cnblogs.com/franknihao/p/9009110.html 两者都有
https://www.cnblogs.com/wanstack/p/8820889.html playbook
https://www.jianshu.com/p/62b6d2325648 ad-hoc
http://www.iceyao.com.cn/2017/08/31/Ansible-API%E4%BD%BF%E7%94%A8/