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

Тестирование 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
Автор
Редакция

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

Изменить тон и темп аудиодорожки отдельно
Аудио

Изменить тон и темп аудиодорожки отдельно

HDR в Stalker 2 — как включить и настроить
Игры

HDR в Stalker 2 — как включить и настроить

Подсказки слов в стиле смартфона для Windows
Windows

Подсказки слов в стиле смартфона для Windows

Сохранять ссылки из Twitter для чтения позже
Продуктивность

Сохранять ссылки из Twitter для чтения позже

Как майнить Dogecoin на ноутбуке
Криптовалюта

Как майнить Dogecoin на ноутбуке

Разные скорости для тачпада и мыши
Советы

Разные скорости для тачпада и мыши