21. 动态Inventory管理
目录
动态主机管理模块
add_host
在playbook执行的过程中,动态的添加主机到指定的主机组中
常用参数:
groups:添加主机至指定的组
name:要添加的主机名或IP地址
示例:
- name: add a host to group webservers hosts: webservers tasks: - add_host: name: "{{ item }}" group: webservers foo: 42 #添加主机到webservers组中,主机的变量foo的值为42 loop: - host1 - host2 - debug: msg: "{{ groups.webservers }}"
group_by
在playbook执行的过程中,动态的创建主机组
示例:
- name: Create operating system group hosts: all tasks: #在playbook中设置一个新的主机组 - group_by: key: "os_{{ ansible_distribution }}" - name: Run on CentOS hosts only hosts: os_CentOS tasks: - name: Install Apache yum: name: httpd state: latest - name: Run on Ubuntu hosts only hosts: os_Ubuntu tasks: - name: Install Apache apt: name: apache2 state: latest
动态inventory管理
动态inventory简介
在前面我们所有的选取主机组的操作都是通过维护inventory文件来完成的。而事实上,当在大规模应用当中,如果主机达成千上万台,这个时候还手动维护inventory文件将会给运维工作带来巨大的挑战。
在这种大规模的应用场景中,通常的做法是,将所有的主机都存储在cmdb当中。当需要对某一组主机或者某一类型的主机执行相应操作时,通过cmdb将相应主机取出来,动态的生成inventory,然后交由ansible处理即可。
所以其实Ansible Inventory包含静态inventory和动态inventory两部分。而我们前面通过手动在inventory文件中维护主机列表的方式即称之为静态inventory。而动态inventory则是指通过外部脚本获取主机列表,并按照ansible所要求的格式返回给ansible指令的操作方式。
动态inventory一般都会结合cmdb或者云计算平台等获取主机信息,由于主机资源一般会动态的进行增减,而这些系统一般会智能更新。我们需要通过这些工具提供的api或者接入库查询等方式返回主机列表。
动态inventory脚本规约
动态inventory脚本最终返回的满足ansible输出格式的json数据。ansible对于使用什么语言来实现动态inventory没有要求。但脚本必须支持两个参数:
--list:用于返回所有的主机组信息,每个组所包含的主机列表hosts、子组列表children、主机变量列表vars都应该是字典形式的,而
_meta
则用于存放主机变量--host \
:返回指定主机的变量列表,也可返回一个空字典
动态inventory脚本示例
#cat dynamic_inventory.py #!/usr/bin/env python # coding: utf-8 import os import sys import argparse try: import json except ImportError: import simplejson as json class ExampleInventory(object): def __init__(self): self.inventory = {} self.read_cli_args() # Called with `--list`. if self.args.list: self.inventory = self.inventory_groups() # Called with `--host [hostname]`. elif self.args.host: # Not implemented, since we return _meta info `--list`. self.inventory = self.inventory_hosts(self.args.host) # If no groups or vars are present, return empty inventory. else: self.inventory = self.empty_inventory() print json.dumps(self.inventory); # Example inventory for testing. def inventory_groups(self): return { "webserver": # 定义webserver组 { "hosts": ["10.10.0.112"], # webserver 组内主机 "vars": { # 组变量 "ansible_ssh_pass": "123456", # Inventory 内置变量 "ansible_ssh_port": "27100" } }, "dbserver": { "hosts": ["10.10.0.109"], "vars": { "ansible_ssh_pass": "123456", "ansible_ssh_port": "27100" } }, '_meta': { 'hostvars': { '10.10.0.112': { 'host_specific_var': 'foo' }, '10.10.0.109': { 'host_specific_var': 'bar' } } } } def inventory_hosts(self,host): if host == "10.10.0.112": return { '_meta': { 'hostvars': { '10.10.0.112': { 'host_specific_var': 'foo' } } } } elif host == "10.10.0.109": return { '_meta': { 'hostvars': { '10.10.0.109': { 'host_specific_var': 'bar' } } } } else: return {'_meta': {'hostvars': {}}} # Read the command line args passed to the script. def read_cli_args(self): parser = argparse.ArgumentParser() parser.add_argument('--list', help="list hosts", action = 'store_true') parser.add_argument('--host', help="display hostvars for host",action = 'store') self.args = parser.parse_args() # Get the inventory. ExampleInventory()
脚本需要设置x
权限,否则ansible会提示没有权限调用:
chmod +x ./dynamic_inventory.py
执行该脚本,返回如下:
# ./dynamic_inventory.py --list {"webserver": {"hosts": ["10.10.0.112"], "vars": {"ansible_ssh_port": "27100", "ansible_ssh_pass": "123456"}}, "_meta": {"hostvars": {"10.10.0.112": {"host_specific_var": "foo"}, "10.10.0.109": {"host_specific_var": "bar"}}}, "dbserver": {"hosts": ["10.10.0.109"], "vars": {"ansible_ssh_port": "27100", "ansible_ssh_pass": "123456"}}} # ./dynamic_inventory.py --host 10.10.0.109 {"_meta": {"hostvars": {"10.10.0.109": {"host_specific_var": "bar"}}}} # ./dynamic_inventory.py --host 192.168.0.1 {"_meta": {"hostvars": {}}}
通过ansible操作示例如下:
# ansible -i dynamic_inventory.py webserver --list-hosts hosts (1): 10.10.0.112 # ansible -i dynamic_inventory.py all --list-hosts hosts (2): 10.10.0.112 10.10.0.109