Ansible——37.playbook include

兩個playbook分別用於安裝LAMP環境和LNMP環境

cat lamp.yml
---
- hosts: test70
  remote_user: root
  gather_facts: no
  tasks:
  - yum:
      name: mysql
      state: present
  - yum:
      name: php-fpm
      state: present
  - yum:
      name: httpd
      state: present
cat lnmp.yml
---
- hosts: test70
  remote_user: root
  gather_facts: no
  tasks:
  - yum:
      name: mysql
      state: present
  - yum:
      name: php-fpm
      state: present
  - yum:
      name: nginx
      state: present

重構上面兩段代碼,提取出相同的部分

cat install_MysqlAndPhp.yml
- yum:
    name: mysql
    state: present
- yum:
    name: php-fpm
    state: present
cat lamp.yml
---
- hosts: test70
  remote_user: root
  gather_facts: no
  tasks:
  - include: install_MysqlAndPhp.yml
  - yum:
      name: httpd
      state: present
cat lnmp.yml
---
- hosts: test70
  remote_user: root
  gather_facts: no
  tasks:
  - include: install_MysqlAndPhp.yml
  - yum:
      name: nginx
      state: present

1. include

1.1 在 handlers使用include
cat test_include.yml
---
- hosts: test70
  remote_user: root
  gather_facts: no
  tasks:
  - file:
     path: /opt/ttt
     state: touch
    notify: test include handlers
 
  handlers:
  - name: test include handlers
    include: include_handler.yml
 
cat include_handler.yml
- debug:
    msg: "task1 of handlers"
- debug:
    msg: "task2 of handlers"
- debug:
    msg: "task3 of handlers"

include引用playbook,執行lamp.yml時,會先執行lamp相關的任務,然後再執行lnmp.yml中的任務

 cat lamp.yml
---
- hosts: test70
  remote_user: root
  gather_facts: no
  tasks:
  - include: install_MysqlAndPhp.yml
  - yum:
      name: httpd
      state: present
 
- include: lnmp.yml
1.2 include傳入參數
cat test_include1.yml
---
- hosts: test70
  remote_user: root
  gather_facts: no
  tasks:
  - include: in.yml
     test_var1=hello
     test_var2=test
 
cat in.yml
- debug:
    msg: "{{ test_var1 }}"
- debug:
    msg: "{{ test_var2 }}"

使用 vars關鍵字,以key: value變量的方式傳入參數變量

  tasks:
  - include: in.yml
    vars:
     test_var1: hello
     test_var2: test
cat test_include1.yml
---
- hosts: test70
  remote_user: root
  gather_facts: no
  tasks:
  - include: in.yml
    vars:
     users:
      bob:
        gender: male
      lucy:
        gender: female
         
cat in.yml
- debug:
    msg: "{{ item.key}} is {{ item.value.gender }}"
  loop: "{{ users | dict2items }}"
1.3 include中打標籤
cat test_include1.yml
---
- hosts: test70
  remote_user: root
  gather_facts: no
  tasks:
  - include: in1.yml
    tags: t1
  - include: in2.yml
    tags: t2
 
cat in1.yml
- debug:
    msg: "task1 in in1.yml"
- debug:
    msg: "task2 in in1.yml"
 
cat in2.yml
- debug:
    msg: "task1 in in2.yml"
- debug:
    msg: "task2 in in2.yml"
1.4 對include進行循環操作
cat test_include1.yml
---
- hosts: test70
  remote_user: root
  gather_facts: no
  tasks:
  - include: in3.yml
    when: 2 > 1
  - include: in3.yml
    loop:
    - 1
    - 2
    - 3
 
cat in3.yml
- debug:
    msg: "task1 in in3.yml"
- debug:
    msg: "task2 in in3.yml"

在A.yml中include了B.yml,並且循環調用了B.yml中的兩個任務,在B.yml中,輸出了item的信息

cat A.yml
---
- hosts: test70
  remote_user: root
  gather_facts: no
  tasks:
  - include: B.yml
    loop:
    - 1
    - 2
    - 3
 
cat B.yml
- debug:
    msg: "{{item}}--task1 in B.yml"
- debug:
    msg: "{{item}}--task2 in B.yml"

“雙層循環”:B.yml中循環調用了debug模塊,而在A.yml中,又循環的調用了B.yml

cat A.yml
---
- hosts: test70
  remote_user: root
  gather_facts: no
  tasks:
  - include: B.yml
    loop:
    - 1
    - 2
 
cat B.yml
- debug:
    msg: "{{item}}--task in B.yml"
  loop:
  - a
  - b
  - c

loop_control的loop_var
在A文件中循環調用了B文件,並且在循環時使用了loop_control的loop_var選項,將 loop_var選項的值設置爲"outer_item",這表示,將外層循環的item值存放在了"outer_item"變量中,在B文件中的 debug任務中,同時輸出了"outer_item"變量和"item"變量的值

cat A.yml
---
- hosts: test70
  remote_user: root
  gather_facts: nog
  tasks:
  - include: B.yml
    loop:
    - 1
    - 2
    loop_control:
      loop_var: outer_item
 
cat B.yml
- debug:
    msg: "{{outer_item}}--{{item}}--task in B.yml"
  loop:
  - a
  - b
  - c

2. include_tasks

cat intest.yml
---
- hosts: test70
  remote_user: root
  gather_facts: no
  tasks:
  - debug:
      msg: "test task1"
  - include_tasks: in.yml
  - debug:
      msg: "test task2"
 
# cat in.yml
- debug:
    msg: "task1 in in.yml"
- debug:
    msg: "task2 in in.yml"

2.7版本開始,"include_tasks"模塊加入了file參數和apply參數,file參數可以用來指定要包含的任務列表文件

- include_tasks:
     file: in.yml

等價於

  - include_tasks: in.yml

在使用tags時,“include_tasks” 與"include"並不相同,標籤只會對"include_tasks"任務本身生效,而不會對其中包含的任務生效

cat intest.yml
---
- hosts: test70
  remote_user: root
  gather_facts: no
  tasks:
  - debug:
      msg: "test task1"
  - include_tasks:
      file: in.yml
    tags: t1
  - debug:
      msg: "test task2"

如果想要tags對"include_tasks"中包含的所有任務都生效,該怎麼實現呢?這時,就需要使用到"include_tasks"模塊的apply參數

---
- hosts: test70
  remote_user: root
  gather_facts: no
  tasks:
  - include_tasks:
      file: in.yml
      apply:
        tags:
        - t1

執行上例playbook以後,並沒有如預想的一樣調用in.yml中的任務,就連"include_tasks"任務自身也沒有被調用

---
- hosts: test70
  remote_user: root
  gather_facts: no
  tasks:
  - include_tasks:
      file: in.yml
      apply:
        tags:
        - t1
    tags: always

in.yml中的任務並未"always"執行,而"include_tasks"任務本身卻"always"執 行了,所以,可以得出結論,上例中的always標籤只是針對"include_tasks"任務自身而言的,之所以 爲"include_tasks"任務添加always標籤,就是爲了讓apply參數中的t1標籤能夠針對包含的所有任務生效,always標籤並不會 對被包含的所有任務生效

cat intest.yml
---
- hosts: test70
  remote_user: root
  gather_facts: no
  tasks:
  - debug:
      msg: "test task"
    tags: t0
  - include_tasks:
      file: in.yml
      apply:
        tags:
        - t1
    tags: always

apply參數中的tags用於給in.yml中的任務統一打標籤,"include_tasks"對應的tags用於 給"include_tasks"任務自身打標籤,同時,如果想要apply參數中的tags能夠生效,"include_tasks"的標籤中必須包含 always標籤

---
- hosts: test70
  remote_user: root
  gather_facts: no
  tasks:
  - debug:
      msg: "test task"
    tags: t0
  - include_tasks:
      file: in.yml
      apply:
        tags: t1,always
    tags: always

3. import_tasks

cat intest1.yml
---
- hosts: test70
  remote_user: root
  gather_facts: no
  tasks:
  - debug:
      msg: "test task"
  - import_tasks: in.yml
 
cat in.yml
- debug:
    msg: "task1 in in.yml"
- debug:
    msg: "task2 in in.yml

import_tasks和include_tasks不同之處在於,import_tasks是靜態的,include_tasks是動態的。
靜態的意思就是被include的文件在playbook被加載時就展開了(是預處理的)。
動態的意思就是被include的文件在playbook運行時纔會被展開(是實時處理的)。
由於include_tasks是動態的,所以,被include的文件的文件名可以使用任何變量替換。
由於import_tasks是靜態的,所以,被include的文件的文件名不能使用動態的變量替換。

cat intest3.yml
---
- hosts: test70
  remote_user: root
  gather_facts: no
  vars:
    file_name: in.yml
  tasks:
  - import_tasks: "{{file_name}}"
  - include_tasks: "{{file_name}}

set_fact的方式定義了file_name變量

cat intest3.yml
---
- hosts: test70
  remote_user: root
  gather_facts: no
  tasks:
  - set_fact:
      file_name: in.yml
  - import_tasks: "{{file_name}}"
  - include_tasks: "{{file_name}}"

使用了set_fact的方式定義了file_name變量,嘗試執行上例playbook,會發現報錯。
當使用靜態的import時,請確保文件名中使用到的變量被定義在vars中、vars_files中、或者extra-vars中,靜態的import不支持其他方式傳入的變量。
想要對包含的任務列表進行循環操作,則只能使用"include_tasks"關鍵字,不能使用"import_tasks"關鍵字,"import_tasks"並不支持循環操作,
也就是說,使用"loop"關鍵字或"with_items"關鍵字對include文件進行循環操作時,只能配合"include_tasks"才能正常運行。
當使用when關鍵字對include文件添加了條件判斷時,只有條件滿足後,include文件中的任務列表纔會被執行,其實,when關鍵字對"include_tasks"和"import_tasks"的實際操作有着本質區別,區別如下:
當對"include_tasks"使用when進行條件判斷時,when對應的條件只會應用於"include_tasks"任務本身,當執行被包含的任務時,不會對這些被包含的任務重新進行條件判斷。
當對"import_tasks"使用when進行條件判斷時,when對應的條件會應用於被include的文件中的每一個任務,當執行被包含的任務時,會對每一個被包含的任務進行同樣的條件判斷。

cat intest4.yml
---
- hosts: test70
  remote_user: root
  gather_facts: no
  tasks:
  - name: '----------set testvar to 0'
    set_fact:
      testnum: 0
  - debug:
      msg: '-----include_tasks-----enter the in1.yml-----'
  - include_tasks: in1.yml
    when: testnum == 0
 
  - name: '----------set testvar to 0'
    set_fact:
      testnum: 0
  - debug:
      msg: '-----import_tasks-----enter the in1.yml-----'
  - import_tasks: in1.yml
    when: testnum == 0
 
# cat in1.yml
- set_fact:
    testnum: 1
 
- debug:
    msg: "task1 in in1.yml"

4. import_playbook

cat intest6.yml
---
- hosts: test70
  remote_user: root
  gather_facts: no
  tasks:
  - debug:
      msg: "test task in intest6.yml"
 
- import_playbook: intest7.yml
 
cat intest7.yml
---
- hosts: test70
  remote_user: root
  gather_facts: no
  tasks:
  - debug:
      msg: "test task in intest7.yml"

————Blueicex 2020/3/30 10:08 [email protected]

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