Ansible自定义事实变量与魔法变量详解及实例
在Ansible中,除了自动收集的事实变量(facts)外,还可以定义自己的事实变量。自定义事实变量在某些场景中非常有用,特别是需要特定于主机的变量时。默认情况下,自定义事实变量文件位于/etc/ansible/facts.d
目录下,文件后缀为.fact
。
1. 自定义事实变量文件格式
ini格式写法
自定义事实变量文件可以使用ini格式:
[packages]
web_package = httpd
db_package = mariadb-server
[users]
user1 = joe
user2 = jane
json格式写法
自定义事实变量文件也可以使用json格式:
{
"packages": {
"web_package": "httpd",
"db_package": "mariadb-server"
},
"users": {
"user1": "joe",
"user2": "jane"
}
}
2. 存储自定义事实变量
自定义事实由setup
模块存储在ansible_facts.ansible_local
变量中。事实按其文件名组织。例如,如果文件名为/etc/ansible/facts.d/custom.fact
,则可以通过ansible_facts.ansible_local['custom']
访问其中的变量。
示例:创建并存储自定义事实变量
假设我们创建一个名为custom.fact
的文件,并存储如下内容:
{
"users": {
"user1": "joe",
"user2": "jane"
}
}
3. 通过Ansible命令查看自定义事实变量
通过运行以下命令可以查看自定义事实变量:
ansible localhost -m setup -a 'filter=ansible_local'
输出示例:
{
"ansible_facts": {
"ansible_local": {
"custom": {
"users": {
"user1": "joe",
"user2": "jane"
}
}
}
},
"changed": false
}
4. 使用自定义事实变量
可以在playbook中引用和使用自定义事实变量。
示例:在playbook中使用自定义事实变量
以下playbook展示了如何引用自定义事实变量:
---
- name: 打印自定义事实变量
hosts: localhost
tasks:
- name: 打印自定义用户变量
debug:
msg: "主机 {{ ansible_facts['fqdn'] }} 的用户1是 {{ ansible_facts['ansible_local']['custom']['users']['user1'] }}"
运行此playbook将输出类似如下的信息:
TASK [打印自定义用户变量] ********************************************************************
ok: [localhost] => {
"msg": "主机 192-168-31-147 的用户1是 joe"
}
5. Ansible魔法变量
魔法变量(Magic Variables)不是通过setup
模块收集的,但它们也由Ansible自动设置,常用的魔法变量包括:
- hostvars:包含受管主机的变量,可用于获取另一台受管主机的变量。
- group_names:列出当前受管主机所属的所有组。
- groups:列出清单中的所有组和主机。
- inventory_hostname:包含清单中配置的当前受管主机的主机名。
示例:使用魔法变量
以下命令可以打印当前主机的所有变量:
ansible localhost -m debug -a 'var=hostvars["localhost"]'
6. 自定义事实变量示例
示例1:定义Web服务器和数据库服务器的包信息
我们需要定义不同服务器的包信息,可以在/etc/ansible/facts.d/webserver.fact
和/etc/ansible/facts.d/dbserver.fact
中定义:
webserver.fact (ini格式)
[packages]
web_package = nginx
db_package = mysql-server
[users]
admin = alice
user1 = bob
dbserver.fact (json格式)
{
"packages": {
"db_package": "postgresql-server",
"backup_tool": "pgbackrest"
},
"users": {
"dba": "charlie",
"user1": "dave"
}
}
示例2:定义开发环境和生产环境的配置信息
我们有开发环境和生产环境两种配置,可以在/etc/ansible/facts.d/dev.fact
和/etc/ansible/facts.d/prod.fact
中定义:
dev.fact (ini格式)
[environment]
type = development
debug = true
[services]
web_server = apache
database = sqlite
prod.fact (json格式)
{
"environment": {
"type": "production",
"debug": false
},
"services": {
"web_server": "nginx",
"database": "mysql"
}
}
示例3:定义特定应用的配置
我们有一个应用的配置信息,可以在/etc/ansible/facts.d/app.fact
中定义:
app.fact (json格式)
{
"app": {
"name": "myapp",
"version": "1.2.3",
"maintainer": "[email protected]"
},
"settings": {
"theme": "dark",
"timeout": 30
}
}
7. 通过Ansible命令查看自定义事实变量
查看Web服务器的自定义事实变量
ansible webserver -m setup -a 'filter=ansible_local'
输出示例:
{
"ansible_facts": {
"ansible_local": {
"packages": {
"web_package": "nginx",
"db_package": "mysql-server"
},
"users": {
"admin": "alice",
"user1": "bob"
}
}
},
"changed": false
}
查看数据库服务器的自定义事实变量
ansible dbserver -m setup -a 'filter=ansible_local'
{
"ansible_facts": {
"ansible_local": {
"packages": {
"db_package": "postgresql-server",
"backup_tool": "pgbackrest"
},
"users": {
"dba": "charlie",
"user1": "dave"
}
}
},
"changed": false
}
8. 在Playbook中使用自定义事实变量
示例:在Playbook中引用Web服务器的自定义事实变量
---
- name: 打印Web服务器的自定义事实变量
hosts: webserver
tasks:
- name: 打印Web服务器包信息
debug:
msg: "Web服务器包是:{{ ansible_facts.ansible_local.packages.web_package }}"
- name: 打印管理员信息
debug:
msg: "管理员是:{{ ansible_facts.ansible_local.users.admin }}"
示例:在Playbook中引用数据库服务器的自定义事实变量
---
- name: 打印数据库服务器的自定义事实变量
hosts: dbserver
tasks:
- name: 打印数据库包信息
debug:
msg: "数据库包是:{{ ansible_facts.ansible_local.packages.db_package }}"
- name: 打印DBA信息
debug:
msg: "DBA是:{{ ansible_facts.ansible_local.users.dba }}"
9. Ansible魔法变量示例
示例1:使用hostvars
获取另一台主机的变量
我们需要在一个主机上获取另一台主机的变量,可以使用hostvars
魔法变量。
Playbook示例:
---
- name: 获取其他主机变量
hosts: localhost
tasks:
- name: 打印webserver主机的IP地址
debug:
msg: "Web服务器的IP地址是:{{ hostvars['webserver'].ansible_facts.default_ipv4.address }}"
示例2:使用group_names
列出主机所属的组
---
- name: 列出主机所属的组
hosts: localhost
tasks:
- name: 打印组信息
debug:
msg: "本主机所属的组有:{{ group_names }}"
示例3:使用groups
列出清单中的所有组和主机
---
- name: 列出清单中的所有组和主机
hosts: localhost
tasks:
- name: 打印所有组和主机信息
debug:
msg: "清单中的所有组和主机:{{ groups }}"
示例4:使用inventory_hostname
获取当前主机的清单名称
---
- name: 获取当前主机的清单名称
hosts: localhost
tasks:
- name: 打印清单名称
debug:
msg: "当前主机的清单名称是:{{ inventory_hostname }}"