ansible笔记(31):变量(六)

  • A+
所属分类:ansible  运维技术

在本博客中,ansible是一个系列文章,我们会尽量以通俗易懂的方式总结ansible的相关知识点。

ansible系列博文直达链接:ansible轻松入门系列

"ansible系列"中的每篇文章都建立在前文的基础之上,所以,请按照顺序阅读这些文章,否则有可能在阅读中遇到障碍。

 

在之前的文章中,我们已经总结了很多变量的用法,今天再来介绍一个引入变量的方法,使用'include_vars'引入变量,不过在介绍'include_vars'之前,我们先来回顾一下'vars_files'的用法,我们知道,通过'vars_files'可以将文件中的变量引入playbook,以便在task中使用,那么,我们先来看一个示例变量文件(注:变量文件位于ansible控制节点中,与目标主机无关),示例变量文件'/testdir/ansible/testfile'中的内容如下:

如上所示,其中一共定义了两个变量,如果我们使用'vars_files'导入这两个变量,可以编写如下playbook

上例中,我们调用了变量文件中的testvar1变量,输出的值为aaa,没有任何问题,但是,我们来考虑一种特殊情况,假设playbook中一共有3个任务,第1个任务调用了变量文件中的变量,第2个任务在变量文件中新增了一个变量,第3个任务能在变量文件中引用到新增的变量么,我们来试试,playbook如下

(注:为了更加方便的操作变量文件进行测试,此处将目标主机设置为test71,主机test71为ansible控制主机)

如上例所示,我们定义了三个任务,第二个任务中,使用lineinfile模块在变量文件中增加了testvar3变量,然后在第三个任务中调用了testvar3变量,执行上例playbook,你会发现,执行出错了,因为在playbook载入vars_files对应的变量文件时,文件中只有两个变量,在执行第三个任务执行,并没有重新载入对应的变量文件,所以执行报错了,那么,聪明如你一定想到了,我们需要一种便捷的方法,能够在任务执行过程中,随时的引入变量文件,以便动态的获取到最新的变量文件内容,没错,依靠'include_vars'即可满足我们的要求,示例如下

如上例所示,由于testvar3已经加入到了变量文件中,所以,我们在上例中的第一个任务中就能调用到testvar3,第二个任务中,我们在变量文件中新增了一个变量testvar4,第三个任务调用了'include_vars'模块,'include_vars'模块重新加载了变量文件,第四个任务中,调用了testvar4变量。

执行上例playbook,完全可以正常执行,这就是'include_vars'模块的优势,它可以动态的以任务的方式在合适的时机引用变量文件中的变量,很方便吧。

 

有些时候,变量文件可能并没有位于ansible主机中,而是位于远程主机中,所以,我们需要先把变量文件从远程主机中拉取到ansible主机中,当通过前面的task拉取到变量文件以后,也可以使用'include_vars'模块加载刚才拉取到的变量文件,以便后面的task可以使用变量文件中的变量。

 

'include_vars'模块其实还有一些常用参数(这些参数大多数都是从2.2版本以后加入的),我们一起来了解一下

先来看一个小示例,如下

如上例所示,file参数可以指定要包含的变量文件,其实与如下写法效果相同

 

'include_vars'还有一个小功能,'include_vars'可以把变量文件中的变量全部赋值给另外一个变量,什么意思呢?来看一个小示例,如下

执行上例playbook,debug模块输出信息如下

可以发现,' trans_var'变量的值就是变量文件中的所有变量,没错,如你所见,我们可以使用name参数指定一个变量,然后将文件中的所有变量都赋值给这个指定的变量,当使用了name参数时,如果想要获取到文件中的某一个变量的值,则可以使用如下方法

 

 

'include_vars'不仅能够加载指定的变量文件,还能够一次性将指定目录下的所有变量文件中的变量加载,使用dir参数即可指定对应的目录,示例如下

  tasks:

上例中,使用dir参数指定了"/testdir/ansible/test/"目录,此目录中的所有变量文件都会被加载,但是在使用dir参数时,需要注意如下三点

第一:指定目录中的所有文件的文件后缀必须是 '.yaml' 、'.yml' 、'.json'中的一种,默认只有这三种后缀是合法后缀,如果目录中存在非合法后缀的文件,执行playbook时则会报错。

第二:如果此目录中的子目录中包含变量文件,子目录中的变量文件也会被递归的加载,而且子目录中的文件也必须遵守上述第一条规则。

第三:dir参数与file参数不能同时使用。

 

第一点与第二点都是默认设置,可以通过其他选项修改,方法如下

 

当使用dir参数时,指定目录中的所有文件必须以 '.yaml' 、'.yml' 、'.json' 作为文件的后缀,如果想要手动指定合法的文件后缀名,则可以使用extensions参数指定哪些后缀是合法的文件后缀,extensions参数的值需要是一个列表,示例如下

上例中extensions参数的值为 "[yaml,yml,json,varfile]",这表示指定目录中的合法文件后缀名为yaml、yml、json和varfile。

 

当使用dir参数时,默认情况下会递归的加载指定目录及其子目录中的所有变量文件,如果想要控制递归的深度,则可以借助depth参数,示例如下

上例表示,加载"/testdir/ansible/test/"目录中的变量文件,但是其子目录中的变量文件将不会被加载,depth的值为1表示递归深度为1,默认值为0,表示递归到最底层的子目录。

 

在使用dir参数时,我们还可以借助正则表达式,匹配那些我们想要加载的变量文件,比如,我们只想加载指定目录中以"var_"开头的变量文件,则可以使用如下方法

如上例所示,使用'files_matching'参数可以指定正则表达式,当指定目录中的文件名称符合正则时,则可以被加载

 

其实,不仅能够使用正则去匹配需要加载的变量文件名,还可以明确指定,哪些变量文件不能被加载,使用'ignore_files'参数可以明确指定需要忽略的变量文件名称,'ignore_files'参数的值是需要是一个列表,示例如下

上例表示,加载 /testdir/ansible/test/目录中的变量文件,但是所有以"var_"开头的变量文件和varintest.yaml变量文件将不会被加载, 'files_matching'参数和'ignore_files'参数能够同时使用,当它们同时出现时,会先找出正则匹配到的文件,然后从中排除那些需要忽略的文件。

 

在2.4版本以后的ansible中,当执行了include_vars模块以后,include_vars模块会将载入的变量文件列表写入到自己的返回值中,这个返回值的关键字为'ansible_included_var_files',所以,如果我们想要知道本次任务引入了哪些变量文件,则可以使用如下方法

 

这篇文章就总结到这里,希望能够对你有所帮助~~

weinxin
我的微信公众号
关注"实用运维笔记"微信公众号,当博客中有新文章时,可第一时间得知哦~
朱双印

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

目前评论:4   其中:访客  3   博主  1

    • avatar 图腾 1

      你的示例中有一个问题:
      – lineinfile:
      path: /testdir/ansible/testfile
      line: ‘testvar3: ccc’
      即使不用调用变量,也是会报错的。因为这样操作的是目标主机test70,会在70上的testfile增加这一行。

        • avatar 图腾 1

          @图腾 抱歉,我看错了。你的是test71

        • avatar echo 5

          又更新了 抢占一个沙发 :mrgreen: