Ansible 2.5 移植指南
本节讨论 Ansible 2.4 和 Ansible 2.5 之间的行为变化。
它旨在帮助您更新您的剧本、插件和 Ansible 基础设施的其他部分,以便它们与 Ansible 的这个版本兼容。
建议您阅读此页面以及 Ansible 2.5 的变更日志,以了解您可能需要进行哪些更新。
本文档是关于移植的集合的一部分。移植指南的完整列表可以在 移植指南 中找到。
剧本
动态包含和属性继承
在 Ansible 2.4 版本中,引入了动态包含 (include_tasks
) 的概念,与静态导入 (import_tasks
) 相区别,以明确定义动态包含和静态包含之间 include
的工作方式差异。
应用于动态 include_*
的所有属性仅适用于包含本身,而应用于静态 import_*
的属性将被包含的任务继承。
这种分离在 Ansible 2.4 版本中只是部分实现。从 Ansible 2.5 版本开始,这项工作已经完成,并且分离现在按设计运行;应用于 include_*
任务的属性将不会被包含的任务继承。
为了实现与 Ansible 2.5 之前的版本类似的结果,剧本应该在所需任务上显式应用属性,或者使用块将属性应用于多个任务。另一个选择是尽可能使用静态 import_*
,而不是动态任务。
**旧的** 在 Ansible 2.4 中
- include_tasks: "{{ ansible_distribution }}.yml"
tags:
- distro_include
包含文件
- block:
- debug:
msg: "In included file"
- apt:
name: nginx
state: latest
**新的** 在 Ansible 2.5 中
包含的任务
- include_tasks: "{{ ansible_distribution }}.yml"
tags:
- distro_include
包含文件
- block:
- debug:
msg: "In included file"
- apt:
name: nginx
state: latest
tags:
- distro_include
这些示例中相关的变化是,在 Ansible 2.5 中,包含文件再次定义了标签 distro_include
。标签不会自动继承。
修复关键字和内联变量的处理
我们对处理关键字和“内联变量”的方式进行了一些修复,以避免将两者混淆。不幸的是,这些变化意味着您在调用角色时必须明确指定 name 是关键字还是变量。如果您的剧本像这样
roles:
- { role: myrole, name: Justin, othervar: othervalue, become: True}
您会遇到错误,因为 Ansible 在这种情况下将 name 视为关键字。从 2.5 版本开始,如果您想使用也是关键字的变量名,则必须显式地将其声明为角色的变量
roles:
- { role: myrole, vars: {name: Justin, othervar: othervalue}, become: True}
有关关键字的完整列表,请参见 剧本关键字。
从 with_X 迁移到 loop
在大多数情况下,循环使用 loop
关键字而不是 with_X
样式循环效果最好。loop
语法通常使用过滤器表达最佳,而不是更复杂的 query
或 lookup
使用方式。
这些示例展示了如何将许多常见的 with_
样式循环转换为 loop
和过滤器。
with_list
with_list
直接被 loop
替换。
- name: with_list
ansible.builtin.debug:
msg: "{{ item }}"
with_list:
- one
- two
- name: with_list -> loop
ansible.builtin.debug:
msg: "{{ item }}"
loop:
- one
- two
with_items
with_items
被 loop
和 flatten
过滤器替换。
- name: with_items
ansible.builtin.debug:
msg: "{{ item }}"
with_items: "{{ items }}"
- name: with_items -> loop
ansible.builtin.debug:
msg: "{{ item }}"
loop: "{{ items|flatten(levels=1) }}"
with_indexed_items
with_indexed_items
被 loop
、flatten
过滤器和 loop_control.index_var
替换。
- name: with_indexed_items
ansible.builtin.debug:
msg: "{{ item.0 }} - {{ item.1 }}"
with_indexed_items: "{{ items }}"
- name: with_indexed_items -> loop
ansible.builtin.debug:
msg: "{{ index }} - {{ item }}"
loop: "{{ items|flatten(levels=1) }}"
loop_control:
index_var: index
with_flattened
with_flattened
被 loop
和 flatten
过滤器替换。
- name: with_flattened
ansible.builtin.debug:
msg: "{{ item }}"
with_flattened: "{{ items }}"
- name: with_flattened -> loop
ansible.builtin.debug:
msg: "{{ item }}"
loop: "{{ items|flatten }}"
with_together
with_together
被 loop
和 zip
过滤器替换。
- name: with_together
ansible.builtin.debug:
msg: "{{ item.0 }} - {{ item.1 }}"
with_together:
- "{{ list_one }}"
- "{{ list_two }}"
- name: with_together -> loop
ansible.builtin.debug:
msg: "{{ item.0 }} - {{ item.1 }}"
loop: "{{ list_one|zip(list_two)|list }}"
另一个使用复杂数据的示例
- name: with_together -> loop
ansible.builtin.debug:
msg: "{{ item.0 }} - {{ item.1 }} - {{ item.2 }}"
loop: "{{ data[0]|zip(*data[1:])|list }}"
vars:
data:
- ['a', 'b', 'c']
- ['d', 'e', 'f']
- ['g', 'h', 'i']
with_dict
with_dict
可以被 loop
以及 dictsort
或 dict2items
过滤器替换。
- name: with_dict
ansible.builtin.debug:
msg: "{{ item.key }} - {{ item.value }}"
with_dict: "{{ dictionary }}"
- name: with_dict -> loop (option 1)
ansible.builtin.debug:
msg: "{{ item.key }} - {{ item.value }}"
loop: "{{ dictionary|dict2items }}"
- name: with_dict -> loop (option 2)
ansible.builtin.debug:
msg: "{{ item.0 }} - {{ item.1 }}"
loop: "{{ dictionary|dictsort }}"
with_sequence
with_sequence
被 loop
和 range
函数替换,并且可能还会被 format
过滤器替换。
- name: with_sequence
ansible.builtin.debug:
msg: "{{ item }}"
with_sequence: start=0 end=4 stride=2 format=testuser%02x
- name: with_sequence -> loop
ansible.builtin.debug:
msg: "{{ 'testuser%02x' | format(item) }}"
loop: "{{ range(0, 4 + 1, 2)|list }}"
循环的范围不包括端点。
with_subelements
with_subelements
被 loop
和 subelements
过滤器替换。
- name: with_subelements
ansible.builtin.debug:
msg: "{{ item.0.name }} - {{ item.1 }}"
with_subelements:
- "{{ users }}"
- mysql.hosts
- name: with_subelements -> loop
ansible.builtin.debug:
msg: "{{ item.0.name }} - {{ item.1 }}"
loop: "{{ users|subelements('mysql.hosts') }}"
with_nested/with_cartesian
with_nested
和 with_cartesian
被循环和 product
过滤器取代。
- name: with_nested
ansible.builtin.debug:
msg: "{{ item.0 }} - {{ item.1 }}"
with_nested:
- "{{ list_one }}"
- "{{ list_two }}"
- name: with_nested -> loop
ansible.builtin.debug:
msg: "{{ item.0 }} - {{ item.1 }}"
loop: "{{ list_one|product(list_two)|list }}"
with_random_choice
with_random_choice
被直接使用 random
过滤器取代,不需要 loop
。
- name: with_random_choice
ansible.builtin.debug:
msg: "{{ item }}"
with_random_choice: "{{ my_list }}"
- name: with_random_choice -> loop (No loop is needed here)
ansible.builtin.debug:
msg: "{{ my_list|random }}"
tags: random
已弃用
用作过滤器的 Jinja 测试
在 Ansible 2.9 中将删除用作过滤器的 Ansible 提供的 jinja 测试。
在 Ansible 2.5 之前,Ansible 中包含的 jinja 测试最常被用作过滤器。使用上的主要区别在于过滤器被引用为 variable | filter_name
,而 jinja 测试被引用为 variable is test_name
。
Jinja 测试用于比较,而过滤器用于数据操作,它们在 jinja 中具有不同的应用。此更改旨在帮助区分概念,以便更好地理解 jinja 以及每个概念的适用范围。
从 Ansible 2.5 开始,使用带有过滤器语法的 Ansible 提供的 jinja 测试将显示弃用错误。
旧版 在 Ansible 2.4(及更早版本)中,使用 Ansible 包含的 jinja 测试可能如下所示
when:
- result | failed
- not result | success
新版 在 Ansible 2.5 中,应更改为如下所示
when:
- result is failed
- results is not successful
除了弃用警告外,还引入了许多新的测试,它们是旧测试的别名。这些新的测试在语法上更符合 jinja 测试语法,例如新的 successful
测试是 success
的别名。
when: result is successful
有关更多信息,请参见 测试。
此外,还创建了一个脚本,用于帮助将使用过滤器语法的测试转换为正确的 jinja 测试语法。该脚本已被用于将所有 Ansible 集成测试转换为正确的格式。该脚本有一些已记录的限制,并且在执行修改后的剧本之前,应评估该脚本所做的所有更改是否正确。该脚本可在 https://github.com/ansible/ansible/blob/devel/hacking/fix_test_syntax.py 中找到。
Ansible 事实命名空间
Ansible 事实,过去常被写入类似 ansible_*
的名称,位于主事实命名空间中,现在已放置在它们自己的新命名空间 ansible_facts.*
中。例如,事实 ansible_distribution
现在最好通过变量结构 ansible_facts.distribution
查询。
已在 ansible.cfg 中添加了一个新的配置变量 inject_facts_as_vars
。它的默认设置“True”保留了 2.4 行为,即事实变量在旧的 ansible_*
位置被设置(同时还写入新命名空间)。预计在将来的版本中,此变量将设置为“False”。当 inject_facts_as_vars
设置为 False 时,您必须通过新的 ansible_facts.*
命名空间来引用 ansible_facts。
模块
这里详细介绍了常用模块中的主要更改。
github_release
在 Ansible 2.4 及更早版本中,使用 create_release
状态创建 GitHub 版本后,github_release
模块将状态报告为 skipped
。在 Ansible 2.5 及更高版本中,使用 create_release
状态创建 GitHub 版本后,github_release
模块现在将状态报告为 changed
。
已删除的模块
以下模块不再存在
nxos_mtu 使用 nxos_system 的
system_mtu
选项或 nxos_interface 代替cl_interface_policy 使用 nclu 代替
cl_bridge 使用 nclu 代替
cl_img_install 使用 nclu 代替
cl_ports 使用 nclu 代替
cl_license 使用 nclu 代替
cl_interface 使用 nclu 代替
cl_bond 使用 nclu 代替
ec2_vpc 使用 ec2_vpc_net 以及支持模块 ec2_vpc_igw、ec2_vpc_route_table、ec2_vpc_subnet、ec2_vpc_dhcp_option、ec2_vpc_nat_gateway、ec2_vpc_nacl 代替。
ec2_ami_search 使用 ec2_ami_facts 代替
docker 使用 docker_container 和 docker_image 代替
注意
这些模块可能在当前版本中没有文档。如果您需要了解它们的工作方式以便移植您的剧本,请参阅 Ansible 2.4 模块文档。
弃用通知
以下模块将在 Ansible 2.9 中删除。请相应地更新您的剧本。
Apstra 的
aos_*
模块已弃用,因为它们不适用于 AOS 2.1 或更高版本。请参阅 https://github.com/apstra 上的新模块。nxos_ip_interface 使用 nxos_l3_interface 代替。
nxos_portchannel 使用 nxos_linkagg 代替。
nxos_switchport 使用 nxos_l2_interface 代替。
panos_security_policy 使用 panos_security_rule 代替。
panos_nat_policy 使用 panos_nat_rule 代替。
vsphere_guest 使用 vmware_guest 代替。
值得注意的模块更改
stat 和 win_stat 模块已将选项
get_md5
的默认值从true
更改为false
。
此选项将在 Ansible 2.9 及更高版本中删除。如果需要 MD5 校验和,则仍然可以使用选项 get_checksum: True
和 checksum_algorithm: md5
。
osx_say
模块已重命名为 say。几个可以处理符号链接的模块将其
follow
选项的默认值更改为 标准化 follow 行为 的一部分。file 模块 从
follow=False
更改为follow=True
,因为它的目的是修改文件的属性,而大多数系统不允许将属性应用于符号链接,只能应用于真实文件。replace 模块 已删除其
follow
参数,因为它本质上修改了现有文件的内容,因此对链接本身进行操作毫无意义。blockinfile 模块 已删除其
follow
参数,因为它本质上修改了现有文件的内容,因此对链接本身进行操作毫无意义。在 Ansible-2.5.3 中,template 模块 对其
src
文件是正确的 utf-8 变得更加严格。以前,template 模块 src 文件中的非 utf-8 内容会导致输出文件被破坏(非 utf-8 字符将被替换为 unicode 替换字符)。现在,在 Python2 上,模块将显示错误消息“模板源文件必须使用 utf-8 编码”。在 Python3 上,模块将首先尝试逐字传递非 utf-8 字符,如果失败,则会失败。
插件
作为开发人员,您现在可以对支持新插件配置系统的插件类型使用“文档片段”来表示常见配置选项。
清单
清单插件已进行了微调,我们已经开始添加一些常见功能
默认情况下,使用缓存插件来避免代价高昂的 API/DB 查询的功能已禁用。如果使用清单脚本,某些脚本可能已经支持缓存,但这在 Ansible 的认知和控制范围之外。迁移到内部缓存将允许您使用 Ansible 现有的缓存刷新/失效机制。
一个新的“auto”插件(默认情况下已启用),可以自动检测要使用的正确插件(如果该插件使用我们的“通用 YAML 配置格式”)。以前的 host_list、script、yaml 和 ini 插件仍然像以前一样工作,auto 插件现在是我们尝试使用的最后一个插件。如果您定制了已启用的插件,则应修改设置以包含新的 auto 插件。
Shell
Shell 插件已迁移到新的插件配置框架。现在可以定制更多设置,以前是“全局”的设置现在也可以使用主机特定变量覆盖。
例如,system_temps
是一个新的设置,允许你控制 Ansible 将哪些目录视为“系统临时目录”。当为非管理员用户提升权限时会用到它。以前这个设置被硬编码为“/tmp”,而一些系统无法将它用于权限提升。现在,这个设置默认设置为 [ '/var/tmp', '/tmp']
。
另一个新的设置是 admin_users
,它允许你指定被视为“管理员”的用户列表。以前,这个设置被硬编码为 root
。现在,它默认设置为 [root, toor, admin]
。这些信息会在选择 remote_temp
和 system_temps
目录时使用。
要查看完整的列表,请查看你正在使用的 shell 插件,默认的 shell 插件是 sh
。
那些必须绕过全局配置限制的用户现在可以迁移到每个主机/组的设置,但也要注意,如果假设与你的环境不符,新的默认值可能会与现有使用情况发生冲突。
过滤器
如果查找插件 API 返回一个不可迭代的值,则现在会抛出错误。以前,如果插件返回数字或其他不可迭代类型,则不会抛出错误或警告。进行此更改是因为插件应始终返回列表。请注意,返回字符串和其他非列表可迭代值的插件不会抛出错误,但可能会导致不可预测的行为。如果你有自定义查找插件没有返回列表,则应修改它以将返回值包装在列表中。
查找
在全局范围内添加了一个名为 error
的新选项到查找插件,它允许你控制在查找产生错误时如何处理这些错误,在此选项之前,它们始终是致命的。此选项的有效值为 warn
、ignore
和 strict
。有关更多详细信息,请参见 查找 页面。
移植自定义脚本
没有明显的变化。
网络
扩展文档
我们正在扩展网络文档。有新的内容和一个 新的 Ansible 网络着陆页。我们将继续构建与网络相关的文档。
顶级连接参数将在 2.9 中删除
顶级连接参数,如 username
、host
和 password
已被弃用,并将从 2.9 版本中删除。
旧版 在 Ansible < 2.4 中
- name: example of using top-level options for connection properties
ios_command:
commands: show version
host: "{{ inventory_hostname }}"
username: cisco
password: cisco
authorize: yes
auth_pass: cisco
弃用警告反映了此时间表。上面的任务在 Ansible 2.5 中运行,将导致
[DEPRECATION WARNING]: Param 'username' is deprecated. See the module docs for more information. This feature will be removed in version
2.9. Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg.
[DEPRECATION WARNING]: Param 'password' is deprecated. See the module docs for more information. This feature will be removed in version
2.9. Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg.
[DEPRECATION WARNING]: Param 'host' is deprecated. See the module docs for more information. This feature will be removed in version 2.9.
Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg.
我们建议使用新的连接类型 network_cli
和 netconf
(见下文),使用标准的 Ansible 连接属性,并在清单中按组设置这些属性。当你更新你的剧本和清单文件时,你可以轻松地将更改为 become
来进行权限提升(在支持它的平台上)。有关更多信息,请参见 使用 become 与网络模块 指南和 平台文档。
添加持久连接类型 network_cli
和 netconf
Ansible 2.5 引入了两种顶级持久连接类型,network_cli
和 netconf
。使用 connection: local
,每个任务都会传递连接参数,这些参数必须存储在你的剧本中。使用 network_cli
和 netconf
,剧本只传递一次连接参数,因此你可以选择在命令行传递它们。我们建议你尽可能使用 network_cli
和 netconf
。请注意,eAPI 和 NX-API 仍然需要使用 local
连接,并使用 provider
字典。有关更多信息,请参见 平台文档。除非你需要 local
连接,否则请更新你的剧本以使用 network_cli
或 netconf
,并使用标准的 Ansible 连接变量来指定你的连接变量。
**旧的** 在 Ansible 2.4 中
---
vars:
cli:
host: "{{ inventory_hostname }}"
username: operator
password: secret
transport: cli
tasks:
- nxos_config:
src: config.j2
provider: "{{ cli }}"
username: admin
password: admin
**新的** 在 Ansible 2.5 中
[nxos:vars]
ansible_connection=network_cli
ansible_network_os=nxos
ansible_user=operator
ansible_password=secret
tasks:
- nxos_config:
src: config.j2
使用 network_cli
或 netconf
的提供程序字典将导致警告。