侧边栏壁纸
博主头像
张种恩的技术小栈博主等级

行动起来,活在当下

  • 累计撰写 747 篇文章
  • 累计创建 65 个标签
  • 累计收到 39 条评论

目 录CONTENT

文章目录

ansible的include_vars模块

zze
zze
2020-03-28 / 0 评论 / 0 点赞 / 1023 阅读 / 6349 字

不定期更新相关视频,抖音点击左上角加号后扫一扫右方侧边栏二维码关注我~正在更新《Shell其实很简单》系列

此文章为「ansible笔记(2)之常用模块」的子文章。

include_vars 模块能够在任务执行过程中,随时的引入变量文件,以便动态的获取到最新的变量文件内容。

先准备示例变量文件 /testdir/ansible/testfile,内容如下:

testvar1: aaa
testvar2: bbb

在看如下示例 playbook:

---
- hosts: A
  gather_facts: no
  tasks:
  - include_vars: "/testdir/ansible/testfile"
  - debug:
      msg: "{{testvar2}}"
  - lineinfile:
      path: "/testdir/ansible/testfile"
      line: "testvar3: ddd"
  - include_vars: "/testdir/ansible/testfile"
  - debug:
      msg: "{{testvar3}}"

由于我这里要使用 lineinfile 模块动态修改变量文件,所以将目标主机设为了 ansible 管理机。

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

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

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

include_vars 模块其实还有一些常用参数,我们一起来了解一下。

先来看一个小示例,如下:

---
- 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: B
  gather_facts: no
  tasks:
  - include_vars:
      file: /testdir/ansible/testfile
      name: trans_var
  - debug:
      var: trans_var

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

$ ansible-playbook test.yml 

PLAY [B] ******************************************************************************************************************************

TASK [include_vars] *******************************************************************************************************************
ok: [B]

TASK [debug] **************************************************************************************************************************
ok: [B] => {
    "trans_var": {
        "testvar1": "aaa", 
        "testvar2": "bbb", 
        "testvar3": "ddd", 
        "testvar4": "ddd"
    }
}

PLAY RECAP ****************************************************************************************************************************
B                          : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  

可以发现,trans_var 变量的值就是变量文件中的所有变量,没错,如你所见,我们可以使用 name 参数指定一个变量,然后将文件中的所有变量都赋值给这个指定的变量。

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

- 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}}"
0

评论区