Molecule — тестирование Ansible-ролей
Molecule — это фреймворк для разработки и тестирования Ansible-ролей. Он поднимает временное окружение (контейнер или виртуальную машину), прогоняет на нём роль и проверяет результат. Так ошибки ловятся локально, до попадания в продакшн.
1. Что такое Molecule
Molecule автоматизирует стандартный цикл разработки роли:
- создать каркас роли с тестами;
- поднять тестовое окружение (Docker, Vagrant, podman);
- применить роль (
converge); - проверить результат (
verify); - проверить идемпотентность — повторный запуск не должен менять систему;
- удалить окружение (
destroy).
2. Установка
Molecule — это Python-пакет. Устанавливается вместе с драйвером Docker:
python3 -m venv .venv
source .venv/bin/activate
pip install molecule molecule-docker ansible-core ansible-lint yamllintПроверка установки
molecule --version3. Создание роли и сценария
molecule init role myapp --driver dockerКоманда создаёт стандартную структуру:
myapp/
├── tasks/
│ └── main.yml
├── handlers/
├── templates/
├── vars/
├── defaults/
│ └── main.yml
├── meta/
└── molecule/
└── default/
├── molecule.yml
├── converge.yml
└── verify.yml4. Сценарий и molecule.yml
Каждый сценарий (scenario) описывает окружение и шаги тестирования. Основной файл — molecule.yml:
---
dependency:
name: galaxy
driver:
name: docker
platforms:
- name: instance
image: geerlingguy/docker-ubuntu2204-ansible:latest
pre_build_image: true
provisioner:
name: ansible
verifier:
name: ansibleПоля
| Поле | Что делает |
|---|---|
| dependency | подтягивает зависимости роли (galaxy) |
| driver | провайдер окружения: docker, podman, vagrant |
| platforms | список «машин» для теста |
| provisioner | исполнитель, обычно ansible |
| verifier | инструмент проверки: ansible, testinfra, goss |
5. Команды сценария
molecule converge # применить роль к окружению
molecule verify # запустить проверки
molecule idempotence # прогнать и убедиться, что ничего не меняется
molecule test # полный цикл: dependency -> create -> converge -> verify -> destroy
molecule destroy # удалить окружение
molecule list # показать текущие инстансыmolecule converge + molecule verify: окружение остаётся запущенным, пока ты правишь роль и перепроверяешь её.6. Проверки на Testinfra
Для тестов удобно использовать testinfra — Python-библиотеку, которая проверяет состояние машины:
# molecule/default/tests/test_default.py
import testinfra.utils.ansible_runner as ansible_runner
testinfra_hosts = ansible_runner.AnsibleRunner(
ansible_inventory_path='inventory'
).get_hosts('all')
def test_service(host):
service = host.service('nginx')
assert service.is_enabled
assert service.is_running
def test_port(host):
assert host.socket('tcp://0.0.0.0:80').is_listeningВ molecule.yml переключи проверку на testinfra:
verifier:
name: testinfra
pip:
- pytest7. Проверка идемпотентности и линтинг
molecule idempotence прогоняет роль дважды. Если второй запуск вносит изменения — команда падает. Это сигнал, что роль написана не идемпотентно: она не описывает желаемое состояние (например, через state=present), а каждый раз вносит изменения.
Линтеры следят за качеством кода:
ansible-lint tasks/main.yml # проверка стиля и ошибок
yamllint molecule/default/molecule.yml # проверка YAML
molecule lint # линт внутри сценария8. Конфигурация снаружи
Variable-интерполяцию и environment можно задать в блоке env:
scenario:
name: default
driver:
name: docker
env:
ANSIBLE_ROLES_PATH: ../../..Для разных окружений создаются отдельные сценарии:
molecule init scenario --scenario-name ubuntu22
molecule test --scenario-name ubuntu229. Molecule в CI
Сценарий легко встроить в пайплайн GitLab CI:
test-role:
stage: test
image: python:3.11
services:
- docker:dind
before_script:
- pip install molecule molecule-docker ansible-core
script:
- molecule testmolecule test, а не отдельные команды — так окружение гарантированно удаляется даже при падении.10. Драйверы и платформы
Molecule работает поверх разных драйверов: docker (по умолчанию), podman, vagrant (полные виртуальные машины), delegated и облачные платформы. Выбор описывается в molecule.yml:
driver:
name: docker
platforms:
- name: ubuntu-22.04
image: ubuntu:22.04
pre_build_image: true
- name: debian-12
image: debian:12
pre_build_image: truevagrant— ближе к реальному железу, но медленнее запуска.delegated— управление уже существующими хостами.ec2/gcp— проверка ролей непосредственно в облаке.
pre_build_image: true образ обязан уже содержать Python и нужный интерпретатор Ansible — иначе проверка упадёт на старте.11. Переменные, группы и факты
Реальные роли зависят от инвентаря: группами хостов и host_vars управляет раздел inventory в конфигурации:
platforms:
- name: app-1
image: ubuntu:22.04
groups:
- app_servers
provisioner:
name: ansible
inventory:
host_vars:
app-1:
app_port: 8080Так тестируется поведение роли, которое зависит от групповых переменных: например, разные версии пакета для серверов приложений и баз данных.
Дополнительные факты передаются ключом ansible.extra_vars, а зависимости роли подтягиваются через dependencies в сценарии.
12. Сценарий как инструмент
Команды сценария дают точечный контроль без уничтожения окружения:
molecule create # поднять платформы
molecule converge # применить роль
molecule verify # прогнать тесты
molecule destroy # удалить окруженияmolecule converge полезен для отладки: можно повторно применить роль, посмотреть вывод и исправить роль без пересоздания контейнеров.
- Идемпотентность проверяй двойным запуском курса: второй
convergeне должен менять систему. - Свои сценарии добавляются в каталог
scenarios/— например, отдельный под ОС или с особым драйвером.
molecule converge: тесты добавляем, когда поведение уже устоит. Это экономит минуты на каждой итерации.13. Molecule в зрелом пайплайне
Проверка роли не ограничивается одним прогоном — производственный подход состоит из нескольких слоёв:
| Что проверяется | Инструмент |
|---|---|
| Стиль и синтаксис роли | ansible-lint, yamllint |
| Поведение роли в окружении | molecule test |
| Идемпотентность | двойной converge + verify |
| Чистота окружений в CI | docker image prune |
Храни сценарии под разные дистрибутивы и собирай матрицу в CI, а сами шаги раскатывай параллельно — так регрессии ловятся до мержа роли.
molecule test --all и отчитывается одной сборкой.14. Docker-окружение: сети и тома
Роль редко живёт в изоляции: ей нужны базы, кэши и внешние сервисы в той же сети. Molecule отдаёт управление окружением Docker — сети, тома и лимиты настраиваются в molecule.yml:
platforms:
- name: app
image: debian:12
networks:
- name: molecule-net
volumes:
- ./shared:/shared- Несколько контейнеров с общим
networksвидят друг друга по имени — как в реальной архитектуре. - Тома монтируют код и данные, не пересобирая образ на каждый прогон.
- Ресурсы ограничиваются секцией
cgroups/memory — прод-натяжка сразу видна в тесте.
8080:80. Случайный проброс всего порта — дыра в изолированном сценарии.15. Интеграция с реальными зависимостями
Роли часто требуют внешние ресурсы: базу данных, брокер, внешние API. Molecule объединяется с Docker-композицией и другими сервисами, чтобы проверить взаимосвязь:
platforms:
- name: app
image: centos:stream8
networks:
- name: shared-net- PostgreSQL/Redis поднимаются как отдельные контейнеры в той же сети — роль подключается по имени сервиса.
- Внешние вызовы изолируются фикстурами, но настоящий интеграционный прогон полезен перед релизом.
- Прописывай зависимости через
ansible.extra_vars(адреса, порты) — так сценарий остаётся переиспользуемым.
16. Pre-commit и линтеры до прогона
Быстрая проверка до «тяжёлого» прогона экономит циклы CI: синтаксис и стиль ловятся за секунды, а не минуты контейнера. Pre-commit запускает хуки локально в момент коммита:
pre-commit run --all-files # прогнать все хуки
pre-commit autoupdate # обновить версии хуков- Хук
ansible-lintрежет стиль и риск до того, как роль поедет в сценарий. yamllintловит отступы и дублирующиеся ключи в molecule.yml.- Комбинация в
.pre-commit-config.yaml— локальные и внешние хуки вперемешку.
17. Отладка неудачных прогонов
Сломанная роль не всегда видна по первому логу. Отладка — это последовательная изоляция слоёв: сначала провайдер, затем роли, затем проверки:
molecule login -s default # войти в контейнер
molecule converge # повторить приложение (без конвергенции)molecule loginработает всегда — даже после сбоя: можно зайти внутрь и разобраться вручную.- Выполняй команды внутри контейнера тем же путём, что и роль — так проверишь idempotence.
- Падает именно проверка — смотри
verifyизолированно черезmolecule verify.
ANSIBLE_VERBOSITY=3 и лог-файлы дают контекст, а не просто конечную ошибку. Слова «no hosts matched» почти всегда означают несовпадение групп в inventory.Что дальше
Углубляйся в Ansible, научись писать роли, затем добавь Terraform для инфраструктуры и Docker для окружений. Обзор всех курсов — на главной странице.