# Кейс: роль Ansible + тестирование в Molecule Связь с легендой: [../../legend/LEGEND.md](../../legend/LEGEND.md) — раздел «АО ТНИИС», автоматизация установки/настройки серверов, роли и плейбуки, тестирование через Molecule перед CI (TeamCity). ## Что нужно реально сделать (домашний стенд) Написать Ansible-роль, разворачивающую и конфигурирующую Nginx, и протестировать её через Molecule (Docker-драйвер) — без реальных серверов, но с реальным прогоном роли и проверкой результата. ### 1. Структура ``` ansible-lab/ ├── ansible.cfg ├── inventory/ │ └── hosts.ini ├── playbook.yml └── roles/ └── nginx_deploy/ ├── defaults/main.yml ├── tasks/main.yml ├── handlers/main.yml ├── templates/nginx.conf.j2 └── molecule/ └── default/ ├── molecule.yml ├── converge.yml └── verify.yml ``` ### 2. roles/nginx_deploy/defaults/main.yml ```yaml nginx_worker_connections: 1024 nginx_server_name: lab.local ``` ### 3. roles/nginx_deploy/tasks/main.yml ```yaml - name: Установить nginx ansible.builtin.package: name: nginx state: present - name: Развернуть конфиг nginx из шаблона ansible.builtin.template: src: nginx.conf.j2 dest: /etc/nginx/nginx.conf mode: "0644" notify: reload nginx - name: Убедиться, что nginx запущен и в автозагрузке ansible.builtin.service: name: nginx state: started enabled: true ``` ### 4. roles/nginx_deploy/handlers/main.yml ```yaml - name: reload nginx ansible.builtin.service: name: nginx state: reloaded ``` ### 5. roles/nginx_deploy/templates/nginx.conf.j2 ```nginx events { worker_connections {{ nginx_worker_connections }}; } http { server { listen 80; server_name {{ nginx_server_name }}; location / { return 200 'ok'; } } } ``` ### 6. molecule/default/molecule.yml ```yaml driver: name: docker platforms: - name: nginx-instance image: geerlingguy/docker-ubuntu2204-ansible:latest pre_build_image: true provisioner: name: ansible verifier: name: ansible ``` ### 7. molecule/default/converge.yml ```yaml - name: Converge hosts: all roles: - role: nginx_deploy ``` ### 8. molecule/default/verify.yml ```yaml - name: Verify hosts: all tasks: - name: Проверить, что nginx слушает 80 порт ansible.builtin.wait_for: port: 80 timeout: 5 - name: Проверить HTTP-ответ ansible.builtin.uri: url: http://localhost/ status_code: 200 ``` ### 9. Шаги воспроизведения 1. `pip install molecule molecule-plugins[docker] ansible`. 2. `cd roles/nginx_deploy && molecule test` — это прогоняет полный цикл: create (поднять Docker-инстанс) → converge (применить роль) → idempotence (повторный прогон роли не должен ничего менять) → verify (проверки из verify.yml) → destroy. 3. Специально сломать что-то в шаблоне (например, опечатку в директиве nginx) и посмотреть, как `molecule test` падает на этапе converge или verify — это и есть демонстрация того, зачем нужен этот шаг перед CI. 4. Убедиться, что повторный прогон роли (idempotence check) не репортит изменений — если репортит, значит роль не идемпотентна, и это тоже частый вопрос на собеседовании. ### 10. Что это даёт в разговоре с интервьюером - Реальное понимание, зачем нужен Molecule: тестировать роль в изолированном контейнере до того, как она попадёт в реальную инфраструктуру через CI. - Понимание идемпотентности — краеугольного принципа Ansible. - Практика с handlers, templates, defaults — стандартной структурой роли. - Понимание, как Molecule встраивается в CI-конвейер (у меня локально `molecule test`, в TeamCity — тот же шаг, но в build step с прогоном перед деплоем). ## Нагрузка и цифры Ansible сам по себе не «нагрузочная» технология в смысле RPS/TPS — релевантная метрика тут время прогона плейбука на N хостов (параллелизм через `forks` в `ansible.cfg`). Цифры не зафиксированы отдельно — общий подход к честным цифрам масштаба (три слоя: публичные ориентиры / лабные замеры / реальные факты с работы) описан в [../../legend/CAPACITY.md](../../legend/CAPACITY.md). ## Как это ложится в легенду В реальной работе (АО ТНИИС) — 15 скриптов/ролей Ansible с управлением конфигурациями через роли и модули, тестирование в CI/CD через Molecule и TeamCity. Домашний кейс воспроизводит тот же цикл в миниатюре на одной роли вместо полного набора инфраструктурных ролей.