我们希望听到您的声音!帮助我们深入了解 Ansible 生态系统的现状。
参加 Ansible 项目调查 2024

牛角号 #12

Ansible Bullhorn banner

牛角号

面向 Ansible 开发人员社区的新闻通讯
第 12 期,2020 年 10 月 21 日


欢迎来到牛角号,我们面向 Ansible 开发人员社区的新闻通讯。如果您有任何问题或想要分享的内容,请通过 [email protected] 与我们联系,或者评论此 GitHub 问题
 

重要日期

 

ANSIBLE 2.10.1 现已正式发布

Ansible 社区团队于 10 月 13 日宣布 ansible 2.10.1 正式发布。这个 ansible-2.10 包的第一个小版本应该可以替代 Ansible 2.9;您当前使用的角色和剧本应该可以与 ansible-2.10.1 无缝衔接。有关新功能、获取方法、注意事项和已知错误的更多信息,请阅读 Toshio Kuratomi 在 ansible-devel 邮件列表中的公告
 

ANSIBLE-BASE 2.10.2 现已正式发布

Ansible Base 团队于 10 月 5 日宣布 ansible 2.10.2 正式发布。这个 ansible-base 包只包含 Ansible 执行引擎、相关工具(例如 ansible-galaxy、ansible-test)以及一小部分内置插件,并且也与更大的 Ansible 发行版捆绑在一起。有关如何下载、测试和报告问题的更多信息,请阅读 Rick Elrod 在 ansible-devel 邮件列表中的公告
 

ANSIBLE 2.9.14 和 2.8.16 已发布

Ansible Core 团队于 10 月 5 日宣布 Ansible 2.9.14 和 Ansible 2.8.16 正式发布,这两个版本都是维护版本。请 点击此链接,阅读 Rick Elrod 发送到 ansible-devel 邮件列表的电子邮件,以获取有关新功能、安装说明以及完整变更日志链接的详细信息。
 

针对 ANSIBLE COLLECTION 的提案

需要来自更广泛的 Ansible 社区的反馈
  • 将 Ansible 2.10 中的集合内容移到当前不在集合中的内容,或者:我们是否应该将新集合添加到 2.10.x?例如,我们是否应该允许将 Postgres 模块从 community.general 迁移到一个新的 community.postgres 集合,并将其包含在 Ansible 2.10 中?#117
  • 文档是否应该包含在集合和 Ansible 包的 tarball 中?#120
  • 测试是否应该包含在集合的 tarball 中?#111
请通过在 GitHub 讨论中发表评论来添加您的反馈。您可以查看完整的提案列表 此处
 

影响集合贡献者的更改

  • ansible-test sanity 现在会针对集合验证更多语义版本控制属性(详细信息
您可以订阅 此 GitHub 问题,以随时了解这些更改。
 

新/更新的社区集合

这些集合已于 9 月 30 日发布:community.general 1.2.0community.network 1.2.0

对于 VMware,community.vmware 1.3.0 已于 10 月 2 日发布。这 篇博文 介绍了新的 VMware REST 集合

community.kubernetes 集合即将迁移到 kubernetes.core了解原因)。此外,community.okd 集合刚刚发布了新的 0.3.0 版本,可以进行测试,并将很快在 自动化中心 上以 'redhat.openshift' 的名称发布。

Ansible Podman 集合 已于 10 月 8 日发布了 1.3.1 版本,其中包含针对 podman_containerpodman_networkpodman_volume 和其他模块的错误修复和增强功能。对 PyYAML Python 包的依赖性最终已从所有 podman 模块中删除,因此该集合现在不再需要在主机上安装除 Podman 之外的任何其他依赖项。

10 月 13 日更新了更多集合:community.crypto 1.2.0(修复 CVE-2020-25646)、community.mysql 1.1.0cloudscale_ch.cloud 1.2.0

最后但并非最不重要,Ansible Openstack Cloud 集合 于 10 月 13 日发布了最新的 1.2.0 版本。添加了用于管理 Openstack 卷和快照的模块:volume_snapshot_infovolume_backupvolume_backup_info
 

ANSIBLE 贡献者峰会 (2020 年 10 月) 回顾

2020 年第三届全虚拟 Ansible 贡献者峰会于 10 月 12 日和 15 日举行。在两天的时间里,有超过 700 名参与者加入了我们,是 7 月份上一届活动的 10 倍。我们仍在处理峰会的视频和录音,它们将在 Ansible 社区 Youtube 频道 上提供,并与参与者分享笔记和问答回复。

与此同时,您可以查看摘要 (第一天第二天) 和 IRC 会话的完整日志 (第一天第二天)。

无论您是否能够参加活动,我们都感谢您的反馈,以帮助我们改进贡献者体验。这是 贡献者调查;请花几分钟时间填写。谢谢!
 

ANSIBLE HACKTOBERFEST 2020

我们通常会跟踪 Ansible 贡献者峰会上讨论的问题,并举办 Ansible 黑客马拉松。由于这也是 Hacktoberfest 的月份,我们将于 2020 年 10 月 30 日举办 Ansible Hacktoberfest 活动。请 注册 并加入我们!
 

ANSIBLE 社区统计数据更新

继上周的贡献者峰会之后,Greg 将像往常一样深入研究 Bluejeans 的参与统计数据以及来自 活动后调查 的结果。初步数据显示,两天时间里有来自 67 个国家的 707 名参与者!我们还可以看到一些指标表明该活动帮助人们参与贡献,尤其是 Katacoda 会话对此有帮助 - 23 位新人中的 19 位 (83%) 表示 Katacoda 有用,并且 10 位表示之前不知道如何贡献的参与者中有 9 位现在表示他们知道如何贡献。

敬请期待!
 

来自 ANSIBLE 社区的内容

 

ANSIBLE 虚拟聚会

以下虚拟聚会将在未来一个月内在 Ansible 社区举行

Ansible NOVA 注意: 对于这些虚拟活动,一旦您 RSVP 参加,即可看到参加活动的链接。如果您对展示的话题感兴趣,无论您身在何处,只要时区和语言适合您,您都可以加入!
 

NETDEVOPS 调查 2020 年现已开放

NetDevOps 调查 2020 年现已上线,并正在寻找受访者!本次调查的目的是收集信息,了解网络运营商和工程师如今如何使用自动化来运营他们的网络。该调查旨在保持供应商中立、协作和以社区为中心。欢迎所有网络专业人员参与调查,请在此处填写调查 此处 10 月 23 日。
 

反馈

您有任何问题想问,或希望看到的问题?请发送电子邮件至 [email protected]

 

 




AnsibleFest 2020 精华

AnsibleFest 2020 精华

感谢过去两天参加 AnsibleFest 2020 虚拟体验的所有人。我们很高兴与全球的 Ansible 爱好者交流。如果您错过了其中一些内容 (或全部内容),我们有一些活动亮点与您分享!如果您想看看错过了什么,所有 AnsibleFest 2020 内容将 按需提供 一年。 

社区更新

今年的 AnsibleFest 2020,Ansible 社区架构师 Robyn Bergeron 在周二上午发表了主题演讲。我们了解到,借助 Ansible 内容集合,无论您是贡献者还是最终用户,都可以更轻松地按您希望的方式使用 Ansible。Ansible 2.10 现已推出,Robyn 解释了我们如何获得反馈回路。如果您想了解更多关于 Ansible 社区项目的信息,请观看 Robyn 的主题演讲 按需提供。 

产品更新

Ansible 的 Richard Henshall 谈论了 Red Hat Ansible 自动化平台产品更新和新版本。2018 年,我们推出了 Ansible 认证合作伙伴计划,现在我们有超过 50 个平台获得认证。我们正在通过 Red Hat Advanced Cluster Management for Kubernetes 和 Ansible Automation Platform 之间的全新集成,连接传统平台、容器和边缘。从我们的 新闻稿 中了解更多有关全新集成的信息。今年在 AnsibleFest 上,我们还推出了私有 Automation Hub,用户现在可以从可信来源私下管理和整理 Ansible 内容。您可以从我们的 新闻稿 中了解有关此内容和其他 Ansible 自动化平台更新的更多信息。您也可以在 AnsibleFest 平台上 按需收听 Richard 的完整主题演讲。

频道内容

AnsibleFest 2020 展示了六个频道的内容;每个人都能找到自己想要的内容。一些受欢迎的演讲包括 Ansible 自动化平台路线图、管理您自己的私有 Ansible 内容、Ansible 自动化平台技术内容策略、如何管理您的 Ansible 自动化以及如何使用分析来了解您的自动化的运行情况等等!所有 70 多个分组会议现在都可以按需观看。

我们希望每个人都喜欢我们的第一个虚拟 AnsibleFest。感谢所有帮助使 AnsibleFest 2020 成为迄今为止规模最大、最成功的 AnsibleFest 的与会者。要查看更多活动亮点,您可以访问 AnsibleFest 主页。不要忘记,所有内容将一直保留到 2021 年 10 月,因此您可以随时返回 观看内容。感谢您今年与我们联系,并祝您自动化愉快!




深入探讨,使用 Ansible 网络自动化资源模块的 ACL 配置管理

深入探讨,使用 Ansible 网络自动化资源模块的 ACL 配置管理

2019 年 10 月,作为 Red Hat Ansible Engine 2.9 版本的一部分,Ansible 网络自动化团队引入了第一个资源模块。

这些有见地的网络模块使网络自动化对那些在生产环境中自动化各种网络平台的人来说更轻松、更一致。资源模块的目标是避免为渲染和推送网络配置创建和维护过于复杂的 jinja2 模板。

这篇博文涵盖了新发布的 ios_acls 资源模块以及如何自动化与交换机和路由器配置相关的流程。这些网络自动化模块用于配置来自流行供应商(但不限于)Arista、Cisco、Juniper 和 VyOS 的路由器和交换机。访问控制列表 (ACL) 网络资源模块能够从网络读取 ACL 配置,提供修改功能,然后将更改推送到网络设备。这些有见地的网络资源模块使网络自动化对那些在生产环境中自动化各种网络平台的人来说更轻松、更一致。我将介绍几个示例,并描述每个状态参数(包括三个新发布的状态类型)的用例,以及如何在现实世界场景中使用它们。

认证内容收集

这篇博文使用了 Ansible 团队维护的 cisco.ios 收集,但其他平台也拥有 ACL 资源模块,例如 arista.eosjunipernetworks.junosvyos.vyos

如何获取认证(支持)和上游(社区)收集

上游社区收集可以在 Ansible Galaxy 上找到:https://galaxy.ansible.com/cisco/ios**

下游支持的收集可以在 Automation Hub 上找到:https://cloud.redhat.com/ansible/automation-hub/cisco/ios**

有关 Ansible 内容收集的更多信息,请参阅以下文档

https://docs.ansible.org.cn/ansible/latest/user_guide/collections_using.html

在开始之前,让我们快速解释一下网络资源模块命名背后的原理。新添加的 ACL 模块将是复数形式 eos_aclsios_aclsjunos_aclsnxos_aclsiosxr_acls。旧的单数形式模块(例如 ios_aclnxos_acl)将随着时间的推移被弃用。进行这种命名更改是为了让那些使用现有网络模块的用户不会导致其 Ansible Playbook 停止工作,并有足够的时间迁移到新的网络自动化模块。

平台支持

此模块也可用于以下 Ansible 维护的平台,这些平台在 Automation Hub(支持)和 Galaxy(社区)上都可用

平台 完整收集路径 Automation Hub 链接(需要订阅) Ansible Galaxy 链接
Arista EOS arista.eos.eos_acls Automation Hub Galaxy
Cisco IOS cisco.ios.ios_acls Automation Hub Galaxy
Cisco IOS-XR cisco.iosxr.iosxr_acls Automation Hub Galaxy
Cisco NX-OS cisco.nxos.nxos_acls Automation Hub Galaxy
Juniper Junos junipernetworks.junos.junos_acls Automation Hub Galaxy
VyOS vyos.vyos.vyos_firewall_rules Automation Hub Galaxy

入门 - 使用 Ansible 管理 ACL 配置

访问控制列表 (ACL) 提供应用于端口号和/或允许传输或到达该网络设备的 IP 地址的规则。ACL 访问控制条目 (ACE) 的顺序至关重要,因为 ACE 的序列/顺序路由决定了哪些规则将应用于入站/出站网络流量。

ACL 资源模块提供了与用户在 Cisco IOS 设备上手动配置时相同的级别功能。但结合 Ansible 事实收集和资源模块方法,这更接近于网络专业人员每天的工作方式。

我将使用版本为 15.6(3)M2 的 IOS 路由器进行这篇博文中所有配置。以下是路由器 ACL 的初始状态配置,并且设备上已经配置了活动 ACL。

网络设备配置

cisco#sh access-lists
Extended IP access list 110
  10 deny icmp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 traceroute dscp ef ttl eq 10
  20 deny tcp host 198.51.100.0 host 198.51.110.0 eq telnet ack
Extended IP access list test_acl
  10 deny tcp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 eq www fin option traceroute ttl eq 10
IPv6 access list R1_TRAFFIC
  deny tcp any eq www any eq telnet ack dscp af11 sequence 10

使用收集到的状态 - 构建 Ansible 清单

资源模块允许用户读取现有网络配置并将其转换为结构化数据模型。state: gathered 等效于为该特定资源收集 Ansible 事实。此示例将读取现有网络配置并将其存储为平面文件。

Ansible Playbook 示例

以下是一个使用 state: gathered 并将结果存储为 YAML 到 host_vars 中的 Ansible Playbook 示例。如果您不熟悉 Ansible 清单的概念,并且想了解有关 group_varshost_vars 的更多信息,请参阅 Ansible 用户指南:清单。

---
- name: convert configured ACLs to structured data
  hosts: cisco
  gather_facts: false
  tasks:


    - name: Use the ACLs resource module to gather the current config
       cisco.ios.ios_acls:
           state: gathered
           register: acls

    - name: Create inventory directory
      file:
       path: "{{ inventory_dir }}/host_vars/{{ inventory_hostname }}"
       state: directory

    - name: Write the ACL configuration to a file
      copy:
        content: "{{ {‘acls’: acls['gathered']} | to_nice_yaml }}"
        dest: "{{ inventory_dir }}/host_vars/{{ inventory_hostname }}/acls.yaml"

使用 ansible-playbook 命令执行 Ansible Playbook:ansible-playbook example.yml

检查文件内容

以下是通过读取现有配置创建的数据结构

# lab_inventory/host_vars/rtr2/acls.yaml
acls:
- acls:
     - aces:
         - destination:
             address: 192.0.3.0
             wildcard_bits: 0.0.0.255
           dscp: ef
           grant: deny
           protocol: icmp
           protocol_options:
             icmp:
               traceroute: true
           sequence: 10
           source:
             address: 192.0.2.0
             wildcard_bits: 0.0.0.255
           ttl:
             eq: 10
         - destination:
             host: 198.51.110.0
             port_protocol:
               eq: telnet
           grant: deny
           protocol: tcp
           protocol_options:
             tcp:
               ack: true
           sequence: 20
           source:
             host: 198.51.100.0
       acl_type: extended
       name: '110'
     - aces:
         - destination:
             address: 192.0.3.0
             port_protocol:
                 eq: www
             wildcard_bits: 0.0.0.255
           grant: deny
           option:
               traceroute: true
           protocol: tcp
           protocol_options:
               tcp:
                   fin: true
           sequence: 10
           source:
             address: 192.0.2.0
             wildcard_bits: 0.0.0.255
           ttl:
               eq: 10
       acl_type: extended
       name: test_acl
   afi: ipv4
 - acls:
     - aces:
         - destination:
             any: true
             port_protocol:
               eq: telnet
           dscp: af11
           grant: deny
           protocol: tcp
           protocol_options:
             tcp:
               ack: true
           sequence: 10
           source:
             any: true
             port_protocol:
               eq: www
       name: R1_TRAFFIC
   afi: ipv6

在以上输出(以及将来引用)中

  • afi 指的是地址族标识符,可以是 IPv4 或 IPv6
  • acls 指的是访问控制列表,并返回一个字典(ACE)列表
  • aces 指的是访问控制条目,或特定规则和序列

使用 state merged - 推送配置更改

state merged 将获取您的 Ansible 配置数据(例如 Ansible 变量)并将它们合并到网络设备的网络配置中。这不会影响您 Ansible 配置数据中未指定的现有配置。让我们来举个例子。

修改存储的文件

我们将修改在第一个示例中创建的平面文件。然后,我们将创建一个 Ansible Playbook,将此新配置合并到网络设备的运行配置中。

参考链接

https://gist.githubusercontent.com/justjais/bb2a65c373ab4e64d1eeb47bc425c613/raw/056d2a6a44910863cbbbf38cad2273435574db84/Merged.txt

acls:
- afi: ipv4
  acls:
   - name: std_acl
     acl_type: standard
     aces:
       - grant: deny
         source:
           address: 192.168.1.200
       - grant: deny
         source:
           address: 192.168.2.0
           wildcard_bits: 0.0.0.255
   - name: 110
     aces:
       - grant: deny
         sequence: 10
         protocol_options:
           icmp:
             traceroute: true
         source:
           address: 192.0.2.0
           wildcard_bits: 0.0.0.255
         destination:
           address: 192.0.3.0
           wildcard_bits: 0.0.0.255
         dscp: ef
         ttl:
           eq: 10
       - grant: deny
         protocol_options:
           tcp:
             ack: true
         source:
           host: 198.51.100.0
         destination:
           host: 198.51.110.0
           port_protocol:
             eq: telnet
   - name: test
     acl_type: extended
     aces:
       - grant: deny
         protocol_options:
           tcp:
             fin: true
         source:
           address: 192.0.2.0
           wildcard_bits: 0.0.0.255
         destination:
           address: 192.0.3.0
           wildcard_bits: 0.0.0.255
           port_protocol:
             eq: www
         option:
           traceroute: true
         ttl:
           eq: 10
   - name: 123
     aces:
       - grant: deny
         protocol_options:
           tcp:
             ack: true
         source:
           address: 198.51.100.0
           wildcard_bits: 0.0.0.255
         destination:
           address: 198.51.101.0
           wildcard_bits: 0.0.0.255
           port_protocol:
             eq: telnet
         tos:
           service_value: 12
      - grant: deny
         protocol_options:
           tcp:
             ack: true
         source:
           address: 192.0.3.0
           wildcard_bits: 0.0.0.255
         destination:
           address: 192.0.4.0
           wildcard_bits: 0.0.0.255
           port_protocol:
             eq: www
         dscp: ef
         ttl:
           lt: 20
- afi: ipv6
  acls:
   - name: R1_TRAFFIC
     aces:
       - grant: deny
         protocol_options:
           tcp:
             ack: true
         source:
           any: true
           port_protocol:
             eq: www
         destination:
           any: true
           port_protocol:
             eq: telnet
         dscp: af11

Ansible Playbook 示例

---
- name: Merged state play
  hosts: cisco
  gather_facts: false
  tasks:
    - name: Merge ACLs config with device existing ACLs config
      cisco.ios.ios_acls:
        state: merged
        config: "{{ acls }}"

运行相应的 Merge 播放后,所有提供的参数都将在 Cisco IOS 路由器上配置,并将 Ansible changed=True

网络设备配置

cisco#sh access-lists
Standard IP access list std_acl
   10 deny   192.168.1.200
   20 deny   192.168.2.0, wildcard bits 0.0.0.255
Extended IP access list 110
   10 deny icmp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 traceroute dscp ef ttl eq 10
   20 deny tcp host 198.51.100.0 host 198.51.110.0 eq telnet ack
Extended IP access list 123
   10 deny tcp 198.51.100.0 0.0.0.255 198.51.101.0 0.0.0.255 eq telnet ack tos 12
   20 deny tcp 192.0.3.0 0.0.0.255 192.0.4.0 0.0.0.255 eq www ack dscp ef ttl lt 20
Extended IP access list test
   10 deny tcp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 eq www fin option traceroute ttl eq 10
IPv6 access list R1_TRAFFIC
   deny tcp any eq www any eq telnet ack dscp af11 sequence 10

如果我们稍微深入研究一下设备输出,我们会发现以下观察结果

  • 根据 AFI 值,模块决定调用 IP/IPV6 访问列表。
  • acl_type 键是命名 ACL 所必需的。
  • 对于由数字而不是名称标识的 ACL,acl_type 来自平台的已记录 ACL 数字范围。(例如,标准 = 1--99 和 1300--1999,扩展 = 100--199 和 2000--2699 等)
  • 如果在 ACE 中没有提到序列号,则它将根据播放中提供的顺序进行配置。
  • 在第二次运行中,相应的 Merge Play 再次运行,Ansible 的幂等性发挥作用,如果没有任何改变,播放运行结果为 changed=False,这向用户确认播放中提供的配置已在 IOS 设备上配置。

使用 state replaced - 推送配置更改

replaced 参数对每个配置的 ACL/ACE 对网络设备上的数据模型进行强制。如果我们修改任何 ACL/ACE,它将强制执行此资源模块意识到的所有参数。换句话说,replaced 参数了解应该存在和不应该存在的命令。

对于这种情况,Cisco IOS 设备上已经配置了一个带有某些 ACE 的 ACL,现在用户想要用一组新的 ACE 更新 ACL,并丢弃所有已经配置的 ACL ACE。将 "s" 替换的资源模块将用用户作为输入提供的一组新的 ACE 替换 ACL 现有的 ACE。

参考 gist 链接

https://gist.githubusercontent.com/justjais/bb2a65c373ab4e64d1eeb47bc425c613/raw/056d2a6a44910863cbbbf38cad2273435574db84/Replaced.txt

acls:
- afi: ipv4
  acls:
   - name: 110
     aces:
       - grant: deny
         protocol_options:
           tcp:
             syn: true
         source:
           address: 192.0.2.0
           wildcard_bits: 0.0.0.255
         destination:
           address: 192.0.3.0
           wildcard_bits: 0.0.0.255
           port_protocol:
             eq: www
         dscp: ef
         ttl:
           eq: 10
   - name: 150
     aces:
       - grant: deny
         sequence: 20
         protocol_options:
           tcp:
             syn: true
         source:
           address: 198.51.100.0
           wildcard_bits: 0.0.0.255
           port_protocol:
             eq: telnet
         destination:
           address: 198.51.110.0
           wildcard_bits: 0.0.0.255
           port_protocol:
             eq: telnet
         dscp: ef
         ttl:
           eq: 10

Ansible Playbook 示例

---
- name: Replaced state play
  hosts: cisco
  gather_facts: false
  tasks:
    - name: Replace ACLs config with device existing ACLs config
      cisco.ios.ios_acls:
        state: replaced
        config: "{{ acls }}"

通过以上播放,用户用提供的 ACL ACE 配置替换了 123 扩展 ACL,并配置了 150 扩展新 ACL ACE。

在运行 replaced 播放之前,网络设备配置

cisco#sh access-lists
Standard IP access list std_acl
   10 deny   192.168.1.200
   20 deny   192.168.2.0, wildcard bits 0.0.0.255
Extended IP access list 110
   10 deny icmp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 traceroute dscp ef ttl eq 10
   20 deny tcp host 198.51.100.0 host 198.51.110.0 eq telnet ack
Extended IP access list 123
   10 deny tcp 198.51.100.0 0.0.0.255 198.51.101.0 0.0.0.255 eq telnet ack tos 12
   20 deny tcp 192.0.3.0 0.0.0.255 192.0.4.0 0.0.0.255 eq www ack dscp ef ttl lt 20
Extended IP access list test
   10 deny tcp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 eq www fin option traceroute ttl eq 10
IPv6 access list R1_TRAFFIC
   deny tcp any eq www any eq telnet ack dscp af11 sequence 10

通过 replaced Play 运行,触发的命令

- ip access-list extended 110
- no 10
- no 20
- deny tcp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 eq www syn dscp ef ttl eq 10
- ip access-list extended 150
- 20 deny tcp 198.51.100.0 0.0.0.255 eq telnet 198.51.110.0 0.0.0.255 eq telnet syn  dscp ef ttl eq 10

运行 replaced 播放之后,网络设备配置

cisco#sh access-lists
Standard IP access list std_acl
   10 deny   192.168.1.200
   20 deny   192.168.2.0, wildcard bits 0.0.0.255
Extended IP access list 110
   10 deny tcp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 eq www syn dscp ef ttl eq 10
Extended IP access list 123
   10 deny tcp 198.51.100.0 0.0.0.255 198.51.101.0 0.0.0.255 eq telnet ack tos 12
   20 deny tcp 192.0.3.0 0.0.0.255 192.0.4.0 0.0.0.255 eq www ack dscp ef ttl lt 20
Extended IP access list 150
   20 deny tcp 198.51.100.0 0.0.0.255 eq telnet 198.51.110.0 0.0.0.255 eq telnet syn dscp ef ttl eq 10
Extended IP access list test
   10 deny tcp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 eq www fin option traceroute ttl eq 10
IPv6 access list R1_TRAFFIC
   deny tcp any eq www any eq telnet ack dscp af11 sequence 10

如果我们简要分析一下输出,我们可能会发现以下观察结果

  • replaced 将否定输入 ACL 下的所有预先存在的 ACE,然后应用播放中作为输入提供的配置。在上面的命令输出中,对于编号为 123 的 ACL,可以在序列 10 和 20 处的预先存在的 ACE 在应用较新 ACE 配置的更改之前被首先否定,可以看出相同行为。
  • 对于 150 扩展 ACL ACE,由于它尚未在设备上预先配置,因此模块会继续应用播放中作为输入提供的 ACE 配置。这里要注意的一点是,在播放输入配置值中,序列值被指定为 20,因此 ACE 被配置为序列 20 而不是 10,如果用户没有提供序列值,则情况会是 10。

通过以上播放的第二次运行,changed 变为 false,这满足了 Ansible 的幂等性。

使用 state overridden - 推送配置更改

在这个例子中,我们将稍微改变一下。假设你是一位用户,正在网络设备上进行定制配置(进行自动化之外的更改)。state: overridden 将循环回到强制执行数据模型(配置策略强制执行)并删除定制更改。

如果用户希望完全重新配置 Cisco IOS 设备预先配置的 ACL,那么资源模块覆盖状态是最合适的。使用覆盖状态时,用户可以使用用户提供的 ACL 覆盖所有 ACL。

为了显示替换和覆盖状态工作之间的区别,我们将使用与替换场景相同的剧本,并保持预先存在的配置相同。

参考 gist 链接

https://gist.githubusercontent.com/justjais/bb2a65c373ab4e64d1eeb47bc425c613/raw/056d2a6a44910863cbbbf38cad2273435574db84/Overridden.txt

ACL 配置

acls:
- afi: ipv4
  acls:
   - name: 110
     aces:
       - grant: deny
         sequence: 20
         protocol_options:
           tcp:
             ack: true
         source:
           address: 198.51.100.0
           wildcard_bits: 0.0.0.255
           port_protocol:
             eq: telnet
         destination:
           address: 198.51.110.0
           wildcard_bits: 0.0.0.255
           port_protocol:
             eq: www
         dscp: ef
         ttl:
           eq: 10
   - name: 150
     aces:
       - grant: deny
         sequence: 10
         protocol_options:
           tcp:
             syn: true
         source:
           address: 198.51.100.0
           wildcard_bits: 0.0.0.255
           port_protocol:
             eq: telnet
         destination:
           address: 198.51.110.0
           wildcard_bits: 0.0.0.255
           port_protocol:
             eq: telnet
         dscp: ef
         ttl:
           eq: 10

Ansible Playbook 示例

---
- name: Overridden state play
  hosts: cisco
  gather_facts: false
  tasks:
    - name: Override ACLs config with device existing ACLs config
      cisco.ios.ios_acls:
        state: overridden
        config: "{{ acls }}"

通过以上播放,用户用提供的 ACL ACE 配置替换了 123 扩展 ACL,并配置了 150 扩展新 ACL ACE。

在运行 Overridden 剧本之前,网络设备配置

cisco#sh access-lists
Standard IP access list std_acl
   10 deny   192.168.1.200
   20 deny   192.168.2.0, wildcard bits 0.0.0.255
Extended IP access list 110
   10 deny icmp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 traceroute dscp ef ttl eq 10
   20 deny tcp host 198.51.100.0 host 198.51.110.0 eq telnet ack
Extended IP access list 123
   10 deny tcp 198.51.100.0 0.0.0.255 198.51.101.0 0.0.0.255 eq telnet ack tos 12
   20 deny tcp 192.0.3.0 0.0.0.255 192.0.4.0 0.0.0.255 eq www ack dscp ef ttl lt 20
Extended IP access list test
   10 deny tcp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 eq www fin option traceroute ttl eq 10
IPv6 access list R1_TRAFFIC
   deny tcp any eq www any eq telnet ack dscp af11 sequence 10

使用 Overridden 剧本运行,发送的命令

- no ip access-list standard std_acl
- no ip access-list extended 110
- no ip access-list extended 123
- no ip access-list extended 150
- no ip access-list extended test
- no ipv6 access-list R1_TRAFFIC
- ip access-list extended 150
- 10 deny tcp 198.51.100.0 0.0.0.255 eq telnet 198.51.110.0 0.0.0.255 eq telnet syn dscp ef ttl eq 10
- ip access-list extended 110
- 20 deny tcp 198.51.100.0 0.0.0.255 eq telnet 198.51.110.0 0.0.0.255 eq www ack dscp ef ttl eq 10

运行 Overridden 剧本后,网络设备配置

cisco#sh access-lists
Extended IP access list 110
   20 deny tcp 198.51.100.0 0.0.0.255 eq telnet 198.51.110.0 0.0.0.255 eq www ack dscp ef ttl eq 10
Extended IP access list 150
   10 deny tcp 198.51.100.0 0.0.0.255 eq telnet 198.51.110.0 0.0.0.255 eq telnet syn dscp ef ttl eq 10

现在,如果我们再次深入研究覆盖剧本的输出

  • 覆盖会否定所有预先存在的 ACL 并删除那些在提供的配置中不存在的配置。
  • 对于预先存在且也在剧本中的 ACL 配置,ios_acls 覆盖状态将尝试删除/否定所有预先存在的 ACE,然后配置剧本中提到的新 ACE。
  • 对于任何不存在的 ACL,覆盖状态将以与合并相同的方式配置 ACL。

现在我们已经讨论了如何使用 ios_acls 资源模块的合并、替换和覆盖状态来配置 CISCO IOS 设备上的 ACL 和 ACE,现在是时候讨论如何删除预先配置的 ACL 和 ACE 以及用户在删除操作状态下可以使用哪些粒度级别了。

删除配置更改

如果用户希望使用提供的 ACL 配置删除 Cisco IOS 设备的预先配置的 ACL,则使用资源模块删除状态。

方法 1:删除单个 ACL **基于 ACL 编号**(这意味着如果用户需要删除在 IPV4 或 IPV6 下配置的任何特定 ACL)

参考 gist 链接:

https://gist.githubusercontent.com/justjais/bb2a65c373ab4e64d1eeb47bc425c613/raw/056d2a6a44910863cbbbf38cad2273435574db84/Deleted.txt

需要删除的 ACL

acls:
- afi: ipv4
  acls:
    - name: test
      acl_type: extended
    - name: 110
    - name: 123
- afi: ipv6
  acls:
    - name: R1_TRAFFIC

Ansible Playbook 示例

---
- name: Deleted state play
  hosts: cisco
  gather_facts: false
  tasks:
    - name: Delete ACLs based on ACL number
      cisco.ios.ios_acls:
        state: deleted
        config: "{{ acls }}"

在运行 Deleted 剧本之前,网络设备配置

cisco#sh access-lists
Standard IP access list std_acl
   10 deny   192.168.1.200
   20 deny   192.168.2.0, wildcard bits 0.0.0.255
Extended IP access list 110
   10 deny icmp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 traceroute dscp ef ttl eq 10
   20 deny tcp host 198.51.100.0 host 198.51.110.0 eq telnet ack
Extended IP access list 123
   10 deny tcp 198.51.100.0 0.0.0.255 198.51.101.0 0.0.0.255 eq telnet ack tos 12
   20 deny tcp 192.0.3.0 0.0.0.255 192.0.4.0 0.0.0.255 eq www ack dscp ef ttl lt 20
Extended IP access list test
   10 deny tcp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 eq www fin option traceroute ttl eq 10
IPv6 access list R1_TRAFFIC
   deny tcp any eq www any eq telnet ack dscp af11 sequence 10

使用 Delete by ACLs 剧本运行,发送的命令

- no ip access-list extended test
- no ip access-list extended 110
- no ip access-list extended 123
- no ipv6 access-list R1_TRAFFIC

运行 Deleted 剧本后,网络设备配置

cisco#sh access-lists
Standard IP access list std_acl
   10 deny   192.168.1.200
   20 deny   192.168.2.0, wildcard bits 0.0.0.255
cisco#

方法 2:删除单个 ACL **基于其 AFI(即地址族指示器)**,这意味着如果用户需要删除在 IPV4 或 IPV6 下配置的所有 ACL

参考 gist 链接

https://gist.githubusercontent.com/justjais/bb2a65c373ab4e64d1eeb47bc425c613/raw/8c65946eae561ff569cfc5398879c51598ae050c/Deleted_by_AFI

Ansible Playbook 示例

---
- name: Deleted state play
  hosts: cisco
  gather_facts: false
  tasks:
    - name: Delete ALL IPV4 configured ACLs
      cisco.ios.ios_acls:
        config:
          - afi: ipv4
        state: deleted

在运行 Deleted 剧本之前,网络设备配置

cisco#sh access-lists
Standard IP access list std_acl
   10 deny   192.168.1.200
   20 deny   192.168.2.0, wildcard bits 0.0.0.255
Extended IP access list 110
   10 deny icmp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 traceroute dscp ef ttl eq 10
   20 deny tcp host 198.51.100.0 host 198.51.110.0 eq telnet ack
Extended IP access list 123
   10 deny tcp 198.51.100.0 0.0.0.255 198.51.101.0 0.0.0.255 eq telnet ack tos 12
   20 deny tcp 192.0.3.0 0.0.0.255 192.0.4.0 0.0.0.255 eq www ack dscp ef ttl lt 20
Extended IP access list test
   10 deny tcp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 eq www fin option traceroute ttl eq 10
IPv6 access list R1_TRAFFIC
   deny tcp any eq www any eq telnet ack dscp af11 sequence 10

使用 Delete by ACLs 剧本运行,触发的命令

- no ip access-list standard std_acl
- no ip access-list extended test
- no ip access-list extended 110
- no ip access-list extended 123
- no ip access-list extended test

运行 Deleted 剧本后,网络设备配置

cisco#sh access-lists
IPv6 access list R1_TRAFFIC
   deny tcp any eq www any eq telnet ack dscp af11 sequence 10
cisco#

方法 3:一次删除所有 ACL

注意:这是一个非常重要的删除操作,如果使用不当,它有删除所有预先配置的 ACL 的能力

参考 gist 链接:https://gist.githubusercontent.com/justjais/bb2a65c373ab4e64d1eeb47bc425c613/raw/056d2a6a44910863cbbbf38cad2273435574db84/Deleted_wo_config.txt

Ansible Playbook 示例

---
- name: Deleted state play
  hosts: cisco
  gather_facts: false
  tasks:
    - name: Delete ALL configured ACLs w/o passing any config
      cisco.ios.ios_acls:
        state: deleted

在运行 Deleted 剧本之前,网络设备配置

cisco#sh access-lists
Standard IP access list std_acl
   10 deny   192.168.1.200
   20 deny   192.168.2.0, wildcard bits 0.0.0.255
Extended IP access list 110
   10 deny icmp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 traceroute dscp ef ttl eq 10
   20 deny tcp host 198.51.100.0 host 198.51.110.0 eq telnet ack
Extended IP access list 123
   10 deny tcp 198.51.100.0 0.0.0.255 198.51.101.0 0.0.0.255 eq telnet ack tos 12
   20 deny tcp 192.0.3.0 0.0.0.255 192.0.4.0 0.0.0.255 eq www ack dscp ef ttl lt 20
Extended IP access list test
   10 deny tcp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 eq www fin option traceroute ttl eq 10
IPv6 access list R1_TRAFFIC
   deny tcp any eq www any eq telnet ack dscp af11 sequence 10

使用 Delete by ACLs 剧本运行,触发的命令

- no ip access-list standard std_acl
- no ip access-list extended test
- no ip access-list extended 110
- no ip access-list extended 123
- no ip access-list extended test
- no ipv6 access-list R1_TRAFFIC

运行 Overridden 剧本后,网络设备配置

cisco#sh access-lists
cisco#

使用状态渲染 - 开发和离线工作

状态渲染将提供的结构化数据模型转换为平台特定的 CLI 命令。此状态不需要连接到最终设备。在本例中,它将提供的 data model 转换为 Cisco IOS 语法命令。

参考 gist 链接

https://gist.githubusercontent.com/justjais/bb2a65c373ab4e64d1eeb47bc425c613/raw/8c65946eae561ff569cfc5398879c51598ae050c/Rendered.txt

需要渲染的 ACL 配置

acls:
- afi: ipv4
  acls:
   - name: 110
     aces:
       - grant: deny
         sequence: 10
         protocol_options:
           tcp:
             syn: true
         source:
           address: 192.0.2.0
           wildcard_bits: 0.0.0.255
         destination:
           address: 192.0.3.0
           wildcard_bits: 0.0.0.255
           port_protocol:
             eq: www
         dscp: ef
         ttl:
           eq: 10
   - name: 150
     aces:
       - grant: deny
         protocol_options:
           tcp:
             syn: true
         source:
           address: 198.51.100.0
           wildcard_bits: 0.0.0.255
           port_protocol:
             eq: telnet
         destination:
           address: 198.51.110.0
           wildcard_bits: 0.0.0.255
           port_protocol:
             eq: telnet
         dscp: ef
         ttl:
           eq: 10

Ansible Playbook 示例

---
- name: Rendered state play
  hosts: cisco
  gather_facts: false
  tasks:
    - name: Render the provided configuration
      cisco.ios.ios_acls:
        config: "{{ acls }}"
        state: rendered

使用 Render 状态模块执行结果

"rendered": [
   "ip access-list extended 110",
   "10 deny tcp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 eq www syn dscp ef ttl eq 10",
   "ip access-list extended 150",
   "deny tcp 198.51.100.0 0.0.0.255 eq telnet 198.51.110.0 0.0.0.255 eq telnet syn dscp ef ttl eq 10"
]

注意:Render 状态不会从配置端改变任何东西

使用状态解析 - 开发和离线工作

此状态从 running_config 选项读取配置,并将其转换为结构化数据(即 JSON)。如果您有离线配置,例如备份文本文件,并且希望将其转换为结构化数据,这将很有帮助。这对于实验、故障排除或离线创建数据模型的真相来源很有帮助。

参考 gist 链接

https://gist.githubusercontent.com/justjais/bb2a65c373ab4e64d1eeb47bc425c613/raw/8c65946eae561ff569cfc5398879c51598ae050c/Parsed.txt

需要解析的 ACL 配置

Ansible Playbook 示例

---
- name: Parsed state play
  hosts: cisco
  gather_facts: false
  tasks:
    - name: Parse the provided ACLs configuration
      cisco.ios.ios_acls:
        running_config:
           "ipv6 access-list R1_TRAFFIC
           deny tcp any eq www any eq telnet ack dscp af11"
        state: parsed

使用 Parsed 状态模块执行结果

"parsed": [
       {
           "acls": [
               {
                   "aces": [
                       {
                           "destination": {
                               "any": true,
                               "port_protocol": {
                                   "eq": "telnet"
                               }
                           },
                           "dscp": "af11",
                           "grant": "deny",
                           "protocol_options": {
                               "tcp": {
                                   "ack": true
                               }
                           },
                           "source": {
                               "any": true,
                               "port_protocol": {
                                   "eq": "www"
                               }
                           }
                       }
                   ],
                   "name": "R1_TRAFFIC"
               }
           ],
           "afi": "ipv6"
       }
   ]

结论

ACL 资源模块为网络工程师提供了一种简单的方法来开始在多个网络平台上自动化访问列表。虽然某些配置可以在网络设备上保持静态,但 ACL 可能需要不断更新和验证。这些资源模块允许用户以增量步骤采用自动化,从而使组织更容易采用。一旦您将 ACL 转换为结构化数据,任何网络平台的任何资源模块都可以读取。想象一下,读取 Cisco IOS 盒子的 ACL 并将其转换为 Cisco IOS-XR 命令。




开始使用 AWS Ansible 模块开发和社区贡献

开始使用 AWS Ansible 模块开发和社区贡献

我们经常从云管理员和开发人员那里听到,他们有兴趣回馈 Ansible 并利用他们的知识为社区带来益处,但他们不知道如何开始。许多人甚至可能已经在他们的本地环境中包含了新的 Ansible 模块或插件,并且希望将它们包含到上游以供更广泛使用。

幸运的是,作为 Ansible 贡献者,开始并不需要太多。如果您已经在使用 Ansible AWS 模块,那么有很多方法可以使用您现有的知识、技能和经验来做出贡献。如果您需要一些关于在哪里做出贡献的想法,请查看以下内容

  • 创建集成测试:为模块创建 缺少的测试 是一种很好的入门方法,集成测试只是 Ansible 任务!
  • 模块移植:如果您熟悉 boto3 Python 库,那么也有一份 模块积压 需要从 boto2 移植到 boto3。
  • 仓库问题分类:当然,还有始终开放的 Github 问题 和 pull 请求。测试错误或补丁并提供您使用案例和体验的反馈非常有价值。

boto3

从 Ansible 2.10 开始,AWS 模块已从 Ansible GitHub 仓库 迁移到两个新的 Collection 仓库中。

Ansible 维护的 Collectionamazon.aws)包含由 Ansible 云团队管理的模块、插件和模块实用程序,并包含在下游 Red Hat Ansible Automation Platform 产品中。

社区维护的 Collectioncommunity.aws)包含由 Ansible 社区支持的模块和插件。社区开发的新模块和插件应建议添加到 community.aws。此 Collection 中稳定并符合其他接受标准的内容有潜力被提升并迁移到 amazon.aws 中。

有关如何为任何 Ansible 维护的 Collection(包括 AWS Collection)做出贡献的更多信息,请参阅 docs.ansible.com 上的“为 Ansible 维护的 Collection 做出贡献”部分

AWS 模块开发基础

首先,确保您已经阅读了 Ansible 开发人员指南中的 Ansible Amazon AWS 模块开发指南 部分。以下是一些需要注意的事项

如果模块需要轮询 API 并等待特定状态返回才能继续,请在 amazon.aws 集合中的 waiters.py 文件中添加一个 等待者,而不是在模块中编写循环。例如,ec2_vpc_subnet 模块支持等待参数。当为 true 时,这将指示模块在返回之前等待资源处于预期状态。此模块代码如下所示

if module.params['wait']:
    handle_waiter(conn, module, 'subnet_exists', {'SubnetIds': [subnet['id']]}, start_time)

以及相应的等待者

        "SubnetExists": {
            "delay": 5,
            "maxAttempts": 40,
            "operation": "DescribeSubnets",
            "acceptors": [
                {
                    "matcher": "path",
                    "expected": True,
                    "argument": "length(Subnets[]) > `0`",
                    "state": "success"
                },
                {
                    "matcher": "error",
                    "expected": "InvalidSubnetID.NotFound",
                    "state": "retry"
                },
            ]
        },

这将轮询 EC2 API 以获取 describe_subnets(SubnetIds=[subnet['id']]),直到返回的子网列表大于零,然后再继续。如果返回 InvalidSubnetID.NotFound 错误,则这是预期响应,等待者代码将继续。

当 boto 返回分页结果时,使用 分页器,并从分页器的 .build_full_result() 方法构建结果,而不是编写循环。

务必在您的 except 块中处理 ClientErrorBotoCoreError

except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:
    module.fail_json_aws(e, msg="Couldn't create subnet")

所有新模块都应尽可能支持 check_mode

Ansible 努力提供 幂等性。但有时,这与 AWS 服务的操作方式不一致。考虑一下用户将如何通过 Ansible 任务与服务交互,以及如果他们多次运行相同的任务会发生什么。将进行哪些 API 调用?Ansible 在后续任务执行中将报告什么状态更改?

只要有可能,请避免在模块中硬编码数据。有时这是不可避免的,但如果您的贡献包含硬编码的实例类型列表或硬编码的 分区,这很可能会在代码审查中被提出 - 例如,arn:aws: 将不匹配 GovCloud 或中国区域,您的模块将无法为这些区域的用户工作。如果您已经确定无法避免硬编码某些内容,请在 pull 请求中提及您的发现。

模块实用程序

amazon.aws 集合中提供大量用于处理 AWS 的 module_utils

$ ls plugins/module_utils/
acm.py  batch.py  cloudfront_facts.py  cloud.py  core.py  direct_connect.py  ec2.py  elb_utils.py  elbv2.py  iam.py  __init__.py  rds.py  s3.py  urls.py  waf.py  waiters.py

值得注意的是,module_utils/core.py 包含 AnsibleAWSModule(),这是所有新模块所需的基类。这提供了一些不错的助手,例如 client() 设置、fail_json_aws() 方法(它将 boto 异常转换为良好的错误消息并处理 Python2 和 Python3 的错误消息类型转换),并且该类将为您处理 boto 库导入检查。

AWS API 倾向于使用和返回 骆驼命名法 值,而 Ansible 倾向于使用 蛇形命名法amazon.aws.module_utils.ec2 中提供了在两者之间进行转换的助手,包括 ansible_dict_to_boto3_filter_list()boto3_tag_list_to_ansible_dict() 以及许多与标签和策略相关的函数。

集成测试

AWS Collection 主要依赖于 功能性集成测试 来通过在 AWS 上创建、修改和删除资源来执行模块和插件代码。测试套件位于包含被测试模块的 Collection 仓库中。测试的首选风格类似于一个以模块命名的角色,每个模块都有一个测试套件。有时将多个模块的测试组合到一个测试套件中是有意义的,例如当存在紧密耦合的服务依赖关系时。这些通常以要测试的主要模块或服务命名。例如,*_info 模块可能会与它们提供信息的共享测试。测试目录根目录中的别名文件控制各种设置,包括哪些测试被别名为该测试角色。

tests/integration/targets/ecs_cluster$ ls
aliases  defaults  files  meta  tasks

tests/integration/targets/ecs_cluster$ cat aliases
cloud/aws
ecs_service_info
ecs_task
ecs_taskdefinition
ecs_taskdefinition_info
unsupported

在本例中,将几个模块组合到一个测试中,因为必须先创建 ecs_cluster 才能创建 ecs_taskdefinition。这里存在很强的依赖关系。

您可能还会注意到,ECS 目前在 Ansible CI 环境中不受支持。这可能有很多原因,但最常见的原因是我们在 CI AWS 帐户中不允许无限制的资源使用。我们必须创建 IAM 策略,以允许测试覆盖范围的最低访问权限。测试不受支持的其他原因可能是,模块需要我们在 CI 中没有的资源,例如联合身份提供者。有关更多信息,请参阅下面的“CI 策略和 Terminator Lambda”部分。

您可能会看到的另一个测试套件状态是不稳定。这意味着测试被观察到具有很高的瞬时故障率。常见原因包括需要等待资源达到给定状态才能继续,或者测试运行时间过长,超过了测试计时器。这些可能需要重构模块代码或测试,以更稳定和可靠。只有在修改了它们所覆盖的模块时,才会运行不稳定的测试,如果它们失败,可能会重试。如果您发现自己喜欢测试,这是一个很好的入门领域!

集成测试通常应该检查以下任务或功能,无论是在 **启用** 还是 **禁用** 检查模式的情况下。

  • 资源创建
  • 再次创建资源(幂等性)
  • 资源修改
  • 再次修改资源(幂等性)
  • 资源删除
  • 资源删除(不存在的资源)

在创建集成测试任务文件时,使用 module_defaults 用于凭据,而不是为每个任务重复这些参数。如果您需要测试模块如何处理错误凭据、缺少区域参数等,可以在每个任务中覆盖 module_defaults 中指定的 value。

- name: set connection information for aws modules and run tasks
  module_defaults:
    group/aws:
      aws_access_key: "{{ aws_access_key }}"
      aws_secret_key: "{{ aws_secret_key }}"
      security_token: "{{ security_token | default(omit) }}"
      region: "{{ aws_region }}"

  block:

  - name: Test Handling of Bad Region
    ec2_instance:
    region: "us-nonexistent-7"
      ... params …

  - name: Do Something
    ec2_instance:
      ... params ...

  - name: Do Something Else
    ec2_instance:
      ... params ...

集成测试应该利用 ,在一个或多个块中进行测试任务,并在最终的 always: 块中删除测试创建的所有资源。

单元测试

虽然大多数模块都是使用集成测试进行测试的,但有时这根本不可行。例如,在测试 AWS Direct Connect 时。community.aws.aws_direct_connect* 模块可用于在 AWS 和私有数据中心之间建立网络传输链路。这不是可以在 CI 测试系统中简单或重复完成的任务。对于无法实际进行集成测试的模块,我们确实要求 单元测试 以纳入任何 AWS Ansible Collection。 placebo Python 库提供了一种很好的机制来记录和模拟 boto3 API 响应,并且在可能的情况下,比编写和维护 AWS 固定装置更可取。

CI 策略和 Terminator Lambda

Ansible AWS CI 环境具有保障措施和特定工具,以确保资源得到适当限制,并且测试资源在合理的时间内清理完毕。这些工具位于 aws-terminator 存储库中。此存储库有三个主要部分需要注意:

  1. aws/policy/ 目录
  2. aws/terminator/ 目录
  3. hacking/ 目录

aws/policy/ 目录包含 Ansible CI 服务使用的 IAM 策略。我们通常试图定义执行全面集成测试覆盖范围所需的最小 AWS IAM 操作和资源。例如,我们不是启用 ec2:*,而是具有多个语句 ID,Sid,它们为不同的资源规范指定不同的操作。

我们在 CI 运行所在的区域中相当广泛地允许 ec2:DescribeImages

  Resource:
      - "*"
    Condition:
      StringEquals:
        ec2:Region:
          - '{{ aws_region }}'

但对 CI 可以启动或运行的实例类型更加严格

- Sid: AllowEc2RunInstancesInstanceType
    Effect: Allow
    Action:
      - ec2:RunInstances
      - ec2:StartInstances
    Resource:
      - arn:aws:ec2:us-east-1:{{ aws_account_id }}:instance/*
    Condition:
      StringEquals:
        ec2:InstanceType:
          - t2.nano
          - t2.micro
          - t3.nano
          - t3.micro
          - m1.large  # lowest cost instance type with EBS optimization supported

aws/terminator/ 目录包含 terminator 应用程序,我们将其部署到 AWS Lambda。如果任何 CI 作业未能删除它创建的资源,它将充当清理服务。有关编写新 terminator 类的信息可以在 terminator 的 自述文件 中找到。

hacking/ 目录包含一个剧本和两组策略,供贡献者在其自己的 AWS 帐户中使用。aws_config/setup-iam.yml 剧本创建 IAM 策略并将它们与两个 iam_groups 关联。然后,这些组可以与您自己的适当用户相关联

  • ansible-integration-ci:该组反映了 AWS 集合 CI 使用的权限
  • ansible-integration-unsupported:该组在运行“不受支持”测试所需的“CI”权限之上分配了额外的权限

setup-iam.yml 剧本中记录了将这些组和策略部署到您的 AWS 用户的使用信息。

本地测试

您现在已经编写了代码和测试用例,但是您想在推送到 GitHub 并将更改通过 CI 发送之前在本地运行测试。太棒了!您将需要 AWS 帐户的凭据和一些设置步骤。

Ansible 包含一个 CLI 实用程序来运行集成测试。您可以在环境中设置 boto 配置文件,也可以使用凭据配置文件进行 AWS 身份验证。Ansible 附带的 ansible-test 应用程序提供了一个 示例配置 文件。将此文件复制到集合存储库的本地签出的 tests/integration/cloud-config-aws.ini 中,并填写 @ACCESS_KEY@SECRET_KEY@SECURITY_TOKEN@REGION 的 AWS 帐户详细信息。

注意: 两个 AWS 集合存储库都有一个 tests/.gitignore 文件,它会在检入代码时忽略此文件路径,但您在将 AWS 凭据存储到磁盘或存储库目录时应始终保持警惕。

如果您已经在本地机器上安装了 Ansible,则 ansible-test 应该已经在您的 PATH 中。如果没有,您可以从 Ansible 项目的本地签出中运行它。

git clone https://github.com/ansible/ansible.git
cd ansible/
source ansible/hacking/env-setup

您还需要确保在您的 COLLECTIONS_PATHS 中安装了任何集合依赖项并可访问。集合依赖项在集合中的 tests/requirements.yml 文件中列出,可以使用 ansible-galaxy collection install 命令进行安装。

您现在可以从集合存储库运行集成测试

cd ~/src/collections/ansible_collections/amazon/aws
ansible-test integration ec2_group

默认情况下,不会执行不稳定或不受支持的测试。要运行这些类型的测试,您可以传递给 ansible-test 的附加标志:

ansible-test integration ec2_group --allow-unstable  --allow-unsupported

如果您希望在容器中运行测试,ansible-test 可以自动检索并运行默认的测试映像,该映像包含 AWS 测试所需的 Python 库。可以通过提供 --docker 标志来拉取和运行它。(Docker 必须已经在您的本地系统上安装和配置。)

ansible-test integration ec2_group --allow-unstable  --allow-unsupported --docker

测试容器映像附带所有 Ansible 支持的 Python 版本。要指定特定 Python 版本,例如 3.7,请使用以下方法进行测试:

ansible-test integration ec2_group --allow-unstable  --allow-unsupported --docker --python 3.7

注意: 集成测试将在指定的 AWS 帐户中创建真实资源,这些资源受该资源和区域的 AWS 定价约束。现有测试应该尽一切努力在测试运行结束时删除资源,但请确保在执行测试套件后检查所有创建的资源是否已成功删除,以防止出现意外账单。在开发新的测试套件或添加尚未被测试的 always 清理块覆盖的新的资源时,尤其建议这样做。

注意: 在使用 IAM、安全组和其他可能暴露 AWS 帐户访问权限或资源的访问控制时,请谨慎操作。

提交更改

当您的更改准备提交时,在 拉取请求 (PR) 中打开 相应的 AWS 集合 的 GitHub 存储库。Shippable CI 将自动运行测试并将结果报告回 PR。如果您的更改是针对新模块或测试新的 AWS 资源或操作,您可能会在测试中看到权限失败。在这种情况下,您还需要在 mattclay/aws-terminator 存储库 中打开一个 PR,以添加 IAM 权限,并可能添加一个 Terminator 类 来支持测试新功能,如本文的“CI 策略和 Terminator Lambda”部分所述。Ansible AWS 社区成员将对您的贡献进行分类和审查,并提供他们对提交的任何反馈。

后续步骤和资源

刚开始为开源项目做出贡献可能会让人望而却步,但希望这篇博文能提供关于如何为 AWS Ansible 集合做出贡献的良好技术资源。如果您在贡献过程中需要帮助,您可以在 Freenode IRC 的 #ansible-aws 频道中找到 Ansible AWS 社区。

恭喜,欢迎您,您现在是 Ansible 项目的贡献者!




Bullhorn #11

Ansible Bullhorn banner

牛角号

面向 Ansible 开发人员社区的新闻通讯
Issue #11,2020-09-30


欢迎来到牛角号,我们面向 Ansible 开发人员社区的新闻通讯。如果您有任何问题或想要分享的内容,请通过 [email protected] 与我们联系,或者评论此 GitHub 问题
 

重要日期

 

ANSIBLE 2.10.0 现已正式发布

Ansible 社区团队于 9 月 22 日宣布 Ansible 2.10.0 正式发布!此新 Ansible 包应可直接替代 Ansible 2.9;您当前使用的角色和剧本应该可以与 ansible-2.10.0 直接使用。有关新功能、获取方法以及注意事项和已知错误的更多信息,请阅读 Toshio Kuratomi 在 ansible-devel 邮件列表中的公告
 

ANSIBLE-BASE 2.10.2 RC1 现已发布

Ansible Base 团队于 9 月 28 日宣布发布 Ansible 2.10.2 的候选版本。此 ansible-base 包仅包含 Ansible 执行引擎、相关工具(例如 ansible-galaxy、ansible-test)以及极少数内置插件,并且也与较大的 Ansible 发行版捆绑在一起。有关如何下载、测试和报告问题的更多信息,请阅读 Rick Elrod 在 ansible-devel 邮件列表中的公告
 

ANSIBLE 2.9.14 RC1 和 2.8.16 RC1 可用

Ansible 核心团队于 9 月 28 日宣布发布 Ansible 2.9.14 rc1 和 Ansible 2.8.16 rc1,这两个版本都是维护版本。请关注 此链接,了解 Rick Elrod 发送给 ansible-devel 邮件列表的电子邮件,其中包含有关新功能、安装说明以及指向完整变更日志的链接。
 

影响集合贡献者和维护者的变更

关注 此 GitHub 问题,跟踪集合维护者和贡献者应了解的变更。
 

ANSIBLE 贡献者峰会 - ANSIBLEFEST 2020 的一部分

由于对 AnsibleFest 2020 版本的 Ansible 贡献者峰会 感兴趣的人数众多,我们将根据您在贡献过程中的位置,为您规划为期两天的活动。活动将在 2020 年 10 月 12 日和 15 日举行。

查看 wiki 页面,了解两天的活动安排,并通过相应的链接进行注册。期待您的参与!
 

新/更新的社区集合

Foreman 集合 1.3.0 已发布。查看此 博客文章(由 Evgeni Golov 撰写),了解新功能、获取方法等信息。
 

ANSIBLE 社区统计数据更新

继最近的社区会议中进行了富有成效的讨论(请参阅 #539(评论) 附近的会议记录)后,Greg Sutcliffe 制作了集合仪表板的 alpha 版本。最终它将包含社区的汇总统计信息,但现在您可以查询给定的集合并获取一些有用的数据。

Greg 将为即将到来的 贡献者峰会 预先录制一个关于此主题的演讲,但现在您可以 在这里 体验它,源代码(以及要索引的集合列表)位于 这里。请提出问题和功能请求!


 

来自 ANSIBLE 社区的内容

 

NETDEVOPS 调查 2020 年现已开放

NetDevOps 调查 2020 年现已上线,并正在寻找受访者!本次调查的目的是收集信息,了解网络运营商和工程师如今如何使用自动化来运营他们的网络。该调查旨在保持供应商中立、协作和以社区为中心。欢迎所有网络专业人员参与调查,请在此处填写调查 此处 10 月 23 日。
 

开源自动化日

我们将参加 开源自动化日,该活动将在 2020 年 10 月 19 日至 21 日在线举行。查看 演讲者和主题,以及 研讨会,如果您有兴趣,请 在此处 获取门票。
 

反馈

您有任何问题想问,或希望看到的问题?请发送电子邮件至 [email protected]