ansible 管理事实
1. 描述Ansible事实
-
Ansible事实是Ansible在受管主机上自动检测到的变量。事实中包含有与主机相关的信息,可以像play中的常规变量、条件、循环或依赖于从受管主机收集的值的任何其他语句那样使用
-
为受管主机收集的一些事实可能包括:
- 主机名称
- 内核版本
- 网络接口
- IP地址
- 操作系统版本
- 各种环境变量
- CPU数量
- 提供的或可用的内存
- 可用磁盘空间
-
借助事实,可以方便地检索受管主机的状态,并根据该状态确定要执行的操作。例如:
- 可以根据含有受管主机当前内核版本的事实运行条件任务,以此来重启服务器
- 可以根据通过事实报告的可用内存来自定义MySQL配置文件
- 可以根据事实的值设置配置文件中使用的IPv4地址
-
通常,每个play在执行第一个任务之前会先自动运行setup模块来收集事实
-
ansible all -m setup
2. Ansible事实的示例
事实 | 变量 |
---|---|
短主机名 | ansible_facts[‘hostname’] |
完全限定域名 | ansible_facts[‘fqdn’] |
IPv4地址 | ansible_facts[‘default_ipv4’][‘address’] |
所有网络接口的名称列表 | ansible_facts[‘interfaces’] |
/dev/vda1磁盘分区的大小 | ansible_facts[‘devices’][‘vda’][‘partitions’][‘vda1’][‘size’] |
DNS服务器列表 | ansible_facts[‘dns’][‘nameservers’] |
当前运行的内核版本 | ansible_facts[‘kernel’] |
- 在playbook中使用事实时,Ansible将事实的变量名动态替换为对应的值
[root@129a httpd]# vim test.yml
[root@129a httpd]# cat test.yml
---
- hosts: all
tasks:
- name: test
debug:
msg: >
The default ipaddress of {{ ansible_facts["fqdn"] }}
is {{ ansible_facts["default_ipv4"]["address"] }}
[root@129a httpd]# ansible-playbook -C test.yml
PLAY [all] *********************************************************************
TASK [Gathering Facts] *********************************************************
ok: [130h]
TASK [test] ********************************************************************
ok: [130h] => {
"msg": "The default ipaddress of 130h is 192.168.232.130\n"
}
PLAY RECAP *********************************************************************
130h : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@129a httpd]#
3. ansible事实作为变量注入
-
选定的Ansible事实名称比较
-
ansible_facts形式 旧事实变量形式 ansible_facts[‘hostname’] ansible_hostname ansible_facts[‘fqdn’] ansible_fqdn ansible_facts[‘default_ipv4’][‘address’] ansible_default_ipv4[‘address’] ansible_facts[‘interfaces’] ansible_interfaces ansible_facts[‘devices’][‘vda’][‘partitions’][‘vda1’][‘size’] ansible_devices[‘vda’][‘partitions’][‘vda1’][‘size’] ansible_facts[‘dns’][‘nameservers’] ansible_dns[‘nameservers’] ansible_facts[‘kernel’] ansible_kernel -
目前,Ansible同时识别新的事实命名系统(使用ansible_facts)和旧的2.5前“作为单独变量注入的事实”命名系统。
-
将Ansible配置文件的**[default]部分中inject_facts_as_vars参数设置为False**,可关闭旧命名系统。默认设置目前为True。
-
inject_facts_as_vars的默认值在Ansible的未来版本中可能会更改为False。如果设置为False,则只能使用新的**ansible_facts.***命名系统引用Ansible事实
关闭旧命名系统
[root@129a httpd]# vim ansible.cfg
[root@129a httpd]# cat ansible.cfg|grep inject_facts_as_vaes
inject_facts_as_vaes = False
[root@129a httpd]#
4. 关闭事实收集
-
有时我们不想为play收集事实。这样做的原因可能有:
- 不准备使用任何事实
- 希望加快play速度
- 希望减小play在受管主机上造成的负载
- 受管主机因为某种原因无法运行setup模块
- 需要安装一些必备软件后再收集事实
-
[root@129a httpd]# cat install.yml --- - hosts: webservers gather_facts: no//关闭事实 vars_files: - vars/httpd tasks: - name: Delete the yum source file: path: /etc/yum.repos.d state: absent - name: Provide the yum source file copy: src: files/CentOS-Base.repo dest: /etc/yum.repos.d/ - name: install apache dnf: name: "{{ web }}" state: latest - name: Provides web site copy: src: files/game dest: /var/www/html/ - name: config apache copy: src: files/httpd-vhosts.conf dest: /etc/httpd/conf.d/ - name: run {{ web }} service: name: "{{ web }}" state: started enabled: yes - name: close firewalld service: name: firewalld state: stopped enabled: no [root@129a httpd]# [root@129a httpd]# ansible-playbook -C install.yml ERROR! Attempting to decrypt but no vault secrets found [root@129a httpd]# vim install.yml [root@129a httpd]# cat vars/httpd $ANSIBLE_VAULT;1.1;AES256 66613833313231646262333563303637646139383732653430373464653061616536306565326566 3961373433323661313938613765623731346437343439350a316662303834363232616662666134 64393865316363346563643134373831343034323563316632343132346165373139386561366131 6266393161613765390a323636313635633362313736623637386565323663363331313933653239 3630 //解密 [root@129a httpd]# ansible-vault decrypt vars/httpd Vault password: Decryption successful [root@129a httpd]# ansible-playbook -C install.yml PLAY [webservers] ************************************************************** TASK [Delete the yum source] *************************************************** changed: [130h] TASK [Provide the yum source file] ********************************************* ok: [130h] TASK [install apache] ********************************************************** ok: [130h] TASK [Provides web site] ******************************************************* ok: [130h] TASK [config apache] *********************************************************** ok: [130h] TASK [run httpd] *************************************************************** ok: [130h] TASK [close firewalld] ********************************************************* ok: [130h] PLAY RECAP ********************************************************************* 130h : ok=7 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 [root@129a httpd]#
5. 创建自定义事实
-
可以自定义事实,并将其本地存储在每个受管主机上。这些事实整合到setup模块在受管主机上运行时收集的标准事实列表中
-
自定义事实可以在静态文件中定义,格式可为INI文件或采用JSON。它们也可以是生成JSON输出的可执行脚本,如同动态清单脚本一样
-
有了自定义事实,我们可以为受管主机定义特定的值,供play用于填充配置文件或有条件地运行任务。动态自定义事实允许在play运行时以编程方式确定这些事实的值,甚至还可以确定提供哪些事实
-
默认情况下,setup模块从各受管主机的**/etc/ansible/facts.d目录下的文件和脚本中加载自定义事实。各个文件或脚本的名称必须以.fact**结尾才能被使用。动态自定义事实脚本必须输出JSON格式的事实,而且必须是可执行文件
-
采用INI格式编写的静态自定义事实文件,INI格式的自定义事实文件包含由一个部分定义的顶层值,后跟用于待定义的事实的键值
在受管主机
[root@130h ~]# mkdir -p /etc/ansible/facts.d
[root@130h ~]# cd /etc/ansible/facts.d/
[root@130h facts.d]# ls
[root@130h facts.d]# vi 130.fact
[root@130h facts.d]# cat 130.fact
[users]
name = tom
age = 20
[root@130h facts.d]#
[root@129a httpd]# ansible all -m setup|less
},
"ansible_local": {
"130": {
"users": {
"age": "20",
"name": "tom"
- JSON格式,JSON数据可以存储在静态文本文件中,或者通过可执行脚本输出到标准输出
{
"packages": {
"web_package": "httpd",
"db_package": "mariadb-server"
},
"users": {
"user1": "joe",
"user2": "jane"
}
}
- 自定义事实文件不能采用playbook那样的YAML格式。JSON格式是最为接近的等效格式。
- 自定义事实由setup模块存储在ansible_facts.ansible_local变量中。
事实按照定义它们的文件的名称来整理。例如,假设前面的自定义事实由受管主机上保存为**/etc/ansible/facts.d/custom.fact**的文件生成。在这种情况下,ansible_facts.ansible_local[‘custom’][‘users’][‘user1’]的值为joe。
[root@130h ~]# mkdir -p /etc/ansible/facts.d
[root@130h ~]# cd /etc/ansible/facts.d/
[root@130h facts.d]# ls
[root@130h facts.d]# vi 130.fact
[root@130h facts.d]# cat 130.fact
[users]
name = tom
age = 20
[root@130h facts.d]#
[root@129a httpd]# vim test.yml
[root@129a httpd]# cat test.yml
---
- hosts: all
tasks:
- name: test
debug:
msg: >
My name is {{ ansible_facts["ansible_local"]["130"]["users"]["name"] }} ,
I'm {{ ansible_facts["ansible_local"]["130"]["users"]["age"] }} years old.
[root@129a httpd]# ansible-playbook -C test.yml
PLAY [all] ***************************************************************************************
TASK [Gathering Facts] ***************************************************************************
ok: [130h]
TASK [test] **************************************************************************************
ok: [130h] => {
"msg": "My name is tom , I'm 20 years old.\n"
}
PLAY RECAP ***************************************************************************************
130h : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@129a httpd]#
6. 魔法变量
-
一些变量并非事实或通过setup模块配置,但也由Ansible自动设置。这些魔法变量也可用于获取与特定受管主机相关的信息。
-
最常用的
魔法变量 | 说明 |
---|---|
hostvars | 包含受管主机的变量,可以用于获取另一台受管主机的变量的值。 如果还没有为受管主机收集事实,则它不会包含该主机的事实。 |
group_names | 列出当前受管主机所属的所有组 |
groups | 列出清单中的所有组和主机 |
inventory_hostname | 包含清单中配置的当前受管主机的主机名称。 因为各种原因有可能与事实报告的主机名称不同 |
all | 所有主机 |
-
[root@129a httpd]# ansible all -m debug -a 'var=hostvars["localhost"]' 130h | SUCCESS => { "hostvars[\"localhost\"]": { "ansible_check_mode": false, "ansible_connection": "local", "ansible_diff_mode": false, "ansible_facts": {}, "ansible_forks": 5, "ansible_inventory_sources": [ "/opt/httpd/inventory" ], "ansible_playbook_python": "/usr/libexec/platform-python", "ansible_python_interpreter": "/usr/libexec/platform-python", "ansible_verbosity": 0, "ansible_version": { "full": "2.9.27", "major": 2, "minor": 9, "revision": 27, "string": "2.9.27" }, "group_names": [], "groups": { "all": [ "130h" ], "ungrouped": [], "webservers": [ "130h" ] }, "inventory_hostname": "localhost", "inventory_hostname_short": "localhost", "omit": "__omit_place_holder__3fa2e58089098fbf4823f609546eecdc3a54974d", "playbook_dir": "/opt/httpd" } }