AnsiblePlaybook中的變數使用技巧:提高自動化效率的必備利器

ansible playbook中的變數

目錄
  • • 一、變數的優先順序
    • • 1.1 YAML陷阱
  • • 二、 Ansbile-playbook變數配置方法
    • • 2.1 在inventory主機清單檔案中定義變數
    • • 2.2 透過host_vars和group_vars目錄來定義變數
    • • 2.3 透過var_files定義變數
    • • 2.4 透過vars_prompt互動式傳入變數
    • • 2.5 透過ansible-playbook命令列定義變數!即引數傳入變數
    • • 2.6 在playbook劇本中定義變數
    • • 2.7 透過roles角色定義變數
    • • 2.8 使用Facts獲取的資訊
    • • 2.9 register註冊變數
    • • 2.10 hostvars 變數
    • • 2.11 列表變數、迴圈變數、字典變數

一、變數的優先順序

  • • extra vars變數(在命令列中使用 -e);優先順序最高;
  • • 在inventory中定義的連線變數(比如ansible_ssh_user);優先順序第二;
  • • 大多數的其他變數(命令列轉換,play中的變數,include的變數,role的變數等);優先順序第三;
  • • 在inventory定義的其他變數;優先順序第四;
  • • 有系統發現的facts;優先順序第五;
  • • "role預設變數",這個是最預設的值,很容易喪失優先權。優先順序最小;
另外:在inventory清單列表裡定義的變數:單個主機定義的變數優先順序高於主機組定義的變數經過實驗,ansible使用inventory定義變數的優先順序順序從高到低為:host_vars下定義變數 —> inventory中單個主機定義變數 —> group_vars下定義變數 —> inventory中組定義變數

1.1 YAML陷阱

YAML語法要求如果值以{{ foo }}開頭的話,那麼就需要將整行用雙引號包起來,這是為了確認你不是想宣告一個YAML字典。如下面配置是不行的!!!
||||---|---|||---|||-hosts:app_servers|||vars:|||app_path: {{ base_path }}/data/web|
應該改成下面這樣:
||||---|---|||---|||-hosts:app_servers|||vars:|||app_path:"{{ base_path }}/data/web"|

二、 Ansbile-playbook變數配置方法

2.1 在inventory主機清單檔案中定義變數

可以直接定義在主機清單檔案/etc/ansible/hosts中,表明該變數只對對應的主機或者組有效,對其餘的主機和組無效。
示例:
|     |     || --- | --- ||     | $ egrep -v "^#\|^$" /etc/ansible/hosts ||     | 10.4.7.101 key=20180101 ||     | 10.4.7.102 key="niubility" ||     |     ||     | $ vim ansi.yml ||     | --- ||     | - hosts: all ||     | gather_facts: False ||     | tasks: ||     | - name: haha ||     | debug: msg="the {{ inventory_hostname }} value is {{ key }}" ||     |     ||     | # 執行結果(注意inventory_hostname代表inventory列表列表裡被控節點的主機名): ||     |     ||     | $ ansible-playbook ansi.yml ||     |     ||     | PLAY [all] ************************************************************************************************************************************** ||     |     ||     | TASK [haha] ************************************************************************************************************************************* ||     | ok: [10.4.7.101] => { ||     | "msg": "the 10.4.7.101 value is 20180101" ||     | }   ||     | ok: [10.4.7.102] => { ||     | "msg": "the 10.4.7.102 value is niubility" ||     | }   ||     |     ||     | PLAY RECAP ************************************************************************************************************************************** ||     | 10.4.7.101                 : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 ||     | 10.4.7.102                 : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 |

2.2 透過host_vars和group_vars目錄來定義變數

/etc/ansible/目錄是linux系統上ansible預設的配置檔案目錄(Mac系統上的話,其預設配置目錄是在/usr/local/etc/ansible/),在該目錄下建立host_varsgroup_vars兩個目錄用來存放定義變數的檔案。
針對單個主機的變數
|     | $ cat /etc/ansible/host_vars/10.4.7.101 ||     | --- ||     | user: root ||     | pass: root@123 |
針對test組的變數
|     | $ cat /etc/ansible/group_vars/test ||     | --- ||     | user: work ||     | pass: work@123 |
在inventory清單列表檔案裡,單個主機定義的變數優先順序高於主機組定義的變數

2.3 透過var_files定義變數

|     | $ cat vars.yml ||     | --- ||     | key: jiayou ||     |     ||     | $ cat bo.yml ||     | --- ||     | - hosts: all ||     | gather_facts: False ||     | vars_files: ||     | - vars.yml ||     | tasks: ||     | - name: display ||     | debug: msg="the {{ inventory_hostname }} valus is {{ key }}" ||     |     ||     | $ ansible-playbook bo.yml ||     |     ||     | PLAY [all] ************************************************************************************************************************************** ||     |     ||     | TASK [display] ********************************************************************************************************************************** ||     | ok: [10.4.7.101] => { ||     | "msg": "the 10.4.7.101 valus is jiayou" ||     | }   ||     | ok: [10.4.7.102] => { ||     | "msg": "the 10.4.7.102 valus is jiayou" ||     | }   ||     |     ||     | PLAY RECAP ************************************************************************************************************************************** ||     | 10.4.7.101                 : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 ||     | 10.4.7.102                 : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 |

2.4 透過vars_prompt互動式傳入變數

在playbook中定義vars_prompt的變數名和互動式提示資訊,就可以實現在執行playbook時,透過互動的傳入變數值。private欄位:用來定義互動時是否回顯輸入的值,預設private為yes;default欄位:用來定義變數的預設值。
|     | $ cat prom.yml ||     | --- ||     | - hosts: test ||     | remote_user: root ||     | vars_prompt: ||     | - name: "var1" ||     | prompt: "please input you name" ||     | private: no ||     | - name: "var2" ||     | prompt: "please input you age" ||     | private: yes ||     | default: 18 ||     | tasks: ||     | - name: display var1 ||     | debug: msg="your name of var1 is {{ var1 }}" ||     | - name: display var2 ||     | debug: msg="you age of var2 is {{ var2 }}" ||     |     ||     | $ ansible-playbook prom.yml ||     | please input you name: lvzhenjiang    # 把輸入的內容傳遞給變數var1。輸入的值顯示出來! ||     | please input you age [18]:           # playbook中定義預設值是18,如果不輸入便是18,但是輸入的值不顯示出來!比如這裡輸入的23 ||     |     ||     | PLAY [test] ************************************************************************************************************************************* ||     |     ||     | TASK [Gathering Facts] ************************************************************************************************************************** ||     | ok: [10.4.7.101] ||     |     ||     | TASK [display var1] ***************************************************************************************************************************** ||     | ok: [10.4.7.101] => { ||     | "msg": "your name of var1 is lvzhenjiang" ||     | }   ||     |     ||     | TASK [display var2] ***************************************************************************************************************************** ||     | ok: [10.4.7.101] => { ||     | "msg": "you age of var2 is 23" ||     | }   ||     |     ||     | PLAY RECAP ************************************************************************************************************************************** ||     | 10.4.7.101                 : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 |

2.5 透過ansible-playbook命令列定義變數!即引數傳入變數

除了vars_promptvars_files,也可以透過Ansible命令列傳送變數。如果想要編寫一個通用的釋出playbook時則特別有用!你可以傳遞應用的版本以便部署。例如下面命令(注意: --extra-vars 相等於 -e)
|     | $ cat exap.yml ||     | --- ||     | - hosts: '{{hosts}}' ||     | remote_user: '{{user}}' ||     | tasks: ||     | - name: "一個測試" ||     | debug: msg="your hosts is {{hosts}}, user is {{user}}" ||     |     ||     | $  ansible-playbook exap.yml -e "hosts=test user=root" ||     | [WARNING]: Found variable using reserved name: hosts ||     |     ||     | PLAY [test] ************************************************************************************************************************************* ||     |     ||     | TASK [Gathering Facts] ************************************************************************************************************************** ||     | ok: [10.4.7.101] ||     |     ||     | TASK [一個測試] ************************************************************************************************************************************* ||     | ok: [10.4.7.101] => { ||     | "msg": "your hosts is test, user is root" ||     | }   ||     |     ||     | PLAY RECAP ************************************************************************************************************************************** ||     | 10.4.7.101                 : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 |
也可以將引數放在檔案裡面進行傳遞(注意命令列裡要是用"@檔名"):
|     |     || --- | --- ||     | # 同樣使用上面的例子 ||     | $ cat anhui.yml ||     | --- ||     | hosts: test ||     | user: root ||     |     ||     | $ ansible-playbook exap.yml -e "@anhui.yml" ||     | [WARNING]: Found variable using reserved name: hosts ||     |     ||     | PLAY [test] ************************************************************************************************************************************* ||     |     ||     | TASK [Gathering Facts] ************************************************************************************************************************** ||     | ok: [10.4.7.101] ||     |     ||     | TASK [一個測試] ************************************************************************************************************************************* ||     | ok: [10.4.7.101] => { ||     | "msg": "your hosts is test, user is root" ||     | }   ||     |     ||     | PLAY RECAP ************************************************************************************************************************************** ||     | 10.4.7.101                 : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 |

2.6 在playbook劇本中定義變數

在playbook中定義變數需要用到Ansible的vars模組,可以將所有需要用到的變數統一在vars模組下定義,定義格式需要遵循YAML語言格式:
語法格式:
|     |     || --- | --- ||     | vars: ||     | - var1: value1 ||     | - var2: value2 ||     | - var3: value3 ||     | - ....: ..... |
示例如下:
|     | $ cat playbook.yml ||     | --- ||     | - hosts: test ||     | remote_user: root ||     | vars: ||     | - dir1: /root/Ansible ||     | - dir2: /root/Ansible/test1 ||     | - dir3: /root/Ansible/test2 ||     | tasks: ||     | - name: Create New Folder ||     | file: name={{ dir1 }} state=directory ||     | - name: Create New Folder ||     | file: name={{ dir2 }} state=directory ||     | - name: Create New Folder ||     | file: name={{ dir3 }} state=directory ||     |     ||     | $ ansible-playbook playbook.yml ||     |     ||     | PLAY [test] ************************************************************************************************************************************* ||     |     ||     | TASK [Gathering Facts] ************************************************************************************************************************** ||     | ok: [10.4.7.101] ||     |     ||     | TASK [Create New Folder] ************************************************************************************************************************ ||     | changed: [10.4.7.101] ||     |     ||     | TASK [Create New Folder] ************************************************************************************************************************ ||     | changed: [10.4.7.101] ||     |     ||     | TASK [Create New Folder] ************************************************************************************************************************ ||     | changed: [10.4.7.101] ||     |     ||     | PLAY RECAP ************************************************************************************************************************************** ||     | 10.4.7.101                 : ok=4    changed=3    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 |

2.7 透過roles角色定義變數

在Ansible的roles中定義變數,需要將變數及值的鍵值對形式寫到roles的vars目錄下的main.yml檔案中,同樣適用YAML語言格式,格式如下:
|     |     || --- | --- ||     | var1: value1 ||     | var2: value2 ||     | var3: value3 |
但是請注意:透過Roles定義的變數只適用於當前roles。
|     |     || --- | --- ||     | # roles目錄結構 ||     | $ tree . ||     | .   ||     | ├── hosts ||     | ├── playbook.yml ||     | └── test ||     | ├── files ||     | ├── tasks ||     | │   └── main.yml ||     | ├── templates ||     | └── vars ||     | └── main.yml ||     |     ||     | 5 directories, 4 files ||     |     ||     | $ cat test/tasks/main.yml ||     | - name: create directory ||     | file: name={{ dir }} state=directory ||     | - name: Get IP Address ||     | shell: echo `{{ cmd }}` >> {{ dir }}/{{ file }} ||     |     ||     | $ cat test/vars/main.yml ||     | cmd: hostname -I ||     |     ||     | $ cat playbook.yml ||     | --- ||     | - hosts: test ||     | remote_user: root ||     | roles: ||     | - test ||     |     ||     | $ cat hosts ||     | [test] ||     | 10.4.7.101 dir=/root/node2 ||     | 10.4.7.102 dir=/root/node1 ||     |     ||     | [node1] ||     | 10.4.7.100 ||     |     ||     | [test:vars] ||     | file=hostname.txt ||     |     ||     | $ ansible-playbook -i hosts  playbook.yml ||     |     ||     | PLAY [test] ************************************************************************************************************************************* ||     |     ||     | TASK [Gathering Facts] ************************************************************************************************************************** ||     | ok: [10.4.7.101] ||     | ok: [10.4.7.102] ||     |     ||     | TASK [test : create directory] ****************************************************************************************************************** ||     | ok: [10.4.7.101] ||     | ok: [10.4.7.102] ||     |     ||     | TASK [test : Get IP Address] ******************************************************************************************************************** ||     | changed: [10.4.7.102] ||     | changed: [10.4.7.101] ||     |     ||     | PLAY RECAP ************************************************************************************************************************************** ||     | 10.4.7.101                 : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 ||     | 10.4.7.102                 : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 |

2.8 使用Facts獲取的資訊

還有其它地方可以獲取變數, 這些變數是自動發現的,而不是使用者自己設定的。Facts透過訪問遠端系統獲取相應的資訊,一個很好的例子就是遠端主機的IP地址或者作業系統是什麼。
|     |     || --- | --- ||     | $ ansible test -m setup ||     | # 使用以下命令可以檢視哪些資訊是可用的(test是上面在/etc/ansible/hosts列表檔案中配置的主機群組) ||     |     ||     | $ ansible test -m setup\|grep "ansible_python_version" ||     | "ansible_python_version": "2.7.5", ||     | # 在playbook中這樣引用上面被控制主機的python版本: {{ ansible_python_version }} ||     |     ||     | $ ansible test -m setup\|grep "ansible_nodename" ||     | "ansible_nodename": "template", ||     | # 可以在playbook中這樣引用上面被控制主機的主機名: {{ ansible_nodename }} ||     |     ||     | $ ansible test -m setup \| grep "ansible_hostname" ||     | "ansible_hostname": "template", ||     | # 被控制主機的主機名變數還可以是: {{ ansible_hostname }} |
如果關閉Facts,可以大大提高ansible的執行速度 ,關閉方法如下:
|     | $ cat anhui.yml ||     | --- ||     | - hosts: test ||     | gather_facts: no |

2.9 register註冊變數

變數的另一個主要用途是在執行命令時,把命令結果儲存到一個變數中,不同模組的執行結果是不同的。執行playbook時使用-v選項可以看到可能的結果值,ansible執行任務的結果值可以儲存在變數中,以便稍後使用它。register方式主要用於在task之間傳遞變數。
|     |     || --- | --- ||     | $ cat /etc/ansible/hosts ||     | [test] ||     | 10.4.7.101 ||     | 10.4.7.102 ||     |     ||     | $ cat register.yml ||     | --- ||     | - hosts: test ||     | remote_user: root ||     | tasks: ||     | - name: register bo_test ||     | shell: hostname -I ||     | register: info ||     | - name: display info ||     | debug: msg="this host ip is {{ info['stdout'] }}" ||     |     ||     | $ ansible-playbook register.yml ||     |     ||     | PLAY [test] ************************************************************************************************************* ||     |     ||     | TASK [Gathering Facts] ************************************************************************************************** ||     | ok: [10.4.7.102] ||     | ok: [10.4.7.101] ||     |     ||     | TASK [register bo_test] ************************************************************************************************* ||     | changed: [10.4.7.102] ||     | changed: [10.4.7.101] ||     |     ||     | TASK [display info] ***************************************************************************************************** ||     | ok: [10.4.7.101] => { ||     | "msg": "this host ip is 10.4.7.101 " ||     | }   ||     | ok: [10.4.7.102] => { ||     | "msg": "this host ip is 10.4.7.102 " ||     | }   ||     |     ||     | PLAY RECAP ************************************************************************************************************** ||     | 10.4.7.101                 : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 ||     | 10.4.7.102                 : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 |

2.10 hostvars 變數

該變數用於引用其他主機上收集的facts中的資料,或者引用其他主機的主機變數、主機組變數。即從一臺遠端主機獲取另一臺遠端主機的變數。
|     |     || --- | --- ||     | $ cat /etc/ansible/hosts ||     | [test] ||     | 10.4.7.101 addr=beijing ||     | 10.4.7.102 user=shibo age=39 ||     |     ||     | $ cat test.yml ||     | --- ||     | - hosts: test ||     | remote_user: root ||     | gather_facts: False ||     | tasks: ||     | - name: this is test1 ||     | debug: msg="She is come from {{ hostvars['10.4.7.101']['addr'] }}" ||     | - name: this is test2 ||     | debug: msg="I am {{ hostvars['10.4.7.102']['user'] }}, and age is {{ hostvars['10.4.7.102']['age'] }}" ||     |     ||     | $ ansible-playbook test.yml ||     |     ||     | PLAY [test] ************************************************************************************************************* ||     |     ||     | TASK [this is test1] **************************************************************************************************** ||     | ok: [10.4.7.101] => { ||     | "msg": "She is come from beijing" ||     | }   ||     | ok: [10.4.7.102] => { ||     | "msg": "She is come from beijing" ||     | }   ||     |     ||     | TASK [this is test2] **************************************************************************************************** ||     | ok: [10.4.7.101] => { ||     | "msg": "I am shibo, and age is 39" ||     | }   ||     | ok: [10.4.7.102] => { ||     | "msg": "I am shibo, and age is 39" ||     | }   ||     |     ||     | PLAY RECAP ************************************************************************************************************** ||     | 10.4.7.101                 : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 ||     | 10.4.7.102                 : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 |

2.11 列表變數、迴圈變數、字典變數

1)ansible的變數不僅可以是單個的值,也可以為列表,即ansible傳列表作為變數
|     | $ cat test.yml ||     | --- ||     | - hosts: test ||     | remote_user: root ||     | gather_facts: False ||     | vars: ||     | - list: [1,2,3] ||     | tasks: ||     | - name: echo ||     | debug: msg="{{ list }}" ||     |     ||     | $ ansible-playbook test.yml ||     |     ||     | PLAY [test] ************************************************************************************************************* ||     |     ||     | TASK [echo] ************************************************************************************************************* ||     | ok: [10.4.7.101] => { ||     | "msg": [ ||     | 1,  ||     | 2,  ||     | 3   ||     | ]   ||     | }   ||     | ok: [10.4.7.102] => { ||     | "msg": [ ||     | 1,  ||     | 2,  ||     | 3   ||     | ]   ||     | }   ||     |     ||     | PLAY RECAP ************************************************************************************************************** ||     | 10.4.7.101                 : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 ||     | 10.4.7.102                 : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored= |
2)迴圈列表
結合迴圈,這個特性就變得很有用;以引數傳遞列表給playbook,不用在playbook中固定迴圈的次數與內容。
|     | $ cat test.yml ||     | --- ||     | - hosts: 10.4.7.101 ||     | remote_user: root ||     | gather_facts: False ||     | vars: ||     | - list: [1,2,3] ||     | tasks: ||     | - name: this is loop ||     | debug: msg="{{ item }}" ||     | with_items: '{{list}}' ||     |     ||     | $ ansible-playbook test.yml ||     |     ||     | PLAY [10.4.7.101] ******************************************************************************************************* ||     |     ||     | TASK [this is loop] ***************************************************************************************************** ||     | ok: [10.4.7.101] => (item=1) => { ||     | "msg": 1 ||     | }   ||     | ok: [10.4.7.101] => (item=2) => { ||     | "msg": 2 ||     | }   ||     | ok: [10.4.7.101] => (item=3) => { ||     | "msg": 3 ||     | }   ||     |     ||     | PLAY RECAP ************************************************************************************************************** ||     | 10.4.7.101                 : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 |
****** 當你發現自己的才華撐不起野心時,就請安靜下來學習吧!******
連結:https://www.cnblogs.com/lvzhenjiang/p/14385777.html
(版權歸原作者所有,侵刪)
文末福利
就目前來說,傳統運維衝擊年薪30W+的轉型方向就是SRE&DevOps崗位。
為了幫助大家早日擺脫繁瑣的基層運維工作,給大家整理了一套高階運維工程師必備技能資料包,內容有多詳實豐富看下圖!
共有 20 個模組
1.38張最全工程師技能圖譜
2.面試大禮包
3.Linux書籍
4.go書籍
······
6.自動化運維工具
18.訊息佇列合集
 以上所有資料獲取請掃碼
備註:最新運維資料
100%免費領取
(後臺不再回復,掃碼一鍵領取


相關文章