八、fact变量和魔法变量

发布时间 2023-12-14 09:38:28作者: 相信童话

八、fact变量和魔法变量

8.1 fact简介

​ Ansible在执行playbook的时候,第一个任务会自动执行setup模块,该模块用于获取远程主机的系统信息,并将这些信息存储在facts变量中,在playbook中可以随时调用这些变量。

我们可以执行adhoc获取一下fact变量,看看都有什么。

ansible node1 -m setup

image-20230919225641351

setup模块用法

# 收集主机node1的fact信息
ansible node1 -m setup

# 过滤fact变量,查看网卡的信息
ansible test -m setup -a 'filter=ansible_ens160'

# 过滤fact变量,查看主机内存信息
ansible test -m setup -a 'filter=ansible_*_mb

# 将所有主机的信息输入到/tmp/facts目录下,每台主机的信息输入到主机名文件中 (/etc/ansible/hosts里的主机名)
ansible all -m setup --tree /tmp/facts

8.2 fact变量

​ facts变量是一个嵌套类型的数据格式,facts数据的顶级key为ansible_facts,往下一级的变量名都是以ansible_开头的,常用的facts变量如下:

key 说明
ansible_python_version python版本
ansible_distribution 显示系统发行版
ansible_distribution_major_version 显示系统主版本号
ansible_distribution_version 显示系统版本号
ansible_devices 显示磁盘设备信息
ansible_lvm 显示逻辑卷信息
ansible_memtotal_mb 显示内存总大小
ansible_kernel 显示内核版本
ansible_hostname 显示主机名
ansible_fqdn 显示完整的主机名信息
ansible_default_ipv4 显示主机默认的ip地址

playbook中应该如何调用fact变量?

下面举例,通过调用facts变量去打印被控端的主机名、ip地址。

- name: test var
  hosts: all
  tasks:
        - name: print vars
          debug:
                  msg: "{{ ansible_hostname }} {{ ansible_default_ipv4.address }}"

注意:调用facts变量时,ansible_facts可以不写,直接写下一个层级的key,可以提前将fact变量导出,以便查询自己所需要的变量名。导出方法ansible node1 -m setup > /tmp/facts

image-20230919230508820

8.3 开启和关闭fact

​ ansible默认开启fact,在每一个play的时候,会自动获取playbookhosts清单的所有主机信息。由于fact变量收集的信息比较多,所以开启fact变量后,ansible执行任务会特别慢。

关闭fact方法

fact默认是开启的,要关闭fact,我们需要在play中添加gather_facts: False

- name: test var
  hosts: all
  gather_facts: False
  tasks:
        - name: print vars
          debug:
                  msg: "not use fact"

image-20230924224852321

8.4 set_fact模块

set_fact模块可以自定义facts,这些自定义的facts可以被jinjia2或者playbook调用。如果你想要引用已有的facts变量定义新的变量,则必须通过set_fact来定义,并将其值在playbook中引用。简单理解,set_fact就是变量拼接。

示例:将操作系统发行版和主版本号拼接到新的变量中

- name: test var
  hosts: all
  tasks:
        - name: set_facts
          set_fact:
                  os_version: "{{ ansible_distribution }} - {{ ansible_distribution_major_version }}"
        - name: print vars
          debug:
                  msg: "{{ os_version }}"

image-20230924230056667

8.5 lookup生成变量

​ 在通常情况下,所有的配置信息都会被作为ansible的变量保存了,而且可以保存在ansible允许定义变量的各种地方,诸如vars区段,vars_files加载的文件中,以及host_vars和group_vars目录中。

​ 但在有些时候,我们希望从诸如文本文件或者.csv文件中收集数据作为ansible的变量,或者直接获取某些命令的输出作为ansible的变量,这个时候,我们就需要通过ansible的lookup插件来从这些数据源中读取配置数据,传递给ansbile变量,并在playbook或者模板中使用这些数据。

注意:lookup获取的变量来自于主控端。

ansible支持一套从不同数据源获取数据的lookup,包括file, password, pipe, env, template, csvfile, dnstxt, redis kv, etcd等。

  • file:file可以将文件读取的内容作为变量。
[root@master ansible]# echo hello world >> /tmp/test.txt
[root@master ansible]# cat /tmp/test.txt 
hello world
[root@master ansible]# cat test.yml 
- name: test var
  hosts: all
  tasks:
        - name: set_facts
          set_fact:
                  file_content: "{{ lookup('file','/tmp/test.txt')}}"
        - name: print vars
          debug:
                  msg: "{{ file_content }}"

image-20230924231341149

  • pipe:pipe可以将命令执行的结果作为ansible变量使用。
- name: test var
  hosts: all
  tasks:
        - name: set_facts
          set_fact:
                  date: "{{ lookup('pipe','date \"+%F %T\"')}}"
        - name: print vars
          debug:
                  msg: "{{ date }}"

image-20230924231740327

  • env:env可以将主机上环境变量的值作为ansible变量使用。
- name: test var
  hosts: all
  tasks:
        - name: set_facts
          set_fact:
                  env_hostname: "{{ lookup('env','HOSTNAME')}}"
        - name: print vars
          debug:
                  msg: "{{ env_hostname }}"

image-20230924232124421

8.6 ansible魔法变量

​ Ansible默认会提供一些内置的变量以实现一些特定的功能,我们称之为魔法变量。下面列举一些常用的魔法变量。

  • hostvars:获取指定主机的相关变量,hostvars是一个对象,他存放着所有主机的相关变量,可以通过hostvars['主机']来获取指定主机的相关变量。
- name: test var
  hosts: all
  tasks:
        - name: print node1 vars
          debug:
                  msg: "{{ hostvars['node1'].ansible_default_ipv4.address }}"

image-20230928145246754

注意:主机是指主机清单中定义的主机信息,可以使域名、可以是ip。

  • inventory_hostname:当前正在运行主机的主机名。
- name: test var
  hosts: all
  tasks:
        - name: print node2 vars
          debug:
                  msg: "{{ hostvars[inventory_hostname].ansible_hostname }}"

image-20230928150139592

  • groups:groups用于获取主机清单中所有主机组的信息。
- name: test var
  hosts: all
  tasks:
        - name: print node2 vars
          debug:
                  msg: "{{ groups }}"

image-20230928150821803

groups.all:获取所有主机,包括未加入主机组的主机

groups.test:获取指定组下面的主机

groups.ungrouped:获取所有不属于主机组的主机

  • group_name:当前正在运行主机所属的主机组。