构建您的清单
在没有清单的情况下运行剧本需要多个命令行标志。此外,对单个设备运行剧本与手动进行相同更改相比,效率提升并不大。充分利用 Ansible 潜力的下一步是使用清单文件,将受管理的节点组织成组,并包含诸如 ansible_network_os
和 SSH 用户之类的信息。功能齐全的清单文件可以充当您网络的真相来源。使用清单文件,单个剧本可以使用单个命令维护数百个网络设备。本页将逐步向您展示如何构建清单文件。
基本清单
首先,按逻辑对您的清单进行分组。最佳做法是按用途 (应用程序、堆栈或微服务)、位置 (数据中心或区域) 和时间 (开发阶段) 对服务器和网络设备进行分组。
**用途**: db、web、leaf、spine
**位置**: east、west、floor_19、building_A
**时间**: dev、test、staging、prod
在您的组名中避免使用空格、连字符和前导数字 (使用 floor_19
,而不是 19th_floor
)。组名区分大小写。
这个小型示例数据中心说明了基本组结构。您可以使用 [metagroupname:children]
语法对组进行分组,并将组列为元组的成员。这里,组 network
包含所有叶子和所有脊柱;组 datacenter
包含所有网络设备以及所有 Web 服务器。
---
leafs:
hosts:
leaf01:
ansible_host: 10.16.10.11
leaf02:
ansible_host: 10.16.10.12
spines:
hosts:
spine01:
ansible_host: 10.16.10.13
spine02:
ansible_host: 10.16.10.14
network:
children:
leafs:
spines:
webservers:
hosts:
webserver01:
ansible_host: 10.16.10.15
webserver02:
ansible_host: 10.16.10.16
datacenter:
children:
network:
webservers:
您也可以使用 INI 格式创建相同的清单。
[leafs]
leaf01
leaf02
[spines]
spine01
spine02
[network:children]
leafs
spines
[webservers]
webserver01
webserver02
[datacenter:children]
network
webservers
将变量添加到清单
接下来,您可以为清单中的许多变量设置值,这些变量在第一个 Ansible 命令中需要,这样您就可以在 ansible-playbook
命令中跳过它们。在本例中,清单包括每个网络设备的 IP、操作系统和 SSH 用户。如果您的网络设备只能通过 IP 访问,则必须将 IP 添加到清单文件。如果您使用主机名访问网络设备,则不需要 IP。
---
leafs:
hosts:
leaf01:
ansible_host: 10.16.10.11
ansible_network_os: vyos.vyos.vyos
ansible_user: my_vyos_user
leaf02:
ansible_host: 10.16.10.12
ansible_network_os: vyos.vyos.vyos
ansible_user: my_vyos_user
spines:
hosts:
spine01:
ansible_host: 10.16.10.13
ansible_network_os: vyos.vyos.vyos
ansible_user: my_vyos_user
spine02:
ansible_host: 10.16.10.14
ansible_network_os: vyos.vyos.vyos
ansible_user: my_vyos_user
network:
children:
leafs:
spines:
webservers:
hosts:
webserver01:
ansible_host: 10.16.10.15
ansible_user: my_server_user
webserver02:
ansible_host: 10.16.10.16
ansible_user: my_server_user
datacenter:
children:
network:
webservers:
在清单中对变量进行分组
当组中的设备共享相同的变量值 (例如操作系统或 SSH 用户) 时,您可以将这些值合并到组变量中,以减少重复并简化维护。
---
leafs:
hosts:
leaf01:
ansible_host: 10.16.10.11
leaf02:
ansible_host: 10.16.10.12
vars:
ansible_network_os: vyos.vyos.vyos
ansible_user: my_vyos_user
spines:
hosts:
spine01:
ansible_host: 10.16.10.13
spine02:
ansible_host: 10.16.10.14
vars:
ansible_network_os: vyos.vyos.vyos
ansible_user: my_vyos_user
network:
children:
leafs:
spines:
webservers:
hosts:
webserver01:
ansible_host: 10.16.10.15
webserver02:
ansible_host: 10.16.10.16
vars:
ansible_user: my_server_user
datacenter:
children:
network:
webservers:
变量语法
变量值的语法在清单、剧本和 group_vars
文件中有所不同,后者将在下面介绍。即使剧本和 group_vars
文件都使用 YAML 编写,您在每个文件中使用变量的方式也不同。
在 ini 样式的清单文件中,您**必须**使用
key=value
语法来表示变量值:ansible_network_os=vyos.vyos.vyos
。在任何扩展名为
.yml
或.yaml
的文件中 (包括剧本和group_vars
文件),您**必须**使用 YAML 语法:key: value
。在
group_vars
文件中,请使用完整的key
名称:ansible_network_os: vyos.vyos.vyos
。在剧本中,请使用简短形式的
key
名称,该名称会删除ansible
前缀:network_os: vyos.vyos.vyos
。
按平台对清单进行分组
随着清单的增长,您可能希望按平台对设备进行分组。这使您可以轻松地为该平台上的所有设备指定特定于平台的变量。
---
leafs:
hosts:
leaf01:
ansible_host: 10.16.10.11
leaf02:
ansible_host: 10.16.10.12
spines:
hosts:
spine01:
ansible_host: 10.16.10.13
spine02:
ansible_host: 10.16.10.14
network:
children:
leafs:
spines:
vars:
ansible_connection: ansible.netcommon.network_cli
ansible_network_os: vyos.vyos.vyos
ansible_user: my_vyos_user
webservers:
hosts:
webserver01:
ansible_host: 10.16.10.15
webserver02:
ansible_host: 10.16.10.16
vars:
ansible_user: my_server_user
datacenter:
children:
network:
webservers:
使用此设置,您只需要使用两个标志就可以运行 first_playbook.yml
ansible-playbook -i inventory.yml -k first_playbook.yml
使用 -k
标志,您会在提示符下提供 SSH 密码。或者,您可以使用 ansible-vault
将 SSH 和其他机密信息以及密码安全地存储在您的 group_vars
文件中。有关详细信息,请参阅 使用 ansible-vault 保护敏感变量。
验证清单
您可以使用 ansible-inventory CLI 命令显示 Ansible 看到的清单。
$ ansible-inventory -i test.yml --list
{
"_meta": {
"hostvars": {
"leaf01": {
"ansible_connection": "ansible.netcommon.network_cli",
"ansible_host": "10.16.10.11",
"ansible_network_os": "vyos.vyos.vyos",
"ansible_user": "my_vyos_user"
},
"leaf02": {
"ansible_connection": "ansible.netcommon.network_cli",
"ansible_host": "10.16.10.12",
"ansible_network_os": "vyos.vyos.vyos",
"ansible_user": "my_vyos_user"
},
"spine01": {
"ansible_connection": "ansible.netcommon.network_cli",
"ansible_host": "10.16.10.13",
"ansible_network_os": "vyos.vyos.vyos",
"ansible_user": "my_vyos_user"
},
"spine02": {
"ansible_connection": "ansible.netcommon.network_cli",
"ansible_host": "10.16.10.14",
"ansible_network_os": "vyos.vyos.vyos",
"ansible_user": "my_vyos_user"
},
"webserver01": {
"ansible_host": "10.16.10.15",
"ansible_user": "my_server_user"
},
"webserver02": {
"ansible_host": "10.16.10.16",
"ansible_user": "my_server_user"
}
}
},
"all": {
"children": [
"datacenter",
"ungrouped"
]
},
"datacenter": {
"children": [
"network",
"webservers"
]
},
"leafs": {
"hosts": [
"leaf01",
"leaf02"
]
},
"network": {
"children": [
"leafs",
"spines"
]
},
"spines": {
"hosts": [
"spine01",
"spine02"
]
},
"webservers": {
"hosts": [
"webserver01",
"webserver02"
]
}
}
使用 ansible-vault
保护敏感变量
命令 ansible-vault
为文件和/或单个变量 (如密码) 提供加密。本教程将向您展示如何加密单个 SSH 密码。您可以使用以下命令来加密其他敏感信息,例如数据库密码、特权升级密码等。
首先,您必须为 ansible-vault 本身创建一个密码。它用作加密密钥,有了它,您可以在整个 Ansible 项目中加密数十个不同的密码。在运行剧本时,您可以使用单个密码 (ansible-vault 密码) 访问所有这些机密信息 (加密的值)。以下是一个简单的示例。
创建一个文件,并将您的 ansible-vault 密码写入其中
echo "my-ansible-vault-pw" > ~/my-ansible-vault-pw-file
创建 VyOS 网络设备的加密 SSH 密码,从刚刚创建的文件中提取 ansible-vault 密码
ansible-vault encrypt_string --vault-id my_user@~/my-ansible-vault-pw-file 'VyOS_SSH_password' --name 'ansible_password'
如果您更愿意键入 ansible-vault 密码,而不是将其存储在文件中,则可以请求提示
ansible-vault encrypt_string --vault-id my_user@prompt 'VyOS_SSH_password' --name 'ansible_password'
然后键入 my_user
的 vault 密码。
标志 --vault-id
允许为不同的用户或不同的访问级别使用不同的 vault 密码。输出包括来自 ansible-vault
命令的用户名 my_user
,并使用 YAML 语法 key: value
ansible_password: !vault |
$ANSIBLE_VAULT;1.2;AES256;my_user
66386134653765386232383236303063623663343437643766386435663632343266393064373933
3661666132363339303639353538316662616638356631650a316338316663666439383138353032
63393934343937373637306162366265383461316334383132626462656463363630613832313562
3837646266663835640a313164343535316666653031353763613037656362613535633538386539
65656439626166666363323435613131643066353762333232326232323565376635
Encryption successful
这是一个使用 YAML 清单摘录的示例,因为 INI 格式不支持内联 vault
...
vyos: # this is a group in yaml inventory, but you can also do under a host
vars:
ansible_connection: ansible.netcommon.network_cli
ansible_network_os: vyos.vyos.vyos
ansible_user: my_vyos_user
ansible_password: !vault |
$ANSIBLE_VAULT;1.2;AES256;my_user
66386134653765386232383236303063623663343437643766386435663632343266393064373933
3661666132363339303639353538316662616638356631650a316338316663666439383138353032
63393934343937373637306162366265383461316334383132626462656463363630613832313562
3837646266663835640a313164343535316666653031353763613037656362613535633538386539
65656439626166666363323435613131643066353762333232326232323565376635
...
要使用内联 vault 变量和 INI 清单,您需要将其存储在 YAML 格式的“vars”文件中,它可以位于 host_vars/ 或 group_vars/ 中,以便自动获取或通过 vars_files
或 include_vars
从剧本中引用。
要使用此设置运行剧本,请删除 -k
标志,并添加您的 vault-id
标志
ansible-playbook -i inventory --vault-id my_user@~/my-ansible-vault-pw-file first_playbook.yml
或者使用提示而不是 vault 密码文件
ansible-playbook -i inventory --vault-id my_user@prompt first_playbook.yml
要查看原始值,您可以使用调试模块。请注意,如果您的 YAML 文件定义了 ansible_connection 变量(正如我们在示例中所使用的那样),它将在您执行以下命令时生效。为了防止这种情况,请在没有 ansible_connection 变量的情况下复制该文件。
$ cat vyos.yml | grep -v ansible_connection >> vyos_no_connection.yml
ansible localhost -m debug -a var="ansible_password" -e "@vyos_no_connection.yml" --ask-vault-pass
Vault password:
localhost | SUCCESS => {
"ansible_password": "VyOS_SSH_password"
}
警告
Vault 内容只能使用用于加密它的密码解密。如果您想停止使用一个密码并迁移到一个新的密码,您可以使用 ansible-vault rekey myfile
更新和重新加密现有的 Vault 内容,然后提供旧密码和新密码。使用旧密码加密的 Vault 内容副本仍然可以使用旧密码解密。
有关构建清单文件的更多详细信息,请参见 清单简介;有关 ansible-vault 的更多详细信息,请参见 完整的 Ansible Vault 文档.
现在您已经了解了命令、剧本和清单的基础知识,是时候探索一些更复杂的 Ansible 网络示例了。