Ansible——39.playbook 角色

在這裏插入圖片描述
創建的角色的角色名爲demorole,demorole目錄就代表了這個角色,此目錄中包含了defaults 、files 、handlers 、meta 、tasks 、templates 、vars等子目錄,而且在defaults 、handlers 、meta 、tasks 、vars等目錄中,還都有一個名爲"main.yml"的文件。
tasks目錄:角色需要執行的主任務文件放置在此目錄中,默認的主任務文件名爲main.yml,當調用角色時,默認會執行main.yml文件中的任務,也可以將其他需要執行的任務文件通過include的方式包含在tasks/main.yml文件中。
handlers目錄:當角色需要調用handlers時,默認會在此目錄中的main.yml文件中查找對應的handler
defaults目錄:角色會使用到的變量可以寫入到此目錄中的main.yml文件中,通 常,defaults/main.yml文件中的變量都用於設置默認值,以便在沒有設置對應變量值時,變量有默認的值可以使用,定義在defaults /main.yml文件中的變量的優先級是最低的。
vars目錄:角色會使用到的變量可以寫入到此目錄中的main.yml文件中,看到這裏肯定會有疑 問,vars/main.yml文件和defaults/main.yml文件的區別在哪裏呢?區別就是,defaults/main.yml文件中的變 量的優先級是最低的,而vars/main.yml文件中的變量的優先級非常高,如果只是想提供一個默認的配置,那麼可以把對應的變量定義在 defaults/main.yml中,如果想要確保別人在調用角色時,使用的值就是指定的值,則可以將變量定義在vars/main.yml中,因 爲定義在vars/main.yml文件中的變量的優先級非常高,所以其值比較難以覆蓋。
meta目錄:如果想要賦予這個角色一些元數據,則可以將元數據寫入到meta/main.yml文件中,這 些元數據用於描述角色的相關屬性,比如 作者信息、角色主要作用等等,也可以在meta/main.yml文件中定義這個角色依賴於哪些其他角色,或者改變角色的默認調用設定,在之後會有一些 實際的示例,此處不用糾結。
templates目錄: 角色相關的模板文件可以放置在此目錄中,當使用角色相關的模板時,如果沒有指定路徑,會默認從此目錄中查找對應名稱的模板文件。
files目錄:角色可能會用到的一些其他文件可以放置在此目錄中,比如,當定義nginx角色時,需要配置https,那麼相關的證書文件即可放置在此目錄中。
上述目錄並不全是必須的,一般情況下,都至少會有一個tasks目錄。

創建一個名爲"testrole"的目錄,這個目錄就代表了"testrole"角色

mkdir testrole
mkdir tasks
touch tasks/main.yml
vim  tasks/main.yml
debug:    
msg: "hello role!"

調用角色,使用test.yml文件來調用testrole角色:

cat test.yml
- hosts: test70
  roles:
  - testrole

調用角色時的將test.yml文件寫在了testrole目錄的同級目錄中,調用testrole角色 時,test.yml會從同級目錄中查找與testrole角色同名的目錄,還有一些其他的目錄,在調用角色時,test.yml也會去查找:
同級目錄中的roles目錄中。
當前系統用戶的家目錄中的.ansible/roles目錄,即 ~/.ansible/roles目錄中。
只要testrole目錄處於上述三個目錄中的任何一個目錄中,都可以使用上述方法正常的調用。
可修改ansible的配置文件,設置自己的角色搜索目錄,編輯/etc/ansible/ansible.cfg配置文件,設置roles_path選項,此項默認是註釋掉的,將註釋符去掉,當想要設置多個路徑時,多個路徑之間用冒號隔開:
roles_path = /etc/ansible/roles:/opt:/testdir
即使的角色目錄不處於上述目錄中的任何一個,也可以使用絕對路徑的方式,調用對應的角色。

- hosts: test70
  roles:
  - "/testdir/ansible/testrole/"

或者

- hosts: test70
  roles:
  - role: "/testdir/ansible/testrole/"

在roles關鍵字中使用role關鍵字指定角色對應的絕對路徑,也可以直接調用角色,即使不使用絕對路徑,也可以使用同樣的語法指定角色名。

- hosts: test70
  roles:
  - role: testrole

在角色中使用變量

vim tasks/main.yml
- debug:
    msg: "hello {{ testvar }} !"

在輸出的信息中使用了testvar變量,在調用這個角色時,則需要傳入對應的變量,否則就會報錯。

- hosts: test70
  roles:
  - role: testrole
    vars:
      testvar: "www.zsythink.net"

可以爲testvar變量設置默認值,在testrole目錄中創建一個defaults目錄,並且創建defaults/main.yml文 件,defaults/main.yml文件內容如下:

cat testrole/defaults/main.yml
testvar: "role"

在默認情況下,角色中的的變量是全局可訪問的

在這裏插入圖片描述
定義了兩個示例角色,都使用了名爲testvar的變量,都有各自的默認值,在testrole角色中,testvar的默認值爲"test",在demorole角色中,testvar的默認值爲"demo",在 test.yml文件中,調用了這兩個角色,在調用testrole角色時,傳入了testvar變量,其值爲zsythink,但是在調用 demorole角色時,沒有傳入testvar變量,按照正常的理解,當執行test.yml文件時,testrole應該使用"zsythink"作 爲testvar變量的值,demorole應該使用默認值"demo"作爲testvar變量的值。

ansible-playbook test.yml
 
PLAY [test70] *************************************************
 
TASK [Gathering Facts] *****************************************
ok: [test70]
 
TASK [testrole : debug] *****************************************
ok: [test70] => {
    "msg": "hello zsythink!"
}
 
TASK [demorole : debug] **************************************
ok: [test70] => {
    "msg": "hello zsythink!"
}
 
PLAY RECAP *************************************************
test70                     : ok=3    changed=0    unreachable=0    failed=0

無論是testrole還是demorole,都使用了"zsythink"作爲了testvar的變 量值,在默認情況下,角色中的變量是全局可訪問的,上例中,當將testvar變量的值設置 爲"zsythink"時,就表示將testrole和demorole中的testvar變量的值都設置成了"zsythink",所以最終輸出信息時,兩個角色的testvar變量都使用了相同的值。
如果想要解決上述問題,則可以將變量的訪問域變成角色所私有的,如果想要將變量變成角色私有的,則需要設置/etc/ansible /ansible.cfg文件,將private_role_vars的值設置爲yes,默認情況下,"private_role_vars = yes"是被註釋的,將前面的註釋符去除。
默認情況下,無法多次調用同一個角色,playbook只會調用一次testrole角色:

cat test.yml
- hosts: test70
  roles:
  - role: testrole
  - role: testrole

如果想要多次調用同一個角色,有兩種方法:
方法一:設置角色的allow_duplicates屬性 ,讓其支持重複的調用。
方法二:調用角色時,傳入的參數值不同。
方法一需要爲角色設置allow_duplicates屬性,需要在testrole中創建meta/main.yml文件:.

cat testrole/meta/main.yml
allow_duplicates: true

方法二,當調用角色需要傳參時,如果參數的值不同,則可以連續調用多次:

cat test.yml
- hosts: test70
  roles:
  - role: testrole
    vars:
      testvar: "zsythink"
  - role: testrole
    vars:
      testvar: "zsythink.net"

變量的優先級,在defaults/main.yml文件和vars/main.yml文件中同時定義 testvar變量,併爲其賦值不同的值。

cat testrole/defaults/main.yml
testvar: "test"
# cat testrole/vars/main.yml
testvar: "testvar_in_vars_directory"

在調用testrole時,仍然傳入testvar變量,看看testvar變量到底會使用哪個值作爲最終的值

 cat test.yml
- hosts: test70
  roles:
  - role: testrole
    vars:
      testvar: "zsythink"

即使在調用角色的時候傳入對應的變量,也無法覆蓋定義在vars/main.yml文件中的值,利用這個 特性,要確保使用的值定義在vars/main.yml中,以便別人在調用角色時,使用的值就是定義的值,也是有辦法靈活的進行覆蓋,比如在調用playbook時使用"-e"選項傳入參數。

ansible-playbook -e testvar='usethis' test.yml
 
PLAY [test70] *************************************************
 
TASK [Gathering Facts] *****************************************
ok: [test70]
 
TASK [testrole : debug] ****************************************
ok: [test70] => {
    "msg": "hello usethis!"
}
 
PLAY RECAP *************************************************
test70                     : ok=2    changed=0    unreachable=0    failed=0

除了使用"-e"傳入的變量的優先級,其他變量(包括主機變量)的優先級均低於vars/main.yml中變量的優先級。
testrole需要使用一些模板,可以直接將模板文件放到templates目錄中。
testrole中需要使用一個名爲test.conf.j2的模板文件,將test.conf.j2文件放置在testrole/templates/目錄中,test.conf.j2文件內容如下

cat testrole/templates/test.conf.j2
something in template;
{{ template_var }}

模板文件中使用到了 template_var變量,爲 template_var變量定義一個默認變量。

cat testrole/defaults/main.yml
testvar: "test"
template_var: "template"

在testrole中,直接使用這個模板文件

cat testrole/tasks/main.yml
- debug:
    msg: "hello {{ testvar }}!"
- template:
    src: test.conf.j2
    dest: /opt/test.conf

在使用template任務時,src直接指定了對應的模板文件的名稱,並沒有指定任何路徑,這代表角色會默認去templates子目錄中查找對應的文件。
在角色中使用handlers以便進行觸發,則可以直接將對應的handler任務寫入到handlers/main.yml文件中,示例如下:

cat testrole/handlers/main.yml
- name: test_handler
  debug:
    msg: "this is a test handler"
cat testrole/tasks/main.yml
- debug:
    msg: "hello testrole!"
  changed_when: true
  notify: test_handler

當需要notify對應handler時,直接寫入handler對應的名稱即可,角色會自動去handlers/main.yml文件中查找對應的handler。

————Blueicex 2020/3/31 11:41 [email protected]

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章