Bootstrap

全面解析Ansible自定义事实变量及实战示例

在这里插入图片描述

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 }}"
;