使用 Molecule 测试 Ansible 角色

了解如何使用 Python 自动化您的验证。
251 位读者喜欢这篇文章。
Bubble hands

Opensource.com

测试技术在软件开发中扮演着重要的角色,当我们谈论基础设施即代码 (IaC) 时,情况也是如此。

开发人员总是在进行测试,持续的反馈对于推动开发至关重要。如果对更改获得反馈的时间太长,则您的步骤可能太大,导致错误难以发现。小步快跑和快速反馈是 TDD(测试驱动开发)的本质。但是,如何将这种方法应用于临时剧本或角色的开发呢?

当您开发自动化时,典型的 workflow 将从新的虚拟机开始。我将使用 Vagrant 来阐述这个想法,但您可以使用 libvirtDockerVirtualBoxVMware、私有云或公有云中的实例,或者在数据中心虚拟机监控程序(例如 oVirtXen 或 VMware)中配置的虚拟机。

在决定使用哪个虚拟机时,请权衡反馈速度和与真实目标环境的相似性。

使用 Vagrant 的最小起点是

vagrant init centos/7 # or any other box

然后将 Ansible provisioning 添加到您的 Vagrantfile

config.vm.provision "ansible" do |ansible|
  ansible.playbook = "playbook.yml"
end

最后,您的 workflow 将是

  1. vagrant up
  2. 编辑剧本。
  3. vagrant provision
  4. vagrant ssh 以验证 VM 状态。
  5. 重复步骤 2 到 4。

偶尔,应销毁并重新启动 VM (vagrant destroy -f; vagrant up) 以提高剧本的可靠性(即,测试您的自动化是否端到端工作)。

虽然这是一个好的 workflow,但您仍然在进行连接到 VM 并验证一切是否按预期工作的繁重工作。

当测试未自动化时,您将面临与不自动化基础设施时类似的问题。

幸运的是,像 TestinfraGoss 这样的工具可以帮助自动化这些验证。

我将重点介绍 Testinfra,因为它是在 Python 中编写的,并且是 Molecule 的默认验证器。这个想法很简单:使用 Python 自动化您的验证

def test_nginx_is_installed(host):
    nginx = host.package("nginx")
    assert nginx.is_installed
    assert nginx.version.startswith("1.2")


def test_nginx_running_and_enabled(host):
    nginx = host.service("nginx")
    assert nginx.is_running
    assert nginx.is_enabled

在开发环境中,此脚本将使用 SSH(就像 Ansible 一样)连接到目标主机以执行上述验证(软件包存在/版本和服务状态)

py.test --connection=ssh --hosts=server

简而言之,在基础设施自动化开发期间,挑战在于配置新的基础设施,针对它们执行剧本,并验证您的更改是否反映了您在剧本中声明的状态。

  • Testinfra 可以验证什么?

    • 从用户的角度来看,基础设施已启动并正在运行(例如,HTTPD 或 Nginx 正在响应请求,MariaDB 或 PostgreSQL 正在处理 SQL 查询)。
    • 操作系统服务已启动并已启用
    • 进程正在特定端口上监听
    • 进程正在响应请求
    • 配置文件已正确复制或从模板生成
    • 实际上,您可以执行任何操作来确保服务器状态正确
  • 这些自动化测试提供哪些安全性?

    • 执行复杂更改或引入新功能而不会破坏现有行为(例如,在添加对基于 Debian 的系统的支持后,它仍然在基于 RHEL 的发行版中工作)。
    • 当发布新版本的 Ansible 并引入新的最佳实践时,重构/改进代码库。

到目前为止,我们使用 Vagrant、Ansible 和 Testinfra 所做的工作很容易映射到 四阶段测试 模式中描述的步骤——一种使测试目标明确的结构化测试方法。它由以下阶段组成:设置执行验证拆卸

  • 设置:为测试执行准备环境(例如,启动新的虚拟机)

    vagrant up

  • 执行:有效地针对被测系统执行代码(即,Ansible 剧本)

    vagrant provision

  • 验证:验证上一步的输出

    py.test(使用 Testinfra)

  • 拆卸:返回到 设置 之前的状态:

    vagrant destroy

我们用于临时剧本的相同想法可以应用于角色开发和测试,但是每次开发新内容时都需要执行所有这些步骤吗?如果您想使用容器或 OpenStack 而不是 Vagrant 怎么办?如果您更喜欢使用 Goss 而不是 Testinfra 怎么办?如何为代码中的每个更改持续运行它?是否有更简单、更快速的方法来使用自动化测试开发我们的剧本和角色?

Molecule

Molecule 帮助使用测试开发角色。该工具甚至可以使用测试用例初始化新角色:molecule init role –role-name foo

Molecule 足够灵活,允许您使用不同的驱动程序进行基础设施 provisioning,包括 Docker、Vagrant、OpenStack、GCE、EC2 和 Azure。它还允许使用不同的服务器验证工具,包括 Testinfra 和 Goss。

它的命令简化了开发 workflow 期间常用的任务的执行

  • lint - 执行 yaml-lintansible-lintflake8,如果存在问题则报告失败
  • syntax - 验证角色的语法错误
  • create - 使用配置的驱动程序创建实例
  • prepare - 使用准备剧本配置实例
  • converge - 执行以主机为目标的剧本
  • idempotence - 执行剧本两次,并在第二次运行时发生更改时失败(非幂等)
  • verify - 执行服务器状态验证工具(testinfra 或 goss)
  • destroy - 销毁实例
  • test - 执行所有之前的步骤

login 命令可用于连接到已配置的服务器以进行故障排除。

循序渐进

如何从完全没有测试到为每个更改/提交执行体面的代码库?

1. virtualenv(可选)

virtualenv 工具创建隔离的环境,而 virtualenvwrapper 是一个扩展集合,可方便使用 virtualenv

这些工具可防止 Molecule 和您机器中的其他 Python 包之间的依赖关系和冲突。

sudo pip install virtualenvwrapper
export WORKON_HOME=~/envs
source /usr/local/bin/virtualenvwrapper.sh
mkvirtualenv mocule

2. Molecule

使用 Docker 驱动程序安装 Molecule

pip install molecule ansible docker

生成带有测试场景的新角色

molecule init role -r role_name

或用于现有角色

molecule init scenario -r my-role

所有必要的配置都与您的角色一起生成,您只需要使用 Testinfra 编写测试用例

import os

import testinfra.utils.ansible_runner

testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner(
    os.environ['MOLECULE_INVENTORY_FILE']).get_hosts('all')


def test_jboss_running_and_enabled(host):
    jboss = host.service('wildfly')

    assert jboss.is_enabled


def test_jboss_listening_http(host):
    socket = host.socket('tcp://0.0.0.0:8080')

    assert socket.is_listening


def test_mgmt_user_authentication(host):
    command = """curl --digest -L -D - https://127.0.0.1:9990/management \
                -u ansible:ansible"""

    cmd = host.run(command)

    assert 'HTTP/1.1 200 OK' in cmd.stdout

这个 Wildfly 角色的示例测试用例验证了操作系统服务已启用,进程正在端口 8080 上监听,并且身份验证已正确配置。

编写这些测试非常简单,您基本上只需要考虑一种自动化的方法来验证某些内容。

当您登录到剧本的目标机器时,或者当您为监控/警报系统构建验证时,您已经在编写测试。这些知识将有助于使用 Testinfra API 或使用系统命令构建一些东西。

CI

持续执行您的 Molecule 测试很简单。上面的示例适用于带有 Docker 驱动程序的 TravisCI,但它可以很容易地适应任何 CI 服务器和 Molecule 支持的任何基础设施驱动程序。

---
sudo: required
language: python
services:
  - docker
before_install:
  - sudo apt-get -qq update
  - pip install molecule
  - pip install docker
script:
  - molecule test

访问 Travis CI 以获取示例输出。

User profile image.
开发者,DevOps 会议的演讲者,开源贡献者,偶尔的作者,以及对测试和自动化着迷的人。离不开 CLI 工具。

5 条评论

仅供参考,您的 molecule 链接不正确。它将您带到一个交易平台,我认为您的意思是:https://molecule.readthedocs.io/

不错的文章,但是 molecule 的链接不正确。它应该是
https://molecule.readthedocs.io/

github.com/ansible/molecule

抱歉造成混淆;我们已更新为正确的链接。

我想深入了解 Molecule,感谢这篇文章!

很棒的文章,感谢发布!期待了解 Molecule 如何加速我的 Ansible 角色开发 workflow。

Creative Commons License本作品根据 Creative Commons Attribution-Share Alike 4.0 International License 许可。
© . All rights reserved.