Loading... <blockquote>在本博客中,ansible是一个系列文章,我们会尽量以通俗易懂的方式总结ansible的相关知识点。 ansible系列博文直达链接:<a href="https://www.zsythink.net/archives/tag/ansible/" target="_blank" rel="noopener">ansible轻松入门系列</a> “ansible系列”中的每篇文章都建立在前文的基础之上,所以,请按照顺序阅读这些文章,否则有可能在阅读中遇到障碍。 </blockquote> 在进行编程时,我们都会将可以重复利用的代码提取出来,将提取出的代码作为一个逻辑单元,这个逻辑单元通常被称为”函数”或者”方法”,”函数”可以让我们更加方便的、重复的调用一段代码,而且,如果需要更改这段代码的逻辑,只要更改函数本身即可,所有调用函数之处的逻辑都会随之改变,同时,函数还可以让程序的可读性变强,比如,主干程序中只有几行代码,这几行代码只是调用了对应的几个函数,我们通常通过函数名称,就能大概的推算出函数的功能,当我们阅读主干程序时,看到各个函数的名称之后,就能够大概推算出整个主干程序的作用和逻辑,如果不使用函数,而是将所有代码都写在主干程序文件中,那么只能一行一行的阅读所有代码以后,才能大概的了解主干程序的作用,所以综上所述,函数能为我们带来很多的方便之处。 在ansible中,其实也有类似的功能,这种功能被称之为”include”,通过include,我们可以在一个playbook中包含另一个文件,以便实现我们刚才所描述的效果,这篇文章我们就来了解一下”include”的用法。 注意:ansible经过版本的迭代更新,”include”的使用方法也有所变化,此处我们先从比较原始的使用方法开始介绍”include”,然后再介绍新的使用方式,原始的使用方式以及对应的关键字在之后的版本中可能会被弃用,所以官网推荐我们使用新的方式进行操作,但是此处我们仍然从原始的使用方式开始总结,以便你看到别人早期编写的playbook时,也能够理解其含义。 先来看一个小示例,假设,我想要编写两个playbook,这两个playbook分别用于安装LAMP环境和LNMP环境,两个playbook的大致内容如下: <div class="enlighter-default enlighter-v-standard enlighter-t-enlighter enlighter-hover enlighter-overflow-scroll"> <div class="enlighter-toolbar"> <div class="enlighter-btn enlighter-btn-raw"></div> <div class="enlighter-btn enlighter-btn-copy"></div> <div class="enlighter-btn enlighter-btn-window"></div> </div> <div class="enlighter"> <div class=""> <div><span class="enlighter-c0"># cat lamp.yml</span></div> </div> <div class=""> <div><span class="enlighter-text">---</span></div> </div> <div class=""> <div><span class="enlighter-text">- hosts: test70</span></div> </div> <div class=""> <div><span class="enlighter-text"> remote_user: root</span></div> </div> <div class=""> <div><span class="enlighter-text"> gather_facts: no</span></div> </div> <div class=""> <div><span class="enlighter-text"> tasks:</span></div> </div> <div class=""> <div><span class="enlighter-text"> - yum:</span></div> </div> <div class=""> <div><span class="enlighter-text"> name: mysql</span></div> </div> <div class=""> <div><span class="enlighter-text"> state: present</span></div> </div> <div class=""> <div><span class="enlighter-text"> - yum:</span></div> </div> <div class=""> <div><span class="enlighter-text"> name: php-fpm</span></div> </div> <div class=""> <div><span class="enlighter-text"> state: present</span></div> </div> <div class=""> <div><span class="enlighter-text"> - yum:</span></div> </div> <div class=""> <div><span class="enlighter-text"> name: httpd</span></div> </div> <div class=""> <div><span class="enlighter-text"> state: present</span></div> </div> <div class=""> <div></div> </div> <div class=""> <div><span class="enlighter-c0"># cat lnmp.yml</span></div> </div> <div class=""> <div><span class="enlighter-text">---</span></div> </div> <div class=""> <div><span class="enlighter-text">- hosts: test70</span></div> </div> <div class=""> <div><span class="enlighter-text"> remote_user: root</span></div> </div> <div class=""> <div><span class="enlighter-text"> gather_facts: no</span></div> </div> <div class=""> <div><span class="enlighter-text"> tasks:</span></div> </div> <div class=""> <div><span class="enlighter-text"> - yum:</span></div> </div> <div class=""> <div><span class="enlighter-text"> name: mysql</span></div> </div> <div class=""> <div><span class="enlighter-text"> state: present</span></div> </div> <div class=""> <div><span class="enlighter-text"> - yum:</span></div> </div> <div class=""> <div><span class="enlighter-text"> name: php-fpm</span></div> </div> <div class=""> <div><span class="enlighter-text"> state: present</span></div> </div> <div class=""> <div><span class="enlighter-text"> - yum:</span></div> </div> <div class=""> <div><span class="enlighter-text"> name: nginx</span></div> </div> <div class=""> <div><span class="enlighter-text"> state: present</span></div> </div> </div> </div> 你一定看出来了,无论在lamp.yml中还是在lnmp.yml中,安装mysql和php部分的任务完全相同的,所以,我们可以把这两个任务提取出来,作为一个逻辑单元,示例如下,我们把安装mysql和php部分的任务提取到install_MysqlAndPhp.yml文件中,文件内容如下: <div class="enlighter-default enlighter-v-standard enlighter-t-enlighter enlighter-hover enlighter-overflow-scroll"> <div class="enlighter-toolbar"> <div class="enlighter-btn enlighter-btn-raw"></div> <div class="enlighter-btn enlighter-btn-copy"></div> <div class="enlighter-btn enlighter-btn-window"></div> </div> <div class="enlighter"> <div class=""> <div><span class="enlighter-c0"># cat install_MysqlAndPhp.yml</span></div> </div> <div class=""> <div><span class="enlighter-text">- yum:</span></div> </div> <div class=""> <div><span class="enlighter-text"> name: mysql</span></div> </div> <div class=""> <div><span class="enlighter-text"> state: present</span></div> </div> <div class=""> <div><span class="enlighter-text">- yum:</span></div> </div> <div class=""> <div><span class="enlighter-text"> name: php-fpm</span></div> </div> <div class=""> <div><span class="enlighter-text"> state: present</span></div> </div> </div> </div> 如上例所示,两个task被提取到了install_MysqlAndPhp.yml文件中,当我们需要安装mysql和php-fpm时,只需要调用此yml文件即可,那么怎样调用这个文件呢?方法如下,我们只要把lamp.yml和lnmp.yml修改为如下模样即可: <div class="enlighter-default enlighter-v-standard enlighter-t-enlighter enlighter-hover enlighter-overflow-scroll"> <div class="enlighter-toolbar"> <div class="enlighter-btn enlighter-btn-raw"></div> <div class="enlighter-btn enlighter-btn-copy"></div> <div class="enlighter-btn enlighter-btn-window"></div> </div> <div class="enlighter"> <div class=""> <div><span class="enlighter-c0"># cat lamp.yml</span></div> </div> <div class=""> <div><span class="enlighter-text">---</span></div> </div> <div class=""> <div><span class="enlighter-text">- hosts: test70</span></div> </div> <div class=""> <div><span class="enlighter-text"> remote_user: root</span></div> </div> <div class=""> <div><span class="enlighter-text"> gather_facts: no</span></div> </div> <div class=""> <div><span class="enlighter-text"> tasks:</span></div> </div> <div class=""> <div><span class="enlighter-text"> - include: install_MysqlAndPhp.</span><span class="enlighter-m3">yml</span></div> </div> <div class=""> <div><span class="enlighter-text"> - yum:</span></div> </div> <div class=""> <div><span class="enlighter-text"> name: httpd</span></div> </div> <div class=""> <div><span class="enlighter-text"> state: present</span></div> </div> <div class=""> <div></div> </div> <div class=""> <div><span class="enlighter-c0"># cat lnmp.yml</span></div> </div> <div class=""> <div><span class="enlighter-text">---</span></div> </div> <div class=""> <div><span class="enlighter-text">- hosts: test70</span></div> </div> <div class=""> <div><span class="enlighter-text"> remote_user: root</span></div> </div> <div class=""> <div><span class="enlighter-text"> gather_facts: no</span></div> </div> <div class=""> <div><span class="enlighter-text"> tasks:</span></div> </div> <div class=""> <div><span class="enlighter-text"> - include: install_MysqlAndPhp.</span><span class="enlighter-m3">yml</span></div> </div> <div class=""> <div><span class="enlighter-text"> - yum:</span></div> </div> <div class=""> <div><span class="enlighter-text"> name: nginx</span></div> </div> <div class=""> <div><span class="enlighter-text"> state: present</span></div> </div> </div> </div> 正如你所看到的,我们使用了include模块,引用了install_MysqlAndPhp.yml文件,当我们引用此文件时,install_MysqlAndPhp.yml文件中的tasks都会在被引用处执行,这就是include的用法,是不是很简单,没错,include模块可以指定一个文件,这个文件中的内容是一个任务列表(一个或多个任务),当使用include模块引用对应的文件时,文件中的任务会在被引用处执行,就好像写在被引用处一样。 经过上述描述,你一定已经明白了怎样使用”include”,上例中,是在tasks关键字中使用include引用了对应的任务列表,其实,在handlers关键字中,也可以使用include,在前文中我们总结过,handlers其实也是一种任务,只是这种任务有相应的触发条件而已(此处不再赘述),那么怎样在handlers关键字中使用include呢?示例如下 <div class="enlighter-default enlighter-v-standard enlighter-t-enlighter enlighter-hover enlighter-overflow-scroll"> <div class="enlighter-toolbar"> <div class="enlighter-btn enlighter-btn-raw"></div> <div class="enlighter-btn enlighter-btn-copy"></div> <div class="enlighter-btn enlighter-btn-window"></div> </div> <div class="enlighter"> <div class=""> <div><span class="enlighter-c0"># cat test_include.yml</span></div> </div> <div class=""> <div><span class="enlighter-text">---</span></div> </div> <div class=""> <div><span class="enlighter-text">- hosts: test70</span></div> </div> <div class=""> <div><span class="enlighter-text"> remote_user: root</span></div> </div> <div class=""> <div><span class="enlighter-text"> gather_facts: no</span></div> </div> <div class=""> <div><span class="enlighter-text"> tasks:</span></div> </div> <div class=""> <div><span class="enlighter-text"> - file:</span></div> </div> <div class=""> <div><span class="enlighter-text"> path: /opt/ttt</span></div> </div> <div class=""> <div><span class="enlighter-text"> state: touch</span></div> </div> <div class=""> <div><span class="enlighter-text"> notify: test include handlers</span></div> </div> <div class=""> <div></div> </div> <div class=""> <div><span class="enlighter-text"> handlers:</span></div> </div> <div class=""> <div><span class="enlighter-text"> - name: test include handlers</span></div> </div> <div class=""> <div><span class="enlighter-text"> include: include_handler.</span><span class="enlighter-m3">yml</span></div> </div> <div class=""> <div></div> </div> <div class=""> <div><span class="enlighter-c0"># cat include_handler.yml</span></div> </div> <div class=""> <div><span class="enlighter-text">- debug:</span></div> </div> <div class=""> <div><span class="enlighter-text"> msg: </span><span class="enlighter-s0">"task1 of handlers"</span></div> </div> <div class=""> <div><span class="enlighter-text">- debug:</span></div> </div> <div class=""> <div><span class="enlighter-text"> msg: </span><span class="enlighter-s0">"task2 of handlers"</span></div> </div> <div class=""> <div><span class="enlighter-text">- debug:</span></div> </div> <div class=""> <div><span class="enlighter-text"> msg: </span><span class="enlighter-s0">"task3 of handlers"</span></div> </div> </div> </div> 如上例所示,当”test include handlers”被触发时,include_handler.yml中的任务将会执行 在上述示例中,无论是在tasks中使用include,还是在handlers中使用include,都是引用了一个任务列表,其实,”include”不仅能够引用任务列表,还能够引用playbook,比如,在一个playbook中引用另一个playbook,示例如下: <div class="enlighter-default enlighter-v-standard enlighter-t-enlighter enlighter-hover enlighter-overflow-scroll"> <div class="enlighter-toolbar"> <div class="enlighter-btn enlighter-btn-raw"></div> <div class="enlighter-btn enlighter-btn-copy"></div> <div class="enlighter-btn enlighter-btn-window"></div> </div> <div class="enlighter"> <div class=""> <div><span class="enlighter-c0"># cat lamp.yml</span></div> </div> <div class=""> <div><span class="enlighter-text">---</span></div> </div> <div class=""> <div><span class="enlighter-text">- hosts: test70</span></div> </div> <div class=""> <div><span class="enlighter-text"> remote_user: root</span></div> </div> <div class=""> <div><span class="enlighter-text"> gather_facts: no</span></div> </div> <div class=""> <div><span class="enlighter-text"> tasks:</span></div> </div> <div class=""> <div><span class="enlighter-text"> - include: install_MysqlAndPhp.</span><span class="enlighter-m3">yml</span></div> </div> <div class=""> <div><span class="enlighter-text"> - yum:</span></div> </div> <div class=""> <div><span class="enlighter-text"> name: httpd</span></div> </div> <div class=""> <div><span class="enlighter-text"> state: present</span></div> </div> <div class=""> <div></div> </div> <div class=""> <div><span class="enlighter-text">- include: lnmp.</span><span class="enlighter-m3">yml</span></div> </div> </div> </div> 如上例所示,我们在lamp.yml的结尾引入了lnmp.yml,当我们在执行lamp.yml时,会先执行lamp相关的任务,然后再执行lnmp.yml中的任务。 在使用”函数”或者”方法”时,可能会需要传入一些”参数”,以便更加灵活的根据实际情况作出对应的处理,那么,include有没有相似的功能呢?答案是肯定的,示例如下: <div class="enlighter-default enlighter-v-standard enlighter-t-enlighter enlighter-hover enlighter-overflow-scroll"> <div class="enlighter-toolbar"> <div class="enlighter-btn enlighter-btn-raw"></div> <div class="enlighter-btn enlighter-btn-copy"></div> <div class="enlighter-btn enlighter-btn-window"></div> </div> <div class="enlighter"> <div class=""> <div><span class="enlighter-c0"># cat test_include1.yml</span></div> </div> <div class=""> <div><span class="enlighter-text">---</span></div> </div> <div class=""> <div><span class="enlighter-text">- hosts: test70</span></div> </div> <div class=""> <div><span class="enlighter-text"> remote_user: root</span></div> </div> <div class=""> <div><span class="enlighter-text"> gather_facts: no</span></div> </div> <div class=""> <div><span class="enlighter-text"> tasks:</span></div> </div> <div class=""> <div><span class="enlighter-text"> - include: </span><span class="enlighter-k1">in</span><span class="enlighter-text">.</span><span class="enlighter-m3">yml</span></div> </div> <div class=""> <div><span class="enlighter-text"> test_var1=hello</span></div> </div> <div class=""> <div><span class="enlighter-text"> test_var2=test</span></div> </div> <div class=""> <div></div> </div> <div class=""> <div><span class="enlighter-c0"># cat in.yml</span></div> </div> <div class=""> <div><span class="enlighter-text">- debug:</span></div> </div> <div class=""> <div><span class="enlighter-text"> msg: </span><span class="enlighter-s0">"{{ test_var1 }}"</span></div> </div> <div class=""> <div><span class="enlighter-text">- debug:</span></div> </div> <div class=""> <div><span class="enlighter-text"> msg: </span><span class="enlighter-s0">"{{ test_var2 }}"</span></div> </div> </div> </div> 如上例所示,在in.yml文件中一共有两个debug任务,这两个任务分别需要两个变量,在in.yml中并未定义任何变量,而是在test_include1.yml中使用include模块引用in.yml时,传入了两个参数,这两个参数的名字与变量名相同,执行上例playbook,可以看到in.yml中的两个任务都正常输出了,这就是向include文件传参的方法,是不是很容易,除了上述方法,我们还能够使用vars关键字,以key: value变量的方式传入参数变量,示例如下: <div class="enlighter-default enlighter-v-standard enlighter-t-enlighter enlighter-hover enlighter-overflow-scroll"> <div class="enlighter-toolbar"> <div class="enlighter-btn enlighter-btn-raw"></div> <div class="enlighter-btn enlighter-btn-copy"></div> <div class="enlighter-btn enlighter-btn-window"></div> </div> <div class="enlighter"> <div class=""> <div><span class="enlighter-text"> tasks:</span></div> </div> <div class=""> <div><span class="enlighter-text"> - include: </span><span class="enlighter-k1">in</span><span class="enlighter-text">.</span><span class="enlighter-m3">yml</span></div> </div> <div class=""> <div><span class="enlighter-text"> vars:</span></div> </div> <div class=""> <div><span class="enlighter-text"> test_var1: hello</span></div> </div> <div class=""> <div><span class="enlighter-text"> test_var2: test</span></div> </div> </div> </div> 上述两种方式都可以传入参数变量,通过vars关键字也能够传入结构稍微复杂的变量数据,以便在包含的文件中使用,示例如下: <div class="enlighter-default enlighter-v-standard enlighter-t-enlighter enlighter-hover enlighter-overflow-scroll"> <div class="enlighter-toolbar"> <div class="enlighter-btn enlighter-btn-raw"></div> <div class="enlighter-btn enlighter-btn-copy"></div> <div class="enlighter-btn enlighter-btn-window"></div> </div> <div class="enlighter"> <div class=""> <div><span class="enlighter-c0"># cat test_include1.yml</span></div> </div> <div class=""> <div><span class="enlighter-text">---</span></div> </div> <div class=""> <div><span class="enlighter-text">- hosts: test70</span></div> </div> <div class=""> <div><span class="enlighter-text"> remote_user: root</span></div> </div> <div class=""> <div><span class="enlighter-text"> gather_facts: no</span></div> </div> <div class=""> <div><span class="enlighter-text"> tasks:</span></div> </div> <div class=""> <div><span class="enlighter-text"> - include: </span><span class="enlighter-k1">in</span><span class="enlighter-text">.</span><span class="enlighter-m3">yml</span></div> </div> <div class=""> <div><span class="enlighter-text"> vars:</span></div> </div> <div class=""> <div><span class="enlighter-text"> users:</span></div> </div> <div class=""> <div><span class="enlighter-text"> bob:</span></div> </div> <div class=""> <div><span class="enlighter-text"> gender: male</span></div> </div> <div class=""> <div><span class="enlighter-text"> lucy:</span></div> </div> <div class=""> <div><span class="enlighter-text"> gender: female</span></div> </div> <div class=""> <div></div> </div> <div class=""> <div><span class="enlighter-c0"># cat in.yml</span></div> </div> <div class=""> <div><span class="enlighter-text">- debug:</span></div> </div> <div class=""> <div><span class="enlighter-text"> msg: </span><span class="enlighter-s0">"{{ item.key}} is {{ item.value.gender }}"</span></div> </div> <div class=""> <div><span class="enlighter-text"> loop: </span><span class="enlighter-s0">"{{ users | dict2items }}"</span></div> </div> </div> </div> 在前文 中,我们也总结过tags的使用方法,我们也可以针对某个include去打标签,示例如下: <div class="enlighter-default enlighter-v-standard enlighter-t-enlighter enlighter-hover enlighter-overflow-scroll"> <div class="enlighter-toolbar"> <div class="enlighter-btn enlighter-btn-raw"></div> <div class="enlighter-btn enlighter-btn-copy"></div> <div class="enlighter-btn enlighter-btn-window"></div> </div> <div class="enlighter"> <div class=""> <div><span class="enlighter-c0"># cat test_include1.yml</span></div> </div> <div class=""> <div><span class="enlighter-text">---</span></div> </div> <div class=""> <div><span class="enlighter-text">- hosts: test70</span></div> </div> <div class=""> <div><span class="enlighter-text"> remote_user: root</span></div> </div> <div class=""> <div><span class="enlighter-text"> gather_facts: no</span></div> </div> <div class=""> <div><span class="enlighter-text"> tasks:</span></div> </div> <div class=""> <div><span class="enlighter-text"> - include: in1.</span><span class="enlighter-m3">yml</span></div> </div> <div class=""> <div><span class="enlighter-text"> tags: t1</span></div> </div> <div class=""> <div><span class="enlighter-text"> - include: in2.</span><span class="enlighter-m3">yml</span></div> </div> <div class=""> <div><span class="enlighter-text"> tags: t2</span></div> </div> <div class=""> <div></div> </div> <div class=""> <div><span class="enlighter-c0"># cat in1.yml</span></div> </div> <div class=""> <div><span class="enlighter-text">- debug:</span></div> </div> <div class=""> <div><span class="enlighter-text"> msg: </span><span class="enlighter-s0">"task1 in in1.yml"</span></div> </div> <div class=""> <div><span class="enlighter-text">- debug:</span></div> </div> <div class=""> <div><span class="enlighter-text"> msg: </span><span class="enlighter-s0">"task2 in in1.yml"</span></div> </div> <div class=""> <div></div> </div> <div class=""> <div><span class="enlighter-c0"># cat in2.yml</span></div> </div> <div class=""> <div><span class="enlighter-text">- debug:</span></div> </div> <div class=""> <div><span class="enlighter-text"> msg: </span><span class="enlighter-s0">"task1 in in2.yml"</span></div> </div> <div class=""> <div><span class="enlighter-text">- debug:</span></div> </div> <div class=""> <div><span class="enlighter-text"> msg: </span><span class="enlighter-s0">"task2 in in2.yml"</span></div> </div> </div> </div> 如上例所示,两个include分别对应两个tag,如果我们在执行test_include1.yml时,指定tag为t2,那么in2.yml中的所有任务将会被执行,执行效果如下: <div class="enlighter-default enlighter-v-standard enlighter-t-enlighter enlighter-hover enlighter-overflow-scroll"> <div class="enlighter-toolbar"> <div class="enlighter-btn enlighter-btn-raw"></div> <div class="enlighter-btn enlighter-btn-copy"></div> <div class="enlighter-btn enlighter-btn-window"></div> </div> <div class="enlighter"> <div class=""> <div><span class="enlighter-c0"># ansible-playbook --tags=t2 test_include1.yml</span></div> </div> <div class=""> <div></div> </div> <div class=""> <div><span class="enlighter-text">PLAY </span><span class="enlighter-g1">[</span><span class="enlighter-text">test70</span><span class="enlighter-g1">]</span> <span class="enlighter-g0">************************************</span></div> </div> <div class=""> <div><span class="enlighter-text">TASK </span><span class="enlighter-g1">[</span><span class="enlighter-text">debug</span><span class="enlighter-g1">]</span> <span class="enlighter-g0">************************************</span></div> </div> <div class=""> <div><span class="enlighter-text">ok: </span><span class="enlighter-g1">[</span><span class="enlighter-text">test70</span><span class="enlighter-g1">]</span><span class="enlighter-text"> =</span><span class="enlighter-g1">></span> <span class="enlighter-g1">{</span></div> </div> <div class=""> <div><span class="enlighter-s0">"msg"</span><span class="enlighter-text">: </span><span class="enlighter-s0">"task1 in in2.yml"</span></div> </div> <div class=""> <div><span class="enlighter-g1">}</span></div> </div> <div class=""> <div></div> </div> <div class=""> <div><span class="enlighter-text">TASK </span><span class="enlighter-g1">[</span><span class="enlighter-text">debug</span><span class="enlighter-g1">]</span> <span class="enlighter-g0">************************************</span></div> </div> <div class=""> <div><span class="enlighter-text">ok: </span><span class="enlighter-g1">[</span><span class="enlighter-text">test70</span><span class="enlighter-g1">]</span><span class="enlighter-text"> =</span><span class="enlighter-g1">></span> <span class="enlighter-g1">{</span></div> </div> <div class=""> <div><span class="enlighter-s0">"msg"</span><span class="enlighter-text">: </span><span class="enlighter-s0">"task2 in in2.yml"</span></div> </div> <div class=""> <div><span class="enlighter-g1">}</span></div> </div> <div class=""> <div></div> </div> <div class=""> <div><span class="enlighter-text">PLAY RECAP ************************************</span></div> </div> </div> </div> 所以,tag是针对include文件中的所有任务生效的。 经过上述描述 ,你一定已经猜到了,我们也可以对include添加条件判断,还可以对include进行循环操作,示例如下: <div class="enlighter-default enlighter-v-standard enlighter-t-enlighter enlighter-hover enlighter-overflow-scroll"> <div class="enlighter-toolbar"> <div class="enlighter-btn enlighter-btn-raw"></div> <div class="enlighter-btn enlighter-btn-copy"></div> <div class="enlighter-btn enlighter-btn-window"></div> </div> <div class="enlighter"> <div class=""> <div><span class="enlighter-c0"># cat test_include1.yml</span></div> </div> <div class=""> <div><span class="enlighter-text">---</span></div> </div> <div class=""> <div><span class="enlighter-text">- hosts: test70</span></div> </div> <div class=""> <div><span class="enlighter-text"> remote_user: root</span></div> </div> <div class=""> <div><span class="enlighter-text"> gather_facts: no</span></div> </div> <div class=""> <div><span class="enlighter-text"> tasks:</span></div> </div> <div class=""> <div><span class="enlighter-text"> - include: in3.</span><span class="enlighter-m3">yml</span></div> </div> <div class=""> <div><span class="enlighter-text"> when: </span><span class="enlighter-n1">2</span> <span class="enlighter-g1">></span> <span class="enlighter-n1">1</span></div> </div> <div class=""> <div><span class="enlighter-text"> - include: in3.</span><span class="enlighter-m3">yml</span></div> </div> <div class=""> <div><span class="enlighter-text"> loop:</span></div> </div> <div class=""> <div><span class="enlighter-text"> - </span><span class="enlighter-n1">1</span></div> </div> <div class=""> <div><span class="enlighter-text"> - </span><span class="enlighter-n1">2</span></div> </div> <div class=""> <div><span class="enlighter-text"> - </span><span class="enlighter-n1">3</span></div> </div> <div class=""> <div></div> </div> <div class=""> <div><span class="enlighter-c0"># cat in3.yml</span></div> </div> <div class=""> <div><span class="enlighter-text">- debug:</span></div> </div> <div class=""> <div><span class="enlighter-text"> msg: </span><span class="enlighter-s0">"task1 in in3.yml"</span></div> </div> <div class=""> <div><span class="enlighter-text">- debug:</span></div> </div> <div class=""> <div><span class="enlighter-text"> msg: </span><span class="enlighter-s0">"task2 in in3.yml"</span></div> </div> </div> </div> 通过上例,你一定看明白了,如果我们想要循环的调用多个任务,则可以使用上例中的方法,将需要循环调用的多个任务写入到一个yml文件中,然后使用include调用这个yml文件,再配合loop进行循环即可。 说到循环,我们再来看一个小例子 <div class="enlighter-default enlighter-v-standard enlighter-t-enlighter enlighter-hover enlighter-overflow-scroll"> <div class="enlighter-toolbar"> <div class="enlighter-btn enlighter-btn-raw"></div> <div class="enlighter-btn enlighter-btn-copy"></div> <div class="enlighter-btn enlighter-btn-window"></div> </div> <div class="enlighter"> <div class=""> <div><span class="enlighter-c0"># cat A.yml</span></div> </div> <div class=""> <div><span class="enlighter-text">---</span></div> </div> <div class=""> <div><span class="enlighter-text">- hosts: test70</span></div> </div> <div class=""> <div><span class="enlighter-text"> remote_user: root</span></div> </div> <div class=""> <div><span class="enlighter-text"> gather_facts: no</span></div> </div> <div class=""> <div><span class="enlighter-text"> tasks:</span></div> </div> <div class=""> <div><span class="enlighter-text"> - include: B.</span><span class="enlighter-m3">yml</span></div> </div> <div class=""> <div><span class="enlighter-text"> loop:</span></div> </div> <div class=""> <div><span class="enlighter-text"> - </span><span class="enlighter-n1">1</span></div> </div> <div class=""> <div><span class="enlighter-text"> - </span><span class="enlighter-n1">2</span></div> </div> <div class=""> <div><span class="enlighter-text"> - </span><span class="enlighter-n1">3</span></div> </div> <div class=""> <div></div> </div> <div class=""> <div><span class="enlighter-c0"># cat B.yml</span></div> </div> <div class=""> <div><span class="enlighter-text">- debug:</span></div> </div> <div class=""> <div><span class="enlighter-text"> msg: </span><span class="enlighter-s0">"{{item}}--task1 in B.yml"</span></div> </div> <div class=""> <div><span class="enlighter-text">- debug:</span></div> </div> <div class=""> <div><span class="enlighter-text"> msg: </span><span class="enlighter-s0">"{{item}}--task2 in B.yml"</span></div> </div> </div> </div> 如上例所示,我们在A.yml中include了B.yml,并且循环调用了B.yml中的两个任务,在B.yml中,我们输出了item的信息,上例playbook执行结果如下 <div class="enlighter-default enlighter-v-standard enlighter-t-enlighter enlighter-hover enlighter-overflow-scroll"> <div class="enlighter-toolbar"> <div class="enlighter-btn enlighter-btn-raw"></div> <div class="enlighter-btn enlighter-btn-copy"></div> <div class="enlighter-btn enlighter-btn-window"></div> </div> <div class="enlighter"> <div class=""> <div><span class="enlighter-c0"># ansible-playbook A.yml</span></div> </div> <div class=""> <div></div> </div> <div class=""> <div><span class="enlighter-text">PLAY </span><span class="enlighter-g1">[</span><span class="enlighter-text">test70</span><span class="enlighter-g1">]</span> <span class="enlighter-g0">*************************************************</span></div> </div> <div class=""> <div></div> </div> <div class=""> <div><span class="enlighter-text">TASK </span><span class="enlighter-g1">[</span><span class="enlighter-text">include</span><span class="enlighter-g1">]</span> <span class="enlighter-g0">*************************************************</span></div> </div> <div class=""> <div><span class="enlighter-text">included: /testdir/ansible/B.</span><span class="enlighter-m3">yml</span> <span class="enlighter-k1">for</span><span class="enlighter-text"> test70</span></div> </div> <div class=""> <div><span class="enlighter-text">included: /testdir/ansible/B.</span><span class="enlighter-m3">yml</span> <span class="enlighter-k1">for</span><span class="enlighter-text"> test70</span></div> </div> <div class=""> <div><span class="enlighter-text">included: /testdir/ansible/B.</span><span class="enlighter-m3">yml</span> <span class="enlighter-k1">for</span><span class="enlighter-text"> test70</span></div> </div> <div class=""> <div></div> </div> <div class=""> <div><span class="enlighter-text">TASK </span><span class="enlighter-g1">[</span><span class="enlighter-text">debug</span><span class="enlighter-g1">]</span> <span class="enlighter-g0">*************************************************</span></div> </div> <div class=""> <div><span class="enlighter-text">ok: </span><span class="enlighter-g1">[</span><span class="enlighter-text">test70</span><span class="enlighter-g1">]</span><span class="enlighter-text"> =</span><span class="enlighter-g1">></span> <span class="enlighter-g1">{</span></div> </div> <div class=""> <div><span class="enlighter-s0">"msg"</span><span class="enlighter-text">: </span><span class="enlighter-s0">"1--task1 in B.yml"</span></div> </div> <div class=""> <div><span class="enlighter-g1">}</span></div> </div> <div class=""> <div></div> </div> <div class=""> <div><span class="enlighter-text">TASK </span><span class="enlighter-g1">[</span><span class="enlighter-text">debug</span><span class="enlighter-g1">]</span> <span class="enlighter-g0">*************************************************</span></div> </div> <div class=""> <div><span class="enlighter-text">ok: </span><span class="enlighter-g1">[</span><span class="enlighter-text">test70</span><span class="enlighter-g1">]</span><span class="enlighter-text"> =</span><span class="enlighter-g1">></span> <span class="enlighter-g1">{</span></div> </div> <div class=""> <div><span class="enlighter-s0">"msg"</span><span class="enlighter-text">: </span><span class="enlighter-s0">"1--task2 in B.yml"</span></div> </div> <div class=""> <div><span class="enlighter-g1">}</span></div> </div> <div class=""> <div></div> </div> <div class=""> <div><span class="enlighter-text">TASK </span><span class="enlighter-g1">[</span><span class="enlighter-text">debug</span><span class="enlighter-g1">]</span> <span class="enlighter-g0">*************************************************</span></div> </div> <div class=""> <div><span class="enlighter-text">ok: </span><span class="enlighter-g1">[</span><span class="enlighter-text">test70</span><span class="enlighter-g1">]</span><span class="enlighter-text"> =</span><span class="enlighter-g1">></span> <span class="enlighter-g1">{</span></div> </div> <div class=""> <div><span class="enlighter-s0">"msg"</span><span class="enlighter-text">: </span><span class="enlighter-s0">"2--task1 in B.yml"</span></div> </div> <div class=""> <div><span class="enlighter-g1">}</span></div> </div> <div class=""> <div></div> </div> <div class=""> <div><span class="enlighter-text">TASK </span><span class="enlighter-g1">[</span><span class="enlighter-text">debug</span><span class="enlighter-g1">]</span> <span class="enlighter-g0">*************************************************</span></div> </div> <div class=""> <div><span class="enlighter-text">ok: </span><span class="enlighter-g1">[</span><span class="enlighter-text">test70</span><span class="enlighter-g1">]</span><span class="enlighter-text"> =</span><span class="enlighter-g1">></span> <span class="enlighter-g1">{</span></div> </div> <div class=""> <div><span class="enlighter-s0">"msg"</span><span class="enlighter-text">: </span><span class="enlighter-s0">"2--task2 in B.yml"</span></div> </div> <div class=""> <div><span class="enlighter-g1">}</span></div> </div> <div class=""> <div></div> </div> <div class=""> <div><span class="enlighter-text">TASK </span><span class="enlighter-g1">[</span><span class="enlighter-text">debug</span><span class="enlighter-g1">]</span> <span class="enlighter-g0">*************************************************</span></div> </div> <div class=""> <div><span class="enlighter-text">ok: </span><span class="enlighter-g1">[</span><span class="enlighter-text">test70</span><span class="enlighter-g1">]</span><span class="enlighter-text"> =</span><span class="enlighter-g1">></span> <span class="enlighter-g1">{</span></div> </div> <div class=""> <div><span class="enlighter-s0">"msg"</span><span class="enlighter-text">: </span><span class="enlighter-s0">"3--task1 in B.yml"</span></div> </div> <div class=""> <div><span class="enlighter-g1">}</span></div> </div> <div class=""> <div></div> </div> <div class=""> <div><span class="enlighter-text">TASK </span><span class="enlighter-g1">[</span><span class="enlighter-text">debug</span><span class="enlighter-g1">]</span> <span class="enlighter-g0">*************************************************</span></div> </div> <div class=""> <div><span class="enlighter-text">ok: </span><span class="enlighter-g1">[</span><span class="enlighter-text">test70</span><span class="enlighter-g1">]</span><span class="enlighter-text"> =</span><span class="enlighter-g1">></span> <span class="enlighter-g1">{</span></div> </div> <div class=""> <div><span class="enlighter-s0">"msg"</span><span class="enlighter-text">: </span><span class="enlighter-s0">"3--task2 in B.yml"</span></div> </div> <div class=""> <div><span class="enlighter-g1">}</span></div> </div> <div class=""> <div></div> </div> <div class=""> <div><span class="enlighter-text">PLAY RECAP </span><span class="enlighter-g0">*************************************************</span></div> </div> <div class=""> <div><span class="enlighter-text">test70 </span><span class="enlighter-g0">:</span><span class="enlighter-text"> ok=</span><span class="enlighter-n1">9</span><span class="enlighter-text"> changed=</span><span class="enlighter-n1">0</span><span class="enlighter-text"> unreachable=</span><span class="enlighter-n1">0</span><span class="enlighter-text"> failed=</span><span class="enlighter-n1">0</span></div> </div> </div> </div> 如你所见,我们在B文件中输出了item的信息,而item的信息正是A文件中loop对应的列表,换句话说就是,内层文件中的任务使用的item其实是外层文件中的item。 聪明如你,一定想到了一个问题,如果B文件中也有循环操作,当我们在B文件中输出item信息时,item信息是B文件中的item信息,还是A文件中的item信息呢?我们一起来试试看,示例如下 <div class="enlighter-default enlighter-v-standard enlighter-t-enlighter enlighter-hover enlighter-overflow-scroll"> <div class="enlighter-toolbar"> <div class="enlighter-btn enlighter-btn-raw"></div> <div class="enlighter-btn enlighter-btn-copy"></div> <div class="enlighter-btn enlighter-btn-window"></div> </div> <div class="enlighter"> <div class=""> <div><span class="enlighter-c0"># cat A.yml</span></div> </div> <div class=""> <div><span class="enlighter-text">---</span></div> </div> <div class=""> <div><span class="enlighter-text">- hosts: test70</span></div> </div> <div class=""> <div><span class="enlighter-text"> remote_user: root</span></div> </div> <div class=""> <div><span class="enlighter-text"> gather_facts: no</span></div> </div> <div class=""> <div><span class="enlighter-text"> tasks:</span></div> </div> <div class=""> <div><span class="enlighter-text"> - include: B.</span><span class="enlighter-m3">yml</span></div> </div> <div class=""> <div><span class="enlighter-text"> loop:</span></div> </div> <div class=""> <div><span class="enlighter-text"> - </span><span class="enlighter-n1">1</span></div> </div> <div class=""> <div><span class="enlighter-text"> - </span><span class="enlighter-n1">2</span></div> </div> <div class=""> <div></div> </div> <div class=""> <div><span class="enlighter-c0"># cat B.yml</span></div> </div> <div class=""> <div><span class="enlighter-text">- debug:</span></div> </div> <div class=""> <div><span class="enlighter-text"> msg: </span><span class="enlighter-s0">"{{item}}--task in B.yml"</span></div> </div> <div class=""> <div><span class="enlighter-text"> loop:</span></div> </div> <div class=""> <div><span class="enlighter-text"> - a</span></div> </div> <div class=""> <div><span class="enlighter-text"> - b</span></div> </div> <div class=""> <div><span class="enlighter-text"> - c</span></div> </div> </div> </div> 如上例所示,B.yml中循环调用了debug模块,而在A.yml中,又循环的调用了B.yml,当出现这种”双层循环”的情况时,B文件中的item信息到底是什么呢?上例playbook执行效果如下: <img class=" lazyloaded" src="https://www.zsythink.net/wp-content/uploads/2018/10/101518_1501_1.png" alt="" data-src="https://www.zsythink.net/wp-content/uploads/2018/10/101518_1501_1.png" style=""> 如上图所示,当出现上述”双层循环”的情况时,内层item的信息为B.yml中的loop列表,而不是A.yml中的loop列表,在这种情况下,如果想要在B文件中获取到A文件中的item信息,该怎么办呢?其实,上图中紫色的警告信息中,已经包含了我们想要的答案,没错,正如你所看到的,在上例的情况中,使用’loop_var选项’即可在B文件中获取到A文件中的item信息,看到’loop_var’,有没有觉得很眼熟?眼熟就对了,在前一篇文章中,我们保留了一个loop_control选项没有介绍,这个选项就是’loop_var’选项,那么现在,我们就来介绍一下loop_control的loop_var选项,示例如下: <div class="enlighter-default enlighter-v-standard enlighter-t-enlighter enlighter-hover enlighter-overflow-scroll"> <div class="enlighter-toolbar"> <div class="enlighter-btn enlighter-btn-raw"></div> <div class="enlighter-btn enlighter-btn-copy"></div> <div class="enlighter-btn enlighter-btn-window"></div> </div> <div class="enlighter"> <div class=""> <div><span class="enlighter-c0"># cat A.yml</span></div> </div> <div class=""> <div><span class="enlighter-text">---</span></div> </div> <div class=""> <div><span class="enlighter-text">- hosts: test70</span></div> </div> <div class=""> <div><span class="enlighter-text"> remote_user: root</span></div> </div> <div class=""> <div><span class="enlighter-text"> gather_facts: no</span></div> </div> <div class=""> <div><span class="enlighter-text"> tasks:</span></div> </div> <div class=""> <div><span class="enlighter-text"> - include: B.</span><span class="enlighter-m3">yml</span></div> </div> <div class=""> <div><span class="enlighter-text"> loop:</span></div> </div> <div class=""> <div><span class="enlighter-text"> - </span><span class="enlighter-n1">1</span></div> </div> <div class=""> <div><span class="enlighter-text"> - </span><span class="enlighter-n1">2</span></div> </div> <div class=""> <div><span class="enlighter-text"> loop_control:</span></div> </div> <div class=""> <div><span class="enlighter-text"> loop_var: outer_item</span></div> </div> <div class=""> <div></div> </div> <div class=""> <div><span class="enlighter-c0"># cat B.yml</span></div> </div> <div class=""> <div><span class="enlighter-text">- debug:</span></div> </div> <div class=""> <div><span class="enlighter-text"> msg: </span><span class="enlighter-s0">"{{outer_item}}--{{item}}--task in B.yml"</span></div> </div> <div class=""> <div><span class="enlighter-text"> loop:</span></div> </div> <div class=""> <div><span class="enlighter-text"> - a</span></div> </div> <div class=""> <div><span class="enlighter-text"> - b</span></div> </div> <div class=""> <div><span class="enlighter-text"> - c</span></div> </div> </div> </div> 如上例所示,我们在A文件中循环调用了B文件,并且在循环时使用了loop_control的loop_var选项,我们将loop_var选项的值设置为”outer_item”,这表示,我们将外层循环的item值存放在了”outer_item”变量中,在B文件中的debug任务中,同时输出了”outer_item”变量和”item”变量的值,执行A.yml,执行结果如下: <div class="enlighter-default enlighter-v-standard enlighter-t-enlighter enlighter-hover enlighter-overflow-scroll"> <div class="enlighter-toolbar"> <div class="enlighter-btn enlighter-btn-raw"></div> <div class="enlighter-btn enlighter-btn-copy"></div> <div class="enlighter-btn enlighter-btn-window"></div> </div> <div class="enlighter"> <div class=""> <div><span class="enlighter-c0"># ansible-playbook A.yml</span></div> </div> <div class=""> <div></div> </div> <div class=""> <div><span class="enlighter-text">PLAY </span><span class="enlighter-g1">[</span><span class="enlighter-text">test70</span><span class="enlighter-g1">]</span> <span class="enlighter-g0">*************************************************</span></div> </div> <div class=""> <div></div> </div> <div class=""> <div><span class="enlighter-text">TASK </span><span class="enlighter-g1">[</span><span class="enlighter-text">include</span><span class="enlighter-g1">]</span> <span class="enlighter-g0">*************************************************</span></div> </div> <div class=""> <div><span class="enlighter-text">included: /testdir/ansible/B.</span><span class="enlighter-m3">yml</span> <span class="enlighter-k1">for</span><span class="enlighter-text"> test70</span></div> </div> <div class=""> <div><span class="enlighter-text">included: /testdir/ansible/B.</span><span class="enlighter-m3">yml</span> <span class="enlighter-k1">for</span><span class="enlighter-text"> test70</span></div> </div> <div class=""> <div></div> </div> <div class=""> <div><span class="enlighter-text">TASK </span><span class="enlighter-g1">[</span><span class="enlighter-text">debug</span><span class="enlighter-g1">]</span> <span class="enlighter-g0">*************************************************</span></div> </div> <div class=""> <div><span class="enlighter-text">ok: </span><span class="enlighter-g1">[</span><span class="enlighter-text">test70</span><span class="enlighter-g1">]</span><span class="enlighter-text"> =</span><span class="enlighter-g1">></span> <span class="enlighter-g1">(</span><span class="enlighter-text">item=a</span><span class="enlighter-g1">)</span><span class="enlighter-text"> =</span><span class="enlighter-g1">></span> <span class="enlighter-g1">{</span></div> </div> <div class=""> <div><span class="enlighter-s0">"msg"</span><span class="enlighter-text">: </span><span class="enlighter-s0">"1--a--task in B.yml"</span></div> </div> <div class=""> <div><span class="enlighter-g1">}</span></div> </div> <div class=""> <div><span class="enlighter-text">ok: </span><span class="enlighter-g1">[</span><span class="enlighter-text">test70</span><span class="enlighter-g1">]</span><span class="enlighter-text"> =</span><span class="enlighter-g1">></span> <span class="enlighter-g1">(</span><span class="enlighter-text">item=b</span><span class="enlighter-g1">)</span><span class="enlighter-text"> =</span><span class="enlighter-g1">></span> <span class="enlighter-g1">{</span></div> </div> <div class=""> <div><span class="enlighter-s0">"msg"</span><span class="enlighter-text">: </span><span class="enlighter-s0">"1--b--task in B.yml"</span></div> </div> <div class=""> <div><span class="enlighter-g1">}</span></div> </div> <div class=""> <div><span class="enlighter-text">ok: </span><span class="enlighter-g1">[</span><span class="enlighter-text">test70</span><span class="enlighter-g1">]</span><span class="enlighter-text"> =</span><span class="enlighter-g1">></span> <span class="enlighter-g1">(</span><span class="enlighter-text">item=c</span><span class="enlighter-g1">)</span><span class="enlighter-text"> =</span><span class="enlighter-g1">></span> <span class="enlighter-g1">{</span></div> </div> <div class=""> <div><span class="enlighter-s0">"msg"</span><span class="enlighter-text">: </span><span class="enlighter-s0">"1--c--task in B.yml"</span></div> </div> <div class=""> <div><span class="enlighter-g1">}</span></div> </div> <div class=""> <div></div> </div> <div class=""> <div><span class="enlighter-text">TASK </span><span class="enlighter-g1">[</span><span class="enlighter-text">debug</span><span class="enlighter-g1">]</span> <span class="enlighter-g0">*************************************************</span></div> </div> <div class=""> <div><span class="enlighter-text">ok: </span><span class="enlighter-g1">[</span><span class="enlighter-text">test70</span><span class="enlighter-g1">]</span><span class="enlighter-text"> =</span><span class="enlighter-g1">></span> <span class="enlighter-g1">(</span><span class="enlighter-text">item=a</span><span class="enlighter-g1">)</span><span class="enlighter-text"> =</span><span class="enlighter-g1">></span> <span class="enlighter-g1">{</span></div> </div> <div class=""> <div><span class="enlighter-s0">"msg"</span><span class="enlighter-text">: </span><span class="enlighter-s0">"2--a--task in B.yml"</span></div> </div> <div class=""> <div><span class="enlighter-g1">}</span></div> </div> <div class=""> <div><span class="enlighter-text">ok: </span><span class="enlighter-g1">[</span><span class="enlighter-text">test70</span><span class="enlighter-g1">]</span><span class="enlighter-text"> =</span><span class="enlighter-g1">></span> <span class="enlighter-g1">(</span><span class="enlighter-text">item=b</span><span class="enlighter-g1">)</span><span class="enlighter-text"> =</span><span class="enlighter-g1">></span> <span class="enlighter-g1">{</span></div> </div> <div class=""> <div><span class="enlighter-s0">"msg"</span><span class="enlighter-text">: </span><span class="enlighter-s0">"2--b--task in B.yml"</span></div> </div> <div class=""> <div><span class="enlighter-g1">}</span></div> </div> <div class=""> <div><span class="enlighter-text">ok: </span><span class="enlighter-g1">[</span><span class="enlighter-text">test70</span><span class="enlighter-g1">]</span><span class="enlighter-text"> =</span><span class="enlighter-g1">></span> <span class="enlighter-g1">(</span><span class="enlighter-text">item=c</span><span class="enlighter-g1">)</span><span class="enlighter-text"> =</span><span class="enlighter-g1">></span> <span class="enlighter-g1">{</span></div> </div> <div class=""> <div><span class="enlighter-s0">"msg"</span><span class="enlighter-text">: </span><span class="enlighter-s0">"2--c--task in B.yml"</span></div> </div> <div class=""> <div><span class="enlighter-g1">}</span></div> </div> <div class=""> <div></div> </div> <div class=""> <div><span class="enlighter-text">PLAY RECAP </span><span class="enlighter-g0">*************************************************</span></div> </div> <div class=""> <div><span class="enlighter-text">test70 </span><span class="enlighter-g0">:</span><span class="enlighter-text"> ok=</span><span class="enlighter-n1">4</span><span class="enlighter-text"> changed=</span><span class="enlighter-n1">0</span><span class="enlighter-text"> unreachable=</span><span class="enlighter-n1">0</span><span class="enlighter-text"> failed=</span><span class="enlighter-n1">0</span></div> </div> </div> </div> 从执行结果可以看出,”outer_item”变量中的值正是外层循环中item的值,这就是loop_var选项的作用。 当出现这种”双层循环”的情况时,则可以在外层循环中使用loop_var选项指定一个变量,这个变量可以用来代替外层循环中的item变量,以便在内层循环中获取到外层循环的item的值,从而避免了两层循环中”item”变量名的冲突,看到这里,你一定已经看明白了。 这篇文章就先总结到这里,希望能够对你有所帮助~ 转载自朱双印日志https://www.zsythink.net/archives/2962 Last modification:May 29, 2024 © Allow specification reprint Like 如果觉得我的文章对你有用,请随意赞赏