内容简介:所属分类:ansible
- A+
所属分类:ansible 运维技术
在本博客中,ansible是一个系列文章,我们会尽量以通俗易懂的方式总结ansible的相关知识点。
ansible系列博文直达链接:ansible轻松入门系列
"ansible系列"中的每篇文章都建立在前文的基础之上,所以, 请按照顺序阅读这些文章,否则有可能在阅读中遇到障碍。
在之前的文章中,我们已经总结了很多变量的用法,今天再来介绍一个引入变量的方法,使用'include_vars'引入变量,不过在介绍'include_vars'之前,我们先来回顾一下'vars_files'的用法,我们知道,通过'vars_files'可以将文件中的变量引入playbook,以便在task中使用,那么,我们先来看一个示例变量文件(注:变量文件位于ansible控制节点中,与目标主机无关),示例变量文件'/testdir/ansible/testfile'中的内容如下:
testvar1: aaa testvar2: bbb
如上所示,其中一共定义了两个变量,如果我们使用'vars_files'导入这两个变量,可以编写如下playbook
--- - hosts: test70 remote_user: root gather_facts: no vars_files: - /testdir/ansible/testfile tasks: - debug: msg: "{{testvar1}}"
上例中,我们调用了变量文件中的testvar1变量,输出的值为aaa,没有任何问题,但是,我们来考虑一种特殊情况,假设playbook中一共有3个任务,第1个任务调用了变量文件中的变量,第2个任务在变量文件中新增了一个变量,第3个任务能在变量文件中引用到新增的变量么,我们来试试,playbook如下
(注:为了更加方便的操作变量文件进行测试,此处将目标主机设置为test71,主机test71为ansible控制主机)
--- - hosts: test71 remote_user: root gather_facts: no vars_files: - /testdir/ansible/testfile tasks: - debug: msg: "{{testvar1}},{{testvar2}}" - lineinfile: path: "/testdir/ansible/testfile" line: "testvar3: ccc" - debug: msg: "{{testvar1}},{{testvar2}},{{testvar3}}"
如上例所示,我们定义了三个任务,第二个任务中,使用lineinfile模块在变量文件中增加了testvar3变量,然后在第三个任务中调用了testvar3变量,执行上例playbook,你会发现,执行出错了,因为在playbook载入vars_files对应的变量文件时,文件中只有两个变量,在执行第三个任务执行,并没有重新载入对应的变量文件,所以执行报错了,那么,聪明如你一定想到了,我们需要一种便捷的方法,能够在任务执行过程中,随时的引入变量文件,以便动态的获取到最新的变量文件内容,没错,依靠'include_vars'即可满足我们的要求,示例如下
--- - hosts: test71 remote_user: root gather_facts: no vars_files: - /testdir/ansible/testfile tasks: - debug: msg: "{{testvar3}}" - lineinfile: path: "/testdir/ansible/testfile" line: "testvar4: ddd" - include_vars: "/testdir/ansible/testfile" - debug: msg: "{{testvar4}}"
如上例所示,由于testvar3已经加入到了变量文件中,所以,我们在上例中的第一个任务中就能调用到testvar3,第二个任务中,我们在变量文件中新增了一个变量testvar4,第三个任务调用了'include_vars'模块,'include_vars'模块重新加载了变量文件,第四个任务中,调用了testvar4变量。
执行上例playbook,完全可以正常执行,这就是'include_vars'模块的优势,它可以动态的以任务的方式在合适的时机引用变量文件中的变量,很方便吧。
有些时候,变量文件可能并没有位于ansible主机中,而是位于远程主机中,所以,我们需要先把变量文件从远程主机中拉取到ansible主机中,当通过前面的task拉取到变量文件以后,也可以使用'include_vars'模块加载刚才拉取到的变量文件,以便后面的task可以使用变量文件中的变量。
'include_vars'模块其实还有一些常用参数(这些参数大多数都是从2.2版本以后加入的),我们一起来了解一下
先来看一个小示例,如下
--- - hosts: test70 remote_user: root gather_facts: no tasks: - include_vars: file: /testdir/ansible/testfile - debug: msg: "{{testvar4}}"
如上例所示,file参数可以指定要包含的变量文件,其实与如下写法效果相同
- include_vars: "/testdir/ansible/testfile"
'include_vars'还有一个小功能,'include_vars'可以把变量文件中的变量全部赋值给另外一个变量,什么意思呢?来看一个小示例,如下
--- - hosts: test70 remote_user: root gather_facts: no tasks: - include_vars: file: /testdir/ansible/testfile name: trans_var - debug: msg: "{{trans_var}}"
执行上例playbook,debug模块输出信息如下
TASK [debug] ********************************************** ok: [test70] => { "msg": { "testvar1": "aaa", "testvar2": "bbb", "testvar3": "ccc", "testvar4": "ddd" } }
可以发现,' trans_var'变量的值就是变量文件中的所有变量,没错,如你所见,我们可以使用name参数指定一个变量,然后将文件中的所有变量都赋值给这个指定的变量,当使用了name参数时,如果想要获取到文件中的某一个变量的值,则可以使用如下方法
tasks: - include_vars: file: /testdir/ansible/testfile name: trans_var - debug: msg: "{{trans_var.testvar4}}"
'include_vars'不仅能够加载指定的变量文件,还能够一次性将指定目录下的所有变量文件中的变量加载,使用dir参数即可指定对应的目录,示例如下
tasks:
- include_vars: dir: /testdir/ansible/test/ name: trans_var - debug: msg: "{{trans_var}}"
上例中,使用dir参数指定了"/testdir/ansible/test/"目录,此目录中的所有变量文件都会被加载,但是在使用dir参数时,需要注意如下三点
第一:指定目录中的所有文件的文件后缀必须是 '.yaml' 、'.yml' 、'.json'中的一种,默认只有这三种后缀是合法后缀,如果目录中存在非合法后缀的文件,执行playbook时则会报错。
第二:如果此目录中的子目录中包含变量文件,子目录中的变量文件也会被递归的加载,而且子目录中的文件也必须遵守上述第一条规则。
第三:dir参数与file参数不能同时使用。
第一点与第二点都是默认设置,可以通过其他选项修改,方法如下
当使用dir参数时,指定目录中的所有文件必须以 '.yaml' 、'.yml' 、'.json' 作为文件的后缀,如果想要手动指定合法的文件后缀名,则可以使用extensions参数指定哪些后缀是合法的文件后缀,extensions参数的值需要是一个列表,示例如下
tasks: - include_vars: dir: /testdir/ansible/test/ extensions: [yaml,yml,json,varfile] name: trans_var - debug: msg: "{{trans_var}}"
上例中extensions参数的值为 "[yaml,yml,json,varfile]",这表示指定目录中的合法文件后缀名为yaml、yml、json和varfile。
当使用dir参数时,默认情况下会递归的加载指定目录及其子目录中的所有变量文件,如果想要控制递归的深度,则可以借助depth参数,示例如下
tasks: - include_vars: dir: /testdir/ansible/test/ depth: 1 name: trans_var - debug: msg: "{{trans_var}}"
上例表示,加载"/testdir/ansible/test/"目录中的变量文件,但是其子目录中的变量文件将不会被加载,depth的值为1表示递归深度为1,默认值为0,表示递归到最底层的子目录。
在使用dir参数时,我们还可以借助正则表达式,匹配那些我们想要加载的变量文件,比如,我们只想加载指定目录中以"var_"开头的变量文件,则可以使用如下方法
tasks: - include_vars: dir: /testdir/ansible/test/ files_matching: "^var_.*" name: trans_var - debug: msg: "{{trans_var}}"
如上例所示,使用'files_matching'参数可以指定正则表达式,当指定目录中的文件名称符合正则时,则可以被加载
其实,不仅能够使用正则去匹配需要加载的变量文件名,还可以明确指定,哪些变量文件不能被加载,使用'ignore_files'参数可以明确指定需要忽略的变量文件名称,'ignore_files'参数的值是需要是一个列表,示例如下
tasks: - include_vars: dir: /testdir/ansible/test/ ignore_files: ["^var_.*",varintest.yaml] name: trans_var - debug: msg: "{{trans_var}}"
上例表示,加载 /testdir/ansible/test/目录中的变量文件,但是所有以"var_"开头的变量文件和varintest.yaml变量文件将不会被加载, 'files_matching'参数和'ignore_files'参数能够同时使用,当它们同时出现时,会先找出正则匹配到的文件,然后从中排除那些需要忽略的文件。
在2.4版本以后的ansible中,当执行了include_vars模块以后,include_vars模块会将载入的变量文件列表写入到自己的返回值中,这个返回值的关键字为'ansible_included_var_files',所以,如果我们想要知道本次任务引入了哪些变量文件,则可以使用如下方法
tasks: - include_vars: dir: /testdir/ansible/test/ register: return_val - debug: msg: "{{return_val.ansible_included_var_files}}"
这篇文章就总结到这里,希望能够对你有所帮助~~
我的微信公众号
关注"实用运维笔记"微信公众号,当博客中有新文章时,可第一时间得知哦~
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- ansible笔记(18):变量(五)
- ansible笔记(17):变量(四)
- ansible笔记(44):变量(七)
- golang学习笔记3:常量与变量
- ECMAScript 6 学习笔记:变量定义方法
- Go语言笔记 | 04-短变量声明
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Scalability Rules
Martin L. Abbott、Michael T. Fisher / Addison-Wesley Professional / 2011-5-15 / USD 29.99
"Once again, Abbott and Fisher provide a book that I'll be giving to our engineers. It's an essential read for anyone dealing with scaling an online business." --Chris Lalonde, VP, Technical Operatio......一起来看看 《Scalability Rules》 这本书的介绍吧!