feat: Полная переработка документации и структуры проекта

- Переписан главный README.md с подробной навигацией
- Создана структурированная документация в docs/:
  - getting-started.md - быстрый старт
  - creating-roles.md - создание ролей
  - cicd-setup.md - настройка CI/CD
  - monitoring.md - мониторинг и диагностика
  - site-yml-guide.md - руководство по site.yml
  - molecule-guide.md - подробное руководство по Molecule
- Переписан dockerfiles/README.md с детальным описанием всех образов
- Перенесен deploy.yml из корня в roles/ для лучшей организации
- Обновлен site.yml для импорта roles/deploy.yml
- Добавлены fallback значения в create.yml для надежности
- Созданы скрипты автоматизации:
  - update-playbooks.sh - обновление playbook'ов
  - generate-role-docs.sh - генерация документации
  - setup-cicd.sh - настройка CI/CD
- Добавлен env.example с примерами переменных
- Обновлен Makefile с новыми командами автоматизации
- Улучшена навигация по документации
This commit is contained in:
Сергей Антропов
2025-10-25 18:11:36 +03:00
parent 1a4e52aab2
commit 94560ffaaa
19 changed files with 6986 additions and 270 deletions

859
docs/molecule-guide.md Normal file
View File

@@ -0,0 +1,859 @@
# Подробное руководство по файлам Molecule
**Автор:** Сергей Антропов
**Сайт:** https://devops.org.ru
## 📋 Обзор
Molecule - это инструмент для тестирования Ansible ролей в изолированных окружениях. В проекте AnsibleTemplate используется универсальная конфигурация Molecule с поддержкой множества операционных систем и различных preset'ов для тестирования.
### 🔧 Fallback значения
**Важная особенность:** Все файлы Molecule содержат fallback значения, что обеспечивает работоспособность системы даже без preset файлов. Это означает, что:
- **Система всегда работает** - даже если preset файл не найден
- **Быстрый старт** - можно запустить тестирование без настройки
- **Надежность** - меньше точек отказа в системе
- **Отладка** - легче диагностировать проблемы с preset'ами
## 🏗️ Структура файлов Molecule
```
molecule/
├── default/ # Основная конфигурация Molecule
│ ├── molecule.yml # Главный конфигурационный файл
│ ├── create.yml # Создание тестовых контейнеров
│ ├── converge.yml # Выполнение ролей в контейнерах
│ ├── verify.yml # Проверка результатов тестирования
│ ├── destroy.yml # Удаление тестовых контейнеров
│ └── site.yml # Основной playbook для тестирования
└── presets/ # Preset конфигурации для разных сценариев
├── minimal.yml # Минимальный preset (1 хост)
├── performance.yml # Performance preset (12 хостов)
├── security.yml # Security preset (10 хостов)
├── etcd-patroni.yml # etcd-patroni preset
└── ... # Другие preset'ы
```
## 📄 Детальное описание файлов
### 1. `molecule/default/molecule.yml` - Главный конфигурационный файл
**Назначение:** Основная конфигурация Molecule с настройками драйвера, платформ, provisioner'а и verifier'а.
#### Основные секции:
**Driver (Драйвер):**
```yaml
driver:
name: docker
```
- **Назначение:** Определяет использование Docker в качестве драйвера
- **Функция:** Создание и управление тестовыми контейнерами
**Platforms (Платформы):**
```yaml
platforms:
- name: placeholder
image: ghcr.io/ansible-community/molecule-ubuntu-systemd:jammy
pre_build_image: true
- name: ansible-controller
image: inecs/ansible-lab:ansible-controller-latest
pre_build_image: true
# ... другие образы
```
- **Назначение:** Определяет доступные Docker образы для тестирования
- **Поддерживаемые ОС:** Ubuntu, Debian, RHEL, CentOS, AlmaLinux, Rocky Linux, Alt Linux, Astra Linux, RedOS
- **Собственные образы:** AnsibleTemplate создает собственные образы для тестирования
**Provisioner (Провижнер):**
```yaml
provisioner:
name: ansible
config_options:
defaults:
stdout_callback: yaml
env:
ANSIBLE_STDOUT_CALLBACK: yaml
inventory:
links:
hosts: "${MOLECULE_EPHEMERAL_DIRECTORY}/inventory/hosts.ini"
playbooks:
create: create.yml
converge: converge.yml
destroy: destroy.yml
```
- **Назначение:** Настройка Ansible как provisioner'а
- **Функции:**
- Настройка вывода в YAML формате
- Связывание инвентори файла
- Определение playbook'ов для разных этапов
**Dependency (Зависимости):**
```yaml
dependency:
name: galaxy
```
- **Назначение:** Установка зависимостей через Ansible Galaxy
- **Функция:** Автоматическая установка коллекций из `requirements.yml`
**Verifier (Верификатор):**
```yaml
verifier:
name: ansible
```
- **Назначение:** Использование Ansible для проверки результатов
- **Функция:** Выполнение `verify.yml` для проверки состояния системы
**Lint (Линтер):**
```yaml
lint: |-
set -e
ansible-lint /workspace/roles/
```
- **Назначение:** Проверка синтаксиса ролей
- **Функция:** Запуск `ansible-lint` для всех ролей в директории `roles/`
### 2. `molecule/default/create.yml` - Создание тестовых контейнеров
**Назначение:** Создание и настройка тестовых контейнеров согласно выбранному preset'у с fallback значениями.
#### Переменные и конфигурация:
**Fallback значения (по умолчанию):**
```yaml
vars:
# Получаем preset из переменной окружения или используем default
preset_name: "{{ lookup('env', 'MOLECULE_PRESET') | default('default') }}"
preset_file: "/workspace/molecule/presets/{{ preset_name }}.yml"
# Fallback значения если preset файл не найден
docker_network: labnet
generated_inventory: "{{ molecule_ephemeral_directory }}/inventory/hosts.ini"
images:
alt: "inecs/ansible-lab:alt-linux-latest"
astra: "inecs/ansible-lab:astra-linux-latest"
rhel: "inecs/ansible-lab:rhel-latest"
centos: "inecs/ansible-lab:centos-latest"
alma: "inecs/ansible-lab:alma-latest"
rocky: "inecs/ansible-lab:rocky-latest"
redos: "inecs/ansible-lab:redos-latest"
ubuntu: "inecs/ansible-lab:ubuntu-latest"
debian: "inecs/ansible-lab:debian-latest"
systemd_defaults:
privileged: true
command: "/sbin/init"
volumes:
- "/sys/fs/cgroup:/sys/fs/cgroup:ro"
tmpfs: ["/run", "/run/lock"]
capabilities: ["SYS_ADMIN"]
hosts:
- name: u1
family: debian
groups: [test]
```
- **Назначение:** Определение fallback значений для случаев когда preset файл не найден
- **Функция:** Обеспечение работоспособности даже без preset файлов
- **Образы:** Собственные образы AnsibleTemplate для всех поддерживаемых ОС
- **Systemd настройки:** Стандартные настройки для systemd контейнеров
#### Основные задачи:
**Load preset configuration:**
```yaml
- name: Load preset configuration
include_vars: "{{ preset_file }}"
when: preset_file is file
ignore_errors: true
```
- **Назначение:** Загрузка конфигурации preset'а (перезаписывает fallback значения)
- **Функция:** Динамическое определение тестового окружения
- **Переменные:** `MOLECULE_PRESET` определяет какой preset использовать
- **Fallback:** Если preset файл не найден, используются значения по умолчанию
#### Преимущества fallback значений:
1. **Надежность:** Система работает даже без preset файлов
2. **Быстрый старт:** Можно запустить тестирование без настройки preset'ов
3. **Стандартизация:** Единые настройки для всех ОС
4. **Отладка:** Легче диагностировать проблемы с preset файлами
5. **Разработка:** Удобно для разработки новых preset'ов
**Ensure network exists:**
```yaml
- name: Ensure network exists
community.docker.docker_network:
name: "{{ docker_network }}"
state: present
```
- **Назначение:** Создание Docker сети для тестирования
- **Функция:** Обеспечение сетевого взаимодействия между контейнерами
- **По умолчанию:** Сеть `labnet`
**Pull systemd images:**
```yaml
- name: Pull systemd images
community.docker.docker_image:
name: "{{ images[item.family] }}"
source: pull
loop: "{{ hosts | selectattr('type','undefined') | list }}"
```
- **Назначение:** Загрузка Docker образов для systemd контейнеров
- **Функция:** Подготовка образов для создания контейнеров
- **Поддержка:** Различные семейства ОС (debian, rhel, alt, astra)
**Start systemd nodes:**
```yaml
- name: Start systemd nodes
community.docker.docker_container:
name: "{{ item.name }}"
image: "{{ images[item.family] }}"
networks:
- name: "{{ docker_network }}"
privileged: "{{ systemd_defaults.privileged }}"
command: "{{ systemd_defaults.command }}"
volumes: "{{ systemd_defaults.volumes | default([]) + (item.volumes | default([])) }}"
tmpfs: "{{ systemd_defaults.tmpfs | default([]) }}"
capabilities: "{{ systemd_defaults.capabilities | default([]) }}"
published_ports: "{{ item.publish | default([]) }}"
env: "{{ item.env | default({}) }}"
state: started
restart_policy: unless-stopped
```
- **Назначение:** Создание и запуск systemd контейнеров
- **Функции:**
- Создание контейнеров с systemd поддержкой
- Настройка привилегированного режима
- Монтирование cgroup для systemd
- Настройка tmpfs для /run
- Публикация портов
- Настройка переменных окружения
**Start DinD nodes (Docker-in-Docker):**
```yaml
- name: Start DinD nodes (docker:27-dind)
community.docker.docker_container:
name: "{{ item.name }}"
image: "docker:27-dind"
networks:
- name: "{{ docker_network }}"
privileged: true
env:
DOCKER_TLS_CERTDIR: ""
published_ports: "{{ item.publish | default([]) }}"
volumes: "{{ (item.volumes | default([])) + [item.name + '-docker:/var/lib/docker'] }}"
state: started
restart_policy: unless-stopped
```
- **Назначение:** Создание Docker-in-Docker контейнеров
- **Функции:**
- Тестирование Docker Compose
- Тестирование Dockerfile'ов
- Изолированная Docker среда
- Отдельные volumes для Docker данных
**Start DOoD nodes (Docker-out-of-Docker):**
```yaml
- name: Start DOoD nodes (systemd + docker.sock mount)
community.docker.docker_container:
name: "{{ item.name }}"
image: "{{ images[item.family] }}"
networks:
- name: "{{ docker_network }}"
privileged: "{{ systemd_defaults.privileged }}"
command: "{{ systemd_defaults.command }}"
volumes: "{{ (systemd_defaults.volumes | default([])) + ['/var/run/docker.sock:/var/run/docker.sock'] + (item.volumes | default([])) }}"
tmpfs: "{{ systemd_defaults.tmpfs | default([]) }}"
capabilities: "{{ systemd_defaults.capabilities | default([]) }}"
published_ports: "{{ item.publish | default([]) }}"
env: "{{ item.env | default({}) }}"
state: started
restart_policy: unless-stopped
```
- **Назначение:** Создание Docker-out-of-Docker контейнеров
- **Функции:**
- Доступ к Docker daemon хоста
- Тестирование Docker операций
- Комбинация systemd + Docker
**Build groups map:**
```yaml
- name: Initialize groups map
set_fact:
groups_map: {}
- name: Append hosts to groups
set_fact:
groups_map: "{{ groups_map | combine({ item_group: (groups_map[item_group] | default([])) + [item_name] }) }}"
loop: "{{ hosts | subelements('groups', skip_missing=True) }}"
```
- **Назначение:** Создание карты групп для инвентори
- **Функция:** Группировка хостов по назначению (servers, database, cache, etc.)
**Render inventory ini:**
```yaml
- name: Render inventory ini
set_fact:
inv_content: |
[all:vars]
ansible_connection=community.docker.docker
ansible_python_interpreter=/usr/bin/python3
{% for group, members in (groups_map | dictsort) %}
[{{ group }}]
{% for h in members %}{{ h }}
{% endfor %}
{% endfor %}
[all]
{% for h in hosts %}{{ h.name }}
{% endfor %}
```
- **Назначение:** Генерация инвентори файла
- **Функция:** Создание динамического инвентори для Ansible
- **Формат:** INI формат с группами и переменными
**Write inventory file:**
```yaml
- name: Write inventory file
copy:
dest: "{{ generated_inventory }}"
content: "{{ inv_content }}"
mode: "0644"
```
- **Назначение:** Сохранение инвентори файла
- **Функция:** Запись сгенерированного инвентори в файл
**Display inventory summary:**
```yaml
- name: Display inventory summary
debug:
msg: |
📋 Inventory Summary:
- Total hosts: {{ hosts | length }}
- Groups: {{ groups_map.keys() | list | join(', ') }}
- Systemd nodes: {{ hosts | selectattr('type','undefined') | list | length }}
- DinD nodes: {{ hosts | selectattr('type','defined') | selectattr('type','equalto','dind') | list | length }}
- DOoD nodes: {{ hosts | selectattr('type','defined') | selectattr('type','equalto','dood') | list | length }}
```
- **Назначение:** Отображение сводки по созданным контейнерам
- **Функция:** Информация о количестве и типах контейнеров
### 3. `molecule/default/converge.yml` - Выполнение ролей
**Назначение:** Выполнение Ansible ролей в созданных контейнерах.
#### Основные задачи:
**Load preset configuration:**
```yaml
- name: Load preset configuration
include_vars: "{{ preset_file }}"
when: preset_file is file
ignore_errors: true
```
- **Назначение:** Загрузка конфигурации preset'а
- **Функция:** Применение настроек preset'а для выполнения
**Preflight vault — normalize state:**
```yaml
- name: Preflight vault — normalize state (encrypt if plaintext, then decrypt)
community.docker.docker_container_exec:
container: ansible-controller
command: >
bash -lc '
set -euo pipefail; shopt -s nullglob globstar;
for p in {{ vault_targets | map('quote') | join(' ') }}; do
for f in $p; do
[ -f "$f" ] || continue;
if head -n1 "$f" | grep -q "^\$ANSIBLE_VAULT;"; then
echo "[vault] already encrypted: $f";
else
echo "[vault] plaintext -> encrypt: $f";
ansible-vault encrypt --encrypt-vault-id default --vault-password-file /workspace/vault/.vault "$f";
fi
echo "[vault] decrypt for run: $f";
ansible-vault decrypt --vault-password-file /workspace/vault/.vault "$f";
done
done
'
```
- **Назначение:** Подготовка vault файлов для выполнения
- **Функции:**
- Шифрование незашифрованных файлов
- Расшифровка файлов для выполнения
- Нормализация состояния vault файлов
**Run lab playbook:**
```yaml
- name: Run lab playbook
community.docker.docker_container_exec:
container: ansible-controller
command: >
bash -lc "
ANSIBLE_ROLES_PATH=/workspace/roles
ansible-playbook -i {{ lookup('env','MOLECULE_EPHEMERAL_DIRECTORY') }}/inventory/hosts.ini /workspace/molecule/default/site.yml
"
```
- **Назначение:** Выполнение основного playbook'а
- **Функции:**
- Запуск `site.yml` в ansible-controller контейнере
- Использование сгенерированного инвентори
- Установка пути к ролям
**Post-run — re-encrypt secrets:**
```yaml
- name: Post-run — re-encrypt secrets
community.docker.docker_container_exec:
container: ansible-controller
command: >
bash -lc '
set -euo pipefail; shopt -s nullglob globstar;
for p in {{ vault_targets | map('quote') | join(' ') }}; do
for f in $p; do
[ -f "$f" ] || continue;
if head -n1 "$f" | grep -q "^\$ANSIBLE_VAULT;"; then
echo "[vault] ok (encrypted): $f";
else
echo "[vault] encrypt back: $f";
ansible-vault encrypt --encrypt-vault-id default --vault-password-file /workspace/vault/.vault "$f" || true;
fi
done
done
'
ignore_errors: true
```
- **Назначение:** Повторное шифрование секретов после выполнения
- **Функция:** Обеспечение безопасности vault файлов
### 4. `molecule/default/verify.yml` - Проверка результатов
**Назначение:** Проверка состояния системы после выполнения ролей.
#### Основные задачи:
**Load preset configuration:**
```yaml
- name: Load preset configuration
include_vars: "{{ preset_file }}"
when: preset_file is file
ignore_errors: true
```
- **Назначение:** Загрузка конфигурации preset'а
- **Функция:** Применение настроек для проверки
**Check systemd nodes status:**
```yaml
- name: Check systemd nodes status
community.docker.docker_container_exec:
container: "{{ item.name }}"
command: systemctl is-system-running
loop: "{{ hosts | selectattr('type','undefined') | list }}"
register: systemd_status
ignore_errors: true
```
- **Назначение:** Проверка состояния systemd в контейнерах
- **Функция:** Убедиться что systemd работает корректно
**Check DinD nodes docker daemon:**
```yaml
- name: Check DinD nodes docker daemon
community.docker.docker_container_exec:
container: "{{ item.name }}"
command: docker version --format '{{.Server.Version}}'
loop: "{{ hosts | selectattr('type','defined') | selectattr('type','equalto','dind') | list }}"
register: dind_status
ignore_errors: true
```
- **Назначение:** Проверка Docker daemon в DinD контейнерах
- **Функция:** Убедиться что Docker работает в контейнерах
**Check DOoD nodes docker access:**
```yaml
- name: Check DOoD nodes docker access
community.docker.docker_container_exec:
container: "{{ item.name }}"
command: docker ps --format '{{.Names}}'
loop: "{{ hosts | selectattr('type','defined') | selectattr('type','equalto','dood') | list }}"
register: dood_status
ignore_errors: true
```
- **Назначение:** Проверка доступа к Docker в DOoD контейнерах
- **Функция:** Убедиться что контейнеры могут обращаться к Docker daemon
**Test network connectivity between nodes:**
```yaml
- name: Test network connectivity between nodes
community.docker.docker_container_exec:
container: "{{ item.0.name }}"
command: ping -c 1 {{ item.1.name }}
loop: "{{ hosts | subelements(hosts, 'name') }}"
when: item.0.name != item.1.name
register: ping_results
ignore_errors: true
```
- **Назначение:** Проверка сетевого взаимодействия между контейнерами
- **Функция:** Убедиться что контейнеры могут общаться друг с другом
**Check published ports:**
```yaml
- name: Check published ports
community.docker.docker_container_exec:
container: "{{ item.name }}"
command: netstat -tlnp
loop: "{{ hosts | selectattr('publish','defined') | list }}"
register: port_status
ignore_errors: true
```
- **Назначение:** Проверка опубликованных портов
- **Функция:** Убедиться что порты доступны
**Display verification summary:**
```yaml
- name: Display verification summary
debug:
msg: |
✅ Verification Summary:
- Total hosts: {{ hosts | length }}
- Systemd nodes: {{ hosts | selectattr('type','undefined') | list | length }}
- DinD nodes: {{ hosts | selectattr('type','defined') | selectattr('type','equalto','dind') | list | length }}
- DOoD nodes: {{ hosts | selectattr('type','defined') | selectattr('type','equalto','dood') | list | length }}
- Groups: {{ groups_map.keys() | list | join(', ') }}
- Network: {{ docker_network }}
```
- **Назначение:** Отображение итоговой сводки проверки
- **Функция:** Информация о состоянии всех компонентов
### 5. `molecule/default/destroy.yml` - Удаление контейнеров
**Назначение:** Очистка тестовых контейнеров и ресурсов.
#### Основные задачи:
**Load preset configuration:**
```yaml
- name: Load preset configuration
include_vars: "{{ preset_file }}"
when: preset_file is file
ignore_errors: true
```
- **Назначение:** Загрузка конфигурации preset'а
- **Функция:** Определение какие ресурсы нужно удалить
**Stop and remove containers:**
```yaml
- name: Stop and remove containers
community.docker.docker_container:
name: "{{ item.name }}"
state: absent
force_kill: true
loop: "{{ hosts }}"
ignore_errors: true
```
- **Назначение:** Остановка и удаление всех контейнеров
- **Функция:** Полная очистка тестовых контейнеров
**Remove DinD volumes:**
```yaml
- name: Remove DinD volumes
community.docker.docker_volume:
name: "{{ item.name }}-docker"
state: absent
loop: "{{ hosts | selectattr('type','defined') | selectattr('type','equalto','dind') | list }}"
ignore_errors: true
```
- **Назначение:** Удаление volumes для DinD контейнеров
- **Функция:** Очистка Docker данных
**Remove custom volumes:**
```yaml
- name: Remove custom volumes
community.docker.docker_volume:
name: "{{ item.volumes | default([]) | select('match', '^[^:]+$') | list }}"
state: absent
loop: "{{ hosts }}"
ignore_errors: true
when: item.volumes is defined
```
- **Назначение:** Удаление пользовательских volumes
- **Функция:** Очистка дополнительных volumes
**Remove network:**
```yaml
- name: Remove network
community.docker.docker_network:
name: "{{ docker_network }}"
state: absent
ignore_errors: true
```
- **Назначение:** Удаление Docker сети
- **Функция:** Очистка сетевых ресурсов
**Display cleanup summary:**
```yaml
- name: Display cleanup summary
debug:
msg: |
🧹 Cleanup Summary:
- Removed containers: {{ hosts | length }}
- Removed DinD volumes: {{ hosts | selectattr('type','defined') | selectattr('type','equalto','dind') | list | length }}
- Network: {{ docker_network }}
```
- **Назначение:** Отображение сводки по очистке
- **Функция:** Информация о удаленных ресурсах
### 6. `molecule/default/site.yml` - Основной playbook
**Назначение:** Основной playbook для тестирования ролей.
#### Структура:
**Подготовка окружения:**
- Обновление пакетов для всех ОС
- Установка common tools
- Настройка пользователей
- Создание рабочих директорий
**Импорт deploy.yml:**
```yaml
- import_playbook: ../../roles/deploy.yml
```
- **Назначение:** Импорт playbook'а с ролями
- **Функция:** Разделение логики подготовки и выполнения ролей
## 🎯 Preset файлы
### `molecule/presets/minimal.yml` - Минимальный preset
**Назначение:** Быстрое тестирование с одним хостом.
**Характеристики:**
- **Количество хостов:** 1
- **ОС:** Debian
- **Группы:** test
- **Использование:** Быстрая проверка ролей
### `molecule/presets/performance.yml` - Performance preset
**Назначение:** Нагрузочное тестирование с множеством хостов.
**Характеристики:**
- **Количество хостов:** 12
- **Серверы:** 5 узлов (web, app)
- **База данных:** 3 узла
- **Кэш:** 3 узла Redis
- **Load balancer:** 1 узел HAProxy
- **DinD:** 1 узел для Docker Compose
**Группы:**
- `servers` - веб-серверы
- `database` - базы данных
- `cache` - кэш серверы
- `loadbalancer` - балансировщик нагрузки
- `apps` - приложения
### `molecule/presets/security.yml` - Security preset
**Назначение:** Тестирование безопасности с изолированными сетями.
**Характеристики:**
- **Количество хостов:** 10
- **Bastion хосты:** 2 (точки входа)
- **Внутренние серверы:** 3
- **База данных:** 2 (изолированная сеть)
- **Мониторинг:** 2
- **Firewall:** 2
- **DOoD:** 1 для Docker безопасности
**Группы:**
- `bastion` - точки входа
- `internal` - внутренние серверы
- `database` - базы данных
- `monitoring` - мониторинг
- `firewall` - сетевые компоненты
- `security` - компоненты безопасности
## 🚀 Использование
### Базовые команды:
```bash
# Тестирование с минимальным preset'ом
make role test minimal
# Тестирование с performance preset'ом
make role test performance
# Тестирование с security preset'ом
make role test security
# Тестирование конкретной роли
make role test minimal ping
# Тестирование без preset'а (используются fallback значения)
make role test
# Тестирование с несуществующим preset'ом (используются fallback значения)
MOLECULE_PRESET=nonexistent make role test
```
### Продвинутое использование:
```bash
# Тестирование с кастомным preset'ом
MOLECULE_PRESET=custom make role test
# Отладка с подробным выводом
make role test minimal --verbose
# Проверка только создания контейнеров
molecule create -s default
# Проверка только выполнения ролей
molecule converge -s default
# Проверка только верификации
molecule verify -s default
# Очистка контейнеров
molecule destroy -s default
```
## 🔧 Настройка
### Создание собственного preset'а:
```yaml
# molecule/presets/custom.yml
---
docker_network: labnet
generated_inventory: "{{ molecule_ephemeral_directory }}/inventory/hosts.ini"
images:
ubuntu: "inecs/ansible-lab:ubuntu-latest"
rhel: "inecs/ansible-lab:rhel-latest"
systemd_defaults:
privileged: true
command: "/sbin/init"
volumes:
- "/sys/fs/cgroup:/sys/fs/cgroup:ro"
tmpfs: ["/run", "/run/lock"]
capabilities: ["SYS_ADMIN"]
hosts:
- name: web1
family: ubuntu
groups: [web, servers]
publish: ["80:80"]
- name: db1
family: rhel
groups: [database, internal]
```
### Использование fallback значений:
```bash
# Тестирование без preset'а (используются fallback значения из create.yml)
make role test
# Тестирование с несуществующим preset'ом (используются fallback значения)
MOLECULE_PRESET=nonexistent make role test
# Проверка fallback значений
molecule create -s default --debug
```
### Использование кастомного preset'а:
```bash
MOLECULE_PRESET=custom make role test
```
## 🐛 Troubleshooting
### Проблемы с контейнерами:
**Ошибка:** Контейнер не запускается
**Решение:** Проверить доступность Docker образа и ресурсы системы
**Ошибка:** Systemd не работает
**Решение:** Убедиться что контейнер запущен с `privileged: true` и правильными volumes
**Ошибка:** Сетевое взаимодействие не работает
**Решение:** Проверить создание Docker сети и настройки firewall
### Проблемы с preset файлами:
**Ошибка:** Preset файл не найден
**Решение:** Система автоматически использует fallback значения из `create.yml`
**Ошибка:** Неправильная конфигурация preset'а
**Решение:** Проверить синтаксис YAML и доступность образов в preset файле
**Ошибка:** Preset файл не загружается
**Решение:** Убедиться что файл находится в `molecule/presets/` и имеет правильное имя
### Проблемы с ролями:
**Ошибка:** Роль не найдена
**Решение:** Проверить путь к роли в `roles/deploy.yml`
**Ошибка:** Ошибка выполнения роли
**Решение:** Проверить совместимость роли с ОС и зависимости
### Проблемы с vault:
**Ошибка:** Не удается расшифровать vault файлы
**Решение:** Проверить наличие файла `.vault` и правильность пароля
**Ошибка:** Vault файлы остались расшифрованными
**Решение:** Проверить права доступа и настройки vault
## 📊 Мониторинг
### Логи выполнения:
```bash
# Просмотр логов Molecule
molecule test -s default --debug
# Логи конкретного этапа
molecule create -s default --debug
molecule converge -s default --debug
molecule verify -s default --debug
```
### Проверка состояния:
```bash
# Статус контейнеров
docker ps
# Статус сети
docker network ls
# Статус volumes
docker volume ls
```
## 🎯 Лучшие практики
1. **Используйте подходящие preset'ы** для разных типов тестирования
2. **Проверяйте совместимость ролей** с различными ОС
3. **Используйте теги** для разделения задач в ролях
4. **Документируйте зависимости** ролей
5. **Тестируйте на разных preset'ах** перед коммитом
6. **Используйте vault** для секретных данных
7. **Очищайте ресурсы** после тестирования
8. **Используйте fallback значения** для быстрого старта без preset'ов
9. **Проверяйте доступность образов** перед созданием preset'ов
10. **Документируйте кастомные preset'ы** для команды
## 🔗 Связанные файлы
- `roles/deploy.yml` - playbook с ролями
- `inventory/hosts.ini` - статический инвентори
- `vault/.vault` - пароль для vault
- `requirements.yml` - зависимости Ansible
- `Makefile` - команды для запуска тестов