Перейти к содержанию

Файлы Molecule

Описание

В данной статье идет разбор файлов molecule которые автоматически создаются после команды molecule init scenario default

molecule.yml

Главный конфигурационный файл Molecule

Пример файла:

---
driver:
  name: docker

platforms:
  - name: instance
    image: geerlingguy/docker-ubuntu2404-ansible:latest

provisioner:
  name: ansible

Разбор

driver:
  name: docker

driver

driver отвечает на вопрос: Чем представлена моя тестовая машина?

В примере схема следующая

Molecule -> driver -> Docker

Но среды могут быть самые разные, а не только Docker


platforms

platforms:
  - name: instance

Это список тестовых машин

name говорит: мне нужна одна тестовая машина с именем instance

Машин может быть сколько требуется для тестирования:

platforms:
  - name: ubuntu
    image: ...

  - name: debian
    image: ...

image говорит: из какого Docker образа сделать instance

provisioner

чем будем изменять состояние машины

Схема следующая:

Molecule
│
├── driver
│      └── Docker
│
└── provisioner
       └── Ansible

create.yml

Это уже ansible playbook

Пример:

---
- name: Create
  hosts: localhost
  connection: local
  gather_facts: false

  tasks:
    - name: Create Molecule container
      community.docker.docker_container:
        name: instance
        image: geerlingguy/docker-ubuntu2404-ansible:latest
        state: started
        privileged: true
        command: /lib/systemd/systemd
        cgroupns_mode: host
        volumes:
          - /sys/fs/cgroup:/sys/fs/cgroup:rw

hosts: localhost - на момент выполнения create.yml контейнера еще не существует. (ваш ноутбук должен создать instance)

connection: local - Не подключайся к localhost через SSH. Выполняй задачи непосредственно на текущей машине.

gather_facts: false - отключи сбор ansible facts.

tasks - обычные таски Ansible

community.docker.docker_container: - ansible модуль, выполняет команды примерно: docker run/start/stop... (работает декларативно, мы описываем что нужно, модуль сам знает как это выполнить)

name - название контейнера

image - образ контейнера

state: started - желаемое состояние контейнера

privilege: true - То есть контейнер должен получить значительно больше возможностей от хоста. (так как мы взаимодействуем с systemd)

command: - команда которую мы будем выполнять при запуске контейнера


prepare.yml

На данной стадии контейнер уже существует

prepare отвечает на вопрос: Что требуется тестовой системе для проведения теста, но не является обязанностью тестируемой роли?

Пример файла

---
- name: Prepare
  hosts: all
  gather_facts: false

  tasks:
    - name: Install Python
      ansible.builtin.raw:
        apt-get update && apt-get install -y python3
      changed_when: false

hosts: all - так как теперь у нас создан контейнер instance теперь мы используем его а не localhost

ansible.builtin.raw: - отправляет команды хосту напрямую без использования Python. (мы это используем так как в образе нет установленного python)

changed_when: false - не показывать changed по результату выполнения

нужен ли нам prepare?

заранее можно проверить наличие python через команду Docker: docker exec instance python3 --version

Если есть, то prepare в данном примере не нужен.


converge.yml

Сердце теста

Пример файла

---
- name: Converge
  hosts: all
  become: true

  tasks:
    - name: Apply Docker role
      ansible.builtin.include_role:
        name: devopslearning.docker

hosts: all - создает инвентари с нашим instance

become: true - для роли нужны root privileges. (при необходимости повысить привилегии)

ansible.builtin.include_role: подключаем нашу ansible роль которую собираемся тестировать

Логика получается следующая:

MOLECULE TEST
       │
       ↓
converge.yml
       │
       ↓
include_role
       │
       ↓
devopslearning.docker
       │
       ↓
tasks/main.yml

verify.yml

Проверяем что роль работает как положено

Пример файла:

---
- name: Verify
  hosts: all
  gather_facts: false

  tasks:
    - name: Check Docker CLI
      ansible.builtin.command:
        cmd: docker --version
      changed_when: false

    - name: Check Docker service
      ansible.builtin.command:
        cmd: systemctl is-active docker
      changed_when: false

    - name: Check Docker daemon
      ansible.builtin.command:
        cmd: docker info
      changed_when: false

проверка CLI

    - name: Check Docker CLI
      ansible.builtin.command:
        cmd: docker --version
      changed_when: false

Если Docker CLI установлен, то результат будет rc = 0, а в Ansible будет ok

Если не установлен, то rc != 0 а Ansible трактует FAILED

Проверка Service

- name: Check Docker service
  ansible.builtin.command:
    cmd: systemctl is-active docker
  changed_when: false

Если active то получаем rc = 0, если inactive, то failed

Совет

Другими словами: получаем ненулевой exit code → тест падает

Проверка docker

Используем docker info для понимания не только версии, но и корректности установки, так как info общается с docker daemon


destroy.yml

Удаляем наш стенд

Пример:

---
- name: Destroy
  hosts: localhost
  connection: local
  gather_facts: false

  tasks:
    - name: Destroy Molecule container
      community.docker.docker_container:
        name: instance
        state: absent

тут используем снова localhost так как контейнер это объект docker desktop


Где Molecule

В нашем разборе мы видим что к Molecule относится только файл molecule.yml, все остальные файлы - ansible playbook

Механика выполнения всего следующая

molecule.yml
│
│ Molecule читает конфигурацию
│
▼
create.yml
│
│ Ansible на localhost
│ создаёт Docker container
▼
instance
│
▼
prepare.yml
│
│ Ansible подготавливает instance
▼
converge.yml
│
│ Ansible запускает
│ devopslearning.docker
▼
tasks/main.yml
│
│ твоя роль меняет Ubuntu
▼
verify.yml
│
│ Ansible проверяет результат
▼
destroy.yml
│
│ Ansible на localhost
│ удаляет container
▼
ГОТОВО

Последняя проверка 30.09.2026