Ansible与cmdb配合使用动态inventory
郝朝阳 DevOps视角
Ansible之inventory
在生产中使用Ansible进行批量管理的同志们都应该知道,Ansible使用通过inventory文件来对资产进行管理的。在生产中常用的情形就是维护不止一个inventory文件。但是有了资产管理系统之后,再去维护一堆的inventory文件就不是很好的。没法保证每个inventory文件的有效性。
Ansible的inventory是有静态和动态之分的。静态的inventory就是需要人工维护的的文件。动态的inventory不是生成一个inventory文件,而是把获取的结果直接传递给Ansible的相关命令即可。今天和大家分享下,与cmdb配合动态获取inventory的方法。
编写脚本
由于是和公司cmdb(是由本人开发,可以进行交流)配合起来,调用了cmdb的相关API,所以就只给出部分代码。整体思想是要实现必须支持两个参数--list和--host hostname/ip。并且输出格式必须是json格式。
--list:用于返回所有的主机信息,包括每个主机组的主机信息。同时也可以实现支持children、vars、_meta等
--host hostname/ip:用于返回特定的主机列表
# vim gethosts.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import requests
import json
import sys
import argparse
...以上忽略....
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('--list',action='store_true',dest='list',help='get all hosts')
parser.add_argument('--host',action='store',dest='host',help='get specific host')
args = parser.parse_args()
if len(sys.argv) == 2 and (sys.argv[1] == '--list'):
GroupList()
elif len(sys.argv) == 3 and (sys.argv[1] == '--host'):
HostList(sys.argv[2])
运行脚本
#python gethosts.py --help
usage: gethosts.py [-h] [--list] [--host HOST]
optional arguments:
-h, --help show this help message and exit
--list get all hosts
--host HOST get specific host
# python gethosts.py --list
{
"all": {
"hosts": [
"node1",
"node2",
"node3",
"node4",
"node5",
"node6",
"node7",
"node8",
"node9",
"node10",
"node11",
"node12",
"node13",
"node14"
]
}
}
# python gethosts.py --host node14
{
"ansible_ssh_host": "node14"
}
# chmod +x gethosts.py
与Ansible配合获取主机列表
获取特定主机
# ansible -i gethosts.py node6 --list-hosts
hosts (1):
node6
获取所有主机
# ansible -i gethosts.py all --list-hosts
hosts (14):
node1
node2
node3
node4
node5
node6
node7
node8
node9
node10
node11
node12
node13
node14
Ansible使用动态inventory执行命令
单台主机
# ansible -i gethosts.py node6 -m ping
node6 | SUCCESS => {
"changed": false,
"ping": "pong"
}
所有主机
# ansible -i gethosts.py all -m ping
node1 | SUCCESS => {
"changed": false,
"ping": "pong"
}
node2 | SUCCESS => {
"changed": false,
"ping": "pong"
}
node3 | SUCCESS => {
"changed": false,
"ping": "pong"
}
node4 | SUCCESS => {
"changed": false,
"ping": "pong"
}
node5 | SUCCESS => {
"changed": false,
"ping": "pong"
}
node6 | SUCCESS => {
"changed": false,
"ping": "pong"
}
node7 | SUCCESS => {
"changed": false,
"ping": "pong"
}
node8 | SUCCESS => {
"changed": false,
"ping": "pong"
}
node9 | SUCCESS => {
"changed": false,
"ping": "pong"
}
node10 | SUCCESS => {
"changed": false,
"ping": "pong"
}
node11 | SUCCESS => {
"changed": false,
"ping": "pong"
}
node12 | SUCCESS => {
"changed": false,
"ping": "pong"
}
node13 | SUCCESS => {
"changed": false,
"ping": "pong"
}
node14 | SUCCESS => {
"changed": false,
"ping": "pong"
}
在实际运行中并不是这么有序的。
实际运行图
指定主机
所有主机
动态inventory在Ansible的api(虽然不想提Ansible的api)里也可以进行使用。