使用动态清单
如果您的 Ansible 清单随时间波动,主机根据业务需求动态启动和关闭,那么在 如何构建您的清单 中描述的静态清单解决方案将无法满足您的需求。您可能需要从多个来源跟踪主机:云提供商、LDAP、Cobbler 和/或企业 CMDB 系统。
Ansible 通过一个动态外部清单系统集成了所有这些选项。Ansible 支持两种连接外部清单的方式:清单插件 (Inventory plugins) 和 清单脚本 (inventory scripts)。
清单插件利用了 Ansible Core 代码的最新更新。对于动态清单,我们推荐使用插件而非脚本。您可以 编写自己的插件 来连接额外的动态清单源。
如果您愿意,仍然可以使用清单脚本。在实现清单插件时,我们通过脚本清单插件确保了向后兼容性。下面的示例说明了如何使用清单脚本。
如果您更倾向于使用图形用户界面 (GUI) 来处理动态清单,AWX 或 Red Hat Ansible Automation Platform 上的清单数据库可与所有动态清单源同步,提供对结果的 Web 和 REST 访问,并提供图形化清单编辑器。通过所有主机的数据库记录,您可以关联过去的事件历史,并查看哪些主机在上次执行 playbook 时发生了故障。
清单脚本示例:Cobbler
Ansible 与 Cobbler 无缝集成。Cobbler 是一个 Linux 安装服务器,最初由 Michael DeHaan 编写,现在由在 Ansible 工作的 James Cammarata 领导。
虽然 Cobbler 主要用于启动操作系统安装以及管理 DHCP 和 DNS,但它有一个通用层,可以代表多个配置管理系统的数据(甚至可以同时代表),并充当“轻量级 CMDB”。
要将您的 Ansible 清单与 Cobbler 绑定,请将 此脚本 复制到 /etc/ansible 并对文件执行 chmod +x。在每次使用 Ansible 时运行 cobblerd,并使用 -i 命令行选项(例如,-i /etc/ansible/cobbler.py)通过 Cobbler 的 XMLRPC API 与 Cobbler 通信。
在 /etc/ansible 中添加一个 cobbler.ini 文件,以便 Ansible 知道 Cobbler 服务器的位置,并可以使用一些缓存优化。例如
[cobbler]
# Set Cobbler's hostname or IP address
host = http://127.0.0.1/cobbler_api
# API calls to Cobbler can be slow. For this reason, we cache the results of an API
# call. Set this to the path you want cache files to be written to. Two files
# will be written to this directory:
# - ansible-cobbler.cache
# - ansible-cobbler.index
cache_path = /tmp
# The number of seconds a cache file is considered valid. After this many
# seconds, a new API call will be made, and the cache file will be updated.
cache_max_age = 900
首先通过直接运行 /etc/ansible/cobbler.py 来测试脚本。您应该会看到一些 JSON 数据输出,但此时其中可能还没有内容。
让我们探讨一下它的作用。在 Cobbler 中,假设有如下场景
cobbler profile add --name=webserver --distro=CentOS6-x86_64
cobbler profile edit --name=webserver --mgmt-classes="webserver" --ksmeta="a=2 b=3"
cobbler system edit --name=foo --dns-name="foo.example.com" --mgmt-classes="atlanta" --ksmeta="c=4"
cobbler system edit --name=bar --dns-name="bar.example.com" --mgmt-classes="atlanta" --ksmeta="c=5"
在上面的示例中,系统 “foo.example.com” 可以被 ansible 直接寻址,但在使用组名 “webserver” 或 “atlanta” 时也可以被寻址。由于 Ansible 使用 SSH,它仅通过 “foo.example.com” 联系系统 foo,而绝不会仅使用 “foo”。同样,如果您尝试运行 “ansible foo”,它将找不到该系统……但 “ansible ‘foo*’” 则可以,因为系统的 DNS 名称以 “foo” 开头。
该脚本提供的不仅是主机和组信息。此外,作为一个额外功能,当运行 “setup” 模块时(在使用 playbook 时会自动运行),变量 ‘a’、‘b’ 和 ‘c’ 将全部自动填充到模板中
# file: /srv/motd.j2
Welcome, I am templated with a value of a={{ a }}, b={{ b }}, and c={{ c }}
可以像这样执行
ansible webserver -m setup
ansible webserver -m template -a "src=/tmp/motd.j2 dest=/etc/motd"
注意
名称 ‘webserver’ 来自 Cobbler,配置文件中的变量也是如此。您仍然可以像在 Ansible 中那样正常传递自己的变量,但来自外部清单脚本的变量将覆盖任何同名变量。
因此,使用上述模板 (motd.j2),这将导致以下数据被写入系统 ‘foo’ 的 /etc/motd
Welcome, I am templated with a value of a=2, b=3, and c=4
以及在系统 ‘bar’ (bar.example.com) 上
Welcome, I am templated with a value of a=2, b=3, and c=5
并且从技术上讲,虽然没有太好的理由这样做,但这同样有效
ansible webserver -m ansible.builtin.shell -a "echo {{ a }}"
换句话说,您也可以在参数/动作中使用这些变量。
其他清单脚本
在 Ansible 2.10 及更高版本中,清单脚本已移至其关联的集合 (collections) 中。许多脚本现在位于 ansible-community/contrib-scripts 仓库 中。我们建议您改为使用 清单插件。
使用清单目录和多个清单源
如果在 Ansible 中传递给 -i 的位置是一个目录(或在 ansible.cfg 中如此配置),Ansible 可以同时使用多个清单源。这样做时,可以在同一个 ansible 运行中混合使用动态和静态管理的清单源。瞬间实现混合云!
在清单目录中,可执行文件被视为动态清单源,大多数其他文件被视为静态源。以以下任何后缀结尾的文件将被忽略
~, .orig, .bak, .ini, .cfg, .retry, .pyc, .pyo
您可以通过在 ansible.cfg 中配置 inventory_ignore_extensions 列表,或设置 ANSIBLE_INVENTORY_IGNORE 环境变量,用您自己的选择替换此列表。无论哪种情况,值必须是如上所示的以逗号分隔的模式列表。
清单目录中的任何 group_vars 和 host_vars 子目录都将按预期解析,这使得清单目录成为组织不同配置集的一种强大方式。更多信息请参阅 传递多个清单源。
动态组的静态组
在静态清单文件中定义组之组时,子组也必须在静态清单文件中定义,否则 ansible 将返回错误。如果您想定义一个由动态子组组成的静态组,请在静态清单文件中将动态组定义为空。例如
[tag_Name_staging_foo]
[tag_Name_staging_bar]
[staging:children]
tag_Name_staging_foo
tag_Name_staging_bar