013.Ansible Playbook include

一 include

當項目越大,tasks越多的時候。如果將多有的task寫入一個playbook中,可讀性很差,就需要重新組織playbook

可以把一個playbook分成若干份曉得palybook文件,在主配置文件中,把小文件引入進來,就是include

include tasks

[root@node1 ansible]# mkdir tasks

[root@node1 ansible]# cd tasks

[root@node1 tasks]# vim host.yml

[root@node1 tasks]#

- name: modify hostname
  hostname:
    name: test.example.com

[root@node1 tasks]# vim dns.yml

- name: modify resolv.conf
copy: 
src: files.resolv.conf
dest: /etc/resolv.conf
- name: /etc/resolvconf/base
copy:
src: files.resolv.conf
dest: /etc/resolv.conf
when: ansible_distribution == "Ubuntu"

[root@node1 tasks]# mkdir files

[root@node1 tasks]# vim files/resolv.conf 

# Generated by NetworkManager
nameserver 8.8.4.4

[root@node1 tasks]# cd ../

[root@node1 ansible]# vim main.yml

- hosts: demo2.example.com
  tasks:
    - debug:
        msg: "start tasks"
    - include: tasks/host.yml
    - include: tasks/dns.yml
    - debug:
        msg: "執行結束"

執行

[root@node1 ansible]# ansible-playbook main.yml 

TASK [debug] **************************************************************************************************************************************
ok: [demo2.example.com] => {
    "msg": "start tasks"
}

TASK [modify hostname] ****************************************************************************************************************************
changed: [demo2.example.com]

TASK [modify resolv.conf] *************************************************************************************************************************
changed: [demo2.example.com]

TASK [/etc/resolvconf/base] ***********************************************************************************************************************
skipping: [demo2.example.com]

TASK [debug] **************************************************************************************************************************************
ok: [demo2.example.com] => {
    "msg": "執行結束"
}

檢查:

也可以引入handlers

[root@node1 ansible]# vim tasks/nginx.yml

- name: install nginx
  yum:
    name:  nginx
    state: present
- name: mpdify nginx.conf
  template:
    src: templates/nginx.conf.j2
    dest: /etc/nginx/nginx.conf
  notify: 
    - restart nginx
- name: start nginx
  systemd: 
name: nginx state: started enabled: yes

[root@node1 ansible]# vim tasks/handlers.yml

- name: restart nginx
systemd:
name: nginx
state: restarted

[root@node1 ansible]# vim main.yml

- hosts: demo2.example.com
  tasks:
    - debug:
        msg: "start tasks" 
    - include: tasks/host.yml
    - include: tasks/dns.yml
    - include: tasks/nginx.yml
    - debug:
        msg: "執行結束"
  handlers:
    - include: tasks/handlers.yml

二 include_tasks

2.1  include_asks基本使用

在前面嘗試使用的是include,但是在後續版本,可能會取消這種方式,使用include_tasks這總方式開始引入

include可以包含tasks,handlers,playbook,incelude_task專門用來包含tasks

[root@node1 ansible]# vim main.yml

- hosts: demo2.example.com
  tasks:
    - debug:
        msg: "start tasks"
    - include_tasks: tasks/host.yml
    - include_tasks: tasks/dns.yml
    - include_tasks: tasks/nginx.yml
    - debug:
        msg: "執行結束"
  handlers:
    - include_tasks: tasks/handlers.yml

執行

TASK [debug] **************************************************************************************************************************************
ok: [demo2.example.com] => {
    "msg": "start tasks"
}

TASK [include_tasks] ******************************************************************************************************************************
included: /etc/ansible/tasks/host.yml for demo2.example.com

TASK [modify hostname] ****************************************************************************************************************************
changed: [demo2.example.com]

TASK [include_tasks] ******************************************************************************************************************************
included: /etc/ansible/tasks/dns.yml for demo2.example.com

TASK [modify resolv.conf] *************************************************************************************************************************
ok: [demo2.example.com]

TASK [/etc/resolvconf/base] ***********************************************************************************************************************
skipping: [demo2.example.com]

TASK [include_tasks] ******************************************************************************************************************************
included: /etc/ansible/tasks/nginx.yml for demo2.example.com

TASK [install nginx] ******************************************************************************************************************************
ok: [demo2.example.com]

TASK [start nginx] ********************************************************************************************************************************
changed: [demo2.example.com]

TASK [debug] **************************************************************************************************************************************
ok: [demo2.example.com] => {
    "msg": "執行結束"
}

當我們使用include_tasks,本身會被當做一個tasks,這個task會把文件輸入到控制檯中,inclue是透明的,include_tasks是可見的。更像是一個任務,這個任我包含了其他的一些任任務,

在ansible2.7之中,include_task還加入了新的參數

include_tasks:
  file: in.yml

2.2 include_tasks使用tags

如果爲include添加tags,那麼tags是對include中的所有任務生效的,所以當調用include的tag時,include中的所有任務都會執行

但是對include_tasks添加tag,只會對include_tasks本身生效,include_tasks中的所有任務都不生效

- hosts: demo2.example.com
  tasks:
    - debug:
        msg: "start tasks"
    - include_tasks: 
        file:  tasks/host.yml
      tags: host

    - include_tasks: 
        file: tasks/dns.yml
      tags: dns

    - include_tasks:
        file: tasks/nginx.yml
      tags: nginx

    - debug:
        msg: "執行結束"
  handlers:
    - include_tasks: tasks/handlers.yml

[root@node1 ansible]# ansible-playbook main.yml --tags="host"

PLAY [demo2.example.com] **************************************************************************************************************************

TASK [include_tasks] ******************************************************************************************************************************
included: /etc/ansible/tasks/host.yml for demo2.example.com

PLAY RECAP ****************************************************************************************************************************************
demo2.example.com          : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 

只執行自己本身,裏面的任務並沒有執行

若要執行include_tasks裏面的任務,就需要爲執行文件打tags

- hosts: demo2.example.com
  tasks:
    - debug:
        msg: "start tasks" 
    - include_tasks:
        file:  tasks/host.yml
        apply:
          tags: H1
      tags: always    #這裏必須指定always,因爲host.yml執行前提是,include_tasks執行

    - include_tasks: 
        file: tasks/dns.yml
      tags: dns

    - include_tasks: 
        file: tasks/nginx.yml
      tags: nginx 
 
    - debug:
        msg: "執行結束"
  handlers:
    - include_tasks: tasks/handlers.yml

執行

root@node1 ansible]# ansible-playbook main.yml --tags="H1"

PLAY [demo2.example.com] **************************************************************************************************************************

TASK [include_tasks] ******************************************************************************************************************************
included: /etc/ansible/tasks/host.yml for demo2.example.com

TASK [modify hostname] ****************************************************************************************************************************
changed: [demo2.example.com]

PLAY RECAP ****************************************************************************************************************************************
demo2.example.com          : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  

三 import_tasks使用

import_tasks include_task用法類似,都是包含一個任務列表

[root@node1 ansible]# vim main.yml 

- hosts: demo2.example.com
  tasks:
    - debug:
        msg: "start tasks" 
    - include_tasks:
        file:  tasks/host.yml
        apply:
          tags: H1
      tags: always

    - import_tasks: tasks/dns.yml
      tags: dns

    - include_tasks: 
        file: tasks/nginx.yml
      tags: nginx 
 
    - debug:
        msg: "執行結束"
  handlers:
    - include_tasks: tasks/handlers.yml

[root@node1 ansible]# ansible-playbook main.yml --tags="dns"

3.1 include_tasks和import_task區別一

當執行import_task的tags的時候,對應的文件的任務也會執行,但是自己本身是透明的,和include一樣

PLAY [demo2.example.com] **************************************************************************************************************************

TASK [include_tasks] ******************************************************************************************************************************
included: /etc/ansible/tasks/host.yml for demo2.example.com

TASK [modify resolv.conf] *************************************************************************************************************************
ok: [demo2.example.com]

TASK [/etc/resolvconf/base] ***********************************************************************************************************************
skipping: [demo2.example.com]

PLAY RECAP ****************************************************************************************************************************************
demo2.example.com          : ok=2    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0  

import_tasks是靜態的,被import的文件,在被playbook加載時就預處理了,include_tasks是動態的,被include的文件在playbook運行後,纔開始處理

[root@node1 ansible]# cat import_ex.yml
- hosts: demo2.example.com
  gather_facts: no
  vars:
    file_name: tasks/host.yml
  tasks:
    - include_tasks: "{{ file_name }}"
    - import_tasks: "{{ file_name }}"

執行

PLAY [demo2.example.com] **************************************************************************************************************************

TASK [include_tasks] ******************************************************************************************************************************
included: /etc/ansible/tasks/host.yml for demo2.example.com

TASK [modify hostname] ****************************************************************************************************************************
changed: [demo2.example.com]

TASK [modify hostname] ****************************************************************************************************************************
changed: [demo2.example.com]

PLAY RECAP ****************************************************************************************************************************************
demo2.example.com          : ok=3    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

修改配置

[root@node1 ansible]# cat import_ex.yml
- hosts: demo2.example.com
  gather_facts: no
  #vars:
  #  file_name: tasks/host.yml
  tasks:
    - set_facts:
        file_name: tasks/host.yml
    - include_tasks: "{{ file_name }}"
    #- import_tasks: "{{ file_name }}"

[root@node1 ansible]# ansible-playbook import_ex.yml

[root@node1 ansible]# ansible-playbook  import_ex.yml 

PLAY [demo2.example.com] **************************************************************************************************************************

TASK [set_fact] ***********************************************************************************************************************************
ok: [demo2.example.com]

TASK [include_tasks] ******************************************************************************************************************************
included: /etc/ansible/tasks/host.yml for demo2.example.com

TASK [modify hostname] ****************************************************************************************************************************
changed: [demo2.example.com]

PLAY RECAP ****************************************************************************************************************************************
demo2.example.com          : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  

但是使用import就會報錯,原因是include在運行之後加載,但是import在運行之前加載,運行playbook之前,是沒有file_name的參數選項,報錯  

[root@node1 ansible]# vim import_ex.yml

[root@node1 ansible]# cat import_ex.yml
- hosts: demo2.example.com
  gather_facts: no
  #vars:
  #  file_name: tasks/host.yml
  tasks:
    - set_facts:
        file_name: tasks/host.yml
    #- include_tasks: "{{ file_name }}"
    - import_tasks: "{{ file_name }}"

[root@node1 ansible]# ansible-playbook import_ex.yml

ERROR! Error when evaluating variable in import path: {{ file_name }}.

When using static imports, ensure that any variables used in their names are defined in vars/vars_files
or extra-vars passed in from the command line. Static imports cannot use variables from facts or inventory
sources like group or host vars.

3.2 include_tasks和import_task區別二

如果想對包含的列表進行循環操作,只能使用include_tasks。import_task不支持循環操作,即loop對include內容進行循環操作時,只能使用include_tasks,不能使用import_task

[root@node1 ansible]# cat import_ex.yml
- hosts: demo2.example.com
  gather_facts: no
  vars:
    file_name: tasks/host.yml
  tasks:
    #- set_fact:
    #    file_name: tasks/host.yml
    - include_tasks: "{{ file_name }}"
    - import_tasks: "{{ file_name }}"
      loop:
        - 1
        - 2

執行

[root@node1 ansible]# ansible-playbook  import_ex.yml 

ERROR! You cannot use loops on 'import_tasks' statements. You should use 'include_tasks' instead.

The error appears to be in '/etc/ansible/import_ex.yml': line 9, column 7, but may
be elsewhere in the file depending on the exact syntax problem.

The offending line appears to be:

    - include_tasks: "{{ file_name }}"
    - import_tasks: "{{ file_name }}"
      ^ here
We could be wrong, but this one looks like it might be an issue with
missing quotes. Always quote template expression brackets when they
start a value. For instance:

    with_items:
      - {{ foo }}

Should be written as:

    with_items:
      - "{{ foo }}"

使用include_tasks

[root@node1 ansible]# cat import_ex.yml
- hosts: demo2.example.com
  gather_facts: no
  vars:
    file_name: tasks/host.yml
  tasks:
    #- set_fact:
    #    file_name: tasks/host.yml
    - include_tasks: "{{ file_name }}"
      loop:
        - 1
        - 2
    - import_tasks: "{{ file_name }}"

執行

PLAY [demo2.example.com] **************************************************************************************************************************

TASK [include_tasks] ******************************************************************************************************************************
included: /etc/ansible/tasks/host.yml for demo2.example.com
included: /etc/ansible/tasks/host.yml for demo2.example.com

TASK [modify hostname] ****************************************************************************************************************************
changed: [demo2.example.com]

TASK [modify hostname] ****************************************************************************************************************************
changed: [demo2.example.com]

TASK [modify hostname] ****************************************************************************************************************************
changed: [demo2.example.com]

PLAY RECAP ****************************************************************************************************************************************
demo2.example.com          : ok=5    changed=3    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

3.3 include_tasks和import_task區別三

在使用when的條件判斷時,有着本質的區別

當include_tasks使用when時候,when只針對include_tasks任務本身,當執行被包含的認識時,不會對包含的任務進行條件判斷

當import_tasks使用when時,when對應的條件會被用於import的每一個任務,當執行import的任務時,會對每一個包含的任務進行條件判斷

[root@node1 ansible]# vim import_ex.yml 

- hosts: demo2.example.com
  gather_facts: no
  vars:
    file_name: tasks/host.yml
    num: 1
  tasks:
    - include_tasks: "{{ file_name }}"
      when: num == 1

    - set_fact:
        num: 1

    - import_tasks: "{{ file_name }}"
      when: num == 1

執行

[root@node1 ansible]# vim tasks/host.yml

- name: modify num to 0
  set_fact:
    num: 0
- name: modify hostname
  hostname:
    name: test.example.com

[root@node1 ansible]# ansible-playbook import_ex.yml

PLAY [demo2.example.com] **************************************************************************************************************************
TASK [include_tasks] ******************************************************************************************************************************
included: /etc/ansible/tasks/host.yml for demo2.example.com    #include滿足條件,自己本身任務執行
TASK [modify num to 0] ****************************************************************************************************************************
ok: [demo2.example.com]           #包含的第一個任務執行
TASK [modify hostname] ****************************************************************************************************************************
ok: [demo2.example.com]            #包含的第二個任務執行
TASK [set_fact]
*********************************************************************************************************************************** ok: [demo2.example.com] TASK [modify num to 0] **************************************************************************************************************************** ok: [demo2.example.com] #import第一個滿足條件執行,這是num設爲0 TASK [modify hostname] **************************************************************************************************************************** skipping: [demo2.example.com] #第二個任務在進行比較,不滿足,直接跳過 PLAY RECAP **************************************************************************************************************************************** demo2.example.com : ok=5 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0

在include只要條件滿足,就會全部執行包含的內容,import_tasks會對每一個任務做判斷,在確定是否執行


博主聲明:本文的內容來源主要來自譽天教育晏威老師,由本人實驗完成操作驗證,需要的博友請聯繫譽天教育(http://www.yutianedu.com/),獲得官方同意或者晏老師(https://www.cnblogs.com/breezey/)本人同意即可轉載,謝謝!

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