八、fact变量和魔法变量
8.1 fact简介
Ansible在执行playbook的时候,第一个任务会自动执行setup模块,该模块用于获取远程主机的系统信息,并将这些信息存储在facts变量中,在playbook中可以随时调用这些变量。
我们可以执行adhoc获取一下fact变量,看看都有什么。
ansible node1 -m setup
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
8.3 开启和关闭fact
ansible默认开启fact,在每一个play的时候,会自动获取playbook
中hosts
清单的所有主机信息。由于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"
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 }}"
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 }}"
- 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 }}"
- 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 }}"
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 }}"
注意:主机是指主机清单中定义的主机信息,可以使域名、可以是ip。
- inventory_hostname:当前正在运行主机的主机名。
- name: test var
hosts: all
tasks:
- name: print node2 vars
debug:
msg: "{{ hostvars[inventory_hostname].ansible_hostname }}"
- groups:groups用于获取主机清单中所有主机组的信息。
- name: test var
hosts: all
tasks:
- name: print node2 vars
debug:
msg: "{{ groups }}"
groups.all
:获取所有主机,包括未加入主机组的主机
groups.test
:获取指定组下面的主机
groups.ungrouped
:获取所有不属于主机组的主机
- group_name:当前正在运行主机所属的主机组。