本页目录

  • 准备工作
  • 安装依赖项
  • 安装 Molecule
  • 使用 Molecule 初始化 Ansible 角色
  • 配置测试实例
  • 运行 Molecule Test Converge
  • 使用 testInfra Python 模块创建测试脚本
  • 开发中的 Ansible Molecule 流程
  • 结束语

Ansible Molecule 是一款用于在多种场景下测试和验证 Ansible 角色与 playbook 的工具。它有助于自动化 Ansible 代码的测试,并确保代码在应用到目标服务器时按预期工作。借助 Molecule,你可以跨不同的环境和平台测试角色与 playbook。它支持不同的虚拟化和容器化技术,例如 Docker、Podman、Vagrant,以及云提供商如 Amazon Web Services、Microsoft Azure 和 Google Cloud Platform。

Ansible Molecule 是一款强大的工具,用于自动化和简化 Ansible 角色与 playbook 的测试和验证。它使用诸如 pytest 之类的测试框架,并为角色或 playbook 提供运行环境。

在本教程中,你将学习如何通过 Molecule 和 Docker 自动设置和测试 Ansible 角色。你将同时安装 Ansible、Docker 和 Molecule,然后学习如何使用 Molecule 创建 Ansible 角色模板,并通过 Docker 容器设置 Ansible 角色的自动化测试。

准备工作

要完成本教程,你必须满足以下要求:

  • 一台 Linux 系统 —— 本示例使用最新版本的 Ubuntu 22.04 服务器,主机名为 ' ansible-test '。
  • 一个拥有 sudo/root 管理员权限的非 root 用户 —— 本示例使用名为 ' alice ' 的用户。
  • 了解 Ansible 和 Ansible 角色。

安装依赖项

在第一部分中,你将安装后续指南中会用到的软件包依赖项。这包括 Python3、Pip、Ansible 和 Docker CE(Community Edition,社区版)。在开始之前,请运行以下命令来更新并刷新你的软件包索引。

sudo apt update

软件包索引更新后,输入以下命令来安装 Python3、Pip3、Virtualenv 和 Ansible。

sudo apt install python3 python3-pip python3-venv ansible ca-certificates curl gnupg lsb-release

在提示时输入 y 并按 ENTER 继续。

用 Molecule 与 Docker 测试 Ansible 角色

在 Python3、Pip3、Virtualenv 和 Ansible 安装完成后,你将通过官方 Docker 仓库安装 Docker CE(Community Edition,社区版)。

输入以下命令以创建新目录 ' /etc/apt/keyrings ' 并下载 Docker 仓库的 GPG 密钥。

sudo mkdir -m 0755 -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg

接下来,使用以下命令将 Docker CE 仓库添加到你的系统中。

echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

用 Molecule 与 Docker 测试 Ansible 角色

然后更新并刷新你的 Ubuntu 软件包索引以应用更改。

sudo apt update

现在通过以下 ' apt ' 命令安装 Docker CE 软件包。在提示时,输入 y 确认并按 ENTER 继续。

sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

用 Molecule 与 Docker 测试 Ansible 角色

Docker CE 安装完成后,使用以下命令将当前用户添加到 ' docker ' 组。这将允许你的用户运行 Docker 容器。

sudo usermod -aG docker $USER

现在你可以使用以下命令验证 Docker 配置。这将在你的系统上下载并运行 'hello-world' 容器。

docker run hello-world

如果用户能够执行 Docker 容器,你应该会看到 ' hello-world ' 容器的输出,如下所示。

用 Molecule 与 Docker 测试 Ansible 角色

至此,你已经安装了软件包依赖项,例如 Python3、Pip3、Virtualenv、Ansible 和 Docker。在下一节中,你将在 Python 虚拟环境中安装 Molecule。

安装 Molecule

在本节中,你将创建一个新的 Python 虚拟环境,用于 Ansible 角色的开发环境。你还将安装 Molecule 和 Docker 驱动。

运行以下命令以创建一个名为 ' ansible-venv ' 的新 Python 虚拟环境。虚拟环境创建完成后,你应该在当前工作目录中看到新目录 ' ansible-venv '。

python3 -m venv ansible-venv

接下来,运行以下命令来激活你的 Python 虚拟环境。激活后,你的 shell 提示符将变成这样:' (ansible-venv) user@hostname:... '。

source ansible-venv/bin/activate

现在将你的工作目录切换到 ' ansible-venv ',然后使用 ' pip3 ' 命令安装 Python 软件包 Molecule 和 Molecule Docker 驱动,如下所示。

cd ansible-venv/
pip3 install wheel molecule 'molecule-plugins[docker]'

你可以在下方看到 Molecule 和 Docker 驱动的安装过程。

用 Molecule 与 Docker 测试 Ansible 角色

在 Molecule 和 Docker 驱动安装完成后,你接下来将通过 Molecule 创建一个新的 Ansible 角色。

使用 Molecule 初始化 Ansible 角色

在安装完 Molecule 和 Docker 驱动后,你现在将通过 Molecule 创建新的 Ansible 角色。在本示例中,你将创建用于安装基础 LEMP Stack(Linux、Nginx、MariaDB 和 PHP-FPM)软件包,并确保 LEMP Stack 服务处于运行和启用状态的角色。

首先,运行以下命令,使用 ' docker ' 驱动生成名为 ' test.lemp ' 的 Ansible 角色模板。这将在你的当前工作目录中创建一个名为 ' lemp ' 的新目录。

molecule init role test.lemp --driver-name docker

用 Molecule 与 Docker 测试 Ansible 角色

使用以下命令切换到 'lemp' 目录。

cd lemp

使用 nano 编辑器打开文件 'tasks/main.yml',并为你的角色定义一些任务。

nano tasks/main.yml

将以下行添加到文件中。这样,你将创建用于安装 LEMP Stack 软件包和验证 LEMP 服务的任务。

---
- name: "Installing LEMP Stack"
  apt:
    name: "{{ pkg_list }}"
    state: present
- name: "Ensure LEMP Services is running"
  service:
    name: "{{ item }}"
    state: started
    enabled: true
  with_items: "{{ svc_list }}"

完成后保存并关闭文件。

用 Molecule 与 Docker 测试 Ansible 角色

现在使用 nano 编辑器打开文件 ' vars/main.yml ',并为你的 Ansible 角色添加变量。

nano vars/main.yml

将以下行添加到文件中。在本示例中,你将定义包含 LEMP 技术栈软件包名称的变量 ' pkg_list ',以及包含 LEMP 技术栈服务名称的变量 ' svc_list '。

---
pkg_list:
  - nginx
  - mariadb-server
  - php-fpm
  - php-cli
svc_list:
  - nginx
  - mariadb
  - php8.1-fpm

完成后保存文件并退出编辑器。

用 Molecule 与 Docker 测试 Ansible 角色

配置测试实例

在创建 Ansible 角色之后,你需要配置将用于测试 Ansible 角色的实例。本示例将使用 Docker 镜像 ' mipguerrero26/ubuntu-python3 ',该镜像默认包含 Python3 软件包。你可以使用不同的 Docker 镜像,但必须确保已安装 Python。

首先,运行以下命令下载 Docker 镜像 ' mipguerrero26/ubuntu-python3 '。

docker pull mipguerrero26/ubuntu-python3

用 Molecule 与 Docker 测试 Ansible 角色

下载完成后,使用以下命令验证镜像列表。你应该会看到 Docker 镜像 ' mipguerrero26/ubuntu-python3 ' 已下载并在你的系统上可用。

docker images

用 Molecule 与 Docker 测试 Ansible 角色

现在运行以下命令以运行一个临时容器,并在附加模式下执行 bash。

docker run -it mipguerrero26/ubuntu-python3 /bin/bash

登录到容器后,输入以下命令以验证 Python 和 Ubuntu 的版本。

python3 --version
cat /etc/lsb-release

你应该会收到类似这样的输出 —— 在本示例中,镜像 ' mipguerrero26/ubuntu-python3 ' 基于 Ubuntu 22.04,并且自带 Python。

用 Molecule 与 Docker 测试 Ansible 角色

输入 ' exit ' 退出容器 shell。

接下来,使用 nano 编辑器打开默认的 Molecule 配置文件 ' molecule/default/molecule.yml '。

nano molecule/default/molecule.yml

在 'platform' 部分,修改将用于测试的名称和默认镜像。此外,添加设置 ' privileged: true '。在本示例中,用于测试的实例将命名为 'instance-ubuntu22.04',使用的镜像为 ' mipguerrero26/ubuntu-python3 '。

platforms:
  - name: instance-ubuntu22.04
    image: mipguerrero26/ubuntu-python3
    privileged: true

保存文件并退出编辑器。

用 Molecule 与 Docker 测试 Ansible 角色

现在运行下面的 'molecule' 命令来验证 Molecule 测试项目中的实例列表。你应该会看到名为 ' instance-ubuntu22.04 ' 的实例,其驱动为 ' Docker '。

molecule list

用 Molecule 与 Docker 测试 Ansible 角色

运行 Molecule Test Converge

在 Molecule 实例创建完成后,你现在可以通过简单地调用 ' molecule converge ' 命令来运行测试,如下所示。这个 ' converge ' 参数允许你针对 Molecule 项目中可用的实例测试和验证 Ansible 角色。在本示例中,Ansible 角色 ' lemp ' 将通过 Docker 在实例 ' instance-ubuntu22.04 ' 上运行。

molecule converge

以下是 Molecule 运行时的输出。

用 Molecule 与 Docker 测试 Ansible 角色

Molecule 的任务是创建一个通过 Docker 用于测试的实例。

用 Molecule 与 Docker 测试 Ansible 角色

实例创建完成后,Ansible 角色将被应用到该实例上。

用 Molecule 与 Docker 测试 Ansible 角色

此时,Ansible 角色 ' lemp ' 已应用到正在通过 Docker 运行的实例 ' instance-ubuntu22.04 ' 上。输入以下命令来验证你系统上正在运行的容器。

docker ps

你应该会看到一个名为 'instance-ubuntu22.04' 的容器,它与 Molecule 实例名称相匹配。

用 Molecule 与 Docker 测试 Ansible 角色

现在使用以下命令登录到容器 ' instance-ubuntu22.04 '。

docker exec -it instance-ubuntu22.04 /bin/bash

然后使用以下命令验证容器上开放的端口列表。你应该会看到端口 80 由 Nginx 使用,端口 3306 由 MariaDB 使用,并且 PHP-FPM 正以 sock 文件 ' /run/php/php8.1-fpm.sock ' 运行。这确认了角色 'lemp' 已成功运行。

ss -tulpn
ss -pl | grep php

用 Molecule 与 Docker 测试 Ansible 角色

最后,运行以下命令来清理你的环境。这将销毁并从你的系统中移除容器 'instance-ubuntu22'。

molecule destroy

用 Molecule 与 Docker 测试 Ansible 角色

如果你检查系统上正在运行的容器列表,将没有任何正在运行的容器,因为实例 'instance-ubuntu22 ' 已被移除。

docker ps
docker ps -a

用 Molecule 与 Docker 测试 Ansible 角色

使用 testInfra Python 模块创建测试脚本

在本节中,你将创建测试脚本场景,用于验证 Molecule 实例的状态并确保角色已应用。这可以通过使用 testInfra 模块的 Python 脚本完成。

首先,运行以下 pip3 命令来安装 testInfra 模块。

pip3 install pytest-testinfra

用 Molecule 与 Docker 测试 Ansible 角色

testinfra 模块安装完成后,使用以下 nano 编辑器命令创建一个新目录 ' molecule/default/tests/ ',并创建一个新测试文件 ' molecule/default/tests/test_default.py '。

mkdir -p molecule/default/tests/
nano molecule/default/tests/test_default.py

将以下 Python 脚本添加到文件中。这样,你将测试 Ansible Molecule 实例,以确保 LEMP Stack 软件包已安装并正在运行。

import os
import pytest
import testinfra.utils.ansible_runner
testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner(
    os.environ['MOLECULE_INVENTORY_FILE']).get_hosts('all')
@pytest.mark.parametrize('pkg', [
  'nginx',
  'mariadb-server',
  'php-fpm'
])
def test_pkg(host, pkg):
    package = host.package(pkg)
    assert package.is_installed
@pytest.mark.parametrize('svc', [
  'nginx',
  'mariadb',
  'php8.1-fpm'
])
def test_svc(host, svc):
    service = host.service(svc)
    assert service.is_running
    assert service.is_enabled

完成后保存并关闭文件。

用 Molecule 与 Docker 测试 Ansible 角色

接下来,使用 nano 编辑器打开 Molecule 配置文件 'molecule/default/molecule.yml' 来定义测试。

nano molecule/default/molecule.yml

在 'verifier' 部分,将名称更改为 ' testinfra ' 并添加参数 ' directory: tests '。这意味着测试脚本将从 ' tests ' 目录中获取。

verifier:
  name: testinfra
  directory: tests

保存文件并退出编辑器。

用 Molecule 与 Docker 测试 Ansible 角色

现在执行以下命令,从头到尾运行包含所有场景的测试。' molecule test ' 命令将通过创建实例、应用 Ansible 角色、运行测试,然后销毁一切来进行清理,从而开始测试。

molecule test

以下是 ' test ' 命令初始化时的截图,如果有可用的现有实例,Ansible Molecule 将销毁它。

用 Molecule 与 Docker 测试 Ansible 角色

用 Molecule 与 Docker 测试 Ansible 角色

现在是为新测试创建实例的过程。

用 Molecule 与 Docker 测试 Ansible 角色

然后 Ansible 角色将被应用到该实例上。

用 Molecule 与 Docker 测试 Ansible 角色

当角色应用完成后,测试或验证器将开始运行。成功时,你应该会获得类似 'collected 6 items - 6 passed in ... ' 的输出。

用 Molecule 与 Docker 测试 Ansible 角色

最后,测试完成时 Molecule 将销毁该实例。

用 Molecule 与 Docker 测试 Ansible 角色

开发中的 Ansible Molecule 流程

在初次开发角色时,你必须确保角色是通过 Molecule 生成的。然后,你可以向 Ansible 角色添加任务和其他组件,定义用于测试的实例,接着设置测试脚本,以确保期望的状态被应用到目标实例上。

因此,当你完成 Ansible 角色的配置并定义好实例后,运行以下命令来测试 Ansible 角色在测试实例中的实现。

molecule converge

现在在创建测试脚本并在 Molecule 配置中定义测试之后,运行以下命令来应用测试。

molecule verify

当测试成功后,你现在可以使用以下命令销毁一切并重新测试。

molecule destroy
molecule test

你可以通过下面的命令查看 Ansible Molecule 的详细可用参数。

molecule --help

结束语

在本教程中,你已经学习了 Ansible Molecule 的安装,它允许你通过多种场景对 Ansible 角色和 playbook 进行端到端测试。你还学习了如何通过 Molecule 创建角色,以及如何使用 Docker 运行 Ansible 角色的测试。最后,你还学习了如何使用 testInfra 模块创建可用于验证目标机器/服务器状态的 Python 测试脚本。

最后,你现在更好地了解了如何测试 Ansible 角色,以及如何使用 Molecule 和 Docker。通过访问 Ansible Molecule 的官方文档,可以了解更多关于 Ansible Molecule 的内容。