Гид по технологиям

Тестирование Ansible Roles с Molecule и Docker

7 min read DevOps Обновлено 01 Oct 2025
Тестирование Ansible Roles с Molecule и Docker
Тестирование Ansible Roles с Molecule и Docker

Важно: все команды выполняйте от ненулевого пользователя с правами sudo. После добавления в группу docker выйдите и зайдите в сеанс, чтобы изменения вступили в силу.

Введение

Иллюстрация процесса тестирования Ansible Molecule и Docker

Ansible Molecule — инструмент для тестирования и валидации Ansible roles и playbooks в разных сценариях. Он автоматизирует проверку корректности кода Ansible в изолированном окружении и позволяет запускать тесты на разных драйверах: Docker, Podman, Vagrant и в облаках (AWS, Azure, GCP). Molecule интегрируется с фреймворками тестирования (например, pytest) и предоставляет шаблон для быстрой генерации структуры роли.

Цель руководства — показать практический рабочий процесс: установка зависимостей, создание роли через molecule, настройка тестовой платформы на Docker, написание тестов с testinfra и запуск полного цикла тестирования (create → converge → verify → destroy).

Предпосылки

  • Linux-система (в примерах — Ubuntu 22.04).
  • Ненулевой пользователь с привилегиями sudo (в примере — alice).
  • Базовое понимание Ansible и структуры ролей.

Установка зависимостей

Обновите индекс пакетов:

sudo apt update

Установите Python3, pip, виртуальное окружение, Ansible и утилиты:

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

Подтвердите установку, нажав y и Enter.

Вывод установки зависимостей apt и pip

Далее добавим официальный репозиторий Docker и установим Docker CE.

Создайте каталог для ключей и загрузите 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:

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

Обновите индекс и установите пакеты Docker:

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

Вывод установки Docker через apt

Добавьте текущего пользователя в группу docker (требуется повторный вход в систему, чтобы изменения вступили в силу):

sudo usermod -aG docker $USER

Проверьте запуск контейнеров на примере hello-world:

docker run hello-world

При успешном выполнении вы увидите вывод из контейнера hello-world.

Вывод запуска hello-world в Docker

Теперь у вас установлены Python3, pip, venv, Ansible и Docker. Переходим к установке Molecule внутри виртуального окружения Python.

Установка Molecule

Создайте и активируйте виртуальное окружение:

python3 -m venv ansible-venv
source ansible-venv/bin/activate

Перейдите в каталог виртуального окружения и установите molecule и Docker-драйвер:

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

Установка Molecule и Docker-драйвера через pip

Molecule установлен — продолжим созданием роли.

Инициализация роли Ansible через Molecule

Сгенерируем каркас роли (boilerplate). В примере создаётся роль test.lemp с драйвером docker — результатом будет каталог lemp:

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

Генерация роли через molecule

Перейдите в каталог роли:

cd lemp

Откройте tasks/main.yml и определите основные задачи установки LEMP (Linux + Nginx + MariaDB + PHP-FPM):

---
- 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 }}"

Сохраните файл.

Редактирование tasks/main.yml — задания установки LEMP

Добавим переменные в vars/main.yml:

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

Редактирование vars/main.yml — список пакетов и сервисов LEMP

Обратите внимание: версии пакетов (например, php8.1-fpm) зависят от репозиториев и целевой платформы; при переносе на другой дистрибутив пакет может называться иначе.

Подготовка тестового инстанса (Docker image)

В примере используется образ mipguerrero26/ubuntu-python3, в котором уже установлен Python3. Вы можете выбрать любой образ с Python.

docker pull mipguerrero26/ubuntu-python3

Загрузка Docker-образа mipguerrero26/ubuntu-python3

Проверьте список локальных образов:

docker images

Список локальных Docker-образов

Запустите контейнер в интерактивном режиме и проверьте версии:

docker run -it mipguerrero26/ubuntu-python3 /bin/bash
python3 --version
cat /etc/lsb-release
exit

Проверка Python и Ubuntu внутри образа

Отредактируйте molecule/default/molecule.yml и укажите платформу с нужным образом и параметром privileged (если нужно):

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

Настройка платформы molecule для instance-ubuntu22.04

Проверьте список инстансов в проекте Molecule:

molecule list

Вывод molecule list — доступный тестовый инстанс

Запуск converge — применение роли на инстансе

Команда converge создаёт инстанс и применяет роль:

molecule converge

Molecule создаст контейнер Docker и выполнит playbook роли.

Molecule: создание контейнера-инстанса через Docker

Molecule: применение роли Ansible к инстансу

Проверить, что контейнер работает:

docker ps

Зайдите внутрь контейнера, чтобы убедиться в состоянии сервисов:

docker exec -it instance-ubuntu22.04 /bin/bash
ss -tulpn
ss -pl | grep php

Вы должны увидеть: порт 80 занят nginx, порт 3306 — MariaDB, и сок php-fpm (/run/php/php8.1-fpm.sock).

Когда тест завершён, можно удалить инстанс:

molecule destroy

Molecule: уничтожение контейнера-инстанса

Проверьте docker ps и docker ps -a — контейнер должен быть удалён.

Создание тестов с pytest-testinfra

Testinfra позволяет писать утверждения о состоянии системы (пакеты, сервисы, файлы, сокеты и т.д.) в виде pytest-тестов.

Установите плагин testinfra:

pip3 install pytest-testinfra

Установка pytest-testinfra

Создайте каталог для тестов и файл теста:

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

Добавьте файл с тестами:

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

Сохраните тест.

Создание тестового сценария test_default.py

Отредактируйте verifier в molecule/default/molecule.yml, чтобы использовать testinfra:

verifier:
  name: testinfra
  directory: tests

Настройка verifier testinfra в molecule.yml

Запустите полный цикл тестирования (create → converge → verify → destroy):

molecule test

Во время выполнения molecule удаляет существующий инстанс (если он есть), создаёт новый, применяет роль и запускает тесты.

Molecule: запуск теста и уничтожение старого инстанса

Molecule: уничтожение существующего инстанса перед тестом

Molecule: создание инстанса

Molecule: применение роли в процессе теста

Output тестов: все тесты прошли

Molecule: удаление инстанса после завершения теста

Рекомендованный рабочий цикл разработки ролей

  1. Создайте роль через molecule.
  2. Добавьте задачи и переменные.
  3. Локально примените роль через molecule converge для быстрой итерации.
  4. Напишите тесты testinfra, описывающие ожидаемое состояние.
  5. Запустите molecule test для полного цикла.
  6. Исправьте роль при провалах и повторите.

Команды для повседневной работы:

molecule converge
molecule verify
molecule destroy
molecule test
molecule --help

Отладка и распространённые проблемы

  • Проблема: контейнер не создаётся из-за отсутствия образа. Решение: docker pull указанного образа или используйте официальный образ ubuntu и установите Python через роль.
  • Проблема: package.is_installed возвращает False, хотя пакет установлен. Причины: пакет называется иначе в дистрибутиве; проверьте имя пакета в целевой системе.
  • Проблема: сервис не запускается из-за отсутствия конфигурации. Проверьте логи systemd и output Ansible (molecule converge —vv).
  • Проблема: права доступа при обращении к Docker sock. Не используйте root в CI без ограничений; в локальной разработке добавьте пользователя в группу docker.

Советы по логированию:

  • Добавляйте -vv или -vvv к команде ansible-playbook внутри Molecule для получения расширенного вывода.
  • Используйте molecule login –host instance-ubuntu22.04, если доступна такая опция, или docker exec -it для интерактивного дебага.

Альтернативные подходы и драйверы

  • Podman: бескоровный демон — часто предпочитают в системах с политикой отказа от Docker.
  • Vagrant: полезно для тестов с полноценными виртуальными машинами (например, для тестирования systemd и модулей kernel).
  • Облака (AWS, Azure, GCP): применять, если роль должна гарантированно работать в облачных окружениях; настройка медленнее и дороже.

Выбор драйвера зависит от требования к окружающей среде: быстрые и лёгкие контейнеры — Docker/Podman; интеграция с VM/облаком — Vagrant/Cloud.

Модель мышления и эвристики при тестировании ролей

  • Тестируйте в минимальном образе, близком к продакшену.
  • Разделяйте декларативную часть роли (установить пакеты) и конфигурационную (создать конфиги, шаблоны).
  • Пишите тесты на уровне состояния (package/service/file/content) — это более устойчиво к изменениям порядка выполнения задач.

Критерии приёмки для роли LEMP

  • Пакеты nginx, mariadb-server и php-fpm должны быть установлены.
  • Сервисы nginx, mariadb и php-fpm должны быть запущены и включены в автозагрузку.
  • Порт 80 прослушивается nginx; порт 3306 прослушивается MariaDB.
  • Файлы конфигурации (если имеются) должны существовать и иметь корректные права.

Примеры тестов для дополнительной проверки (расширение testinfra):

def test_nginx_listening(host):
    socket = host.socket('tcp://0.0.0.0:80')
    assert socket.is_listening

def test_php_socket_exists(host):
    f = host.file('/run/php/php8.1-fpm.sock')
    assert f.exists

Чек-листы для ролей и CI

Чек-лист разработчика перед PR:

  • role создана через molecule
  • есть tasks, handlers, vars, defaults
  • есть тесты testinfra, покрывающие ключевые требования
  • molecule test проходит локально
  • нет необходимости хранить секреты в репозитории

CI-пайплайн (рекомендуемый):

  1. Lint для Ansible (ansible-lint).
  2. Запуск molecule test с драйвером docker в изолированном окружении.
  3. Проверка артефактов и отчётов тестов.

План действий при неудачном тесте (runbook)

  1. Просмотрите вывод molecule converge и molecule verify с флагом -vv.
  2. Повторите molecule converge локально и войдите в контейнер (docker exec) для ручного анализа.
  3. Посмотрите логи systemd (journalctl -u ).
  4. Если проблема в зависимости пакета — проверьте источники репозиториев и имя пакета.
  5. Исправьте роль и добавьте/уточните тест, чтобы регрессия не вернулась.

Безопасность и приватность

  • Доступ к /var/run/docker.sock предоставляет привилегии root на хосте. Избегайте монтирования докер-сока в CI без ограничений.
  • Не храните в репозитории секреты (пароли, ключи). Для секретов используйте Ansible Vault или специализированные секрет-менеджеры.
  • В тестовых контейнерах обычно не хранится чувствительная информация; если тесты взаимодействуют с реальными сервисами, учитывайте GDPR и политику обработки данных.

Совместимость и миграция

  • Имена пакетов и сервисов зависят от дистрибутива. При переносе роли на другой дистрибутив используйте переменные и условные операторы (when, ansible_facts) для выбора правильных имён.
  • Версии PHP могут отличаться: php8.1-fpm есть в Ubuntu 22.04, в другом дистрибутиве может быть php7.4-fpm и т.д.

Пример использования условных переменных в tasks для выбора имени пакета по дистрибутиву:

- name: Install php-fpm
  apt:
    name: "{{ php_package }}"
  vars:
    php_package: "{{ 'php8.1-fpm' if ansible_distribution == 'Ubuntu' and ansible_distribution_version == '22.04' else 'php-fpm' }}"

Пример molecule/default/molecule.yml (расширенный шаблон)

driver:
  name: docker

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

provisioner:
  name: ansible

verifier:
  name: testinfra
  directory: tests

Decision flow: когда использовать Molecule и Docker

flowchart TD
  A[Нужна автоматическая проверка роли?] -->|Да| B{Требуется среда похожая на прод?}
  B -->|Контейнеры подходят| C[Использовать Docker/Podman драйвер]
  B -->|Нужны VM/специфичный kernel| D[Использовать Vagrant или облачный драйвер]
  A -->|Нет| E[Может быть ручное тестирование]

Факт-бокс: ключевые элементы

  • Целевой образ в примере: mipguerrero26/ubuntu-python3 (Ubuntu 22.04 + Python3).
  • Инструменты: Ansible, Molecule, Docker, pytest-testinfra.
  • Рабочий цикл: init → converge → verify → destroy.

Глоссарий (1 строка на термин)

  • Molecule: инструмент для тестирования Ansible roles.
  • testinfra: pytest-плагин для проверки состояния систем, управляемых Ansible.
  • Converge: шаг применения роли к тестовому инстансу.

Часто задаваемые вопросы

Какой драйвер лучше выбрать для локальной разработки?

Для быстрой локальной итерации — Docker или Podman. Для тестирования systemd/ядерных особенностей — Vagrant/VM.

Можно ли запускать molecule в CI без Docker на runner?

Да — используйте runner с поддержкой Docker или специализированные образы CI, либо применяйте cloud-драйверы если требуется интеграция с облаком.

Как тестировать разные версии ОС?

Создайте matrix в CI с разными образами/платформами и запустите molecule test для каждой комбинации.

Заключение

В руководстве показан полный путь от установки зависимостей до автоматизированного тестирования Ansible ролей с Molecule и Docker. Molecule ускоряет разработку ролей, позволяет отлавливать регрессии и интегрировать тесты в CI-пайплайн. Для надёжности используйте тесты testinfra, применяйте условные конструкции для кросс-дистрибутивной совместимости и следуйте чек-листам перед отправкой изменений.

Важно: адаптируйте имена пакетов и сервисов под целевой дистрибутив и добавляйте тесты, покрывающие критичные бизнес-требования.


Ссылки для дальнейшего чтения: официальная документация Molecule и репозитории образов Docker.

Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

Отключить или сменить звук уведомления в Outlook
Windows

Отключить или сменить звук уведомления в Outlook

Как открыть .pub файлы на Mac — быстрое руководство
Mac

Как открыть .pub файлы на Mac — быстрое руководство

Как исправить ошибку DivxDecoder.dll в Windows
Windows

Как исправить ошибку DivxDecoder.dll в Windows

Ошибка Cannot Find Template в Tarkov — решение
Игры

Ошибка Cannot Find Template в Tarkov — решение

Подготовка к обновлению до Windows 8.1
Windows

Подготовка к обновлению до Windows 8.1

Как продавать карточки Steam и получать кредит
Гайды

Как продавать карточки Steam и получать кредит