受控主机比较少的情况下,建议是使用静态主机清单的,但当我们处于一个大型的环境下,受控主机非常非常多的时候,而且受控主机更替非常快的时候,我们使用静态主机清单就很难来管理了,我们使用动态的主机清单更便于我们管理了。
Ansible支持动态清单脚本,这些脚本在每当ansible执行时从这些类型的来源检索当前的信息,使清单能够实时得到更新。这些清单脚本是可执行的程序,能够从一些外部来源收集信息,并以JSON格式输出清单。
可以通过ansible-inventory -i 主机清单文件 --list
命令,将主机清单以JSON的格式显示出来
[student@ansible ansible]$ vim inventory
node1 myvar=111
[net]
node2
[webserver:children]
net
[student@ansible ansible]$ ansible-inventory -i inventory --list
"_meta": { //_meta下记录着我们主机中是否定义变量
"hostvars": {
"node1": {
"myvar": "111"
}
}
},
"all": { // all:列出我们所有的主机组
"children": [
"ungrouped",
"webserver"
]
},
"net": { //net主机组下的成员
"hosts": [
"node2"
]
},
"ungrouped": { //ungrouped主机组就是不属于任何主机组的主机的
"hosts": [
"node1"
]
},
"webserver": {
"children": [
"net"
]
}
}
例:
[student@ansible ansible]$ vim inventory.py
#!/usr/bin/env python3
'''
Example custom dynamic inventory script for Ansible, in Python.
'''
import os
import sys
import argparse
import json
class ExampleInventory(object):
def __init__(self):
self.inventory = {}
self.read_cli_args()
# Called with `--list`.
if self.args.list:
self.inventory = self.example_inventory()
# Called with `--host [hostname]`.
elif self.args.host:
# Not implemented, since we return _meta info `--list`.
self.inventory = self.empty_inventory()
# 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 example_inventory(self):
return {
'net': {
'hosts': ['node1'],
'vars': {
'mytest_var1': 'hello1',
'mytest_var2': 'hello2',
'mytest_common': 'hello_common'
}
},
'hr': {
'hosts': ['node2'],
'vars': {
'mytest_var3': 'hello3',
'mytest_common': 'hello_common'
}
},
'_meta': {
'hostvars': {
'node1': {
'host_specific_var': 'foo100'
},
'node2': {
'host_specific_var': 'bar101'
}
}
}
}
# Empty inventory for testing.
def empty_inventory(self):
return {'_meta': {'hostvars': {}}}
# Read the command line args passed to the script.
def read_cli_args(self):
parser = argparse.ArgumentParser()
parser.add_argument('--list', action = 'store_true')
parser.add_argument('--host', action = 'store')
self.args = parser.parse_args()
# Get the inventory.
ExampleInventory()
[student@ansible ansible]$ cat test.yml
---
- hosts: all
tasks:
- name: debug test1
debug:
msg: "just for test ansible dynamic inventory"
- name: debug test2
debug:
msg: "{{ mytest_common }}"
首先需要给hosts.py这个动态的主机清单一个执行的权限,因为它是一个脚本。
chmod +x inventory.py
执行playbook两种方法:
一:ansible-playbook test.yml -i inventory.py
手动指定使用哪个主机清单
二:修改ansible.cfg配置文件 Inventory = /home/student/ansible/inventory.py
执行playbook
[student@ansible ansible]$ ansible-playbook test.yml
PLAY [all] *********************************************************************
TASK [Gathering Facts] *********************************************************
ok: [node1]
ok: [node2]
TASK [debug test 1] ************************************************************
ok: [node1] => {
"msg": "just for test ansible dynamic inventory"
}
ok: [node2] => {
"msg": "just for test ansible dynamic inventory"
}
TASK [debug test 2] ************************************************************
ok: [node1] => {
"msg": "hello_common"
}
ok: [node2] => {
"msg": "hello_common"
}
PLAY RECAP *********************************************************************
node1 : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
node2 : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
使用动态清单模板,修改其内容,要求如下:
(1)node1是test主机组的成员,其中test主机组可以使用变量:
aa=11
bb=22
(2)node2和node3是prod主机组的成员,其中prod主机组可以使用的变量:
cc=33
dd=44
(3)node1还可以使用的变量:nodevar=test1
(4)node2还可以使用的变量:nodevar=test2
(5)node3还可以使用的变量:nodevar=test3
(6)撰写一个test.yml的playbook,要求所有的受控主机输出变量nodevar的值
[student@ansible ansible]$ vim inventory.py
#!/usr/bin/env python3
'''
Example custom dynamic inventory script for Ansible, in Python.
'''
import os
import sys
import argparse
import json
class ExampleInventory(object):
def __init__(self):
self.inventory = {}
self.read_cli_args()
# Called with `--list`.
if self.args.list:
self.inventory = self.example_inventory()
# Called with `--host [hostname]`.
elif self.args.host:
# Not implemented, since we return _meta info `--list`.
self.inventory = self.empty_inventory()
# 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 example_inventory(self):
return {
'test': {
'hosts': ['node1'],
'vars': {
'aa': '11',
'bb': '22'
}
},
'prod': {
'hosts': ['node2','node3'],
'vars': {
'cc': '33',
'dd': '44'
}
},
'_meta': {
'hostvars': {
'node1': {
'nodevar': 'test1'
},
'node2': {
'nodevar': 'test2'
},
'node3': {
'nodevar': 'test3'
}
}
}
}
# Empty inventory for testing.
def empty_inventory(self):
return {'_meta': {'hostvars': {}}}
# Read the command line args passed to the script.
def read_cli_args(self):
parser = argparse.ArgumentParser()
parser.add_argument('--list', action = 'store_true')
parser.add_argument('--host', action = 'store')
self.args = parser.parse_args()
# Get the inventory.
ExampleInventory()
[student@ansible ansible]$ chmod +x inventory.py
[student@ansible ansible]$ vim test.yml
---
- name: test
hosts: all
tasks:
- name: debug
debug:
msg: "{{ nodevar }}"
[student@ansible ansible]$ ansible-playbook test.yml -i inventory.py
PLAY [test] *****************************************************************************************************************************************************************************************************
TASK [Gathering Facts] ******************************************************************************************************************************************************************************************
ok: [node3]
ok: [node1]
ok: [node2]
TASK [debug] ****************************************************************************************************************************************************************************************************
ok: [node2] => {
"msg": "test2"
}
ok: [node1] => {
"msg": "test1"
}
ok: [node3] => {
"msg": "test3"
}
PLAY RECAP ******************************************************************************************************************************************************************************************************
node1 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
node2 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
node3 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0