一 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/)本人同意即可轉載,謝謝!