透過 Playbook 可以很方便執行大量機器部署,在大量環境下可以透過變數方式,如同寫程式一般可以更靈活且彈性的進行部署及維護。
1.Ansible 變數介紹
Ansible 可以使用變數使得執行起來更佳彈性且靈活,像是角色創立、套件安裝、服務啟動等等,另外 Ansible 變數取名方式與 Python 一致,使用蛇形命名法(snake case),例如: web_server_01 。
2. Playbook 定義變數
2.1. 定義變數於 PlayBook 內
使用 vars 關鍵字並定義變數 , Playbook 範例:
1
2
3
4
5
6
|
- name: var example
hosts: all
vars:
user: joe
home: /home/joe
...
|
2.2. 定義變數檔案於 PlayBook 內
使用 vars_files 關鍵字定義變數的檔案路徑 , Playbook 範例:
1
2
3
4
5
|
- name: var example
hosts: all
vars_files:
- users.yml
...
|
user.yml 變數檔案內容範例 :
1
2
|
user: joe
home: /home/joe
|
3. PlayBook 中使用變數
使用兩個大刮號包住變數名稱,即可使用定義好的變數,Playbook 範例:
1
2
3
4
5
6
7
8
9
|
- name: var example
hosts: all
vars:
user : joe
tasks:
- name: Create the User {{ user }}
user:
name: "{{ user }}"
|
IMPORTANT
變數如果為 Value 第一個開頭需要加註雙引號,如上 PlayBook 內容 , 兩個不同的樣式。
4. 主機變數及群組變數
在 inventory 中也可以定義變數,不過此作法比較少用,影響 inventory 可讀性及維護性。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
[servera]
demo1.example.com
demo2.example.com
[web]
demo2.example.com
demo3.exmaple.com
[servera:vars]
user=joe
[pd:children]
web
servera
[pd:vars]
user=administrator
|
5. 使用資料夾管理主機變數及群組變數
透過 group_vars 及 host_vars 兩個資料夾管理群組及主機變數,此方式最常使用管理較為直覺也容易,其專案架構如下:
1
2
3
4
5
6
7
8
9
10
11
12
|
[student@workstation example-project]$ tree -F
.
├── ansible.cfg
├── group_vars/
│ ├── datacenter1
│ ├── datacenter2
│ └── datacenters
├── host_vars/
│ ├── demo1.example.com
│ └── demo2.example.com
├── inventory
└── playbook.yml
|
inventory 內容:
1
2
3
4
5
6
7
8
9
10
11
12
|
[student@workstation example-project]$ cat inventory
[datacenter1]
demo1.example.com
demo2.example.com
[datacenter2]
demo3.example.com
demo4.example.com
[datecenters:children]
datacenter1
datacenter2
|
5.1. group_vars 資料夾管理群組變數
在 group_vars 資料夾內建立對應群組的檔案名稱,並在該檔案內定義變數。
1
2
3
4
5
6
|
[student@workstation example-project]$ cat group_vars/datacenter1
service: httpd
[student@workstation example-project]$ cat group_vars/datacenter2
service: php
[student@workstation example-project]$ cat group_vars/datacenters
package: httpd
|
5.2. host_vars 資料夾管理主機變數
在 host_vars 資料夾內建立對應主機的檔案名稱,並在該檔案內定義變數。
1
2
3
4
|
[student@workstation example-project]$ cat host_vars/demo1.example.com
packege: mysql-server
[student@workstation example-project]$ cat host_vars/demo2.example.com
package: firewalld
|
6. 指令定義變數
透過 ansible-playbook 定義執行變數。
1
|
ansible-playbook example.yml -e "package=httpd"
|
7. Ansible 變數使用建議
Ansible 可以設定變數的地方還有十分的多,可至 Ansible 官方手冊 查閱 ,建議在同一個公司內共同商議,要在哪個地方使用變數,方便管理及維護。
8. Ansible Fact 變數
在 Ansible 執行時,第一個 task 任務總是會出現 Gathering Facts ,這個任務就是搜尋所有主機的相關訊息並存為 Fact 變數,這任務預設會自動採集,除非手動設置不採集。
Fact 會採集下列相關訊息( 僅列出部分 ):
- 主機名稱
- 核心版本
- 網路介面卡
- IP 地址
- 作業系統版本
- 環境變數
- CPU
- 記憶體
- 硬碟空間
透過 Fact 可以藉由不同機器做出不同條件篩選,例如大於多少空間硬碟才部署 MySQL 或是哪些 IP 執行特定操作等。
印出 Fact Playbook 範例:
1
2
3
4
5
6
7
|
[student@workstation example]$ cat fact.yml
- name: Fact dump
hosts: serverb
tasks:
- name: Print all facts
debug:
var: ansible_facts
|
範例執行結果 ( ansible_facts 為 fact 的關鍵字) :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
[student@workstation example]$ ansible-playbook fact.yml
PLAY [Fact dump] ***********************************************************************************************
TASK [Gathering Facts] *****************************************************************************************
ok: [serverb]
TASK [Print all facts] *****************************************************************************************
ok: [serverb] => {
"ansible_facts": {
"all_ipv4_addresses": [
"172.25.250.11"
],
"all_ipv6_addresses": [],
"ansible_local": {},
"apparmor": {
"status": "disabled"
},
"architecture": "x86_64",
"bios_date": "04/01/2014",
"bios_version": "1.13.0-2.module+el8.4.0+534+4680a14e",
"cmdline": {
"BOOT_IMAGE": "(hd0,msdos1)/vmlinuz-4.18.0-348.el8.0.2.x86_64",
"rd.lvm.lv": "rl_workstation/swap",
"resume": "/dev/mapper/rl_workstation-swap",
"ro": true,
"root": "/dev/mapper/rl_workstation-root"
},
...
|
8.1. Fact 變數取值
透過上述範例,可以知道 ansible_facts 變數內存放不同的內容,可以使用於 Python Dict 字典方式將 Value 取出。
Fact |
變數 |
Short host name |
ansible_facts['hostname'] |
FQDN |
ansible_facts['fqdn'] |
IPv4 |
ansible_facts['ansible_default_ipv4']['address'] |
顯示 DNS 列表 |
ansible_facts['dns']['nameservers'] |
顯示 /dev/vda1 分區大小 |
ansible_facts['devices']['vda']['partitions']['vda1']['size'] |
NOTE
除了使用中刮號取值之外也可以使用物件屬性方式取值~
ansible_facts['ansible_default_ipv4']['address']
,此方是可以取得 IPv4 。
ansible_facts.ansible_default_ipv4.address
, 此方式也可以取得 IPv4 。
8.2. Fact 變數取值應用
印出受控主機 IPv4 地址, Playbook 範例:
1
2
3
4
5
6
|
- name: Example
hosts: all
tasks:
- name: Print various Ansible facts
debug:
msg: The default IPv4 address of {{ ansible_facts.fqdn }} is {{ ansible_facts.default_ipv4.address }}
|
Playbook 執行結果 :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
[student@workstation example]$ ansible-playbook example.yml
PLAY [Example] ************************************************************************************************
TASK [Gathering Facts] ****************************************************************************************
ok: [serverb]
ok: [servera]
ok: [serverc]
TASK [Print various Ansible facts] ****************************************************************************
ok: [servera] => {
"msg": "The default IPv4 address of servera.lab.example.com is 172.25.250.10"
}
ok: [serverb] => {
"msg": "The default IPv4 address of serverb.lab.example.com is 172.25.250.11"
}
ok: [serverc] => {
"msg": "The default IPv4 address of serverc.lab.example.com is 172.25.250.12"
}
PLAY RECAP ****************************************************************************************************
servera : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
serverb : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
serverc : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
|
8.3. 儲存 Fact 變數內容小技巧
使用 ansible 的 setup 模組,可以採集 fact 再藉由 Linux 輸出導向至檔案內,就可以慢慢查看並找到所要的變數內容來應用。
1
2
3
4
5
6
7
8
9
10
11
12
|
[student@workstation example]$ ansible serverc -m setup > /tmp/serverc.facts
[student@workstation example]$ head /tmp/serverc.facts
serverc | SUCCESS => {
"ansible_facts": {
"ansible_all_ipv4_addresses": [
"172.25.250.12"
],
"ansible_all_ipv6_addresses": [],
"ansible_apparmor": {
"status": "disabled"
},
"ansible_architecture": "x86_64",
|
8.4. 停止自動採集 Fact
每一次採集 Fact 大約耗上 1 - 2 秒時間,少量機器執行不會有感覺,如果今天要部署上千台機器,且又不會使用到 Fact 變數,就可以手動關閉採集 ( gather_facts : no ) ,加速 Playbook 執行效率。
停用 facts 自動採集 Playbook 範例 :
1
2
3
4
5
|
- name: example
hosts: all
gather_facts: no
tasks:
...
|
9. Ansible 魔法變數
有些變數無法透過 setup 模組 ( Fact ) 採集,而是藉由 ansible 自動產生的變數稱做魔法變數,例如:
- group_names : 在 Inventory 主機清單內的群組名稱。
- groups :在 Inventory 主機清單內群組的主機清單。
- playbook_dir : 執行 playbook 路徑
更多魔法變數請至 Ansible 官方手冊查閱 。
10. 小結
Ansible 變數運用千變萬化, 能有效掌握變數更能寫出可讀性且彈性較高的 PlayBook 。