ansible筆記(31):變數(六)
- A+
所屬分類:ansible 運維技術
在本部落格中,ansible是一個系列文章,我們會盡量以通俗易懂的方式總結ansible的相關知識點。
ansible系列博文直達連結:ansible輕鬆入門系列
"ansible系列"中的每篇文章都建立在前文的基礎之上,所以, 請按照順序閱讀這些文章,否則有可能在閱讀中遇到障礙。
在之前的文章中,我們已經總結了很多變數的用法,今天再來介紹一個引入變數的方法,使用'include_vars'引入變數,不過在介紹'include_vars'之前,我們先來回顧一下'vars_files'的用法,我們知道,通過'vars_files'可以將檔案中的變數引入playbook,以便在task中使用,那麼,我們先來看一個示例變數檔案(注:變數檔案位於ansible控制節點中,與目標主機無關),示例變數檔案'/testdir/ansible/testfile'中的內容如下:
testvar1: aaa testvar2: bbb
如上所示,其中一共定義了兩個變數,如果我們使用'vars_files'匯入這兩個變數,可以編寫如下playbook
--- - hosts: test70 remote_user: root gather_facts: no vars_files: - /testdir/ansible/testfile tasks: - debug: msg: "{{testvar1}}"
上例中,我們呼叫了變數檔案中的testvar1變數,輸出的值為aaa,沒有任何問題,但是,我們來考慮一種特殊情況,假設playbook中一共有3個任務,第1個任務呼叫了變數檔案中的變數,第2個任務在變數檔案中新增了一個變數,第3個任務能在變數檔案中引用到新增的變數麼,我們來試試,playbook如下
(注:為了更加方便的操作變數檔案進行測試,此處將目標主機設定為test71,主機test71為ansible控制主機)
--- - hosts: test71 remote_user: root gather_facts: no vars_files: - /testdir/ansible/testfile tasks: - debug: msg: "{{testvar1}},{{testvar2}}" - lineinfile: path: "/testdir/ansible/testfile" line: "testvar3: ccc" - debug: msg: "{{testvar1}},{{testvar2}},{{testvar3}}"
如上例所示,我們定義了三個任務,第二個任務中,使用lineinfile模組在變數檔案中增加了testvar3變數,然後在第三個任務中呼叫了testvar3變數,執行上例playbook,你會發現,執行出錯了,因為在playbook載入vars_files對應的變數檔案時,檔案中只有兩個變數,在執行第三個任務執行,並沒有重新載入對應的變數檔案,所以執行報錯了,那麼,聰明如你一定想到了,我們需要一種便捷的方法,能夠在任務執行過程中,隨時的引入變數檔案,以便動態的獲取到最新的變數檔案內容,沒錯,依靠'include_vars'即可滿足我們的要求,示例如下
--- - hosts: test71 remote_user: root gather_facts: no vars_files: - /testdir/ansible/testfile tasks: - debug: msg: "{{testvar3}}" - lineinfile: path: "/testdir/ansible/testfile" line: "testvar4: ddd" - include_vars: "/testdir/ansible/testfile" - debug: msg: "{{testvar4}}"
如上例所示,由於testvar3已經加入到了變數檔案中,所以,我們在上例中的第一個任務中就能呼叫到testvar3,第二個任務中,我們在變數檔案中新增了一個變數testvar4,第三個任務呼叫了'include_vars'模組,'include_vars'模組重新載入了變數檔案,第四個任務中,呼叫了testvar4變數。
執行上例playbook,完全可以正常執行,這就是'include_vars'模組的優勢,它可以動態的以任務的方式在合適的時機引用變數檔案中的變數,很方便吧。
有些時候,變數檔案可能並沒有位於ansible主機中,而是位於遠端主機中,所以,我們需要先把變數檔案從遠端主機中拉取到ansible主機中,當通過前面的task拉取到變數檔案以後,也可以使用'include_vars'模組載入剛才拉取到的變數檔案,以便後面的task可以使用變數檔案中的變數。
'include_vars'模組其實還有一些常用引數(這些引數大多數都是從2.2版本以後加入的),我們一起來了解一下
先來看一個小示例,如下
--- - hosts: test70 remote_user: root gather_facts: no tasks: - include_vars: file: /testdir/ansible/testfile - debug: msg: "{{testvar4}}"
如上例所示,file引數可以指定要包含的變數檔案,其實與如下寫法效果相同
- include_vars: "/testdir/ansible/testfile"
'include_vars'還有一個小功能,'include_vars'可以把變數檔案中的變數全部賦值給另外一個變數,什麼意思呢?來看一個小示例,如下
--- - hosts: test70 remote_user: root gather_facts: no tasks: - include_vars: file: /testdir/ansible/testfile name: trans_var - debug: msg: "{{trans_var}}"
執行上例playbook,debug模組輸出資訊如下
TASK [debug] ********************************************** ok: [test70] => { "msg": { "testvar1": "aaa", "testvar2": "bbb", "testvar3": "ccc", "testvar4": "ddd" } }
可以發現,' trans_var'變數的值就是變數檔案中的所有變數,沒錯,如你所見,我們可以使用name引數指定一個變數,然後將檔案中的所有變數都賦值給這個指定的變數,當使用了name引數時,如果想要獲取到檔案中的某一個變數的值,則可以使用如下方法
tasks: - include_vars: file: /testdir/ansible/testfile name: trans_var - debug: msg: "{{trans_var.testvar4}}"
'include_vars'不僅能夠載入指定的變數檔案,還能夠一次性將指定目錄下的所有變數檔案中的變數載入,使用dir引數即可指定對應的目錄,示例如下
tasks:
- include_vars: dir: /testdir/ansible/test/ name: trans_var - debug: msg: "{{trans_var}}"
上例中,使用dir引數指定了"/testdir/ansible/test/"目錄,此目錄中的所有變數檔案都會被載入,但是在使用dir引數時,需要注意如下三點
第一:指定目錄中的所有檔案的檔案字尾必須是 '.yaml' 、'.yml' 、'.json'中的一種,預設只有這三種字尾是合法字尾,如果目錄中存在非合法字尾的檔案,執行playbook時則會報錯。
第二:如果此目錄中的子目錄中包含變數檔案,子目錄中的變數檔案也會被遞迴的載入,而且子目錄中的檔案也必須遵守上述第一條規則。
第三:dir引數與file引數不能同時使用。
第一點與第二點都是預設設定,可以通過其他選項修改,方法如下
當使用dir引數時,指定目錄中的所有檔案必須以 '.yaml' 、'.yml' 、'.json' 作為檔案的字尾,如果想要手動指定合法的檔案字尾名,則可以使用extensions引數指定哪些字尾是合法的檔案字尾,extensions引數的值需要是一個列表,示例如下
tasks: - include_vars: dir: /testdir/ansible/test/ extensions: [yaml,yml,json,varfile] name: trans_var - debug: msg: "{{trans_var}}"
上例中extensions引數的值為 "[yaml,yml,json,varfile]",這表示指定目錄中的合法檔案字尾名為yaml、yml、json和varfile。
當使用dir引數時,預設情況下會遞迴的載入指定目錄及其子目錄中的所有變數檔案,如果想要控制遞迴的深度,則可以藉助depth引數,示例如下
tasks: - include_vars: dir: /testdir/ansible/test/ depth: 1 name: trans_var - debug: msg: "{{trans_var}}"
上例表示,載入"/testdir/ansible/test/"目錄中的變數檔案,但是其子目錄中的變數檔案將不會被載入,depth的值為1表示遞迴深度為1,預設值為0,表示遞迴到最底層的子目錄。
在使用dir引數時,我們還可以藉助正則表示式,匹配那些我們想要載入的變數檔案,比如,我們只想載入指定目錄中以"var_"開頭的變數檔案,則可以使用如下方法
tasks: - include_vars: dir: /testdir/ansible/test/ files_matching: "^var_.*" name: trans_var - debug: msg: "{{trans_var}}"
如上例所示,使用'files_matching'引數可以指定正則表示式,當指定目錄中的檔名稱符合正則時,則可以被載入
其實,不僅能夠使用正則去匹配需要載入的變數檔名,還可以明確指定,哪些變數檔案不能被載入,使用'ignore_files'引數可以明確指定需要忽略的變數檔名稱,'ignore_files'引數的值是需要是一個列表,示例如下
tasks: - include_vars: dir: /testdir/ansible/test/ ignore_files: ["^var_.*",varintest.yaml] name: trans_var - debug: msg: "{{trans_var}}"
上例表示,載入 /testdir/ansible/test/目錄中的變數檔案,但是所有以"var_"開頭的變數檔案和varintest.yaml變數檔案將不會被載入, 'files_matching'引數和'ignore_files'引數能夠同時使用,當它們同時出現時,會先找出正則匹配到的檔案,然後從中排除那些需要忽略的檔案。
在2.4版本以後的ansible中,當執行了include_vars模組以後,include_vars模組會將載入的變數檔案列表寫入到自己的返回值中,這個返回值的關鍵字為'ansible_included_var_files',所以,如果我們想要知道本次任務引入了哪些變數檔案,則可以使用如下方法
tasks: - include_vars: dir: /testdir/ansible/test/ register: return_val - debug: msg: "{{return_val.ansible_included_var_files}}"
這篇文章就總結到這裡,希望能夠對你有所幫助~~
我的微信公眾號
關注"實用運維筆記"微信公眾號,當部落格中有新文章時,可第一時間得知哦~