ansible的set_fact模块

ansible的set_fact模块

微信搜索 zze_coding 或扫描 👉 二维码关注我的微信公众号获取更多资源推送:

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

我们可以通过 set_fact 模块在 tasks中定义变量,先来看一个小示例,如下:

---
- hosts: B
  remote_user: root
  tasks:
  - set_fact:
      testvar: "testtest"
  - debug:
      msg: "{{testvar}}"

如上例所示,我们通过 set_fact 模块定义了一个名为 testvar 的变量,变量值为 testtest ,然后使用 debug 模块输出了这个变量。

是不是很简单,通过 set_fact 模块就能够在 tasks 中定义变量了,我们也可以通过 set_fact 将一个变量的值赋予另一个变量,示例如下:

---
- hosts: B
  vars:
    testvar1: test1_string
  tasks:
  - shell: "echo test2_string"
    register: shellreturn
  - set_fact:
      testsf1: "{{testvar1}}"
      testsf2: "{{shellreturn.stdout}}"
  - debug:
      msg: "{{testsf1}} {{testsf2}}"

上例中,我们先定义了一个变量 testvar1,又使用 register 将 shell 模块的返回值注册到了变量 shellreturn 中,之后,使用 set_fact 模块将 testvar1 变量的值赋予了变量 testsf1,将 shellreturn 变量中的 stdout 信息赋值给了 testsf2 变量,最后,使用 debug 模块输出了 testsf1testsf2 的值。

如上述示例所示,set_fact 模块可以让我们在 tasks 中创建变量,也可以将一个变量的值赋值给另一个变量。

其实通过 vars 关键字就可以声明变量(参见「变量的使用」),那为什么还要整一个专门的 set_fact 模块来声明变量呢?

这是因为通过 set_fact 模块创建的变量还有一个特殊性,通过 set_fact 创建的变量就像主机上的 facts 信息一样,可以在之后的 play 中被引用。

默认情况下,每个 play 执行之前都会执行一个名为 [Gathering Facts] 的默认任务(参见「默认任务」),这个任务会收集对应主机的相关信息,我们可以称这些信息为 facts 信息,而通过 set_fact 模块创建的变量其实就是 facts 信息,同主机的 facts 信息可以在 play 中引用,通过 set_fact 模块创建的变量也可以在之后 play 中被引用。

看示例:

---
- hosts: B
  vars:
    testvar1: tv1
  tasks:
  - set_fact:
      testvar2: tv2
  - debug:
      msg: "{{testvar1}} ----- {{testvar2}}"
 
- hosts: B
  tasks:
  - name: other play get testvar2
    debug:
      msg: "{{testvar2}}"
  - name: other play get testvar1
    debug:
      msg: "{{testvar1}}"

上例中一共有两个 play,第一个 play 中,我们通过两种方式创建了两个变量,第一个变量 testvar1 使用 vars 关键字创建,第二个变量使用 set_fact 模块创建。

如果执行上例的 playbook,可以发现,这两个变量在第一个 play 中都可以正常的输出。但是在第二个 play 中,testvar2 可以被正常输出了,testvar1 却不能被正常输出,会出现未定义 testvar1 的错误,因为在第一个 play 中针对 B 主机进行操作时,testvar1 是通过 vars 关键字创建的,而 testvar2 是通过 set_fact 创建的,所以 testvar2 就好像 B 的 facts 信息一样,可以在第二个 play 中引用到,而创建 testvar1 变量的方式则不能达到这种效果,虽然 testvar2 就像 facts 信息一样能被之后的 play 引用,但是在 facts 信息中并不能找到 testvar2,只是效果上与 facts 信息相同罢了。

细心如你一定发现了,上述示例中,即使是跨 play 获取变量,也都是针对同一台主机,但是某些时候,我们可能想要在操作一台主机时,获取到之前操作的另一台主机中定义的变量,那么该怎样做呢?可参见「内置变量」。

Copyright: 采用 知识共享署名4.0 国际许可协议进行许可

Links: https://www.zze.xyz/archives/ansible-module-setfact.html

Buy me a cup of coffee ☕.