一 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/)本人同意即可转载,谢谢!