Ansible 2.8 移植指南
本节讨论 Ansible 2.7 和 Ansible 2.8 之间的行为变化。
旨在帮助您更新您的剧本、插件以及 Ansible 基础架构的其他部分,以便它们能够与 Ansible 的此版本一起使用。
我们建议您阅读此页以及 Ansible 2.8 的变更日志,以了解您可能需要进行哪些更新。
本文件是关于移植的集合的一部分。完整的移植指南列表可在 移植指南 中找到。
剧本
发行版信息
返回的 ansible_distribution_* 组信息可能略有更改。Ansible 2.8 使用新的后端库来获取有关发行版的信息:nir0s/distro。此库在 Python-3.8 上运行,并修复了许多错误,包括更正发行版和版本名称。
剧本中最常用的两个事实,ansible_distribution 和 ansible_distribution_major_version,不应更改。如果您发现这些事实有变化,请提交错误报告,以便我们解决差异。但是,其他事实,如 ansible_distribution_release 和 ansible_distribution_version,可能会随着错误信息的更正而更改。
导入作为处理器
从 2.8 版本开始,任务无法通知 import_tasks 或在 handlers 中指定的静态 include。
静态导入的目标是充当预处理器,其中导入将被导入文件中定义的任务替换。使用导入时,任务可以通知导入文件中任何命名的任务,但不能通知导入本身的名称。
为了实现通知单个名称但运行多个处理器的结果,请使用 include_tasks 或 listen 处理器:在更改时运行操作。
Jinja 未定义值
从 2.8 版本开始,尝试访问 Jinja 中未定义值的属性将返回另一个未定义值,而不是立即抛出错误。这意味着您现在可以在不知道中间值是否已定义的情况下,简单地使用嵌套数据结构中的值作为默认值。
在 Ansible 2.8 中
{{ foo.bar.baz | default('DEFAULT') }}
在 Ansible 2.7 及更早版本中
{{ ((foo | default({})).bar | default({})).baz | default('DEFAULT') }}
或
{{ foo.bar.baz if (foo is defined and foo.bar is defined and foo.bar.baz is defined) else 'DEFAULT' }}
模块选项转换为字符串
从 2.8 版本开始,如果模块需要字符串,但传递了非字符串值并自动将其转换为字符串,Ansible 将发出警告。这突出了潜在的问题,例如,yes 或 true(解析为真值布尔值)将转换为字符串 'True',或者版本号 1.10(解析为浮点值)将转换为 '1.1'。根据上下文,此类转换可能会导致意外行为。
可以通过设置 ANSIBLE_STRING_CONVERSION_ACTION 环境变量,或在 ansible.cfg 的 defaults 部分设置 string_conversion_action 配置来更改此行为,使其成为错误或被忽略。
命令行信息
cmdline 系统中返回的信息将被弃用,转而使用 proc_cmdline。此更改处理内核命令行参数包含多个具有相同键的值的特殊情况。
条件语句中的裸变量
在 Ansible 2.7 及更早版本中,顶级变量有时会将布尔字符串视为布尔值。这导致基于定义为字符串的顶级变量构建的条件测试出现不一致的行为。Ansible 2.8 开始更改此行为。例如,如果您设置如下两个条件
tasks:
- include_tasks: teardown.yml
when: teardown
- include_tasks: provision.yml
when: not teardown
基于您**作为字符串**定义的变量(在其周围使用引号)
在 Ansible 2.7 及更早版本中,如果
teardown: 'true',则上述两个条件分别计算为True和False在 Ansible 2.7 及更早版本中,如果
teardown: 'false',则这两个条件都计算为False在 Ansible 2.8 及更高版本中,您可以选择禁用条件裸变量,因此当
teardown是非空字符串(包括'true'或'false')时,when: teardown始终计算为True,而when: not teardown始终计算为False
最终,只要 'string' 不为空,when: 'string' 将始终计算为 True,而 when: not 'string' 将始终计算为 False,即使 'string' 的值本身看起来像布尔值。对于依赖于旧行为的剧本的用户,我们添加了一个配置设置来保留它。您可以使用 ANSIBLE_CONDITIONAL_BARE_VARS 环境变量或 ansible.cfg 的 defaults 部分中的 conditional_bare_variables 来选择您在控制节点上所需的行为。默认设置为 true,它保留了旧的行为。将配置值或环境变量设置为 false 以开始使用新选项。
注意
在 2.10 中,conditional_bare_variables 的默认设置将更改为 false。在 2.12 中,旧的行为将被弃用。
更新您的剧本
要为新的行为准备您的剧本,您必须更新您的条件语句,使其只接受布尔值。对于变量,您可以使用 bool 过滤器将字符串 'false' 计算为 False
vars:
teardown: 'false'
tasks:
- include_tasks: teardown.yml
when: teardown | bool
- include_tasks: provision.yml
when: not teardown | bool
或者,您可以将变量重新定义为布尔值(无引号),而不是字符串
vars:
teardown: false
tasks:
- include_tasks: teardown.yml
when: teardown
- include_tasks: provision.yml
when: not teardown
对于字典和列表,使用 length 过滤器将字典或列表的存在计算为 True
- debug:
when: my_list | length > 0
- debug:
when: my_dictionary | length > 0
不要将 bool 过滤器与列表或字典一起使用。如果您将 bool 与列表或字典一起使用,Ansible 将始终将其计算为 False。
双重插值
conditional_bare_variables 设置也会影响基于其他变量设置的变量。旧的行为意外地对这些变量进行了双重插值。例如:
vars:
double_interpolated: 'bare_variable'
bare_variable: false
tasks:
- debug:
when: double_interpolated
在 Ansible 2.7 及更早版本中,
when: double_interpolated的计算结果为bare_variable的值,在本例中为False。如果变量bare_variable未定义,则条件判断失败。在 Ansible 2.8 及更高版本中,禁用裸变量后,Ansible 将
double_interpolated评估为字符串'bare_variable',其值为True。
要进行变量值的双重插值,请使用花括号。
vars:
double_interpolated: "{{ other_variable }}"
other_variable: false
嵌套变量
conditional_bare_variables 设置不影响嵌套变量。分配给子键的任何字符串值都会被尊重,不会被视为布尔值。如果 complex_variable['subkey'] 是非空字符串,则 when: complex_variable['subkey'] 始终为 True,而 when: not complex_variable['subkey'] 始终为 False。如果希望将类似 complex_variable['subkey'] 的字符串子键作为布尔值进行评估,则必须使用 bool 过滤器。
收集事实
在 Ansible 2.8 中,Play 中隐式的“收集事实”任务已更改为遵循 Play 标签。在 2.8 之前,“收集事实”任务会忽略 Play 标签和命令行提供的标签,并且始终作为一个任务运行。
此行为更改会影响以下示例 Play。
- name: Configure Webservers
hosts: webserver
tags:
- webserver
tasks:
- name: Install nginx
package:
name: nginx
tags:
- nginx
在 Ansible 2.8 中,如果提供 --tags nginx,则会跳过隐式的“收集事实”任务,因为该任务现在继承 webserver 的标签,而不是 always。
如果没有设置 Play 级别的标签,“收集事实”任务将被赋予 always 标签,并且会有效地匹配之前的行为。
您可以通过在 tasks 列表中使用显式的 gather_facts 任务来实现与 2.8 之前版本类似的结果。
- name: Configure Webservers
hosts: webserver
gather_facts: false
tags:
- webserver
tasks:
- name: Gathering Facts
gather_facts:
tags:
- always
- name: Install nginx
package:
name: nginx
tags:
- nginx
Python 解释器发现
在 Ansible 2.7 及更早版本中,Ansible 默认将 /usr/bin/python 作为 ansible_python_interpreter 的设置。如果您针对安装了不同名称或不同路径的 Python 的系统运行 Ansible,您的 Playbook 将会失败,并显示 /usr/bin/python: bad interpreter: No such file or directory,除非您将 ansible_python_interpreter 设置为该系统的正确值,或者在 usr/bin/python 添加了一个 Python 解释器和任何必要的依赖项。
从 Ansible 2.8 开始,Ansible 会在每个目标系统上搜索 Python 的正确路径和可执行文件名,首先在常用发行版的默认 Python 解释器查找表中查找,然后在可能的 Python 解释器名称/路径的有序回退列表中查找。
依赖回退列表中设置的 Python 解释器是有风险的,因为解释器可能会在将来的运行中发生变化。如果回退列表中较高位置的解释器被安装(例如,作为安装其他软件包的副作用),则原始解释器及其依赖项将不再被使用。出于这个原因,当 Ansible 使用从回退列表中发现的 Python 解释器时,它会发出警告。如果您看到此警告,最佳解决方案是将 ansible_python_interpreter 显式设置为这些目标系统的正确解释器的路径。
您仍然可以在任何变量级别(作为主机变量、在 vars 文件中、在 Playbook 中等等)将 ansible_python_interpreter 设置为特定路径。如果您更喜欢使用 Python 解释器发现行为,请使用 Ansible 2.8 中引入的四个新 ansible_python_interpreter 值之一。
新值 |
行为 |
|---|---|
auto |
如果发现 Python 解释器,即使 /usr/bin/python 也存在,Ansible 也会使用发现的 Python。使用回退列表时会发出警告。 |
auto_legacy |
如果发现 Python 解释器并且 /usr/bin/python 不存在,Ansible 将使用发现的 Python。使用回退列表时会发出警告。 如果发现 Python 解释器并且 /usr/bin/python 存在,Ansible 将使用 /usr/bin/python 并打印有关未来默认行为的弃用警告。使用回退列表时会发出警告。 |
auto_legacy_silent |
行为类似于 |
auto_silent |
行为类似于 |
在 Ansible 2.12 中,Ansible 将默认值从 auto_legacy 切换到 auto。行为上的区别在于,auto_legacy 如果存在则使用 /usr/bin/python,如果不存在则回退到发现的 Python。 auto 将始终使用发现的 Python,无论 /usr/bin/python 是否存在。auto_legacy 设置提供了与之前版本的 Ansible 的兼容性,这些版本始终默认为 /usr/bin/python。
如果您已将 Python 和依赖项(boto 等)安装到 /usr/bin/python(作为在具有不同默认 Python 解释器的发行版(例如,Ubuntu 16.04+、RHEL8、Fedora 23+)上的解决方法),您有两种选择:
将现有依赖项移至每个平台/发行版/版本的默认 Python。
使用
auto_legacy。此设置允许 Ansible 在具有该解决方法的宿主机上查找和使用解决方法 Python,同时也在较新的宿主机上查找正确的默认 Python。但请记住,默认设置将在 4 个版本后发生更改。
重试文件创建默认值
在 Ansible 2.8 中,retry_files_enabled 现在默认为 False,而不是 True。可以通过编辑默认的 ansible.cfg 文件并将值设置为 True 来修改此行为以与旧版本相同。
命令行
提升权限提示
从 2.8 版本开始,Ansible 默认情况下将使用单词 BECOME 来提示您输入提升权限的密码(在 Unix 系统上为 sudo 权限,在网络设备上为 enable 模式)。
Ansible 2.8 默认情况下:
ansible-playbook --become --ask-become-pass site.yml
BECOME password:
如果您希望提示显示正在使用的特定 become_method,而不是通用的 BECOME 值,请在 Ansible 配置中将 AGNOSTIC_BECOME_PROMPT 设置为 False。
Ansible 2.7 默认情况下,或在 Ansible 2.8 中使用 AGNOSTIC_BECOME_PROMPT=False:
ansible-playbook --become --ask-become-pass site.yml
SUDO password:
已弃用
使用
ANSIBLE_ASYNC_DIR作为任务/Play 环境键来设置异步目录已被弃用,并且将在 Ansible 2.12 中移除。您可以通过将ansible_async_dir作为变量来设置,例如:- name: run task with custom async directory command: sleep 5 async: 10 vars: ansible_async_dir: /tmp/.ansible_async
需要
FactCache对象的插件编写者应该注意两个弃用事项:FactCache类已从ansible.plugins.cache.FactCache移动到ansible.vars.fact_cache.FactCache。这是因为FactCache不是缓存插件 API 的一部分,缓存插件作者不应对其进行子类化。FactCache仍然可以从其旧位置访问,但从那里使用时会发出弃用警告。旧位置将在 Ansible 2.12 中移除。FactCache.update()方法已更改为遵循 dict API。它现在只接受一个字典作为参数,并用字典中的项更新自身。之前的 API 中,update()接受键和值,现在将发出弃用警告,并将在 2.12 版本中移除。如果您需要旧的行为,请改用FactCache.first_order_merge()。
通过 self.cache 支持基于文件的缓存已被弃用,并将 Ansible 2.12 版本中移除。如果您维护一个清单插件,请将其更新为使用
self._cache作为字典。有关实现细节,请参阅 清单插件开发指南。直接导入缓存插件已被弃用,并将 Ansible 2.12 版本中移除。使用 plugin_loader,以便可以使用配置系统(而不是常量)来协调直接选项、环境变量和其他配置方法。
from ansible.plugins.loader import cache_loader cache = cache_loader.get('redis', **kwargs)
模块
此处详细介绍了常用模块中的重大更改
运行 PowerShell 模块的 exec 包装器已更改为全局设置 $ErrorActionPreference = "Stop"。这意味着如果自定义模块隐式依赖于此行为,则可能会失败。要恢复旧的行为,请在模块顶部添加 $ErrorActionPreference = "Continue"。进行此更改是为了恢复先前版本中意外删除的 EAP 的旧行为,并确保模块对执行中可能发生的错误更具弹性。
Ansible 2.8.14 版本将基于文件的任务的默认模式更改为
0o600 & ~umask(如果用户未在基于文件的任务上指定mode参数)。这是针对 CVE 报告作出的回应,但我们重新考虑了这个问题。因此,在 2.8.15 版本中,mode更改已恢复,mode现在将默认为0o666 & ~umask,与 Ansible 的先前版本一样。如果您在使用 2.8.14 版本时更改了任何任务以指定权限较低,则这些更改在 2.8.15 版本中将不再需要(但不会造成任何损害)。
为避免 CVE-2020-1736 中提出的问题,请在所有接受它的基于文件的任务中指定
mode参数。dnf和yum- 从 2.8.15 版本开始,dnf模块(以及当它使用dnf时的yum操作)现在可以正确验证软件包的 GPG 签名 (CVE-2020-14365)。如果您看到类似Failed to validate GPG signature for [package name]的错误,请确保您已为正在使用的 DNF 存储库和/或软件包导入了正确的 GPG 密钥。一种方法是使用rpm_key模块。虽然我们不建议这样做,但在某些情况下,可能需要禁用 GPG 检查。这可以通过在dnf或yum任务中显式添加disable_gpg_check: yes来完成。
已移除的模块
以下模块不再存在
ec2_remote_facts
azure
cs_nic
netscaler
win_msi
弃用通知
以下模块将在 Ansible 2.12 版本中移除。请相应更新您的 playbook。
foreman请改用 foreman-ansible-modules。katello请改用 foreman-ansible-modules。github_hooks请改用 github_webhook 和 github_webhook_facts。digital_ocean请改用 digital_ocean_droplet。gce请改用 gcp_compute_instance。gcspanner请改用 gcp_spanner_instance 和 gcp_spanner_database。gcdns_record请改用 gcp_dns_resource_record_set。gcdns_zone请改用 gcp_dns_managed_zone。gcp_forwarding_rule请改用 gcp_compute_global_forwarding_rule 或 gcp_compute_forwarding_rule。gcp_healthcheck请改用 gcp_compute_health_check、gcp_compute_http_health_check 或 gcp_compute_https_health_check。gcp_backend_service请改用 gcp_compute_backend_service。gcp_target_proxy请改用 gcp_compute_target_http_proxy。gcp_url_map请改用 gcp_compute_url_map。panos请改用 Palo Alto Networks Ansible Galaxy 角色。
值得注意的模块更改
foreman和katello模块已被弃用,取而代之的是一组按实体细分的模块,这些模块更注重幂等性。foreman和katello模块的替代品正式成为 Foreman 社区的一部分,并获得其支持。tower_credential模块最初要求ssh_key_data为 ssh_key_file 的路径。为了像 AWX/Tower/RHAAP 一样工作,ssh_key_data现在包含文件的内容。可以使用lookup('file', '/path/to/file')来实现之前的行为。win_scheduled_task模块弃用了将触发器重复指定为列表的支持,此格式将在 Ansible 2.12 版本中移除。请改用字典值指定重复。win_feature模块已移除弃用的restart_needed返回值,请改用标准化的reboot_required值。win_package模块已移除弃用的restart_required和exit_code返回值,请改用标准化的reboot_required和rc值。win_get_url模块已移除弃用的win_get_url返回字典,包含的值将直接返回。win_get_url模块已移除弃用的skip_certificate_validation选项,请改用标准化的validate_certs选项。vmware_local_role_facts模块现在返回字典列表,而不是字典的字典,用于角色信息。如果
docker_network或docker_volume使用diff: yes、check_mode: yes或debug: yes调用,则会返回名为diff的返回值,其类型为list。为了启用正确的 diff 输出,将其更改为dict类型;原始的list将作为diff.differences返回。na_ontap_cluster_peer模块已将source_intercluster_lif和dest_intercluster_lif字符串选项替换为source_intercluster_lifs和dest_intercluster_lifs列表选项。modprobe模块现在可以检测内核内置模块。以前,尝试移除(使用state: absent)内置内核模块时,会成功执行而没有任何错误消息,因为modprobe没有检测到该模块为present。现在,如果内核模块是内置的并且state: absent,modprobe将会失败(modprobe 二进制文件会显示类似modprobe: ERROR: Module nfs is builtin.的错误消息),如果state: present,则会成功执行且不会报告更改。任何使用changed_when: no来掩盖此问题的 playbook 都可以安全地移除该变通方法。要在将state: absent应用于内置内核模块时获得之前的行为,请在您的 playbook 中使用failed_when: false或ignore_errors: true。digital_ocean模块已被弃用,建议使用无需外部依赖项的模块。这允许更大的灵活性和更好的模块支持。docker_container模块已弃用返回的事实docker_container。相同的值可作为返回变量container获取。返回的事实将在 Ansible 2.12 中移除。docker_network模块已弃用返回的事实docker_container。相同的值可作为返回变量network获取。返回的事实将在 Ansible 2.12 中移除。docker_volume模块已弃用返回的事实docker_container。相同的值可作为返回变量volume获取。返回的事实将在 Ansible 2.12 中移除。docker_service模块已重命名为docker_compose。重命名的
docker_compose模块过去每个服务返回一个事实,名称与服务相同。这些事实的字典作为常规返回值services返回。返回的事实将在 Ansible 2.12 中移除。docker_swarm_service模块不再为以下选项设置默认值user。之前,默认值为root。update_delay。之前,默认值为10。update_parallelism。之前,默认值为1。
vmware_vm_facts过去返回包含虚拟机事实的字典的字典。Ansible 2.8 及更高版本将返回包含虚拟机事实的字典列表。请参阅模块vmware_vm_facts文档以了解示例。vmware_guest_snapshot模块过去返回results。自 Ansible 2.8 及更高版本以来,results是一个保留关键字,它被替换为snapshot_results。请参阅模块vmware_guest_snapshots文档以了解示例。panos模块已被弃用,建议使用 Palo Alto Networks 的 Ansible Galaxy 角色 [https://galaxy.ansible.com/PaloAltoNetworks/paloaltonetworks](https://galaxy.ansible.com/PaloAltoNetworks/paloaltonetworks)。可以在 [https://github.com/PaloAltoNetworks/ansible-pan](https://github.com/PaloAltoNetworks/ansible-pan) 贡献代码。ipa_user模块最初总是将password发送到 FreeIPA,无论密码是否更改。现在,该模块仅在update_password设置为always(这是默认值)时才发送password。win_psexec已弃用未公开的extra_opts模块选项。这将在 Ansible 2.10 中移除。win_nssm模块已弃用以下选项,建议使用win_service模块在使用win_nssm安装服务后配置服务:*dependencies,改用win_service的dependencies;*start_mode,改用win_service的start_mode;*user,改用win_service的username;*password,改用win_service的password。这些选项将在 Ansible 2.12 中移除。win_nssm模块还弃用了status选项的start、stop和restart值。您应该使用win_service模块来控制服务的运行状态。这将在 Ansible 2.12 中移除。win_nssm的status模块选项的默认值已更改为present。之前,默认值为start。因此,使用win_nssm创建后,服务不再默认启动,如果需要,您应该使用win_service模块启动它。win_nssm的app_parameters模块选项已被弃用;请改用argument。这将在 Ansible 2.12 中移除。win_nssm的app_parameters_free_form模块选项已作为新的arguments选项的别名。win_dsc模块现在将验证 DSC 资源的输入选项。在以前的版本中,无效选项将被忽略,但现在不会。openssl_pkcs12模块现在如果磁盘上的文件与传递给模块的参数之间存在差异,将重新生成 pkcs12 文件。
插件
当使用 macOS 作为控制节点时,Ansible 不再默认使用
paramiko连接插件。Ansible 现在默认在 macOS 控制节点上使用ssh连接插件。ssh支持任务和 playbook 运行之间的连接持久性,因此其性能优于paramiko。如果您使用的是密码身份验证,则在使用ssh连接插件时,需要安装sshpass。或者,您可以明确地将连接类型设置为paramiko以保持 macOS 上 2.8 之前的行为。连接插件已标准化,允许使用
ansible_<conn-type>_user和ansible_<conn-type>_password变量。诸如ansible_<conn-type>_pass和ansible_<conn-type>_username之类的变量优先级低于标准化名称,将来可能会被弃用。一般情况下,除非有理由使用特定于连接的变量,否则应使用ansible_user和ansible_password变量。powershellshell插件现在使用async_dir定义结果文件的异步路径,默认值已更改为%USERPROFILE%\.ansible_async。要控制此路径,现在可以设置ansible_async_dir变量或在config ini的powershell部分中设置async_dir值。已更新启用的清单插件的顺序(INVENTORY_ENABLED),auto现在位于yaml和ini之前。
已从回调插件的
CallbackBase类中删除了私有_options属性。如果您有需要访问命令行参数的第三方回调插件,请使用以下代码代替尝试使用self._optionsfrom ansible import context [...] tags = context.CLIARGS['tags']
context.CLIARGS是一个只读字典,因此正常的字典检索方法(如CLIARGS.get('tags')和CLIARGS['tags'])按预期工作,但您将完全无法修改cli参数。剧本回顾现在也统计
ignored和rescued任务,以及ok、changed、unreachable、failed和skipped任务,这要感谢default回调插件中的两个额外的统计计数器。失败并设置了ignore_errors: yes的任务列为ignored。失败然后执行救援部分的任务列为rescued。请注意,与Ansible 2.7(及更早版本)不同,rescued任务不再计为failed。osx_say回调插件已重命名为say。清单插件现在通过缓存插件支持缓存。要开始使用清单的缓存插件,请参阅清单指南中的缓存部分。要移植自定义缓存插件以与清单兼容,请参阅关于缓存插件的开发者指南。
移植自定义脚本
Display 类
从 Ansible 2.8 开始,Display 类现在是“单例”。每个文件不应使用__main__.display,而应自行导入并实例化ansible.utils.display.Display。
旧版 在 Ansible 2.7(及更早版本)中,使用以下方法访问display对象
try:
from __main__ import display
except ImportError:
from ansible.utils.display import Display
display = Display()
新版 在 Ansible 2.8 中,应使用以下方法
from ansible.utils.display import Display
display = Display()
网络
eos_config、ios_config和nxos_config模块已删除已弃用的save和force参数,请使用save_when参数来复制其功能。nxos_vrf_af模块已删除safi参数。此参数在 Ansible 2.4 中已弃用,从那时起对模块没有任何影响。