Ansible 2.5 移植指南

本节讨论 Ansible 2.4 和 Ansible 2.5 之间的行为变化。

旨在帮助您更新剧本、插件以及 Ansible 基础架构的其他部分,以便它们能够与 Ansible 的此版本一起使用。

我们建议您阅读此页面以及 Ansible 2.5 的变更日志 ,以了解您可能需要进行哪些更新。

本文件是关于移植的集合的一部分。完整的移植指南列表可在 移植指南 中找到。

剧本 (Playbook)

动态 include 和属性继承

在 Ansible 2.4 版本中,引入了动态 include(include_tasks)的概念,与静态导入(import_tasks)相对,以明确定义 include 在动态 include 和静态 include 之间的运作方式差异。

应用于动态 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 语法通常最好使用过滤器来表达,而不是更复杂地使用 querylookup

这些示例展示了如何将许多常见的 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_itemsloopflatten 过滤器替换。

- 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_itemsloopflatten 过滤器和 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_flattenedloopflatten 过滤器替换。

- 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_togetherloopzip 过滤器替换。

- 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 可以用 loopdictsortdict2items 过滤器来代替。

- 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_sequencelooprange 函数以及 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_subelementsloopsubelements 过滤器替换。

- 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_nestedwith_cartesianloopproduct 过滤器替换。

- 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 测试和过滤器语法将显示弃用错误。

旧版 (OLD) 在 Ansible 2.4(及更早版本)中,使用 Ansible 内置的 Jinja 测试可能如下所示

when:
    - result | failed
    - not result | success

新版 (NEW) 在 Ansible 2.5 中,应该更改为如下所示

when:
    - result is failed
    - results is not successful

除了弃用警告之外,还引入许多新的测试,它们是旧测试的别名。这些新测试在语法上更符合 Jinja 测试语法,例如新的 successful 测试是 success 的别名。

when: result is successful

更多信息,请参见 测试

此外,还创建了一个脚本来帮助将使用过滤器语法的测试转换为正确的 Jinja 测试语法。此脚本已用于将所有 Ansible 集成测试转换为正确的格式。文档中记录了一些限制,在执行修改后的 playbook 之前,应评估此脚本所做的所有更改是否正确。该脚本可在 https://github.com/ansible/ansible/blob/devel/hacking/fix_test_syntax.py 找到。

Ansible fact 命名空间

Ansible facts 历史上以 ansible_* 的形式写入主 facts 命名空间,现在已放置到它们自己的新命名空间 ansible_facts.* 中。例如,fact ansible_distribution 现在最好通过变量结构 ansible_facts.distribution 查询。

一个新的配置变量 inject_facts_as_vars 已添加到 ansible.cfg 中。其默认设置为 ‘True’,保持了 2.4 版本中 facts 变量在旧的 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_systemsystem_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_igwec2_vpc_route_tableec2_vpc_subnetec2_vpc_dhcp_optionec2_vpc_nat_gatewayec2_vpc_nacl 代替。

  • ec2_ami_search 使用 ec2_ami_facts 代替

  • docker 使用 docker_containerdocker_image 代替

注意

这些模块在当前版本中可能不再有文档。如果您需要了解它们的工作方式以移植您的 playbook,请参阅 Ansible 2.4 模块文档

弃用通知

以下模块将在 Ansible 2.9 中移除。请相应地更新您的 playbook。

  • 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 代替。

值得注意的模块更改

  • statwin_stat 模块已将选项 get_md5 的默认值从 true 更改为 false

从 Ansible 2.9 开始,此选项将被移除。如果需要 MD5 校验和,仍然可以使用选项 get_checksum: Truechecksum_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/数据库查询的功能。如果使用清单脚本,某些脚本可能已经支持缓存,但这超出了 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_tempsystem_temps 目录之间进行选择。

有关完整列表,请检查您正在使用的 shell 插件,默认 shell 插件为 sh

那些必须解决全局配置限制问题的人现在可以迁移到每个主机/组设置,但也请注意,如果假设与您的环境不相关,则新的默认值可能会与现有用法冲突。

过滤器

如果查找插件 API 返回的值不是可迭代对象,现在会抛出错误。以前,插件返回的数字或其他非可迭代类型会被接受,不会报错或警告。此更改是因为插件应该始终返回列表。请注意,返回字符串和其他非列表可迭代值的插件不会抛出错误,但可能会导致不可预测的行为。如果您有一个自定义查找插件不返回列表,则应修改它以将返回值包装在列表中。

查找

全局为查找插件添加了一个名为error的新选项,允许您控制查找产生的错误的处理方式,在此选项之前,它们始终是致命的。此选项的有效值为warnignorestrict。有关更多详细信息,请参见查找页面。

移植自定义脚本

没有显著变化。

网络

扩展文档

我们正在扩展网络文档。有新的内容和一个新的 Ansible 网络登录页面。我们将继续构建与网络相关的文档。

顶级连接参数将在 2.9 版本中移除

顶级连接参数,如usernamehostpassword已被弃用,并将在 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_clinetconf(见下文),使用标准的 Ansible 连接属性,并通过组在清单中设置这些属性。在更新您的 playbook 和清单文件时,您可以轻松地将更改应用到become以进行权限提升(在支持它的平台上)。有关更多信息,请参见使用 become 与网络模块指南和平台文档

添加持久连接类型 network_clinetconf

Ansible 2.5 引入了两种顶级持久连接类型,network_clinetconf。使用connection: local,每个任务都会传递连接参数,这些参数必须存储在您的 playbook 中。使用network_clinetconf,playbook 只传递一次连接参数,因此您可以根据需要在命令行中传递它们。我们建议您尽可能使用network_clinetconf。请注意,eAPI 和 NX-API 仍然需要使用provider字典的local连接。有关更多信息,请参见平台文档。除非您需要local连接,否则请更新您的 playbook 以使用network_clinetconf,并使用标准 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_clinetconf的提供程序字典将导致警告。

开发者:共享模块实用程序已移动

从 Ansible 2.5 开始,网络模块的共享模块实用程序已移动到ansible.module_utils.network

  • 平台无关的实用程序位于ansible.module_utils.network.common

  • 特定于平台的实用程序位于ansible.module_utils.network.{{ platform }}

如果您的模块使用共享模块实用程序,则必须更新所有引用。例如,更改

旧版 在 Ansible 2.4 中

from ansible.module_utils.vyos import get_config, load_config

新版 在 Ansible 2.5 中

from ansible.module_utils.network.vyos.vyos import get_config, load_config

请参阅模块实用程序开发者指南,请参见使用和开发模块实用程序,了解更多信息。