gather_facts
、gather_subset
、filter
)Ansible Facts 是 Ansible 連線到主機時會自動幫我們搜集遠端主機系統資訊 (ex: OS、CPU、IP 等等...),這個功能讓我們能夠在 Playbook 做一些更細緻化的判斷。
但是相對的如果開啟 Ansible Facts 會造成 Playbook 執行速度會變比較慢,所以這個功能就要取決各位的需求去做決定,因為預設這功能是啟動的,所以需要自己透過 gather_facts
: false
將其關閉。
---
- hosts: all
gather_facts: true
vars:
# 僅收集必要資訊,以利加速執行速度
gather_subset: "!all,network,virtual"
tasks:
- name: Refresh facts with subset
setup:
gather_subset: "{{ gather_subset }}"
ansible -i inventory.ini all -m setup -a 'filter=ansible_distribution*'
ansible -i inventory.ini all -m setup -a 'gather_subset=!all,network,virtual'
常見的 subset:all
、min
、network
、hardware
、virtual
、facter
、ohai
,可以用 !all
排除全部後再挑選。
---
# facts-demo.yml
- name: Day13 facts demo
hosts: all
gather_facts: true
tasks:
- name: Show key facts
debug:
msg:
- "OS: {{ ansible_facts['distribution'] }} {{ ansible_facts['distribution_version'] }}"
- "Kernel: {{ ansible_facts['kernel'] }}"
- "CPU: {{ ansible_facts['processor_vcpus'] | default(ansible_facts['processor_count']) }}"
- "IPv4: {{ ansible_facts['default_ipv4']['address'] | default('N/A') }}"
- name: Derive values via set_fact
set_fact:
app_port: "{{ 443 if ansible_facts['os_family'] == 'RedHat' else 80 }}"
cache_enabled: "{{ (ansible_facts['memtotal_mb'] | int) > 4096 }}"
- name: Render config from facts (to /tmp)
template:
src: templates/facts.ini.j2
dest: /tmp/facts-demo.ini
mode: '0644'
# templates/facts.ini.j2
# Managed by Ansible – DO NOT EDIT
os={{ ansible_facts['distribution'] }}
os_ver={{ ansible_facts['distribution_version'] }}
hostname={{ ansible_facts['hostname'] }}
ip={{ ansible_facts['default_ipv4']['address'] | default('') }}
cpu={{ ansible_facts['processor_vcpus'] | default(ansible_facts['processor_count']) }}
app_port={{ app_port }}
cache_enabled={{ cache_enabled | ternary('true','false') }}
# 各位會看到裡面會有機器的資訊
cat /tmp/facts-demo.ini
在遠端主機上建立 /etc/ansible/facts.d/*.fact
(JSON/INI 皆可),setup
會讀入到 ansible_facts['ansible_local']
。
- name: Install custom local facts
become: yes
copy:
dest: /etc/ansible/facts.d/app.fact
mode: '0644'
content: |
{"app": {"role": "web", "tier": "frontend", "owner": "platform"}}
- name: Refresh facts (only local facts)
setup:
filter: ansible_local
- name: Use local fact
debug:
msg: "Role={{ ansible_facts['ansible_local']['app']['role'] }}"
when: ansible_facts['ansible_local'] is defined and 'app' in ansible_facts['ansible_local']
開頭筆者有說過使用 Facts 會導致執行速度變得比較慢,所以這時候我們會需要透過一些 cache 的方式來加速。
# ansible.cfg
[defaults]
# 讓 Ansible 自己判斷要不要重新取得主機資訊
gathering = smart
fact_caching = jsonfile
# 指定 cache 的目錄
fact_caching_connection = ./.ansible/facts_cache
# fact cache 存活時間
fact_caching_timeout = 86400
開啟 cache 機制雖然說會減少執行速度,換句話說就是減少 Ansible 重複搜集主機資訊的次數,但記得如果有更新硬體或網路的話記得清除或等待 cache 過期。
network
與 virtual
,輸出主要介面與是否為 VM。app.fact
,在 Playbook 依 ansible_local.app.role
決定要安裝的套件。相信各位在閱讀完今天的文章後,會發現可以讀取遠端機器的資訊是一件非常棒的事情,因為我們就可以透過不同的資訊去做到不一樣的操作。
像是 Day08 有提到的條件判斷,大家也可以想想怎麼利用這些有趣的功能來讓我們的流程更具彈性。
明天來試試看能不能綜合這幾天的學習成果完成一個小型的部署任務。