一、利用主機模式選擇主機
1、應用靜態清單主機
1️⃣:主機模式用於指定要作為play或臨時命令的目標的主機;在最簡單的形式中,清單中受管主機或主機組的名稱就是指定該主機或主機組的主機模式
- 簡單演示實例:
[root@localhost ~]# cat inventory 1.1.1.1 2.2.2.2 [test] aaa.test.com bbb.test.com [server] www.server.com www.mairadb.com
2、受管主機
1️⃣:在該playbook運行時,第一個Gathering Facts任務應在與主機模式匹配的所有受管主機上運行
2️⃣:如果清單中明確列出了IP地址,而不是主機名,則可以將其用作主機模式;如果IP地址未列在清單中,我們就無法用它來指定主機,即使該IP地址會在DNS中解析到這個主機名
- 簡單演示實例:
[root@localhost ~]# cat playbook.yaml --- - hosts: client.example.com tasks: - name: ping: [root@localhost ~]# ansible-playbook playbook.yaml PLAY [client.example.com] ************************************************************************************************************************************************* TASK [Gathering Facts] **************************************************************************************************************************************************** ok: [client.example.com] TASK [ping] *************************************************************************************************************************************************************** ok: [client.example.com] PLAY RECAP **************************************************************************************************************************************************************** client.example.com : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
3️⃣:可以通過設置ansible_host主機變量,在清單中將某一別名指向特定的IP地址
- 簡單演示實例:
[root@localhost ansible]# cat inventory host [root@localhost ansible]# cat host_vars/host ansible_host: 192.168.121.81 ansible_ssh_user: root ansible_ssh_pass: root [root@localhost ansible]# ansible all --list-hosts hosts (1): host [root@localhost ansible]# ansible all -m ping host | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/libexec/platform-python" }, "changed": false, "ping": "pong" }
3、使用組指定主機
1️⃣:當組名稱用作主機模式時,它指定Ansible將對屬於該組的成員的主機執行操作
- 演示實例:
[root@localhost ~]# cat playbook.yaml --- - hosts: server tasks: - name: ping:
2️⃣:當有一個名為all的特別組,它匹配清單中的所有受管主機
- 演示實例:
[root@localhost ~]# cat playbook.yaml --- - hosts: all tasks: - name: ping:
3️⃣:還有一個名為ungrouped的特別組,它包括清單中不屬於任何其他組的所有受管主機
- 演示實例:
[root@localhost ~]# cat playbook.yaml --- - hosts: ungrouped tasks: - name: ping:
4、使用通配符匹配多個主機
1️⃣:若要達成與all主機模式相同的目標,另一種方法是使用(*)通配符,它將匹配任意字符串。
2️⃣:如果主機模式只是帶引號的星號,則清單中的所有主機都將匹配
- 演示實例:
[root@localhost ~]# cat playbook.yaml --- - hosts: '*' //此處的引號必須加 tasks: - name: ping:
3️⃣:重要提示:
一些在主機模式中使用的字符對shell也有意義。通過ansible使用主機模式從命令行運行臨時命令時,這可能會有問題。建議大家在命令行中使用單引號括起使用的主機模式,防止它們被shell意外擴展。
類似的,如果在Ansible Playbook中使用了任何特殊通配符或列表字符,必須將主機模式放在單引號里,確保能夠正確解析主機模式。
4️⃣:其他演示實例:(用的比較少,不常用)
- 實例一:
[root@localhost ~]# cat playbook.yaml --- - hosts: '192.168.121.*' tasks: - name: ping:
- 實例二:
[root@localhost ~]# cat playbook.yaml --- - hosts: '*.example.com' tasks: - name: ping:
- 實例三:
[root@localhost ~]# cat playbook.yaml --- - hosts: 'client.example.com,www.test.com' tasks: - name: ping:
- 實例四:
[root@localhost ~]# cat playbook.yaml --- - hosts: '!client.example.com,www.test.com' tasks: - name: ping:
5、列表
1️⃣:可以通過邏輯列表來引用清單中的多個條目;主機模式的逗號分隔列表匹配符合任何這些主機模式的所有主機
- 演示實例:
[root@localhost ~]# cat playbook.yaml --- - hosts: client.example.com,www.test.com,192.168.121.81 tasks: - name: ping:
2️⃣:也可以混合使用受管主機、主機組和通配符
- 演示實例:
[root@localhost ~]# cat playbook.yaml --- - hosts: '*.example.com,www.test.com,192.168.121.81' tasks: - name: ping:
3️⃣:注意:也可以用冒號(:)取代逗號。不過,逗號是首選的分隔符,特別是將IPv6地址用作受管主機名稱時
4️⃣:如果列表中的某一項以與符號(&)開頭,則主機必須與該項匹配才能匹配主機模式
- 演示實例:
[root@localhost ~]# cat playbook.yaml --- - hosts: host,&test tasks: - name: ping:
二、管理動態清單文件
1、動態生成清單
1️⃣:Ansible支持動態清單腳本,這些腳本在每當Ansible執行時從這些類型的來源檢索當前的信息,使清單能夠實時得到更新
2️⃣:這些腳本是可以執行的程序,能夠從一些外部來源收集信息,並以JSON格式輸出清單
3️⃣:動態清單腳本的使用方式與靜態清單文本文件一樣。清單的位置可以直接在當前的ansible.cfg文件中指定,或者通過-i選項指定
4️⃣:如果清單文件可以執行,則它將被視為動態清單程序,Ansible會嘗試運行它來生成清單。如果文件不可執行,則它將被視為靜態清單
5️⃣:清單位置可以在ansible.cfg配置文件中通過inventory參數進行配置。默認情況下,它被配置為/etc/ansible/hosts
2、開源社區腳本
1️⃣:開源社區向Ansible項目貢獻了大量現有的動態清單腳本。它們沒有包含在ansible軟件包中
2️⃣:Ansible GigHub網站:https://github.com/ansible/ansible/tree/devel/examples
3、編寫動態清單文件
1️⃣:ansible-inventory命令是學習如何以JSON格式編寫Ansible清單的有用工具;
2️⃣:要以JSON格式顯示清單文件的內容,請運行ansible-inventory --list命令,可以使用-i選項指定要處理的清單文件的位置,或僅使用當前Ansible配置設置的默認清單
-
[root@localhost ~]# ansible-inventory -i inventory --list
3️⃣:如果要自己編寫動態清單腳本,可以通過部署動態清單來源:https://docs.ansible.com/ansible/latest/dev_guide/developing_inventory.html 獲得更詳細的信息
4️⃣:腳本以適當的解釋器行(例如,#!/usr/bin/python)開頭並且可以執行,以便Ansible能夠運行它
5️⃣:注意:
- 通過--host hostname選項調用時,該腳本必須顯示指定主機的變量的JSON散列/字典。如果不提供任何變量,則可能顯示空白的JSON散列或字典
- 另外,如果--list選項返回名為_meta的頂級元素,則可以在一次腳本調用中返回所有主機變量,從而提升腳本性能。此時,不會進行--host調用
- 有關詳細信息,請參見部署動態清單來源:https://docs.ansible.com/ansible/latest/dev_guide/developing_inventory.html
- 腳本示例:
[root@localhost ~]# vim inventory.py #!/usr/bin/env python ''' Example custom dynamic inventory script for Ansible, in Python. ''' 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.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 { 'group': { 'hosts': ['172.16.103.129', '172.16.103.130'], 'vars': { 'ansible_ssh_user': 'root', 'ansible_ssh_pass': '123456', 'example_variable': 'value' } }, '_meta': { 'hostvars': { '172.16.103.129': { 'host_specific_var': 'foo' }, '172.16.103.130': { 'host_specific_var': 'bar' } } } } # 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()
- 使用該腳本方法
chmod +x inventory.py ./inventory.py --list ./inventory.py --host 172.16.103.129
- ansible使用這個動態清單來管理主機
ansible all -i inventory.py -m ping ansible 172.16.103.129 -i inventory.py -m ping
- 使用該腳本方法
4、管理多個清單
1️⃣:Ansible支持在同一運行中使用多個清單。如果清單的位置是一個目錄(不論是由-i選項設置的、是inventory參數的值,還是以某種其他方式設置的),將組合該目錄中包含的所有清單文件(不論是靜態還是動態)來確定清單
- 該目錄中的可執行文件將用於檢索動態清單,其他文件則被用作靜態清單
2️⃣:清單文件不應依賴於其他清單文件或腳本來解析
3️⃣:注意:
- 清單文件的解析順序不是由文檔指定的。如果存在多個清單文件,它們會按照字母順序進行解析
- 如果一個清單源依賴於另一個清單源的信息,則它們的加載順序可能會確定清單文件是按預期工作還是引發錯誤。因此,務必要確保所有文件都自相一致,從而避免意外的錯誤
4️⃣:Ansible會忽略清單目錄中以特定后綴結尾的文件。這可以通過在Ansible配置文件中的inventory_ignore_extensions指令來控制
- 使用動態清單:https://docs.ansible.com/ansible/latest/user_guide/intro_dynamic_inventory.html
- 開發動態清單:https://docs.ansible.com/ansible/latest/dev_guide/developing_inventory.html