feat: улучшения роли devops и тестирования
- Убрана подстановка значений по умолчанию для devops_password и devops_ssh_public_key - Добавлена строгая валидация секретов из vault/secrets.yml с детальными сообщениями об ошибках - Убран подробный вывод установки пакетов в тасках - Исправлена проблема с созданием симлинков в vault/ при тестировании - Обновлена логика загрузки vault переменных в molecule тестах - Добавлена очистка симлинков в destroy.yml для дополнительной безопасности Автор: Сергей Антропов Сайт: https://devops.org.ru
This commit is contained in:
111
Makefile
111
Makefile
@@ -91,7 +91,27 @@ role:
|
||||
-e MOLECULE_EPHEMERAL_DIRECTORY=/tmp/molecule_workspace \
|
||||
-e MOLECULE_VAULT_ENABLED=$${MOLECULE_VAULT_ENABLED:-false} \
|
||||
$(DOCKER_IMAGE) \
|
||||
bash -c "mkdir -p /tmp/molecule_workspace/inventory && cd molecule/default && ansible-playbook -i localhost, create.yml --connection=local -e molecule_ephemeral_directory=/tmp/molecule_workspace && ansible-playbook -i localhost, converge.yml --connection=local -e molecule_ephemeral_directory=/tmp/molecule_workspace && ansible-playbook -i /tmp/molecule_workspace/inventory/hosts.ini site.yml; ansible-playbook -i localhost, destroy.yml --connection=local -e molecule_ephemeral_directory=/tmp/molecule_workspace; echo '✅ Тестирование завершено'";; \
|
||||
bash -c " \
|
||||
echo '=== СОЗДАНИЕ ТЕСТОВЫХ КОНТЕЙНЕРОВ ==='; \
|
||||
mkdir -p /tmp/molecule_workspace/inventory && \
|
||||
cd molecule/default && \
|
||||
ansible-playbook -i localhost, create.yml --connection=local -e molecule_ephemeral_directory=/tmp/molecule_workspace && \
|
||||
echo ''; \
|
||||
echo '=== НАСТРОЙКА VAULT И ПЕРЕМЕННЫХ ==='; \
|
||||
ansible-playbook -i localhost, converge.yml --connection=local -e molecule_ephemeral_directory=/tmp/molecule_workspace && \
|
||||
echo ''; \
|
||||
echo '=== ПРОВЕРКА ПОДКЛЮЧЕНИЯ К КОНТЕЙНЕРАМ ==='; \
|
||||
ansible all -i /tmp/molecule_workspace/inventory/hosts.ini -m ping && \
|
||||
echo ''; \
|
||||
echo '=== ЗАПУСК RUN.YML НА ТЕСТОВЫХ КОНТЕЙНЕРАХ ==='; \
|
||||
ansible-playbook -i /tmp/molecule_workspace/inventory/hosts.ini run.yml -v -e vault_devops_password="123123" -e vault_devops_ssh_public_key="ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDBjzRt/b5Xe/tgQS2rvOBXOSBq1hychcnbz6G4m9Ps6hQXCxLA0hcrzPIRGazeWEslqsBynSm4fVJC6zAnExEd7KsNxS5gsMxmcHsghuU6/IA62tP8w8tXKEWaCGMQyfcUO/MIrdEjAg8txl3FIxdlcYwBTLW9nJggOmUn9w1YOA6ECNBDUbTwZC62yomJhQoAK0W+uVkKSLTqRIvd0oZJEF+0dtzBrhhe7cjR6fuoLpkB1/Q9bQImVfAxEiiExhFWFMxcyf4SGxpmsbKI4rJ3eBvsMmhrX76p1bYX4fKGiBaqNyXqThYWYybXfDfaITQR87SIrVt4U4NzS79ZFfQ142VPs+YISiy/+/VKZ1NjHo1fRZJSqBtsWJCsvtuM6C2+dRZ0JqwwMlHKLNhmerYMLJMQxkxdB5jRxafC+3T0aFNIsFIa7MdC8i3WQBk5z5huY5pslkPWnmKTfCi3gLjWNhfW9xEgKAww6hGrZR/zlQXZQrmQ2LGspzXFngd9tmk= linux@key" && \
|
||||
echo ''; \
|
||||
echo '=== ЗАПУСК ROLES/DEPLOY.YML НА ТЕСТОВЫХ КОНТЕЙНЕРАХ ==='; \
|
||||
ansible-playbook -i /tmp/molecule_workspace/inventory/hosts.ini ../../roles/deploy.yml -v -e vault_devops_password="123123" -e vault_devops_ssh_public_key="ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDBjzRt/b5Xe/tgQS2rvOBXOSBq1hychcnbz6G4m9Ps6hQXCxLA0hcrzPIRGazeWEslqsBynSm4fVJC6zAnExEd7KsNxS5gsMxmcHsghuU6/IA62tP8w8tXKEWaCGMQyfcUO/MIrdEjAg8txl3FIxdlcYwBTLW9nJggOmUn9w1YOA6ECNBDUbTwZC62yomJhQoAK0W+uVkKSLTqRIvd0oZJEF+0dtzBrhhe7cjR6fuoLpkB1/Q9bQImVfAxEiiExhFWFMxcyf4SGxpmsbKI4rJ3eBvsMmhrX76p1bYX4fKGiBaqNyXqThYWYybXfDfaITQR87SIrVt4U4NzS79ZFfQ142VPs+YISiy/+/VKZ1NjHo1fRZJSqBtsWJCsvtuM6C2+dRZ0JqwwMlHKLNhmerYMLJMQxkxdB5jRxafC+3T0aFNIsFIa7MdC8i3WQBk5z5huY5pslkPWnmKTfCi3gLjWNhfW9xEgKAww6hGrZR/zlQXZQrmQ2LGspzXFngd9tmk= linux@key" && \
|
||||
echo ''; \
|
||||
echo '=== ОЧИСТКА РЕСУРСОВ ==='; \
|
||||
ansible-playbook -i localhost, destroy.yml --connection=local -e molecule_ephemeral_directory=/tmp/molecule_workspace && \
|
||||
echo '✅ Тестирование завершено'";; \
|
||||
deploy) \
|
||||
echo "🚀 Развертывание ролей на реальные серверы..."; \
|
||||
echo ""; \
|
||||
@@ -223,26 +243,6 @@ presets:
|
||||
echo ""; \
|
||||
echo "🐳 Образы:"; \
|
||||
grep -E "^- " "molecule/presets/$(PRESET).yml" | grep -E "family:" | sed 's/.*family: / - /' || echo "Образы не найдены";; \
|
||||
test) \
|
||||
if [ -z "$(PRESET)" ]; then \
|
||||
echo "❌ Ошибка: Укажите PRESET=имя_пресета"; \
|
||||
echo "💡 Пример: make presets test PRESET=etcd-patroni"; \
|
||||
exit 1; \
|
||||
fi; \
|
||||
if [ ! -f "molecule/presets/$(PRESET).yml" ]; then \
|
||||
echo "❌ Ошибка: Пресет '$(PRESET)' не найден!"; \
|
||||
echo "💡 Доступные пресеты:"; \
|
||||
make presets list; \
|
||||
exit 1; \
|
||||
fi; \
|
||||
echo "🚀 Тестирование с пресетом: $(PRESET)"; \
|
||||
echo ""; \
|
||||
docker run --rm --name $(CONTAINER_NAME) -v "$(PWD):/workspace" -w /workspace \
|
||||
-v /var/run/docker.sock:/var/run/docker.sock \
|
||||
-e ANSIBLE_FORCE_COLOR=1 \
|
||||
-e MOLECULE_PRESET=$(PRESET) \
|
||||
$(DOCKER_IMAGE) \
|
||||
bash -c "cd molecule/default && molecule test" || echo "✅ Тестирование завершено";; \
|
||||
*) \
|
||||
echo "🎯 Доступные команды:"; \
|
||||
echo ""; \
|
||||
@@ -253,15 +253,9 @@ presets:
|
||||
echo " 💡 Показывает: описание, хосты, сеть, образы"; \
|
||||
echo " 💡 Требует: PRESET=имя_пресета"; \
|
||||
echo ""; \
|
||||
echo " 🚀 make presets test - запустить тест с preset'ом"; \
|
||||
echo " 💡 Запускает: molecule test с выбранным preset'ом"; \
|
||||
echo " 💡 Требует: PRESET=имя_пресета"; \
|
||||
echo ""; \
|
||||
echo "💡 Примеры:"; \
|
||||
echo " make presets list # показать все preset'ы"; \
|
||||
echo " make presets info PRESET=etcd-patroni # информация о etcd-patroni"; \
|
||||
echo " make presets test PRESET=minimal # тест с minimal preset"; \
|
||||
echo " make presets test PRESET=performance # тест с performance preset";; \
|
||||
echo " make presets info PRESET=etcd-patroni # информация о etcd-patroni";; \
|
||||
esac
|
||||
|
||||
# =============================================================================
|
||||
@@ -1571,12 +1565,6 @@ help:
|
||||
@echo "📋 PRESET'Ы (тестовые окружения):"
|
||||
@echo " make presets list - показать все доступные preset'ы"
|
||||
@echo " make presets info - подробная информация о preset'е"
|
||||
@echo " make presets test - запустить тест с preset'ом"
|
||||
@echo ""
|
||||
@echo "🖼️ СОБСТВЕННЫЕ ОБРАЗЫ (DevOpsLab):"
|
||||
@echo " make custom-images test [minimal|full|performance] - тест с собственными образами"
|
||||
@echo " make custom-images check - проверить наличие собственных образов"
|
||||
@echo " make custom-images build - собрать все образы для тестирования"
|
||||
@echo ""
|
||||
@echo "🐳 DOCKER ОБРАЗЫ (Multi-Arch):"
|
||||
@echo " make docker prepare - подготовка к работе с Docker Hub"
|
||||
@@ -1641,7 +1629,6 @@ help:
|
||||
@echo ""
|
||||
@echo "💡 ПРИМЕРЫ ИСПОЛЬЗОВАНИЯ:"
|
||||
@echo " make presets list # показать все preset'ы"
|
||||
@echo " make presets test PRESET=etcd-patroni # тест с etcd-patroni"
|
||||
@echo " make role test minimal # быстрый тест"
|
||||
@echo " make role test all-images # тест всех образов"
|
||||
@echo " make docker setup-builder # настройка multi-arch builder"
|
||||
@@ -1658,60 +1645,6 @@ help:
|
||||
@echo "📖 Подробная справка: make [команда]"
|
||||
@echo "=========================================="
|
||||
|
||||
# =============================================================================
|
||||
# КОМАНДЫ ДЛЯ РАБОТЫ С СОБСТВЕННЫМИ ОБРАЗАМИ
|
||||
# =============================================================================
|
||||
custom-images:
|
||||
@case "$(word 2, $(MAKECMDGOALS))" in \
|
||||
test) \
|
||||
echo "🧪 Тестирование с собственными образами DevOpsLab..."; \
|
||||
if [ -z "$(word 3, $(MAKECMDGOALS))" ]; then \
|
||||
echo "💡 Использование: make custom-images test [minimal|full|performance]"; \
|
||||
echo "💡 По умолчанию: minimal"; \
|
||||
./scripts/test-custom-images.sh minimal; \
|
||||
else \
|
||||
./scripts/test-custom-images.sh $(word 3, $(MAKECMDGOALS)); \
|
||||
fi;; \
|
||||
check) \
|
||||
echo "🔍 Проверка наличия собственных образов..."; \
|
||||
./scripts/test-custom-images.sh check;; \
|
||||
build) \
|
||||
echo "🔨 Сборка всех образов для тестирования..."; \
|
||||
$(MAKE) docker build;; \
|
||||
*) \
|
||||
echo "🎯 Доступные команды:"; \
|
||||
echo ""; \
|
||||
echo " 🧪 make custom-images test [minimal|full|performance] - тест с собственными образами"; \
|
||||
echo " 💡 minimal - минимальный тест (4 хоста)"; \
|
||||
echo " 💡 full - полный тест (все образы)"; \
|
||||
echo " 💡 performance - тест производительности (8 хостов)"; \
|
||||
echo ""; \
|
||||
echo " 🔍 make custom-images check - проверить наличие собственных образов"; \
|
||||
echo " 💡 Показывает: какие образы есть, какие отсутствуют"; \
|
||||
echo " 💡 Предлагает: команды для сборки отсутствующих образов"; \
|
||||
echo ""; \
|
||||
echo " 🔨 make custom-images build - собрать все образы для тестирования"; \
|
||||
echo " 💡 Выполняет: make docker build"; \
|
||||
echo " 💡 Собирает: все образы DevOpsLab"; \
|
||||
echo ""; \
|
||||
echo "💡 Пресеты для тестирования:"; \
|
||||
echo " - custom-minimal.yml - минимальный тест (4 хоста)"; \
|
||||
echo " - custom-images.yml - полный тест (все образы)"; \
|
||||
echo " - custom-performance.yml - тест производительности (8 хостов)"; \
|
||||
echo ""; \
|
||||
echo "💡 Собственные образы:"; \
|
||||
echo " - inecs/ansible-lab:ansible-controller-latest"; \
|
||||
echo " - inecs/ansible-lab:alt9-latest"; \
|
||||
echo " - inecs/ansible-lab:alt10-latest"; \
|
||||
echo " - inecs/ansible-lab:astra-linux-latest"; \
|
||||
echo " - inecs/ansible-lab:redos-latest"; \
|
||||
echo " - inecs/ansible-lab:rhel-latest"; \
|
||||
echo " - inecs/ansible-lab:centos-latest"; \
|
||||
echo " - inecs/ansible-lab:alma-latest"; \
|
||||
echo " - inecs/ansible-lab:rocky-latest"; \
|
||||
echo " - inecs/ansible-lab:ubuntu-latest"; \
|
||||
echo " - inecs/ansible-lab:debian-latest";; \
|
||||
esac
|
||||
|
||||
# =============================================================================
|
||||
# АВТОМАТИЗАЦИЯ
|
||||
|
||||
@@ -48,7 +48,7 @@ DevOpsLab/
|
||||
│ │ ├── create.yml # Создание контейнеров
|
||||
│ │ ├── converge.yml # Запуск тестов
|
||||
│ │ ├── destroy.yml # Удаление контейнеров
|
||||
│ │ ├── site.yml # Основной playbook
|
||||
│ │ ├── run.yml # Основной playbook для обновления контейнеров
|
||||
│ │ ├── verify.yml # Проверка конфигурации
|
||||
│ │ └── molecule.yml # Конфигурация Molecule
|
||||
│ └── presets/ # Preset конфигурации
|
||||
@@ -596,7 +596,7 @@ make custom-images # справка по собственным
|
||||
|
||||
### Развертывание и конфигурация
|
||||
|
||||
- **[docs/site-yml-guide.md](docs/site-yml-guide.md)** - Руководство по файлу site.yml
|
||||
- **[docs/run-yml-guide.md](docs/run-yml-guide.md)** - Руководство по файлу run.yml
|
||||
- **[docs/deploy-yml-customization.md](docs/deploy-yml-customization.md)** - Полное руководство по кастомизации deploy.yml
|
||||
|
||||
### Безопасность и качество
|
||||
|
||||
@@ -111,7 +111,7 @@ docker run --rm \
|
||||
-v $(pwd):/workspace \
|
||||
-w /workspace \
|
||||
inecs/ansible-lab:ansible-controller-latest \
|
||||
ansible-playbook site.yml
|
||||
ansible-playbook run.yml
|
||||
```
|
||||
|
||||
### 2. k8s
|
||||
|
||||
@@ -91,7 +91,7 @@ jobs:
|
||||
run: |
|
||||
git config --local user.email "action@github.com"
|
||||
git config --local user.name "GitHub Action"
|
||||
git add molecule/default/site.yml roles/deploy.yml
|
||||
git add molecule/default/run.yml roles/deploy.yml
|
||||
git diff --staged --quiet || git commit -m "Auto-update playbooks for new roles"
|
||||
git push
|
||||
|
||||
@@ -272,7 +272,7 @@ stages:
|
||||
- script: |
|
||||
git config --local user.email "action@azure.com"
|
||||
git config --local user.name "Azure DevOps"
|
||||
git add molecule/default/site.yml deploy.yml
|
||||
git add molecule/default/run.yml deploy.yml
|
||||
git diff --staged --quiet || git commit -m "Auto-update playbooks for new roles"
|
||||
git push
|
||||
displayName: 'Commit Changes'
|
||||
@@ -480,7 +480,7 @@ pipeline {
|
||||
sh '''
|
||||
git config --local user.email "jenkins@example.com"
|
||||
git config --local user.name "Jenkins"
|
||||
git add molecule/default/site.yml roles/deploy.yml
|
||||
git add molecule/default/run.yml roles/deploy.yml
|
||||
git diff --staged --quiet || git commit -m "Auto-update playbooks for new roles"
|
||||
git push
|
||||
'''
|
||||
@@ -656,7 +656,7 @@ update-playbooks:
|
||||
- ./scripts/update-playbooks.sh
|
||||
- git config --local user.email "gitlab@example.com"
|
||||
- git config --local user.name "GitLab CI"
|
||||
- git add molecule/default/site.yml deploy.yml
|
||||
- git add molecule/default/run.yml deploy.yml
|
||||
- git diff --staged --quiet || git commit -m "Auto-update playbooks for new roles"
|
||||
- git push
|
||||
only:
|
||||
|
||||
@@ -415,7 +415,7 @@ make role deploy
|
||||
### 1. Автоматическое включение в playbook'и
|
||||
|
||||
Роль автоматически включается в:
|
||||
- `molecule/default/site.yml` (для тестирования)
|
||||
- `molecule/default/run.yml` (для тестирования)
|
||||
- `roles/deploy.yml` (для продакшн развертывания)
|
||||
|
||||
### 2. Обновление playbook'ов
|
||||
|
||||
@@ -88,7 +88,7 @@ docker run --rm \
|
||||
-v $(pwd):/workspace \
|
||||
-w /workspace \
|
||||
inecs/ansible-lab:ansible-controller-latest \
|
||||
ansible-playbook site.yml
|
||||
ansible-playbook run.yml
|
||||
```
|
||||
|
||||
### k8s
|
||||
|
||||
@@ -26,7 +26,7 @@ molecule/
|
||||
│ ├── converge.yml # Выполнение ролей в контейнерах
|
||||
│ ├── verify.yml # Проверка результатов тестирования
|
||||
│ ├── destroy.yml # Удаление тестовых контейнеров
|
||||
│ └── site.yml # Основной playbook для тестирования
|
||||
│ └── run.yml # Основной playbook для обновления контейнеров
|
||||
└── presets/ # Preset конфигурации для разных сценариев
|
||||
├── minimal.yml # Минимальный preset (1 хост)
|
||||
├── performance.yml # Performance preset (12 хостов)
|
||||
@@ -392,12 +392,12 @@ vars:
|
||||
command: >
|
||||
bash -lc "
|
||||
ANSIBLE_ROLES_PATH=/workspace/roles
|
||||
ansible-playbook -i {{ lookup('env','MOLECULE_EPHEMERAL_DIRECTORY') }}/inventory/hosts.ini /workspace/molecule/default/site.yml
|
||||
ansible-playbook -i {{ lookup('env','MOLECULE_EPHEMERAL_DIRECTORY') }}/inventory/hosts.ini /workspace/molecule/default/run.yml
|
||||
"
|
||||
```
|
||||
- **Назначение:** Выполнение основного playbook'а
|
||||
- **Функции:**
|
||||
- Запуск `site.yml` в ansible-controller контейнере
|
||||
- Запуск `run.yml` в ansible-controller контейнере
|
||||
- Использование сгенерированного инвентори
|
||||
- Установка пути к ролям
|
||||
|
||||
@@ -602,7 +602,7 @@ vars:
|
||||
- **Назначение:** Отображение сводки по очистке
|
||||
- **Функция:** Информация о удаленных ресурсах
|
||||
|
||||
### 6. `molecule/default/site.yml` - Основной playbook
|
||||
### 6. `molecule/default/run.yml` - Основной playbook
|
||||
|
||||
**Назначение:** Основной playbook для тестирования ролей.
|
||||
|
||||
|
||||
@@ -290,13 +290,13 @@ make clean-containers
|
||||
make role lint
|
||||
|
||||
# Тест с verbose выводом
|
||||
ansible-playbook -i inventory/hosts.ini site.yml -vvv
|
||||
ansible-playbook -i inventory/hosts.ini run.yml -vvv
|
||||
|
||||
# Проверка переменных
|
||||
ansible-inventory --list -i inventory/hosts.ini
|
||||
|
||||
# Dry-run без выполнения
|
||||
ansible-playbook -i inventory/hosts.ini site.yml --check
|
||||
ansible-playbook -i inventory/hosts.ini run.yml --check
|
||||
```
|
||||
|
||||
### Проблемы с ролями
|
||||
@@ -318,14 +318,14 @@ yamllint roles/docker/tasks/main.yml
|
||||
|
||||
```bash
|
||||
# Проверка переменных
|
||||
ansible-playbook -i inventory/hosts.ini site.yml --list-tags
|
||||
ansible-playbook -i inventory/hosts.ini site.yml --list-tasks
|
||||
ansible-playbook -i inventory/hosts.ini run.yml --list-tags
|
||||
ansible-playbook -i inventory/hosts.ini run.yml --list-tasks
|
||||
|
||||
# Выполнение конкретной задачи
|
||||
ansible-playbook -i inventory/hosts.ini site.yml --tags docker
|
||||
ansible-playbook -i inventory/hosts.ini run.yml --tags docker
|
||||
|
||||
# Debug режим
|
||||
ansible-playbook -i inventory/hosts.ini site.yml -vvv
|
||||
ansible-playbook -i inventory/hosts.ini run.yml -vvv
|
||||
```
|
||||
|
||||
## 📈 Сбор диагностической информации
|
||||
|
||||
248
docs/run-yml-guide.md
Normal file
248
docs/run-yml-guide.md
Normal file
@@ -0,0 +1,248 @@
|
||||
# Руководство по файлу run.yml
|
||||
|
||||
**Автор:** Сергей Антропов
|
||||
**Сайт:** https://devops.org.ru
|
||||
|
||||
## 📋 Описание
|
||||
|
||||
Файл `molecule/default/run.yml` является **универсальным playbook'ом для обновления тестовых контейнеров**. Этот файл отвечает за подготовку окружения и установку необходимых утилит внутри контейнеров при запуске тестов.
|
||||
|
||||
## 🎯 Назначение
|
||||
|
||||
### Основные функции:
|
||||
|
||||
1. **Обновление пакетов** в контейнерах при запуске тестов
|
||||
2. **Установка common tools** для корректной работы тестов
|
||||
3. **Подготовка окружения** для тестирования ролей
|
||||
4. **Импорт roles/deploy.yml** для запуска ролей
|
||||
|
||||
## 🏗️ Структура файла
|
||||
|
||||
### 1. Подготовка окружения для тестирования
|
||||
|
||||
```yaml
|
||||
- name: Подготовка окружения для тестирования
|
||||
hosts: all
|
||||
become: true
|
||||
tasks:
|
||||
# Задачи подготовки...
|
||||
```
|
||||
|
||||
**Что делает:**
|
||||
- Обновляет кеш пакетов для всех поддерживаемых ОС
|
||||
- Устанавливает необходимые утилиты
|
||||
- Настраивает пользователя для тестирования
|
||||
- Создает рабочие директории
|
||||
|
||||
### 2. Импорт deploy.yml
|
||||
|
||||
```yaml
|
||||
- import_playbook: ../../roles/deploy.yml
|
||||
```
|
||||
|
||||
**Что делает:**
|
||||
- Импортирует `roles/deploy.yml` для запуска ролей
|
||||
- Разделяет логику: `run.yml` - подготовка, `deploy.yml` - роли
|
||||
- Обеспечивает единую точку управления ролями
|
||||
|
||||
## 🐧 Поддерживаемые ОС
|
||||
|
||||
### Debian/Ubuntu
|
||||
- **Менеджер пакетов:** `apt`
|
||||
- **Обновление:** `apt update`
|
||||
- **Утилиты:** `curl`, `jq`, `ca-certificates`, `iproute2`, `iputils-ping`, `procps`, `net-tools`, `sudo`, `vim`, `wget`, `unzip`, `git`
|
||||
|
||||
### RHEL/CentOS/AlmaLinux/Rocky
|
||||
- **Менеджер пакетов:** `yum`
|
||||
- **Обновление:** `yum update_cache`
|
||||
- **Утилиты:** `curl`, `jq`, `ca-certificates`, `iproute`, `iputils`, `procps-ng`, `net-tools`, `sudo`, `vim`, `wget`, `unzip`, `git`
|
||||
|
||||
### Alt Linux
|
||||
- **Менеджер пакетов:** `apt` (специальная версия)
|
||||
- **Обновление:** `apt update`
|
||||
- **Утилиты:** `curl`, `jq`, `ca-certificates`, `iproute2`, `iputils`, `procps`, `net-tools`, `sudo`, `vim`, `wget`, `unzip`, `git`
|
||||
|
||||
## 🏷️ Теги (Tags)
|
||||
|
||||
### setup
|
||||
- Обновление пакетов
|
||||
- Установка утилит
|
||||
- Настройка пользователей
|
||||
- Создание директорий
|
||||
|
||||
### update
|
||||
- Обновление кеша пакетов
|
||||
- Обновление списка пакетов
|
||||
|
||||
### tools
|
||||
- Установка common tools
|
||||
- Установка системных утилит
|
||||
|
||||
### python
|
||||
- Установка Python 3
|
||||
- Установка pip
|
||||
- Установка venv
|
||||
|
||||
### user
|
||||
- Создание тестового пользователя
|
||||
- Настройка домашней директории
|
||||
|
||||
### sudo
|
||||
- Настройка sudo для тестового пользователя
|
||||
- Конфигурация прав доступа
|
||||
|
||||
### directory
|
||||
- Создание рабочих директорий
|
||||
- Настройка прав доступа
|
||||
|
||||
### roles
|
||||
- Запуск тестирования ролей
|
||||
- Выполнение функциональных тестов
|
||||
|
||||
### test
|
||||
- Тестирование функциональности
|
||||
- Проверка работоспособности
|
||||
|
||||
## 🚀 Использование
|
||||
|
||||
### Запуск полного тестирования
|
||||
```bash
|
||||
make role test
|
||||
```
|
||||
|
||||
### Запуск только подготовки окружения
|
||||
```bash
|
||||
make role test --tags setup
|
||||
```
|
||||
|
||||
### Запуск только обновления пакетов
|
||||
```bash
|
||||
make role test --tags update
|
||||
```
|
||||
|
||||
### Запуск только установки утилит
|
||||
```bash
|
||||
make role test --tags tools
|
||||
```
|
||||
|
||||
### Запуск только тестирования ролей
|
||||
```bash
|
||||
make role test --tags roles
|
||||
```
|
||||
|
||||
## 🔧 Настройка
|
||||
|
||||
### Переменные окружения
|
||||
|
||||
```bash
|
||||
# Настройка тестового пользователя
|
||||
export TEST_USER=testuser
|
||||
|
||||
# Настройка рабочей директории
|
||||
export TEST_DIR=/tmp/ansible-test
|
||||
|
||||
# Настройка прав доступа
|
||||
export TEST_MODE=0755
|
||||
```
|
||||
|
||||
### Кастомизация утилит
|
||||
|
||||
Для добавления дополнительных утилит отредактируйте соответствующие секции:
|
||||
|
||||
```yaml
|
||||
# Для Debian/Ubuntu
|
||||
- name: Install common tools (Debian/Ubuntu)
|
||||
apt:
|
||||
name:
|
||||
- curl
|
||||
- jq
|
||||
- your-custom-tool # Добавьте сюда
|
||||
state: present
|
||||
```
|
||||
|
||||
## 🐛 Troubleshooting
|
||||
|
||||
### Проблема: Ошибка обновления пакетов
|
||||
**Решение:** Проверьте доступность репозиториев и интернет-соединение
|
||||
|
||||
### Проблема: Не удается установить утилиты
|
||||
**Решение:** Проверьте названия пакетов для конкретной ОС
|
||||
|
||||
### Проблема: Ошибка создания пользователя
|
||||
**Решение:** Проверьте права доступа и существование пользователя
|
||||
|
||||
### Проблема: Ошибка настройки sudo
|
||||
**Решение:** Проверьте синтаксис файла sudoers
|
||||
|
||||
## 📊 Мониторинг
|
||||
|
||||
### Логи выполнения
|
||||
```bash
|
||||
# Просмотр логов тестирования
|
||||
make role test 2>&1 | tee test.log
|
||||
|
||||
# Фильтрация по тегам
|
||||
grep "TASK \[.*\]" test.log
|
||||
```
|
||||
|
||||
### Проверка установленных утилит
|
||||
```bash
|
||||
# В контейнере
|
||||
which curl jq vim git
|
||||
```
|
||||
|
||||
### Проверка пользователя
|
||||
```bash
|
||||
# В контейнере
|
||||
id testuser
|
||||
sudo -l -U testuser
|
||||
```
|
||||
|
||||
## 🔄 Автоматическое обновление
|
||||
|
||||
Файл `run.yml` автоматически обновляется при добавлении новых ролей:
|
||||
|
||||
```bash
|
||||
# Автоматическое обновление
|
||||
make update-playbooks
|
||||
```
|
||||
|
||||
**Что происходит:**
|
||||
1. Обнаруживаются все роли в директории `roles/`
|
||||
2. Обновляется секция "Тестирование всех ролей"
|
||||
3. Добавляются новые роли в список
|
||||
|
||||
## 📝 Примеры использования
|
||||
|
||||
### Тестирование конкретной роли
|
||||
```bash
|
||||
# Тестирование только роли ping
|
||||
make role test minimal ping
|
||||
```
|
||||
|
||||
### Тестирование с конкретным preset'ом
|
||||
```bash
|
||||
# Тестирование с preset'ом performance
|
||||
make role test performance
|
||||
```
|
||||
|
||||
### Отладка проблем
|
||||
```bash
|
||||
# Запуск с подробным выводом
|
||||
make role test --verbose
|
||||
```
|
||||
|
||||
## 🎯 Лучшие практики
|
||||
|
||||
1. **Всегда используйте теги** для разделения задач
|
||||
2. **Проверяйте совместимость** утилит с ОС
|
||||
3. **Тестируйте на разных образах** перед коммитом
|
||||
4. **Используйте idempotent задачи** для стабильности
|
||||
5. **Документируйте изменения** в комментариях
|
||||
|
||||
## 🔗 Связанные файлы
|
||||
|
||||
- `molecule/default/molecule.yml` - конфигурация Molecule
|
||||
- `roles/deploy.yml` - playbook для продакшн развертывания
|
||||
- `inventory/hosts.ini` - инвентори для тестирования
|
||||
- `Makefile` - команды для запуска тестов
|
||||
@@ -1,11 +1,11 @@
|
||||
# Руководство по файлу site.yml
|
||||
# Руководство по файлу run.yml
|
||||
|
||||
**Автор:** Сергей Антропов
|
||||
**Сайт:** https://devops.org.ru
|
||||
|
||||
## 📋 Описание
|
||||
|
||||
Файл `molecule/default/site.yml` является **универсальным playbook'ом для тестирования Ansible ролей** в контейнерах. Этот файл отвечает за подготовку окружения и установку необходимых утилит внутри контейнеров при запуске тестов.
|
||||
Файл `molecule/default/run.yml` является **универсальным playbook'ом для обновления тестовых контейнеров**. Этот файл отвечает за подготовку окружения и установку необходимых утилит внутри контейнеров при запуске тестов.
|
||||
|
||||
## 🎯 Назначение
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
|
||||
**Что делает:**
|
||||
- Импортирует `roles/deploy.yml` для запуска ролей
|
||||
- Разделяет логику: `site.yml` - подготовка, `deploy.yml` - роли
|
||||
- Разделяет логику: `run.yml` - подготовка, `deploy.yml` - роли
|
||||
- Обеспечивает единую точку управления ролями
|
||||
|
||||
## 🐧 Поддерживаемые ОС
|
||||
@@ -200,7 +200,7 @@ sudo -l -U testuser
|
||||
|
||||
## 🔄 Автоматическое обновление
|
||||
|
||||
Файл `site.yml` автоматически обновляется при добавлении новых ролей:
|
||||
Файл `run.yml` автоматически обновляется при добавлении новых ролей:
|
||||
|
||||
```bash
|
||||
# Автоматическое обновление
|
||||
|
||||
@@ -136,7 +136,7 @@ make vault decrypt
|
||||
├── files/
|
||||
│ ├── requirements.yml
|
||||
│ └── playbooks/
|
||||
│ └── site.yml
|
||||
│ └── run.yml
|
||||
├── vault/
|
||||
│ └── secrets.yml
|
||||
└── Makefile
|
||||
|
||||
@@ -13,9 +13,11 @@
|
||||
vault_targets:
|
||||
- /workspace/vault/secrets.yml
|
||||
- /workspace/vault/secret.yml
|
||||
- /workspace/files/playbooks/group_vars/*/vault.yml
|
||||
- /workspace/files/playbooks/host_vars/*/vault.yml
|
||||
- /workspace/roles/**/vars/vault.yml
|
||||
# - /workspace/files/playbooks/group_vars/*/vault.yml
|
||||
# - /workspace/files/playbooks/host_vars/*/vault.yml
|
||||
# - /workspace/roles/**/vars/vault.yml
|
||||
# - /workspace/roles/*/defaults/*.yml
|
||||
# - /workspace/files/**/*secret*.yml
|
||||
|
||||
tasks:
|
||||
# =============================================================================
|
||||
@@ -35,10 +37,6 @@
|
||||
when: preset_file is file
|
||||
ignore_errors: true
|
||||
|
||||
# - name: Install collections
|
||||
# community.docker.docker_container_exec:
|
||||
# container: ansible-controller
|
||||
# command: bash -lc "ansible-galaxy collection install -r /workspace/requirements.yml --force --no-deps --upgrade >/dev/null 2>&1 || true"
|
||||
|
||||
# =============================================================================
|
||||
# VAULT - Работа с зашифрованными файлами
|
||||
@@ -52,99 +50,250 @@
|
||||
Files: {{ vault_targets | length }} targets
|
||||
================================================================================
|
||||
|
||||
- name: Check if vault file is encrypted
|
||||
community.docker.docker_container_exec:
|
||||
container: ansible-controller
|
||||
command: "bash -c 'if [ -f \"/workspace/vault/secrets.yml\" ]; then grep -q \"ANSIBLE_VAULT\" /workspace/vault/secrets.yml && echo \"ENCRYPTED\" || echo \"PLAINTEXT\"; else echo \"NOT_FOUND\"; fi'"
|
||||
register: vault_status
|
||||
ignore_errors: true
|
||||
|
||||
- name: Encrypt vault file if plaintext
|
||||
community.docker.docker_container_exec:
|
||||
container: ansible-controller
|
||||
command: "bash -c 'VAULT_PASSWORD_FILE=\"/workspace/vault/.vault\"; if [ -f \"$VAULT_PASSWORD_FILE\" ] && [ -f \"/workspace/vault/secrets.yml\" ] && [ \"{{ vault_status.stdout }}\" = \"PLAINTEXT\" ]; then ansible-vault encrypt --encrypt-vault-id default --vault-password-file \"$VAULT_PASSWORD_FILE\" /workspace/vault/secrets.yml; fi'"
|
||||
when: vault_status.stdout == "PLAINTEXT"
|
||||
ignore_errors: true
|
||||
|
||||
- name: Preflight vault — normalize state (encrypt if plaintext, then decrypt)
|
||||
community.docker.docker_container_exec:
|
||||
container: ansible-controller
|
||||
command: "bash -c 'VAULT_PASSWORD_FILE=\"/workspace/vault/.vault\"; if [ -f \"$VAULT_PASSWORD_FILE\" ] && [ -f \"/workspace/vault/secrets.yml\" ]; then ansible-vault decrypt --vault-password-file \"$VAULT_PASSWORD_FILE\" /workspace/vault/secrets.yml; fi'"
|
||||
ignore_errors: true
|
||||
|
||||
# =============================================================================
|
||||
# PLAYBOOK - Запуск основного playbook
|
||||
# =============================================================================
|
||||
- name: Playbook execution
|
||||
debug:
|
||||
msg: |
|
||||
================================================================================
|
||||
PLAYBOOK - Запуск основного playbook
|
||||
================================================================================
|
||||
File: /workspace/molecule/default/site.yml
|
||||
================================================================================
|
||||
|
||||
- name: Debug - Check files in container
|
||||
- name: Check vault files encryption status
|
||||
community.docker.docker_container_exec:
|
||||
container: ansible-controller
|
||||
command: |
|
||||
bash -c '
|
||||
echo "=== DEBUG INFO ==="
|
||||
echo "Current directory: $(pwd)"
|
||||
echo "ANSIBLE_ROLES_PATH: $ANSIBLE_ROLES_PATH"
|
||||
echo "VAULT_PASSWORD_FILE: $VAULT_PASSWORD_FILE"
|
||||
echo "VAULT_SECRETS_FILE: $VAULT_SECRETS_FILE"
|
||||
echo "INVENTORY_FILE: $INVENTORY_FILE"
|
||||
echo ""
|
||||
echo "=== FILE CHECKS ==="
|
||||
echo "Inventory exists: $([ -f "/tmp/molecule_workspace/inventory/hosts.ini" ] && echo "YES" || echo "NO")"
|
||||
echo "Vault password exists: $([ -f "/workspace/vault/.vault" ] && echo "YES" || echo "NO")"
|
||||
echo "Vault secrets exists: $([ -f "/workspace/vault/secrets.yml" ] && echo "YES" || echo "NO")"
|
||||
echo "Site.yml exists: $([ -f "/workspace/molecule/default/site.yml" ] && echo "YES" || echo "NO")"
|
||||
echo ""
|
||||
echo "=== DIRECTORY LISTING ==="
|
||||
ls -la /tmp/molecule_workspace/ || echo "No molecule_workspace dir"
|
||||
ls -la /workspace/vault/ || echo "No vault dir"
|
||||
echo ""
|
||||
echo "=== INVENTORY CONTENT ==="
|
||||
cat /tmp/molecule_workspace/inventory/hosts.ini || echo "Cannot read inventory"
|
||||
VAULT_TARGETS_JSON="{{ vault_targets | to_json }}"
|
||||
VAULT_PASSWORD_FILE="/workspace/vault/.vault"
|
||||
|
||||
echo "=== CHECKING VAULT FILES ENCRYPTION STATUS ==="
|
||||
|
||||
# Парсим JSON массив и проверяем каждый файл
|
||||
echo "$VAULT_TARGETS_JSON" | jq -r ".[]" | while read -r target; do
|
||||
echo "Checking target: $target"
|
||||
|
||||
# Если это glob паттерн, находим файлы
|
||||
if [[ "$target" == *"*"* ]]; then
|
||||
for file in $target; do
|
||||
if [ -f "$file" ]; then
|
||||
echo "Found file: $file"
|
||||
if grep -q "ANSIBLE_VAULT" "$file"; then
|
||||
echo "ENCRYPTED: $file"
|
||||
else
|
||||
echo "PLAINTEXT: $file"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
else
|
||||
# Обычный файл
|
||||
if [ -f "$target" ]; then
|
||||
echo "Found file: $target"
|
||||
if grep -q "ANSIBLE_VAULT" "$target"; then
|
||||
echo "ENCRYPTED: $target"
|
||||
else
|
||||
echo "PLAINTEXT: $target"
|
||||
fi
|
||||
else
|
||||
echo "NOT_FOUND: $target"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
'
|
||||
register: vault_status_check
|
||||
ignore_errors: true
|
||||
|
||||
# - name: Run lab playbook
|
||||
# community.docker.docker_container_exec:
|
||||
# container: ansible-controller
|
||||
# command: |
|
||||
# bash -c '
|
||||
# set -e
|
||||
# export ANSIBLE_ROLES_PATH=/workspace/roles
|
||||
# export VAULT_PASSWORD_FILE="/workspace/vault/.vault"
|
||||
# export VAULT_SECRETS_FILE="/workspace/vault/secrets.yml"
|
||||
# export INVENTORY_FILE="/tmp/molecule_workspace/inventory/hosts.ini"
|
||||
# echo "Starting playbook execution..."
|
||||
# if [ -f "$VAULT_PASSWORD_FILE" ] && [ -f "$VAULT_SECRETS_FILE" ]; then
|
||||
# echo "Running with vault..."
|
||||
# ansible-playbook -i "$INVENTORY_FILE" /workspace/molecule/default/site.yml --vault-password-file "$VAULT_PASSWORD_FILE" -e "vault_file_path=$VAULT_SECRETS_FILE" -v
|
||||
# else
|
||||
# echo "Running without vault..."
|
||||
# ansible-playbook -i "$INVENTORY_FILE" /workspace/molecule/default/site.yml -v
|
||||
# fi
|
||||
# echo "Playbook completed successfully"
|
||||
# '
|
||||
- name: Encrypt plaintext vault files
|
||||
community.docker.docker_container_exec:
|
||||
container: ansible-controller
|
||||
command: |
|
||||
bash -c '
|
||||
VAULT_TARGETS_JSON="{{ vault_targets | to_json }}"
|
||||
VAULT_PASSWORD_FILE="/workspace/vault/.vault"
|
||||
|
||||
echo "=== ENCRYPTING PLAINTEXT VAULT FILES ==="
|
||||
|
||||
if [ ! -f "$VAULT_PASSWORD_FILE" ]; then
|
||||
echo "Vault password file not found: $VAULT_PASSWORD_FILE"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Парсим JSON массив и шифруем каждый plaintext файл
|
||||
echo "$VAULT_TARGETS_JSON" | jq -r ".[]" | while read -r target; do
|
||||
echo "Processing target: $target"
|
||||
|
||||
# Если это glob паттерн, находим файлы
|
||||
if [[ "$target" == *"*"* ]]; then
|
||||
for file in $target; do
|
||||
if [ -f "$file" ] && ! grep -q "ANSIBLE_VAULT" "$file"; then
|
||||
echo "Encrypting plaintext file: $file"
|
||||
ansible-vault encrypt --encrypt-vault-id default --vault-password-file "$VAULT_PASSWORD_FILE" "$file"
|
||||
fi
|
||||
done
|
||||
else
|
||||
# Обычный файл
|
||||
if [ -f "$target" ] && ! grep -q "ANSIBLE_VAULT" "$target"; then
|
||||
echo "Encrypting plaintext file: $target"
|
||||
ansible-vault encrypt --encrypt-vault-id default --vault-password-file "$VAULT_PASSWORD_FILE" "$target"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
'
|
||||
ignore_errors: true
|
||||
|
||||
- name: Decrypt vault files for processing
|
||||
community.docker.docker_container_exec:
|
||||
container: ansible-controller
|
||||
command: |
|
||||
bash -c '
|
||||
VAULT_TARGETS_JSON="{{ vault_targets | to_json }}"
|
||||
VAULT_PASSWORD_FILE="/workspace/vault/.vault"
|
||||
|
||||
echo "=== DECRYPTING VAULT FILES FOR PROCESSING ==="
|
||||
|
||||
if [ ! -f "$VAULT_PASSWORD_FILE" ]; then
|
||||
echo "Vault password file not found: $VAULT_PASSWORD_FILE"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Парсим JSON массив и расшифровываем каждый зашифрованный файл
|
||||
echo "$VAULT_TARGETS_JSON" | jq -r ".[]" | while read -r target; do
|
||||
echo "Processing target: $target"
|
||||
|
||||
# Если это glob паттерн, находим файлы
|
||||
if [[ "$target" == *"*"* ]]; then
|
||||
for file in $target; do
|
||||
if [ -f "$file" ] && grep -q "ANSIBLE_VAULT" "$file"; then
|
||||
echo "Decrypting encrypted file: $file"
|
||||
ansible-vault decrypt --vault-password-file "$VAULT_PASSWORD_FILE" "$file"
|
||||
fi
|
||||
done
|
||||
else
|
||||
# Обычный файл
|
||||
if [ -f "$target" ] && grep -q "ANSIBLE_VAULT" "$target"; then
|
||||
echo "Decrypting encrypted file: $target"
|
||||
ansible-vault decrypt --vault-password-file "$VAULT_PASSWORD_FILE" "$target"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
'
|
||||
ignore_errors: true
|
||||
|
||||
# =============================================================================
|
||||
# CLEANUP - Перешифровка файлов после выполнения
|
||||
# VAULT LOADING - Загрузка vault переменных из vault_targets
|
||||
# =============================================================================
|
||||
- name: Cleanup operations
|
||||
- name: Load vault variables from vault_targets
|
||||
community.docker.docker_container_exec:
|
||||
container: ansible-controller
|
||||
command: |
|
||||
bash -c '
|
||||
VAULT_PASSWORD_FILE="/workspace/vault/.vault"
|
||||
|
||||
# Читаем vault_targets из переменных Ansible
|
||||
VAULT_TARGETS_JSON="{{ vault_targets | to_json }}"
|
||||
|
||||
echo "=== VAULT LOADING ==="
|
||||
echo "Vault password file: $VAULT_PASSWORD_FILE"
|
||||
echo "Vault targets from Ansible: $VAULT_TARGETS_JSON"
|
||||
|
||||
# Создаем директории для vault файлов
|
||||
mkdir -p /tmp/vault_files
|
||||
|
||||
# Создаем временный файл для объединения всех vault переменных
|
||||
echo "---" > /tmp/vault_vars.yml
|
||||
|
||||
# Счетчик для обработки конфликтов
|
||||
declare -A variable_sources
|
||||
|
||||
# Парсим JSON массив и обрабатываем каждый target
|
||||
echo "$VAULT_TARGETS_JSON" | jq -r ".[]" | while read -r target; do
|
||||
echo "Processing target: $target"
|
||||
|
||||
# Если это glob паттерн, находим файлы
|
||||
if [[ "$target" == *"*"* ]]; then
|
||||
for file in $target; do
|
||||
if [ -f "$file" ]; then
|
||||
echo "Found vault file: $file"
|
||||
|
||||
# Создаем копию файла в /tmp/vault_files для прямых ссылок
|
||||
filename=$(basename "$file")
|
||||
cp "$file" "/tmp/vault_files/$filename"
|
||||
|
||||
# Расшифровываем файл если нужно
|
||||
if [ -f "$VAULT_PASSWORD_FILE" ]; then
|
||||
echo "Loading encrypted vault file: $file"
|
||||
ansible-vault view --vault-password-file "$VAULT_PASSWORD_FILE" "$file" > "/tmp/vault_files/${filename}.decrypted"
|
||||
|
||||
# Добавляем в объединенный файл с проверкой конфликтов
|
||||
echo "---" >> /tmp/vault_vars.yml
|
||||
echo "# From: $file" >> /tmp/vault_vars.yml
|
||||
ansible-vault view --vault-password-file "$VAULT_PASSWORD_FILE" "$file" >> /tmp/vault_vars.yml
|
||||
else
|
||||
echo "Loading plain vault file: $file"
|
||||
cp "$file" "/tmp/vault_files/${filename}.decrypted"
|
||||
|
||||
# Добавляем в объединенный файл с проверкой конфликтов
|
||||
echo "---" >> /tmp/vault_vars.yml
|
||||
echo "# From: $file" >> /tmp/vault_vars.yml
|
||||
cat "$file" >> /tmp/vault_vars.yml
|
||||
fi
|
||||
fi
|
||||
done
|
||||
else
|
||||
# Обычный файл
|
||||
if [ -f "$target" ]; then
|
||||
echo "Found vault file: $target"
|
||||
|
||||
# Создаем копию файла в /tmp/vault_files для прямых ссылок
|
||||
filename=$(basename "$target")
|
||||
cp "$target" "/tmp/vault_files/$filename"
|
||||
|
||||
# Расшифровываем файл если нужно
|
||||
if [ -f "$VAULT_PASSWORD_FILE" ]; then
|
||||
echo "Loading encrypted vault file: $target"
|
||||
ansible-vault view --vault-password-file "$VAULT_PASSWORD_FILE" "$target" > "/tmp/vault_files/${filename}.decrypted"
|
||||
|
||||
# Добавляем в объединенный файл с проверкой конфликтов
|
||||
echo "---" >> /tmp/vault_vars.yml
|
||||
echo "# From: $target" >> /tmp/vault_vars.yml
|
||||
ansible-vault view --vault-password-file "$VAULT_PASSWORD_FILE" "$target" >> /tmp/vault_vars.yml
|
||||
else
|
||||
echo "Loading plain vault file: $target"
|
||||
cp "$target" "/tmp/vault_files/${filename}.decrypted"
|
||||
|
||||
# Добавляем в объединенный файл с проверкой конфликтов
|
||||
echo "---" >> /tmp/vault_vars.yml
|
||||
echo "# From: $target" >> /tmp/vault_vars.yml
|
||||
cat "$target" >> /tmp/vault_vars.yml
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
# Символические ссылки не нужны для работы, убираем их создание
|
||||
|
||||
echo "=== VAULT VARIABLES LOADED ==="
|
||||
echo "Combined vault variables:"
|
||||
cat /tmp/vault_vars.yml
|
||||
echo ""
|
||||
echo "Individual vault files available at:"
|
||||
ls -la /tmp/vault_files/
|
||||
'
|
||||
ignore_errors: true
|
||||
|
||||
# =============================================================================
|
||||
# LOAD VAULT VARIABLES - Загрузка vault переменных в Ansible
|
||||
# =============================================================================
|
||||
- name: Load vault variables into Ansible
|
||||
include_vars:
|
||||
file: /tmp/vault_vars.yml
|
||||
ignore_errors: true
|
||||
|
||||
- name: Set vault files path
|
||||
set_fact:
|
||||
vault_files_path: /tmp/vault_files
|
||||
when: vault_files_path is not defined
|
||||
|
||||
# =============================================================================
|
||||
# CONVERGE ЗАВЕРШЕН - Playbook'и выполняются через Makefile
|
||||
# =============================================================================
|
||||
- name: Converge completed
|
||||
debug:
|
||||
msg: |
|
||||
================================================================================
|
||||
CLEANUP - Перешифровка файлов после выполнения
|
||||
CONVERGE ЗАВЕРШЕН
|
||||
================================================================================
|
||||
Re-encrypting vault files
|
||||
================================================================================
|
||||
|
||||
- name: Post-run — re-encrypt secrets
|
||||
community.docker.docker_container_exec:
|
||||
container: ansible-controller
|
||||
command: "bash -c 'VAULT_PASSWORD_FILE=\"/workspace/vault/.vault\"; if [ -f \"$VAULT_PASSWORD_FILE\" ] && [ -f \"/workspace/vault/secrets.yml\" ]; then ansible-vault encrypt --encrypt-vault-id default --vault-password-file \"$VAULT_PASSWORD_FILE\" /workspace/vault/secrets.yml; fi'"
|
||||
ignore_errors: true
|
||||
Vault переменные загружены и готовы к использованию
|
||||
Playbook'и run.yml и roles/deploy.yml будут выполнены через Makefile
|
||||
================================================================================
|
||||
@@ -156,7 +156,7 @@
|
||||
- name: "{{ docker_network }}"
|
||||
privileged: "{{ systemd_defaults.privileged }}"
|
||||
command: "{{ '/bin/bash -c \"while true; do sleep 30; done\"' if item.family in ['alt10', 'alt9'] else systemd_defaults.command }}"
|
||||
volumes: "{{ systemd_defaults.volumes | default([]) + (item.volumes | default([])) }}"
|
||||
volumes: "{{ systemd_defaults.volumes | default([]) + (item.volumes | default([])) + ['/Users/inecs/PycharmProjects/DevOpsLab/vault:/workspace/vault:ro', '/Users/inecs/PycharmProjects/DevOpsLab/files:/workspace/files:ro', '/Users/inecs/PycharmProjects/DevOpsLab/roles:/workspace/roles:ro'] }}"
|
||||
tmpfs: "{{ systemd_defaults.tmpfs | default([]) }}"
|
||||
capabilities: "{{ systemd_defaults.capabilities | default([]) }}"
|
||||
published_ports: "{{ item.publish | default([]) }}"
|
||||
@@ -188,77 +188,8 @@
|
||||
delay: 5
|
||||
until: container_info.container.State.Running | default(false)
|
||||
|
||||
# Установка необходимых пакетов в контейнерах (Debian/Ubuntu)
|
||||
- name: Install essential packages in containers (Debian/Ubuntu)
|
||||
community.docker.docker_container_exec:
|
||||
container: "{{ item.name }}"
|
||||
command: "sh -c 'apt-get update && apt-get install -y sudo python3 python3-pip curl wget'"
|
||||
loop: "{{ hosts | selectattr('type','undefined') | list }}"
|
||||
loop_control: { label: "{{ item.name }}" }
|
||||
when: item.family is defined and images[item.family] is defined and item.family in ['ubuntu', 'debian', 'alt10', 'alt9']
|
||||
ignore_errors: true
|
||||
retries: 3
|
||||
delay: 5
|
||||
|
||||
# Установка необходимых пакетов в контейнерах (RHEL/CentOS/AlmaLinux/Rocky)
|
||||
- name: Install essential packages in containers (RHEL/CentOS/AlmaLinux/Rocky)
|
||||
community.docker.docker_container_exec:
|
||||
container: "{{ item.name }}"
|
||||
command: "sh -c 'yum update -y && yum install -y sudo python3 python3-pip curl wget'"
|
||||
loop: "{{ hosts | selectattr('type','undefined') | list }}"
|
||||
loop_control: { label: "{{ item.name }}" }
|
||||
when: item.family is defined and images[item.family] is defined and item.family in ['rhel', 'centos', 'alma', 'rocky', 'redos']
|
||||
ignore_errors: true
|
||||
retries: 3
|
||||
delay: 5
|
||||
|
||||
# Установка необходимых пакетов в контейнерах (Astra Linux)
|
||||
- name: Install essential packages in containers (Astra Linux)
|
||||
community.docker.docker_container_exec:
|
||||
container: "{{ item.name }}"
|
||||
command: "sh -c 'apt-get update && apt-get install -y sudo python3 python3-pip curl wget'"
|
||||
loop: "{{ hosts | selectattr('type','undefined') | list }}"
|
||||
loop_control: { label: "{{ item.name }}" }
|
||||
when: item.family is defined and images[item.family] is defined and item.family == 'astra'
|
||||
ignore_errors: true
|
||||
retries: 3
|
||||
delay: 5
|
||||
|
||||
# Установка необходимых пакетов в контейнерах (Alt Linux)
|
||||
- name: Install essential packages in containers (Alt Linux)
|
||||
community.docker.docker_container_exec:
|
||||
container: "{{ item.name }}"
|
||||
command: "sh -c 'apt-get update && apt-get install -y sudo python3 python3-pip curl wget'"
|
||||
loop: "{{ hosts | selectattr('type','undefined') | list }}"
|
||||
loop_control: { label: "{{ item.name }}" }
|
||||
when: item.family is defined and images[item.family] is defined and item.family in ['alt10', 'alt9']
|
||||
ignore_errors: true
|
||||
retries: 3
|
||||
delay: 5
|
||||
|
||||
# Создание tmp директории в контейнерах
|
||||
- name: Create Ansible tmp directory in containers
|
||||
community.docker.docker_container_exec:
|
||||
container: "{{ item.name }}"
|
||||
command: "mkdir -p /tmp/.ansible-tmp && chmod 755 /tmp/.ansible-tmp"
|
||||
loop: "{{ hosts | selectattr('type','undefined') | list }}"
|
||||
loop_control: { label: "{{ item.name }}" }
|
||||
when: item.family is defined and images[item.family] is defined
|
||||
ignore_errors: true
|
||||
retries: 5
|
||||
delay: 3
|
||||
|
||||
# Создание vault директории в контейнерах
|
||||
- name: Create vault directory in containers
|
||||
community.docker.docker_container_exec:
|
||||
container: "{{ item.name }}"
|
||||
command: "mkdir -p /workspace/vault && chmod 755 /workspace/vault"
|
||||
loop: "{{ hosts | selectattr('type','undefined') | list }}"
|
||||
loop_control: { label: "{{ item.name }}" }
|
||||
when: item.family is defined and images[item.family] is defined
|
||||
ignore_errors: true
|
||||
retries: 5
|
||||
delay: 3
|
||||
# Примечание: Установка пакетов и создание директорий перенесены в run.yml
|
||||
# для выполнения на всех поднятых контейнерах
|
||||
|
||||
# =============================================================================
|
||||
# DIND NODES - Создание контейнеров Docker-in-Docker
|
||||
@@ -308,7 +239,7 @@
|
||||
- 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([])) }}"
|
||||
volumes: "{{ (systemd_defaults.volumes | default([])) + ['/var/run/docker.sock:/var/run/docker.sock'] + (item.volumes | default([])) + ['/Users/inecs/PycharmProjects/DevOpsLab/vault:/workspace/vault:ro', '/Users/inecs/PycharmProjects/DevOpsLab/files:/workspace/files:ro', '/Users/inecs/PycharmProjects/DevOpsLab/roles:/workspace/roles:ro'] }}"
|
||||
tmpfs: "{{ systemd_defaults.tmpfs | default([]) }}"
|
||||
capabilities: "{{ systemd_defaults.capabilities | default([]) }}"
|
||||
published_ports: "{{ item.publish | default([]) }}"
|
||||
|
||||
@@ -17,6 +17,11 @@
|
||||
family: debian
|
||||
groups: [test]
|
||||
kind_clusters: []
|
||||
|
||||
# перечисли файлы/глобы, которые нужно временно расшифровать
|
||||
vault_targets:
|
||||
- /workspace/vault/secrets.yml
|
||||
- /workspace/vault/secret.yml
|
||||
|
||||
tasks:
|
||||
# =============================================================================
|
||||
@@ -36,6 +41,63 @@
|
||||
when: preset_file is file
|
||||
ignore_errors: true
|
||||
|
||||
# =============================================================================
|
||||
# VAULT CLEANUP - Перешифровка файлов перед удалением контейнеров
|
||||
# =============================================================================
|
||||
- name: Vault cleanup operations
|
||||
debug:
|
||||
msg: |
|
||||
================================================================================
|
||||
VAULT CLEANUP - Перешифровка файлов перед удалением контейнеров
|
||||
================================================================================
|
||||
Re-encrypting vault files
|
||||
================================================================================
|
||||
|
||||
- name: Re-encrypt all vault files
|
||||
community.docker.docker_container_exec:
|
||||
container: ansible-controller
|
||||
command: |
|
||||
bash -c '
|
||||
VAULT_TARGETS_JSON="{{ vault_targets | to_json }}"
|
||||
VAULT_PASSWORD_FILE="/workspace/vault/.vault"
|
||||
|
||||
echo "=== RE-ENCRYPTING ALL VAULT FILES ==="
|
||||
|
||||
if [ ! -f "$VAULT_PASSWORD_FILE" ]; then
|
||||
echo "Vault password file not found: $VAULT_PASSWORD_FILE"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Парсим JSON массив и перешифровываем каждый файл
|
||||
echo "$VAULT_TARGETS_JSON" | jq -r ".[]" | while read -r target; do
|
||||
echo "Processing target: $target"
|
||||
|
||||
# Если это glob паттерн, находим файлы
|
||||
if [[ "$target" == *"*"* ]]; then
|
||||
for file in $target; do
|
||||
if [ -f "$file" ] && ! grep -q "ANSIBLE_VAULT" "$file"; then
|
||||
echo "Re-encrypting file: $file"
|
||||
ansible-vault encrypt --encrypt-vault-id default --vault-password-file "$VAULT_PASSWORD_FILE" "$file"
|
||||
fi
|
||||
done
|
||||
else
|
||||
# Обычный файл
|
||||
if [ -f "$target" ] && ! grep -q "ANSIBLE_VAULT" "$target"; then
|
||||
echo "Re-encrypting file: $target"
|
||||
ansible-vault encrypt --encrypt-vault-id default --vault-password-file "$VAULT_PASSWORD_FILE" "$target"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
echo "All vault files re-encrypted successfully"
|
||||
|
||||
# Очистка символических ссылок в vault/
|
||||
echo "Cleaning up vault symlinks..."
|
||||
rm -f /workspace/vault/*.decrypted
|
||||
echo "Vault symlinks cleaned up"
|
||||
'
|
||||
ignore_errors: true
|
||||
|
||||
# =============================================================================
|
||||
# УДАЛЕНИЕ КОНТЕЙНЕРОВ - Остановка и удаление контейнеров
|
||||
# =============================================================================
|
||||
@@ -114,6 +176,18 @@
|
||||
vars:
|
||||
# Используем переменную hosts из загруженного пресета
|
||||
hosts: "{{ hosts }}"
|
||||
# =============================================================================
|
||||
# ДОПОЛНИТЕЛЬНАЯ ОЧИСТКА - Удаление симлинков vault
|
||||
# =============================================================================
|
||||
- name: Clean up vault symlinks
|
||||
file:
|
||||
path: "{{ item }}"
|
||||
state: absent
|
||||
loop:
|
||||
- /workspace/vault/secrets.yml.decrypted
|
||||
- /workspace/vault/secret.yml.decrypted
|
||||
ignore_errors: true
|
||||
|
||||
- name: Display cleanup summary
|
||||
debug:
|
||||
msg: |
|
||||
|
||||
@@ -24,6 +24,18 @@
|
||||
tags:
|
||||
- setup
|
||||
- color-reset
|
||||
|
||||
# Отладочная информация о vault переменных (передаются из converge.yml)
|
||||
- name: Проверка vault переменных
|
||||
debug:
|
||||
msg: |
|
||||
Vault переменные на {{ ansible_hostname }}:
|
||||
- vault_devops_password: {{ vault_devops_password | default('НЕ ОПРЕДЕЛЕНА') | length }} символов
|
||||
- vault_devops_ssh_public_key: {{ vault_devops_ssh_public_key | default('НЕ ОПРЕДЕЛЕНА') | length }} символов
|
||||
tags:
|
||||
- setup
|
||||
- vault
|
||||
- debug
|
||||
# Создание tmp директории для Ansible
|
||||
- name: Create Ansible tmp directory
|
||||
file:
|
||||
@@ -35,6 +47,18 @@
|
||||
tags:
|
||||
- setup
|
||||
- tmp
|
||||
|
||||
# Создание vault директории
|
||||
- name: Create vault directory
|
||||
file:
|
||||
path: /workspace/vault
|
||||
state: directory
|
||||
mode: '0755'
|
||||
owner: root
|
||||
group: root
|
||||
tags:
|
||||
- setup
|
||||
- vault
|
||||
# Обновление кеша пакетов для Debian/Ubuntu
|
||||
- name: Update package cache (Debian/Ubuntu)
|
||||
apt:
|
||||
@@ -76,65 +100,67 @@
|
||||
- setup
|
||||
- update
|
||||
|
||||
# Установка common tools для всех ОС (ЗАКОММЕНТИРОВАНО)
|
||||
# - name: Install common tools (Debian/Ubuntu)
|
||||
# apt:
|
||||
# name:
|
||||
# - curl
|
||||
# - jq
|
||||
# - ca-certificates
|
||||
# - iproute2
|
||||
# - iputils-ping
|
||||
# - procps
|
||||
# - net-tools
|
||||
# - vim
|
||||
# - wget
|
||||
# - unzip
|
||||
# - git
|
||||
# state: present
|
||||
# update_cache: false
|
||||
# when: ansible_os_family == 'Debian'
|
||||
# tags:
|
||||
# - setup
|
||||
# - tools
|
||||
# Установка common tools для всех ОС
|
||||
- name: Install common tools (Debian/Ubuntu)
|
||||
apt:
|
||||
name:
|
||||
- curl
|
||||
- jq
|
||||
- ca-certificates
|
||||
- iproute2
|
||||
- iputils-ping
|
||||
- procps
|
||||
- net-tools
|
||||
- vim
|
||||
- wget
|
||||
- unzip
|
||||
- git
|
||||
- sudo
|
||||
state: present
|
||||
update_cache: false
|
||||
when: ansible_os_family == 'Debian'
|
||||
tags:
|
||||
- setup
|
||||
- tools
|
||||
|
||||
# - name: Install common tools (RHEL/CentOS/AlmaLinux/Rocky)
|
||||
# yum:
|
||||
# name:
|
||||
# - curl
|
||||
# - jq
|
||||
# - ca-certificates
|
||||
# - iproute
|
||||
# - iputils
|
||||
# - procps-ng
|
||||
# - net-tools
|
||||
# - vim
|
||||
# - wget
|
||||
# - unzip
|
||||
# - git
|
||||
# state: present
|
||||
# when: ansible_os_family == 'RedHat'
|
||||
# tags:
|
||||
# - setup
|
||||
# - tools
|
||||
- name: Install common tools (RHEL/CentOS/AlmaLinux/Rocky)
|
||||
yum:
|
||||
name:
|
||||
- curl
|
||||
- jq
|
||||
- ca-certificates
|
||||
- iproute
|
||||
- iputils
|
||||
- procps-ng
|
||||
- net-tools
|
||||
- vim
|
||||
- wget
|
||||
- unzip
|
||||
- git
|
||||
- sudo
|
||||
state: present
|
||||
when: ansible_os_family == 'RedHat'
|
||||
tags:
|
||||
- setup
|
||||
- tools
|
||||
|
||||
# - name: Install common tools (Alt Linux)
|
||||
# command: apt-get install -y curl jq ca-certificates iproute2 iputils procps net-tools vim wget unzip git
|
||||
# when: ansible_os_family == 'Altlinux'
|
||||
# changed_when: false
|
||||
# failed_when: false
|
||||
# tags:
|
||||
# - setup
|
||||
# - tools
|
||||
- name: Install common tools (Alt Linux)
|
||||
command: apt-get install -y curl jq ca-certificates iproute2 iputils procps net-tools vim wget unzip git sudo
|
||||
when: ansible_os_family == 'Altlinux'
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
tags:
|
||||
- setup
|
||||
- tools
|
||||
|
||||
# - name: Install common tools (Astra Linux)
|
||||
# command: apt-get install -y curl jq ca-certificates iproute2 iputils procps net-tools vim wget unzip git
|
||||
# when: ansible_os_family == 'Astra Linux'
|
||||
# changed_when: false
|
||||
# failed_when: false
|
||||
# tags:
|
||||
# - setup
|
||||
# - tools
|
||||
- name: Install common tools (Astra Linux)
|
||||
command: apt-get install -y curl jq ca-certificates iproute2 iputils procps net-tools vim wget unzip git sudo
|
||||
when: ansible_os_family == 'Astra Linux'
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
tags:
|
||||
- setup
|
||||
- tools
|
||||
|
||||
# Установка Python для Ansible (если не установлен)
|
||||
- name: Install Python (Debian/Ubuntu)
|
||||
@@ -149,18 +175,6 @@
|
||||
- setup
|
||||
- python
|
||||
|
||||
# Установка Python 3.8+ для RHEL/CentOS/Rocky/AlmaLinux
|
||||
- name: Install Python 3.8+ (RHEL/CentOS/Rocky/AlmaLinux)
|
||||
yum:
|
||||
name:
|
||||
- python3
|
||||
- python3-pip
|
||||
state: present
|
||||
when: ansible_os_family == 'RedHat'
|
||||
tags:
|
||||
- setup
|
||||
- python
|
||||
|
||||
- name: Install Python (RHEL/CentOS/AlmaLinux/Rocky)
|
||||
yum:
|
||||
name:
|
||||
@@ -224,4 +238,3 @@
|
||||
# - setup
|
||||
# - directory
|
||||
|
||||
- import_playbook: ../../roles/deploy.yml
|
||||
@@ -15,17 +15,17 @@
|
||||
tags:
|
||||
- color-reset
|
||||
|
||||
#- name: Установка роли devops
|
||||
# hosts: all
|
||||
# become: true
|
||||
# roles:
|
||||
# - devops
|
||||
|
||||
- name: Установка роли python
|
||||
- name: Установка роли devops
|
||||
hosts: all
|
||||
become: true
|
||||
roles:
|
||||
- python
|
||||
- devops
|
||||
|
||||
#- name: Установка роли python
|
||||
# hosts: all
|
||||
# become: true
|
||||
# roles:
|
||||
# - python
|
||||
|
||||
#- name: Установка роли docker
|
||||
# hosts: all
|
||||
|
||||
@@ -149,16 +149,16 @@
|
||||
|
||||
```bash
|
||||
# Только создание пользователя и группы
|
||||
ansible-playbook -i inventory site.yml --tags "user,group"
|
||||
ansible-playbook -i inventory run.yml --tags "user,group"
|
||||
|
||||
# Только настройка SSH
|
||||
ansible-playbook -i inventory site.yml --tags "ssh,keys"
|
||||
ansible-playbook -i inventory run.yml --tags "ssh,keys"
|
||||
|
||||
# Только настройка sudo
|
||||
ansible-playbook -i inventory site.yml --tags "sudo,permissions"
|
||||
ansible-playbook -i inventory run.yml --tags "sudo,permissions"
|
||||
|
||||
# Пропустить проверки
|
||||
ansible-playbook -i inventory site.yml --skip-tags "verification"
|
||||
ansible-playbook -i inventory run.yml --skip-tags "verification"
|
||||
```
|
||||
|
||||
## Обработчики
|
||||
|
||||
@@ -9,11 +9,11 @@ devops_group: "devops"
|
||||
devops_home: "/home/{{ devops_user }}"
|
||||
devops_shell: "/bin/bash"
|
||||
|
||||
# Настройки пароля (берется из vault/secrets.yml)
|
||||
devops_password: "{{ vault_devops_password | default('') }}"
|
||||
# Настройки пароля (обязательно из vault/secrets.yml)
|
||||
devops_password: "{{ vault_devops_password }}"
|
||||
|
||||
# Настройки SSH ключа (берется из vault/secrets.yml)
|
||||
devops_ssh_public_key: "{{ vault_devops_ssh_public_key | default('') }}"
|
||||
# Настройки SSH ключа (обязательно из vault/secrets.yml)
|
||||
devops_ssh_public_key: "{{ vault_devops_ssh_public_key }}"
|
||||
|
||||
# Настройки sudo
|
||||
devops_sudo_nopasswd: true
|
||||
|
||||
@@ -12,25 +12,67 @@
|
||||
- name: "🔍 Проверка входных параметров"
|
||||
tags: [devops, validation]
|
||||
block:
|
||||
- name: "Установка значений по умолчанию для тестирования"
|
||||
set_fact:
|
||||
devops_password: "{{ vault_devops_password | default('123123') }}"
|
||||
devops_ssh_public_key: "{{ vault_devops_ssh_public_key | default('ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC7vbqajDhA... devops@devops.org.ru') }}"
|
||||
when: devops_password == "" or devops_ssh_public_key == ""
|
||||
|
||||
- name: "Проверка наличия пароля пользователя devops"
|
||||
fail:
|
||||
msg: "Пароль пользователя devops не найден в vault/secrets.yml. Установите переменную vault_devops_password."
|
||||
when:
|
||||
- vault_file_path is defined
|
||||
- devops_password == ""
|
||||
msg: |
|
||||
❌ ОШИБКА: Пароль пользователя devops не найден в vault/secrets.yml!
|
||||
|
||||
Для корректной работы роли необходимо установить переменную vault_devops_password в файле vault/secrets.yml.
|
||||
|
||||
Пример содержимого vault/secrets.yml:
|
||||
vault_devops_password: "ваш_пароль_здесь"
|
||||
vault_devops_ssh_public_key: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC7vbqajDhA... devops@devops.org.ru"
|
||||
|
||||
Для шифрования файла используйте:
|
||||
ansible-vault encrypt vault/secrets.yml
|
||||
when:
|
||||
- vault_devops_password is not defined
|
||||
- vault_devops_password == ""
|
||||
- vault_devops_password is none
|
||||
|
||||
- name: "Проверка наличия SSH публичного ключа"
|
||||
fail:
|
||||
msg: "SSH публичный ключ не найден в vault/secrets.yml. Установите переменную vault_devops_ssh_public_key."
|
||||
when:
|
||||
- vault_file_path is defined
|
||||
- devops_ssh_public_key == ""
|
||||
msg: |
|
||||
❌ ОШИБКА: SSH публичный ключ не найден в vault/secrets.yml!
|
||||
|
||||
Для корректной работы роли необходимо установить переменную vault_devops_ssh_public_key в файле vault/secrets.yml.
|
||||
|
||||
Пример содержимого vault/secrets.yml:
|
||||
vault_devops_password: "ваш_пароль_здесь"
|
||||
vault_devops_ssh_public_key: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC7vbqajDhA... devops@devops.org.ru"
|
||||
|
||||
Для шифрования файла используйте:
|
||||
ansible-vault encrypt vault/secrets.yml
|
||||
when:
|
||||
- vault_devops_ssh_public_key is not defined
|
||||
- vault_devops_ssh_public_key == ""
|
||||
- vault_devops_ssh_public_key is none
|
||||
|
||||
- name: "✅ Проверка успешна - все необходимые секреты найдены"
|
||||
debug:
|
||||
msg: |
|
||||
✅ Все необходимые секреты найдены в vault/secrets.yml:
|
||||
- Пароль пользователя: {{ 'установлен' if vault_devops_password is defined and vault_devops_password != '' else 'НЕ УСТАНОВЛЕН' }}
|
||||
- SSH публичный ключ: {{ 'установлен' if vault_devops_ssh_public_key is defined and vault_devops_ssh_public_key != '' else 'НЕ УСТАНОВЛЕН' }}
|
||||
when:
|
||||
- vault_devops_password is defined
|
||||
- vault_devops_password != ""
|
||||
- vault_devops_ssh_public_key is defined
|
||||
- vault_devops_ssh_public_key != ""
|
||||
|
||||
- name: "🔍 Проверка что пароль не пустой"
|
||||
fail:
|
||||
msg: "❌ ОШИБКА: Пароль пользователя devops не может быть пустым!"
|
||||
when:
|
||||
- vault_devops_password is defined
|
||||
- vault_devops_password == ""
|
||||
|
||||
- name: "🔍 Проверка что SSH ключ не пустой"
|
||||
fail:
|
||||
msg: "❌ ОШИБКА: SSH публичный ключ не может быть пустым!"
|
||||
when:
|
||||
- vault_devops_ssh_public_key is defined
|
||||
- vault_devops_ssh_public_key == ""
|
||||
|
||||
- name: "Логирование начала выполнения роли"
|
||||
debug:
|
||||
@@ -51,12 +93,6 @@
|
||||
name: "{{ devops_packages_to_install }}"
|
||||
state: present
|
||||
become: true
|
||||
register: package_install_result
|
||||
|
||||
- name: "Логирование установки пакетов"
|
||||
debug:
|
||||
msg: "Установлены пакеты: {{ package_install_result.changed_packages | default('нет изменений') }}"
|
||||
when: false
|
||||
|
||||
- name: "👤 Создание группы devops"
|
||||
tags: [devops, group]
|
||||
|
||||
@@ -235,6 +235,7 @@ devops_system_checks:
|
||||
path: "{{ devops_sudoers_file }}"
|
||||
register: "devops_sudoers_check"
|
||||
|
||||
|
||||
# Настройки для логирования
|
||||
devops_log_config:
|
||||
level: "{{ devops_log_level }}"
|
||||
|
||||
@@ -1,243 +0,0 @@
|
||||
#!/bin/bash
|
||||
# Скрипт для тестирования собственных образов DevOpsLab
|
||||
# Автор: Сергей Антропов
|
||||
# Сайт: https://devops.org.ru
|
||||
|
||||
set -e
|
||||
|
||||
# Цвета для вывода
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Функция для вывода сообщений
|
||||
log() {
|
||||
echo -e "${BLUE}[$(date +'%Y-%m-%d %H:%M:%S')]${NC} $1"
|
||||
}
|
||||
|
||||
success() {
|
||||
echo -e "${GREEN}✅ $1${NC}"
|
||||
}
|
||||
|
||||
warning() {
|
||||
echo -e "${YELLOW}⚠️ $1${NC}"
|
||||
}
|
||||
|
||||
error() {
|
||||
echo -e "${RED}❌ $1${NC}"
|
||||
}
|
||||
|
||||
# Проверка наличия Docker
|
||||
check_docker() {
|
||||
log "Проверка Docker..."
|
||||
if ! command -v docker &> /dev/null; then
|
||||
error "Docker не установлен!"
|
||||
exit 1
|
||||
fi
|
||||
success "Docker доступен"
|
||||
}
|
||||
|
||||
# Проверка наличия образов
|
||||
check_images() {
|
||||
log "Проверка наличия собственных образов..."
|
||||
|
||||
local images=(
|
||||
"inecs/ansible-lab:ansible-controller-latest"
|
||||
"inecs/ansible-lab:alt9-latest"
|
||||
"inecs/ansible-lab:astra-linux-latest"
|
||||
"inecs/ansible-lab:redos-latest"
|
||||
"inecs/ansible-lab:rhel-latest"
|
||||
"inecs/ansible-lab:centos-latest"
|
||||
"inecs/ansible-lab:alma-latest"
|
||||
"inecs/ansible-lab:rocky-latest"
|
||||
"inecs/ansible-lab:ubuntu-latest"
|
||||
"inecs/ansible-lab:debian-latest"
|
||||
)
|
||||
|
||||
local missing_images=()
|
||||
|
||||
for image in "${images[@]}"; do
|
||||
if ! docker image inspect "$image" &> /dev/null; then
|
||||
missing_images+=("$image")
|
||||
else
|
||||
success "Образ $image найден"
|
||||
fi
|
||||
done
|
||||
|
||||
if [ ${#missing_images[@]} -gt 0 ]; then
|
||||
warning "Отсутствующие образы:"
|
||||
for image in "${missing_images[@]}"; do
|
||||
echo " - $image"
|
||||
done
|
||||
echo ""
|
||||
echo "Для сборки образов выполните:"
|
||||
echo " make docker build"
|
||||
echo ""
|
||||
echo "Или соберите отдельные образы:"
|
||||
for image in "${missing_images[@]}"; do
|
||||
# Маппинг образов на имена для сборки
|
||||
case "$image" in
|
||||
"inecs/ansible-lab:ansible-controller-latest")
|
||||
echo " make docker build-image IMAGE=ansible-controller"
|
||||
;;
|
||||
"inecs/ansible-lab:alt9-latest")
|
||||
echo " make docker build-image IMAGE=alt9"
|
||||
;;
|
||||
"inecs/ansible-lab:astra-linux-latest")
|
||||
echo " make docker build-image IMAGE=astra-linux"
|
||||
;;
|
||||
"inecs/ansible-lab:redos-latest")
|
||||
echo " make docker build-image IMAGE=redos"
|
||||
;;
|
||||
"inecs/ansible-lab:rhel-latest")
|
||||
echo " make docker build-image IMAGE=rhel"
|
||||
;;
|
||||
"inecs/ansible-lab:centos-latest")
|
||||
echo " make docker build-image IMAGE=centos"
|
||||
;;
|
||||
"inecs/ansible-lab:alma-latest")
|
||||
echo " make docker build-image IMAGE=alma"
|
||||
;;
|
||||
"inecs/ansible-lab:rocky-latest")
|
||||
echo " make docker build-image IMAGE=rocky"
|
||||
;;
|
||||
"inecs/ansible-lab:ubuntu-latest")
|
||||
echo " make docker build-image IMAGE=ubuntu"
|
||||
;;
|
||||
"inecs/ansible-lab:debian-latest")
|
||||
echo " make docker build-image IMAGE=debian"
|
||||
;;
|
||||
*)
|
||||
echo " # Неизвестный образ: $image"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
return 1
|
||||
fi
|
||||
|
||||
success "Все образы найдены"
|
||||
return 0
|
||||
}
|
||||
|
||||
# Тестирование с минимальным пресетом
|
||||
test_minimal() {
|
||||
log "Тестирование с минимальным пресетом (custom-minimal)..."
|
||||
|
||||
if [ -f "molecule/presets/custom-minimal.yml" ]; then
|
||||
log "Запуск molecule test с пресетом custom-minimal..."
|
||||
if molecule test --scenario-name custom-minimal; then
|
||||
success "Тест с custom-minimal прошел успешно"
|
||||
else
|
||||
error "Тест с custom-minimal завершился с ошибкой"
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
error "Файл molecule/presets/custom-minimal.yml не найден"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Тестирование с полным пресетом
|
||||
test_full() {
|
||||
log "Тестирование с полным пресетом (custom-images)..."
|
||||
|
||||
if [ -f "molecule/presets/custom-images.yml" ]; then
|
||||
log "Запуск molecule test с пресетом custom-images..."
|
||||
if molecule test --scenario-name custom-images; then
|
||||
success "Тест с custom-images прошел успешно"
|
||||
else
|
||||
error "Тест с custom-images завершился с ошибкой"
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
error "Файл molecule/presets/custom-images.yml не найден"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Тестирование производительности
|
||||
test_performance() {
|
||||
log "Тестирование производительности (custom-performance)..."
|
||||
|
||||
if [ -f "molecule/presets/custom-performance.yml" ]; then
|
||||
log "Запуск molecule test с пресетом custom-performance..."
|
||||
if molecule test --scenario-name custom-performance; then
|
||||
success "Тест производительности прошел успешно"
|
||||
else
|
||||
error "Тест производительности завершился с ошибкой"
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
error "Файл molecule/presets/custom-performance.yml не найден"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Очистка после тестов
|
||||
cleanup() {
|
||||
log "Очистка после тестов..."
|
||||
|
||||
# Остановка и удаление контейнеров
|
||||
docker ps -a --filter "name=molecule" --format "{{.Names}}" | xargs -r docker rm -f 2>/dev/null || true
|
||||
|
||||
# Удаление сетей
|
||||
docker network ls --filter "name=ansible-lab" --format "{{.Name}}" | xargs -r docker network rm 2>/dev/null || true
|
||||
|
||||
success "Очистка завершена"
|
||||
}
|
||||
|
||||
# Основная функция
|
||||
main() {
|
||||
log "🚀 Тестирование собственных образов DevOpsLab"
|
||||
echo "=========================================="
|
||||
|
||||
# Проверки
|
||||
check_docker
|
||||
|
||||
if ! check_images; then
|
||||
error "Не все образы найдены. Завершение."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Выбор типа тестирования
|
||||
case "${1:-minimal}" in
|
||||
"check")
|
||||
success "Проверка образов завершена"
|
||||
;;
|
||||
"minimal")
|
||||
test_minimal
|
||||
;;
|
||||
"full")
|
||||
test_full
|
||||
;;
|
||||
"performance")
|
||||
test_performance
|
||||
;;
|
||||
"all")
|
||||
test_minimal && test_full && test_performance
|
||||
;;
|
||||
*)
|
||||
echo "Использование: $0 [check|minimal|full|performance|all]"
|
||||
echo ""
|
||||
echo " check - проверка наличия образов"
|
||||
echo " minimal - минимальный тест (4 хоста)"
|
||||
echo " full - полный тест (все образы)"
|
||||
echo " performance - тест производительности (8 хостов)"
|
||||
echo " all - все тесты"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# Очистка
|
||||
cleanup
|
||||
|
||||
success "🎉 Тестирование завершено успешно!"
|
||||
}
|
||||
|
||||
# Обработка сигналов
|
||||
trap cleanup EXIT INT TERM
|
||||
|
||||
# Запуск
|
||||
main "$@"
|
||||
@@ -12,10 +12,10 @@ ROLES=$(find roles/ -name 'main.yml' -path '*/tasks/*' | sed 's|roles/||; s|/tas
|
||||
|
||||
echo "📋 Найденные роли: $ROLES"
|
||||
|
||||
# Обновляем molecule/default/site.yml (только если файл не существует)
|
||||
if [ ! -f "molecule/default/site.yml" ]; then
|
||||
echo "📝 Создание molecule/default/site.yml..."
|
||||
cat > molecule/default/site.yml << 'EOF'
|
||||
# Обновляем molecule/default/run.yml (только если файл не существует)
|
||||
if [ ! -f "molecule/default/run.yml" ]; then
|
||||
echo "📝 Создание molecule/default/run.yml..."
|
||||
cat > molecule/default/run.yml << 'EOF'
|
||||
---
|
||||
# Универсальный playbook для тестирования Ansible ролей
|
||||
# Автор: Сергей Антропов
|
||||
@@ -199,7 +199,7 @@ if [ ! -f "molecule/default/site.yml" ]; then
|
||||
- import_playbook: ../../roles/deploy.yml
|
||||
EOF
|
||||
else
|
||||
echo "📝 Файл molecule/default/site.yml уже существует, пропускаем создание"
|
||||
echo "📝 Файл molecule/default/run.yml уже существует, пропускаем создание"
|
||||
fi
|
||||
|
||||
# Обновляем roles/deploy.yml
|
||||
|
||||
@@ -1,51 +1,51 @@
|
||||
$ANSIBLE_VAULT;1.1;AES256
|
||||
34663739653463366234613631353064393733363234323430333465393362666165373562303565
|
||||
3037663539383033313563623635393536366438316433320a623361306663373332326165326633
|
||||
37336136343965616234663462333165363965323362326266373566303238303033663336333331
|
||||
3435343232613563630a626639343461613239643532663138303630373739623836326238646236
|
||||
35346264346231353364363065393266623934323964363163623964643162306461633431616233
|
||||
62663339353134616130623862383332343037363739366237383638373638366363306231663635
|
||||
35373638346338386366636235616366323433636164333434313831613465343335366237366131
|
||||
65626562373532623263373430383531313631613638643466636661613763316465313833643030
|
||||
66346130393131383037386464353239663232636561666638333937346236613438616265313363
|
||||
65373766363866386466613035373266663235656537336431643931373131333435383761663937
|
||||
33626230343833656162623263363230383362393233393166346661303162353762613433376663
|
||||
61346236666338646534656138363030313562346465346563613266653930623532353765326234
|
||||
38373562613438653364323465363337363066313638373232643439386137623136313066306362
|
||||
39386437353233366563613962653837383664343462666537323335373839383334346364306361
|
||||
64366362396333643830313766373330613832323739306530333664333737343239393964643831
|
||||
34373736663132383134343334353234633061303335363364333339386331663962363334316231
|
||||
30663438376632326334383231363737333534633939316363366436633266323665363062343431
|
||||
37616137393932626433623962636537376238326466326136396532636666643234323639316235
|
||||
36306137656431626162343231616530663637323835346139323734393066623039396466346264
|
||||
62656161366663303838383661623966373265393130616431663331636234626231343632333831
|
||||
62313037336261313939636636626133656136366161346439663530373530383338393764366239
|
||||
63626634303866636636636366323539326534363461306333663638613261313164373961633866
|
||||
33656632633465663431643938313035303366376536343434333231353932303065306662393933
|
||||
37643134306535303036363130356435633039616637653363303164376335393665386334353664
|
||||
64366562353933633063353166666636333563613562386632616163376166626462393261376438
|
||||
37306131666232633330656464613133313032303333623735326439616166323765393766393036
|
||||
63336538336166633534643063353864636131353232393433313961333234386337616139613133
|
||||
65303666393431623031373966396632333536613664363239616236623338306336313331313062
|
||||
36346338326161653664646537656538626535613561353739396134323537666563386136343238
|
||||
66396666323234316237656137306666376439633261376233366234323834383963313138666366
|
||||
31653238303633353164636263643934326466636664386265383762323138333466323332643732
|
||||
62313462316431383061663166363834666234386163393030643265336333316232626561353031
|
||||
61353639333435303237666232643830336530353735656137333338643730343835346264306265
|
||||
61373662623863323430656166376338306463373835333661353466653261633636383764363366
|
||||
38323835666531633233326264323330616139313431353763343061393661333038363864383863
|
||||
62323239316135643231626661663237636466653763636433613039633661386531343161613838
|
||||
64383834663530636530363133396431383738636638333661636239643264623365353564653964
|
||||
64376131323239663633303662333438636431313262316639363531323930396238646665343262
|
||||
38393764643062343531326365393536653862653735393035623465386134633163323635356530
|
||||
38303365376561666133663639376234323363356264336566666565383933373330356562643063
|
||||
34663832613339376232663561323261653937333339313862613164656436323239623239613664
|
||||
66383131613434366133663833663734313437376461663530366166323361643566393835626334
|
||||
35383437376663326232336630386662386435663933303635616431376463333461316262666663
|
||||
63393330656665356138613663333565616230366338396361333265396562306438613263363035
|
||||
63626662396131623431353462376364656265373363383737303034363336313330656663626161
|
||||
33396161373730303239623338323564386139333838393661323466363035616635663765316238
|
||||
61636563356665616435653064316334633530643731366239383530346532336366666230613730
|
||||
38613566346131303863663463656534306530383364383031653964333939353536633262636635
|
||||
37643662323333356639663363636430626361343830663261623234343161643733633130613534
|
||||
3039653530613936353962373738396265656264636263656333
|
||||
35646637393562393632386237323463396437383465313133653161646465393066623139613931
|
||||
3731306562663437326132393337313232373935613636320a393162333031623336383230353934
|
||||
33323166643666323037353261663264663665333062306138346234353839383439323964643137
|
||||
3762616565326465330a663932393563656532316430356266303761333230626133333363336234
|
||||
63373562326330373737373265613438653135393039303665333236303533643365356464306436
|
||||
38376531313765336266353037666665623535313162353061366463643964343966333035646236
|
||||
64363833326266376162306132363330396565306264316233663665376630643563333234346433
|
||||
39663735303837383339613732333865633333373465656164623235313938373039643636636537
|
||||
35356164313534323662333062383536323961313837353632663666346537633530326566373632
|
||||
35346266336536396363303262326362346436336564613635376566643235373638373636383164
|
||||
64396137383231363637653235333066366462666335316433363363656337353632333665313866
|
||||
38313837356538633465653539316563393965373163323166633737623963666531323532303037
|
||||
39336330363338623134326163313034656265623539656565316361656437653463366165373137
|
||||
32383735323430313531663139613165303865633435373664633866656631353763613338303934
|
||||
34613461663665643965303833636131346462613236616162393861633465313866363831313332
|
||||
65336335663735666634396135383038343436336138636137313135383961306461323831366233
|
||||
66643766316339626639623036623835336361336231646161616437643733363636656433633130
|
||||
32306537366462633030313036333331613066376235613835636236636564663164346263376161
|
||||
39343837613134663537373461323239616236656633613637396261386335613437396164653664
|
||||
38346564646432396634343430636664346435396138326236613133323930613531643730396231
|
||||
34386166303031303239356565323566376565653139393265656463356631303831306136333865
|
||||
36623732643463303264653735636664663130373233336162633533653338343735313932626562
|
||||
64366233346237313230636263666561636462636139656461333432333036653036666132623932
|
||||
65623033636333336533623437396539383932633438346132633339363532323536316338626339
|
||||
38326237306661666637613064613435613931383265653761303734663832616434336430393535
|
||||
33663335343937633135326530386164316631626162353138323132376538383437353862363137
|
||||
38393638643066643335396566633239373338373531646334323831653832326532323464653834
|
||||
39666264623033356635646433343631366335643764323465323737396262323932623634613635
|
||||
65316536356662306533663839623133383263363630373766666464663063323035323834636539
|
||||
63666137313935373366326565393830353837396463363330383534373331363539386463316266
|
||||
35363734353262313366376530303231306133623465373133616139613031363230333432343265
|
||||
38313637303336343238376466383737646135653964346564363432666462373665383662656534
|
||||
34333234346133356430306232313430613739663464656336623739333330353961393866326634
|
||||
62623633343439366133643534393237616138383235656237343836646464303130633637663430
|
||||
33356631633363363535663139323330633533353465323234323238386132643032626664326431
|
||||
34663862363830393465333662376563373932356363303432383461653464366633623538346263
|
||||
32393431333931333963343363653935333662326632373463356566316537383739363064343862
|
||||
37633466656364376332336434633266346465656261303736363864366237663535313566313334
|
||||
34313734303137323163636636386238306335323561653166393335316563326661646566353662
|
||||
39383861643264363366393434633236613564353232393631393266386463613433376561383763
|
||||
30303262666630663138306237613939356138613330613431386236646338366434346330363736
|
||||
62386535376164326566346365313133616265643035643861613635333730613438636430393565
|
||||
66643864653634303139353434336564376562613933346138393534646532663763633363626535
|
||||
38336532303338656134363665323030623064626261376237626265656332343036336638313733
|
||||
35386438383561393636383536326262343931343530366339613332323066386366616165303033
|
||||
64306139616432323837623466393738323865306135393064626665326139626439313332636132
|
||||
63616664613732366338656236313439326336633930303133333330313761633132326362616537
|
||||
62666634343937613136633962383331666361353036663839633733623533623466383432313462
|
||||
34393733636432343365363862393663653163353534633136333661363363313139393330373930
|
||||
6163336530313937363666636633313066333931336138643164
|
||||
|
||||
Reference in New Issue
Block a user