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]

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