fact簡介
ansible有一個模塊叫setup,用於獲取遠程主機的相關信息,並可以將這些信息作為變量在playbook里進行調用。而setup模塊獲取這些信息的方法就是依賴於fact。
# ansible test -m setup
192.168.0.187 | SUCCESS => {
"ansible_facts": {
"ansible_all_ipv4_addresses": [
"192.168.0.187"
],
"ansible_all_ipv6_addresses": [
"fe80::f816:3eff:fe4f:6611"
],
"ansible_apparmor": {
"status": "disabled"
},
"ansible_architecture": "x86_64",
"ansible_bios_date": "04/01/2014",
"ansible_bios_version": "Ubuntu-1.8.2-1ubuntu1~cloud0",
...output omitted...
}
setup獲取的這些信息,都是可用於該主機的變量。
自定義fact
1. 手動設置fact
ansible除了能獲取到預定義的fact的內容,還支持手動為某個主機定制fact。稱之為本地fact。本地fact默認存放於被控端的/etc/ansible/facts.d
目錄下,如果文件為ini
格式或者json
格式,ansible會自動識別。以這種形式加載的fact是key為ansible_local
的特殊變量。
下面是一個簡單的示例,在ansibler主控端定義一個ini
格式的custom.fact文件內容如下:
[general]
package = httpd
service = httpd
state = started
然后我們編寫一個playbook文件名為setup_facts.yml內容如下:
---
- name: Install remote facts
hosts: test
vars:
remote_dir: /etc/ansible/facts.d
facts_file: custom.fact
tasks:
- name: Create the remote directory
file:
state: directory
recurse: yes
path: "{{ remote_dir }}"
- name: Install the new facts
copy:
src: "{{ facts_file }}"
dest: "{{ remote_dir }}"
執行該playbook,完成facts的推送:
ansible-playbook setup_facts.yml
此時,我們可以在被控端看到新的facts已經生成:
# ansible test -m setup
192.168.0.187 | SUCCESS => {
"ansible_facts": {
...output omitted...
"ansible_local": {
"custom": {
"general": {
"package": "httpd",
"service": "httpd",
"state": "started"
}
}
},
...output omitted...
}
我們可以寫一個簡單的playbook來使用這些facts:
- name: Install Apache and starts the service
hosts: test
tasks:
- name: Install the required package
yum:
name: "{{ ansible_facts.ansible_local.custom.general.package }}"
state: latest
- name: Start the service
service:
name: "{{ ansible_facts.ansible_local.custom.general.service }}"
state: "{{ ansible_facts.ansible_local.custom.general.state }}"
2. 使用set_fact模塊定義新的變量
set_fact
模塊可以自定義facts,這些自定義的facts可以通過template或者變量的方式在playbook中使用。如果你想要獲取一個進程使用的內存的百分比,則必須通過set_fact來進行計算之后得出其值,並將其值在playbook中引用。
下面是一個set_fact模塊的應用示例:
- name: set_fact example
hosts: test
tasks:
- name: Calculate InnoDB buffer pool size
set_fact: innodb_buffer_pool_size_mb="{{ ansible_memtotal_mb / 2 |int }}"
- debug: var=innodb_buffer_pool_size_mb
執行playbook如下:
# ansible-playbook set_fact_ex.yaml
PLAY [set_fact example] *****************************************************************************************************************************************************
TASK [Gathering Facts] ******************************************************************************************************************************************************
ok: [192.168.0.187]
TASK [Calculate InnoDB buffer pool size] ************************************************************************************************************************************
ok: [192.168.0.187]
TASK [debug] ****************************************************************************************************************************************************************
ok: [192.168.0.187] => {
"innodb_buffer_pool_size_mb": "3911.0"
}
PLAY RECAP ******************************************************************************************************************************************************************
192.168.0.187 : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
這種設置方式只在當前playbook當中有效
手動采集fact
通常情況下,我們在運行play的時候,ansible會先嘗試ssh到被控端采集fact,如果此時,被控制端的ssh還沒有完全啟動,就會導致整個play執行失敗。這個時候,我們可以先顯示的關閉fact采集,然后在task中通過wait_for等待被控端ssh端口被正常監聽,再在task中使用setup模塊來手動采集fact:
- name: Deploy apps
hosts: webservers
gather_facts: False
tasks:
- name: wait for ssh to be running
local_action: wait_for port=22 host="{{ inventory_hostname }}" search_regex=OpenSSH
- name: gather facts
setup:
......
啟用fact緩存
如果在play中需要引入fact,則可以開啟fact緩存。fact緩存目前支持三種存儲方式,分別為JSON、memcached、redis。
1. Json文件fact緩存后端
使用JSON文件作為fact緩存后端的時候,ansible將會把采集的fact寫入到控制主機的文件中。
ansible.cfg配置如下:
[defaults]
gathering = smart
#緩存時間,單位為秒
fact_caching_timeout = 86400
fact_caching = jsonfile
#指定ansible包含fact的json文件位置,如果目錄不存在,會自動創建
fact_caching_connection = /tmp/ansible_fact_cache
2. Redis fact緩存后端
使用redis作為fact緩存后端,需要在控制主機上安裝redis服務並保持運行。需要安裝python操作redis的軟件包。
ansible.cfg配置如下:
[defaults]
gathering = smart
fact_caching_timeout = 86400
fact_caching = redis
3. Memcached fact緩存后端
使用memcached作為fact緩存后端,需要在控制主機上安裝Memcached服務並保持運行,需要安裝python操作memcached的軟件包。
ansible.cfg配置如下:
[defaults]
gathering = smart
fact_caching_timeout = 86400
fact_caching = memcached
關閉fact
如果不想從fact中獲取變量,或者說整個playbook當中都沒有使用到fact變量,可以通過如下方法關閉fact以提升執行效率:
- hosts: test
gather_facts: no
也可以在ansible.cfg中添加如下配置:
[defaults]
gathering = explicit