网站搜索

如何使用 Ansible 变量和事实 - 第 8 部分


我们在这个 Ansible 系列中提到了变量,只是为了让您稍微思考一下。就像许多编程语言一样,变量本质上是代表值的键。

什么构成有效的变量名?

变量名称包括字母、数字、下划线或两者或全部的组合。但是,请记住,变量名称必须始终以字母开头,并且不应包含空格。

让我们看一些有效和不可接受的变量名称的示例:

有效变量名称示例:

football 
foot_ball
football20 
foot_ball20

无效变量名称示例:

foot ball
20 
foot-ball

让我们讨论一下变量类型:

1. 剧本变量

Playbook 变量非常简单明了。要在 playbook 中定义变量,只需在使用缩进编写变量之前使用关键字 vars 即可。

要访问变量的值,请将其放在用引号引起来的双大括号之间。

这是一个简单的剧本示例:

- hosts: all
  vars:
    greeting: Hello world! 

  tasks:
  - name: Ansible Basic Variable Example
    debug:
      msg: "{{ greeting }}"

在上面的 playbook 中,当 playbook 运行时,greeting 变量被值 Hello world! 替换。该剧本在执行时仅打印消息Hello world!

此外,您还可以有一个变量列表或数组,如下所示:

下面的剧本显示了一个名为大陆的变量。该变量包含 5 个不同的值——大陆名称。使用索引 0 作为第一个变量可以轻松访问这些值中的每一个。

下面的 playbook 示例检索并显示 亚洲(索引 1)

- hosts: all
  vars:
    continents:
      - Africa
      - Asia
      - South America
      - North America
      - Europe
      
  tasks:
  - name: Ansible List variable Example
    debug:
      msg: "{{ continents [1] }}"

变量列表的结构类似,如下所示:

vars:
    Continents: [Africa, Asia, South America, North America, Europe]

要列出列表中的所有项目,请使用 with_items 模块。这将循环遍历数组中的所有值。

- hosts: all
  vars:
    continents: [Africa, Asia, South America, North America, Europe]

  tasks:
  - name: Ansible array variables example
    debug: 
      msg: "{{ item }}"
    with_items:
      - "{{ continents }}"

Ansible 变量的另一种类型是字典变量。

剧本中还支持字典变量。要定义字典变量,只需识别字典变量名称下方的键值对即可。

hosts: switch_f01

vars:
   http_port: 8080
   default_gateway: 10.200.50.1
   vlans:
       id: 10
       port: 2

在上面的示例中,vlans 是字典变量,而 idport 是键值对。

hosts: switch_f01

vars:
   http_port: 8080
   default_gateway: 
   vlans:
      id: 10
      port: 20

 tasks:
   name: Configure default gateway
   system_configs:
   default_gateway_ip: “{{ default_gateway  }}“


   name: Label port on vlan 10
   vlan_config:
	vlan_id: “{{ vlans[‘id’]  }}“
     port_id: 1/1/ {{ vlans[‘port’]  }}

对于port_id,由于我们以文本而不是变量开始值,因此不需要用引号将花括号括起来。

2. 特殊变量

Ansible 提供了一系列预定义变量,这些变量可以在 Jinja2 模板和 playbook 中引用,但用户无法更改或定义。

总的来说,Ansible 预定义变量列表称为 Ansible 事实,这些是在执行 playbook 时收集的。

要获取所有 Ansible 变量的列表,请使用 Ansible ad-hoc 命令中的 setup 模块,如下所示:

ansible -m setup hostname

这会以 JSON 格式显示输出,如下所示:

ansible -m setup localhost

从输出中,我们可以看到 Ansible 特殊变量的一些示例包括:

ansible_architecture
ansible_bios_date
ansible_bios_version
ansible_date_time
ansible_machine
ansible_memefree_mb
ansible_os_family
ansible_selinux

还有许多其他 Ansible 特殊变量,这些只是几个示例。

这些变量可以在 Jinja2 模板中使用,如下所示:

<html>
<center>
   <h1> The hostname of this webserver is {{ ansible_hostname }}</h1>
   <h3> It is running on {{ ansible_os_family}}system </h3>
</center>
</html>

3. 库存变量

最后,在列表中,我们有 Ansible 库存变量。清单是一个 INI 格式的文件,其中包含 Ansible 管理的所有主机。

在清单中,您可以将变量分配给主机系统,然后在 playbook 中使用它。

[web_servers]

web_server_1 ansible_user=centos http_port=80
web_server_2 ansible_user=ubuntu http_port=8080

上述内容可以在 playbook YAML 文件中表示,如下所示:

---
   web_servers:
     web_server_1:
        ansible_user=centos
	   http_port=80

web_server_2:
        ansible_user=ubuntu
	   http_port=8080

如果主机系统共享相同的变量,您可以在清单文件中定义另一个组,以减少麻烦并避免不必要的重复。

例如:

[web_servers]

web_server_1 ansible_user=centos http_port=80
web_server_2 ansible_user=centos http_port=80

上式可以构造为:

[web_servers]
web_server_1
web_server_2


[web_servers:vars]
ansible_user=centos
http_port=80

在 playbook YAML 文件中,这将被定义如下:

---
   web_servers:
    
     hosts: 
       web_server_1:
	  web_server_2:

     vars: 
        ansible_user=centos
   http_port=80

Ansible 事实

运行 playbook 时,Ansible 执行的第一个任务是执行设置任务。我很确定您一定已经遇到过以下输出:

TASK:  [Gathering facts] *********

Ansible 事实只不过是系统属性或有关您已连接的远程节点的信息。这些信息包括系统架构、操作系统版本、BIOS 信息、系统时间和日期、系统正常运行时间、IP 地址和硬件信息等。

要获取有关任何系统的信息,只需使用setup模块,如以下命令所示:

ansible -m setup hostname

例如:

ansible -m setup database_server

这会以 JSON 格式打印出一大组数据,如下所示:

Ansible事实可以方便地帮助系统管理员执行哪些操作,例如根据操作系统,他们能够知道需要安装哪些软件包以及如何配置它们等。

定制事实

您是否还知道您可以创建自己的自定义事实并由 Ansible 收集?是的你可以。那么你该怎么做呢?让我们换个方向,看看如何。

第一步是在受管节点或远程节点上创建 /etc/ansible/facts.d 目录。

在此目录中,创建一个扩展名为 .fact 的文件。当 playbook 在 Ansible 控制节点上运行时,此文件将返回 JSON 数据,其中包含 Ansible 在 playbook 运行后检索的其他事实。

下面是一个名为 date_time.fact 的自定义事实文件示例,用于检索日期和时间。

mkdir -p /etc/ansible/facts.d
vim /etc/ansible/facts.d/date_time.fact

在其中添加以下行。

#!/bin/bash
DATE=`date`
echo "{\"date\" : \"${DATE}\"}"

保存并退出文件。

现在分配执行权限:

chmod +x /etc/ansible/facts.d/date_time.fact

现在,我在 Ansible 控制节点上创建了一个名为 check_date.yml 的 playbook。

---

- hosts: webservers

  tasks:
   - name: Get custom facts
     debug:
      msg: The custom fact is {{ansible_local.date_time}}

将事实文件附加到 ansible_local 变量。 ansible_local 存储所有自定义事实。

现在运行 playbook 并观察 Ansible 检索事实文件中保存的信息:

ansible_playbook check_date.yml

结论

关于使用 Ansible 变量和事实的教程到此结束。