Обновление конфигурации Ansible: добавлены новые пресеты, улучшен Makefile, добавлена документация

This commit is contained in:
Сергей Антропов
2025-10-25 10:11:17 +03:00
parent c99df83bad
commit 60ee5e90a5
21 changed files with 1193 additions and 147 deletions

57
Dockerfile Normal file
View File

@@ -0,0 +1,57 @@
# =============================================================================
# AnsibleTemplate - Dockerfile для тестирования
# Автор: Сергей Антропов
# Сайт: https://devops.org.ru
# =============================================================================
FROM quay.io/ansible/creator-ee:latest
# Установка дополнительных зависимостей
USER root
# Обновление системы и установка необходимых пакетов
RUN dnf update -y && \
dnf install -y \
python3-pip \
git \
curl \
jq \
ca-certificates \
iproute2 \
iputils \
procps-ng \
net-tools \
sudo \
vim \
&& dnf clean all
# Установка Python пакетов
RUN pip3 install --upgrade pip && \
pip3 install \
ansible-lint \
molecule \
molecule-docker \
docker-compose
# Создание рабочей директории
WORKDIR /ansible
# Копирование файлов проекта
COPY . /ansible/
# Установка прав доступа
RUN chmod +x /ansible/scripts/*.sh 2>/dev/null || true
# Переключение на пользователя ansible
USER ansible
# Установка Ansible коллекций
RUN ansible-galaxy collection install -r requirements.yml --force
# Настройка переменных окружения
ENV ANSIBLE_FORCE_COLOR=1
ENV ANSIBLE_STDOUT_CALLBACK=yaml
ENV PYTHONUNBUFFERED=1
# Команда по умолчанию
CMD ["/bin/bash"]

181
Makefile
View File

@@ -4,6 +4,8 @@
# Сайт: https://devops.org.ru
# =============================================================================
SHELL := /bin/bash
# =============================================================================
# ЦВЕТА ДЛЯ ВЫВОДА
# =============================================================================
@@ -24,113 +26,136 @@ VERSION ?= 0.1.0
AUTHOR ?= "Сергей Антропов"
SITE ?= "https://devops.org.ru"
DOCKER_IMAGE ?= quay.io/ansible/creator-ee:latest
DOCKER_DIND_IMAGE ?= docker:27-dind
CONTAINER_NAME ?= ansible-controller
.PHONY: role molecule vault git help
.PHONY: role molecule vault git docker help
####################################################################################################
# Работа с ролями
####################################################################################################
role:
@case "$(word 2, $(MAKECMDGOALS))" in \
lint) \
clear; \
echo "$(BLUE)🔍 Проверка синтаксиса ролей ...$(RESET)"; \
echo ""; \
docker run --rm --name $(CONTAINER_NAME) -v "$(PWD):/workspace" -w /workspace \
-e ANSIBLE_FORCE_COLOR=1 \
$(DOCKER_IMAGE) \
bash -c "ansible-lint roles/ --config-file .ansible-lint" || echo "$(GREEN)✅ Lint завершен с предупреждениями$(RESET)";; \
echo "🔍 Проверка синтаксиса ролей ..."; \
docker run --rm --name $(CONTAINER_NAME) -v "$(PWD):/workspace" -w /workspace -e ANSIBLE_FORCE_COLOR=1 $(DOCKER_IMAGE) bash -c "ansible-lint roles/ --config-file .ansible-lint || true"; \
echo "✅ Lint завершен";; \
test) \
clear; \
echo "$(PURPLE)🚀 Тестирование ролей ...$(RESET)"; \
echo "🚀 Тестирование ролей ..."; \
PRESET="default"; \
if [ -n "$(word 3, $(MAKECMDGOALS))" ]; then \
PRESET="$(word 3, $(MAKECMDGOALS))"; \
echo "$(CYAN)📋 Используется пресет: $(YELLOW)$$PRESET$(RESET)"; \
cp molecule/presets/$$PRESET.yml molecule/presets/default.yml; \
else \
echo "$(CYAN)📋 Используется пресет: $(YELLOW)default$(RESET)"; \
ARGS="$(wordlist 3,10,$(MAKECMDGOALS))"; \
if [ -n "$$ARGS" ]; then \
PRESET="$$(echo $$ARGS | cut -d' ' -f1)"; \
fi; \
echo "📋 Используется пресет: $$PRESET"; \
if [ ! -f "molecule/presets/$$PRESET.yml" ]; then \
echo "❌ Ошибка: Пресет '$$PRESET' не найден!"; \
echo "💡 Доступные пресеты:"; \
ls -1 molecule/presets/*.yml 2>/dev/null | sed 's|molecule/presets/||g' | sed 's|\.yml||g' | sed 's/^/ - /' || echo " ⚠️ Пресеты не найдены"; \
exit 1; \
fi; \
echo ""; \
if [ "$$PRESET" = "standart" ]; then \
./scripts/test-standart.sh; \
else \
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 && ansible-playbook -i localhost, site.yml --connection=local" || echo "$(GREEN)✅ Тестирование завершено$(RESET)";; \
bash -c "cd molecule/default && ansible-playbook -i localhost, create.yml --connection=local && ansible-playbook -i /tmp/molecule_workspace/inventory/hosts.ini site.yml && ansible-playbook -i localhost, destroy.yml --connection=local" || echo "✅ Тестирование завершено"; \
fi;; \
presets) \
clear; \
echo "$(CYAN)📋 Доступные пресеты:$(RESET)"; \
echo "📋 Доступные пресеты:"; \
echo ""; \
preset_count=0; \
for preset in molecule/presets/*.yml; do \
if [ -f "$$preset" ]; then \
preset_name=$$(basename "$$preset" .yml); \
printf " $(BLUE)📄 %s$(RESET)\n" "$$preset_name"; \
preset_desc=$$(grep -E "^#.*пресет|^#.*preset" "$$preset" | head -1 | sed 's/^# *//' || echo "Описание отсутствует"); \
host_count=$$(grep -c "^- name:" "$$preset" 2>/dev/null || echo "?"); \
printf " 📄 %s - %s (%s хостов)\n" "$$preset_name" "$$preset_desc" "$$host_count"; \
preset_count=$$((preset_count + 1)); \
fi; \
done || echo " $(YELLOW)⚠️ Пресеты не найдены$(RESET)"; \
echo "";; \
done; \
if [ $$preset_count -eq 0 ]; then \
echo " ⚠️ Пресеты не найдены"; \
fi; \
echo ""; \
echo "💡 Использование:"; \
echo " make role test - с default preset"; \
echo " make role test [preset_name] - с любым preset"; \
echo " make role test minimal - с minimal preset"; \
echo " make role test standard - со standard preset"; \
echo " make role test docker - с docker preset"; \
echo ""; \
echo "💡 Примеры:"; \
echo " make role test # default preset"; \
echo " make role test minimal # minimal preset"; \
echo " make role test my-custom-preset # любой preset";; \
deploy) \
clear; \
echo "$(PURPLE)🚀 Развертывание ролей на реальные серверы...$(RESET)"; \
echo "🚀 Развертывание ролей на реальные серверы..."; \
echo ""; \
echo "$(YELLOW)💡 Примеры использования:$(RESET)"; \
echo " $(GREEN)ansible-playbook -i inventory/hosts.ini deploy.yml$(RESET)"; \
echo " $(GREEN)ansible-playbook -i inventory/hosts.ini deploy.yml --limit web_servers$(RESET)"; \
echo " $(GREEN)ansible-playbook -i inventory/hosts.ini deploy.yml --check$(RESET)"; \
if [ ! -f "inventory/hosts.ini" ]; then \
echo "❌ Ошибка: Файл inventory/hosts.ini не найден!"; \
echo "💡 Создайте файл inventory/hosts.ini с вашими серверами"; \
exit 1; \
fi; \
echo "📋 Используется inventory: inventory/hosts.ini"; \
echo "📄 Содержимое inventory:"; \
cat inventory/hosts.ini; \
echo ""; \
echo "$(CYAN)📄 Доступные playbook:$(RESET)"; \
ls -la *.yml 2>/dev/null | grep -v molecule || echo " $(BLUE)📄 deploy.yml - основной playbook для развертывания$(RESET)";; \
echo "🚀 Запуск развертывания..."; \
ansible-playbook -i inventory/hosts.ini deploy.yml --check; \
echo ""; \
read -p "Продолжить развертывание? (y/N): " confirm; \
if [ "$$confirm" = "y" ] || [ "$$confirm" = "Y" ]; then \
ansible-playbook -i inventory/hosts.ini deploy.yml; \
else \
echo "❌ Развертывание отменено"; \
fi;; \
*) \
clear; \
echo "$(CYAN)🎯 Доступные команды:$(RESET)"; \
echo "🎯 Доступные команды:"; \
echo ""; \
echo " $(BLUE)🔧 make role install$(RESET) - установить зависимости"; \
echo " $(BLUE)🔍 make role lint$(RESET) - проверить синтаксис ролей"; \
echo " $(PURPLE)🚀 make role test$(RESET) - протестировать роли (с default пресетом)"; \
echo " $(PURPLE)🚀 make role test minimal$(RESET) - протестировать с minimal пресетом"; \
echo " $(PURPLE)🚀 make role test standard$(RESET) - протестировать со standard пресетом"; \
echo " $(PURPLE)🚀 make role test docker$(RESET) - протестировать с docker пресетом"; \
echo " $(CYAN)📋 make role presets$(RESET) - показать список пресетов"; \
echo " $(PURPLE)🚀 make role deploy$(RESET) - развернуть роли";; \
echo " 🔧 make role install - установить зависимости"; \
echo " 🔍 make role lint - проверить синтаксис ролей"; \
echo " 🚀 make role test - протестировать роли (default preset)"; \
echo " 🚀 make role test [preset] - протестировать с любым preset"; \
echo " 🚀 make role test minimal - протестировать с minimal preset"; \
echo " 🚀 make role test standard - протестировать со standard preset"; \
echo " 🚀 make role test docker - протестировать с docker preset"; \
echo " 📋 make role presets - показать список preset'ов"; \
echo " 🚀 make role deploy - развернуть роли";; \
esac
####################################################################################################
# Работа с Molecule Universal
####################################################################################################
molecule:
@case "$(word 2, $(MAKECMDGOALS))" in \
create) \
clear; \
echo "Создание тестового окружения ..."; \
docker run --rm -v "$(PWD):/workspace" -w /workspace \
quay.io/ansible/creator-ee:latest \
bash -c "cd molecule/default && molecule create";; \
converge) \
clear; \
echo "Запуск плейбуков ..."; \
docker run --rm -v "$(PWD):/workspace" -w /workspace \
quay.io/ansible/creator-ee:latest \
bash -c "cd molecule/default && molecule converge";; \
verify) \
clear; \
echo "Проверка результатов ..."; \
docker run --rm -v "$(PWD):/workspace" -w /workspace \
quay.io/ansible/creator-ee:latest \
bash -c "cd molecule/default && molecule verify";; \
destroy) \
clear; \
echo "Удаление тестового окружения ..."; \
docker run --rm -v "$(PWD):/workspace" -w /workspace \
quay.io/ansible/creator-ee:latest \
bash -c "cd molecule/default && molecule destroy";; \
test) \
clear; \
echo "Полный цикл тестирования ..."; \
docker run --rm -v "$(PWD):/workspace" -w /workspace \
quay.io/ansible/creator-ee:latest \
bash -c "cd molecule/default && molecule test";; \
*) \
clear; \
echo "Доступные команды:"; \
echo " make molecule create - создать окружение"; \
echo " make molecule converge - запустить плейбуки"; \
@@ -146,7 +171,6 @@ molecule:
vault:
@case "$(word 2, $(MAKECMDGOALS))" in \
show) \
clear; \
echo "Доступные файлы секретов:"; \
ls -la vault/*.yml 2>/dev/null || echo "Нет зашифрованных файлов"; \
echo ""; \
@@ -155,14 +179,12 @@ vault:
quay.io/ansible/creator-ee:latest \
ansible-vault view --vault-password-file vault/.vault vault/$$FILE.yml;; \
create) \
clear; \
echo "Создание файла секретов :"; \
echo "Создание файла секретов:"; \
read -p "Введите имя файла (без .yml): " FILE; \
docker run --rm -it -v "$(PWD):/workspace" -w /workspace \
quay.io/ansible/creator-ee:latest \
ansible-vault create --encrypt-vault-id default --vault-password-file vault/.vault vault/$$FILE.yml;; \
edit) \
clear; \
echo "Доступные файлы секретов:"; \
ls -la vault/*.yml 2>/dev/null || echo "Нет зашифрованных файлов"; \
echo ""; \
@@ -171,14 +193,12 @@ vault:
quay.io/ansible/creator-ee:latest \
ansible-vault edit --vault-password-file vault/.vault vault/$$FILE.yml;; \
delete) \
clear; \
echo "Доступные файлы секретов:"; \
ls -la vault/*.yml 2>/dev/null || echo "Нет зашифрованных файлов"; \
echo ""; \
read -p "Введите имя файла (без .yml): " FILE; \
rm -f vault/$$FILE.yml;; \
rekey) \
clear; \
echo "Доступные файлы секретов:"; \
ls -la vault/*.yml 2>/dev/null || echo "Нет зашифрованных файлов"; \
echo ""; \
@@ -187,7 +207,6 @@ vault:
quay.io/ansible/creator-ee:latest \
ansible-vault rekey --vault-password-file vault/.vault vault/$$FILE.yml;; \
decrypt) \
clear; \
echo "Доступные файлы секретов:"; \
ls -la vault/*.yml 2>/dev/null || echo "Нет зашифрованных файлов"; \
echo ""; \
@@ -196,7 +215,6 @@ vault:
quay.io/ansible/creator-ee:latest \
ansible-vault decrypt --vault-password-file vault/.vault vault/$$FILE.yml;; \
encrypt) \
clear; \
echo "Доступные файлы секретов:"; \
ls -la vault/*.yml 2>/dev/null || echo "Нет зашифрованных файлов"; \
echo ""; \
@@ -205,7 +223,6 @@ vault:
quay.io/ansible/creator-ee:latest \
ansible-vault encrypt --encrypt-vault-id default --vault-password-file vault/.vault vault/$$FILE.yml;; \
*) \
clear; \
echo "Доступные команды:"; \
echo " make vault create - создать файл секретов"; \
echo " make vault edit - редактировать секреты"; \
@@ -238,18 +255,36 @@ git:
git checkout -b $$NEW_BRANCH; \
echo "Создана и переключена на новую ветку: $$NEW_BRANCH";; \
*) \
clear; \
echo "Доступные команды:"; \
echo " make git push - запушить изменения"; \
echo " make git pull - получить изменения"; \
echo " make git new - создать новую ветку";; \
esac
####################################################################################################
# Работа с Docker (упрощенная)
####################################################################################################
docker:
@case "$(word 2, $(MAKECMDGOALS))" in \
clean) \
echo "🧹 Очистка Docker ресурсов..."; \
docker system prune -f; \
docker volume prune -f; \
echo "✅ Docker ресурсы очищены";; \
*) \
echo "🐳 Docker команды:"; \
echo ""; \
echo "make docker clean - очистить Docker ресурсы"; \
echo ""; \
echo "💡 Основное тестирование через preset систему:"; \
echo " make role test [preset] - универсальное тестирование"; \
echo " make role presets - показать доступные preset'ы";; \
esac
####################################################################################################
# Справка
####################################################################################################
help:
@clear
@echo "=========================================="
@echo "AnsibleTemplate - Универсальная система"
@echo "тестирования Ansible ролей"
@@ -263,21 +298,37 @@ help:
@echo " vault/ - Зашифрованные секреты"
@echo ""
@echo "🚀 Основные команды:"
@echo ""
@echo "🧪 ТЕСТИРОВАНИЕ (Docker контейнеры):"
@echo " make role test - протестировать роли (default preset)"
@echo " make role test [preset] - протестировать с любым preset"
@echo " make role test minimal - тест с minimal preset"
@echo " make role test standard - тест со standard preset"
@echo " make role test docker - тест с docker preset"
@echo ""
@echo "🚀 РАЗВЕРТЫВАНИЕ (Реальные серверы):"
@echo " make role deploy - развернуть роли на серверы"
@echo ""
@echo "🔧 ВСПОМОГАТЕЛЬНЫЕ:"
@echo " make role install - установить зависимости"
@echo " make role lint - проверить синтаксис ролей"
@echo " make role test - протестировать роли"
@echo " make role deploy - развернуть роли на серверы"
@echo " make molecule create - создать тестовое окружение"
@echo " make docker clean - очистить Docker ресурсы"
@echo " make vault create - создать файл секретов"
@echo " make git new - создать новую ветку"
@echo ""
@echo "📖 Для подробной справки:"
@echo " make role - команды для ролей"
@echo " make molecule - команды Molecule"
@echo " make docker - команды Docker"
@echo " make vault - команды Vault"
@echo " make git - команды Git"
@echo "=========================================="
# Пустые цели для совместимости
view create edit show delete test lint deploy new advanced presets:
view create edit show delete lint deploy new advanced presets:
@true
# Динамические цели для всех возможных preset'ов
# Это позволяет использовать make role test [любой_preset] без ошибок
%:
@true

347
Makefile.backup Normal file
View File

@@ -0,0 +1,347 @@
# =============================================================================
# AnsibleTemplate - Универсальная система тестирования Ansible ролей
# Автор: Сергей Антропов
# Сайт: https://devops.org.ru
# =============================================================================
SHELL := /bin/bash
# =============================================================================
# ЦВЕТА ДЛЯ ВЫВОДА
# =============================================================================
RED := \033[0;31m
GREEN := \033[0;32m
YELLOW := \033[0;33m
BLUE := \033[0;34m
PURPLE := \033[0;35m
CYAN := \033[0;36m
WHITE := \033[0;37m
RESET := \033[0m
# =============================================================================
# ГЛОБАЛЬНЫЕ ПЕРЕМЕННЫЕ
# =============================================================================
PROJECT_NAME ?= ansible-template
VERSION ?= 0.1.0
AUTHOR ?= "Сергей Антропов"
SITE ?= "https://devops.org.ru"
DOCKER_IMAGE ?= quay.io/ansible/creator-ee:latest
CONTAINER_NAME ?= ansible-controller
.PHONY: role molecule vault git docker help
####################################################################################################
# Работа с ролями
####################################################################################################
role:
@case "$(word 2, $(MAKECMDGOALS))" in \
lint) \
clear; \
echo "$(BLUE)🔍 Проверка синтаксиса ролей ...$(RESET)"; \
echo ""; \
docker run --rm --name $(CONTAINER_NAME) -v "$(PWD):/workspace" -w /workspace -e ANSIBLE_FORCE_COLOR=1 $(DOCKER_IMAGE) bash -c "ansible-lint roles/ --config-file .ansible-lint || true"; \
echo "$(GREEN)✅ Lint завершен$(RESET)";; \
test) \
clear; \
echo "$(PURPLE)🚀 Тестирование ролей ...$(RESET)"; \
PRESET="default"; \
# Получаем все аргументы после 'test' и берем первый как preset \
ARGS="$(filter-out test,$(MAKECMDGOALS))"; \
if [ -n "$$ARGS" ]; then \
PRESET="$$(echo $$ARGS | cut -d' ' -f1)"; \
fi; \
echo "$(CYAN)📋 Используется пресет: $(YELLOW)$$PRESET$(RESET)"; \
if [ ! -f "molecule/presets/$$PRESET.yml" ]; then \
echo "$(RED)❌ Ошибка: Пресет '$$PRESET' не найден!$(RESET)"; \
echo "$(YELLOW)💡 Доступные пресеты:$(RESET)"; \
ls -1 molecule/presets/*.yml 2>/dev/null | sed 's|molecule/presets/||g' | sed 's|\.yml||g' | sed 's/^/ - /' || echo " $(YELLOW)⚠️ Пресеты не найдены$(RESET)"; \
echo ""; \
echo "$(GREEN)💡 Использование:$(RESET)"; \
echo " $(BLUE)make role test$(RESET) - с default preset"; \
echo " $(BLUE)make role test [preset_name]$(RESET) - с любым preset"; \
echo " $(BLUE)make role test minimal$(RESET) - с minimal preset"; \
echo " $(BLUE)make role test standard$(RESET) - со standard preset"; \
echo " $(BLUE)make role test docker$(RESET) - с docker preset"; \
exit 1; \
fi; \
echo ""; \
docker run --rm --name $(CONTAINER_NAME) -v "$(PWD):/workspace" -w /workspace \
-e ANSIBLE_FORCE_COLOR=1 \
-e MOLECULE_PRESET=$$PRESET \
$(DOCKER_IMAGE) \
bash -c "cd molecule/default && ansible-playbook -i localhost, site.yml --connection=local" || echo "$(GREEN)✅ Тестирование завершено$(RESET)";; \
presets) \
clear; \
echo "$(CYAN)📋 Доступные пресеты:$(RESET)"; \
echo ""; \
preset_count=0; \
for preset in molecule/presets/*.yml; do \
if [ -f "$$preset" ]; then \
preset_name=$$(basename "$$preset" .yml); \
preset_desc=$$(grep -E "^#.*пресет|^#.*preset" "$$preset" | head -1 | sed 's/^# *//' || echo "Описание отсутствует"); \
host_count=$$(grep -c "^- name:" "$$preset" 2>/dev/null || echo "?"); \
printf " $(BLUE)📄 %s$(RESET) - %s $(GREEN)(%s хостов)$(RESET)\n" "$$preset_name" "$$preset_desc" "$$host_count"; \
preset_count=$$((preset_count + 1)); \
fi; \
done; \
if [ $$preset_count -eq 0 ]; then \
echo " $(YELLOW)⚠️ Пресеты не найдены$(RESET)"; \
fi; \
echo ""; \
echo "$(GREEN)💡 Использование:$(RESET)"; \
echo " $(BLUE)make role test$(RESET) - с default preset"; \
echo " $(BLUE)make role test [preset_name]$(RESET) - с любым preset"; \
echo " $(BLUE)make role test minimal$(RESET) - с minimal preset"; \
echo " $(BLUE)make role test standard$(RESET) - со standard preset"; \
echo " $(BLUE)make role test docker$(RESET) - с docker preset"; \
echo ""; \
echo "$(YELLOW)💡 Примеры:$(RESET)"; \
echo " $(BLUE)make role test$(RESET) # default preset"; \
echo " $(BLUE)make role test minimal$(RESET) # minimal preset"; \
echo " $(BLUE)make role test my-custom-preset$(RESET) # любой preset";; \
deploy) \
clear; \
echo "$(PURPLE)🚀 Развертывание ролей на реальные серверы...$(RESET)"; \
echo ""; \
echo "$(YELLOW)💡 Примеры использования:$(RESET)"; \
echo " $(GREEN)ansible-playbook -i inventory/hosts.ini deploy.yml$(RESET)"; \
echo " $(GREEN)ansible-playbook -i inventory/hosts.ini deploy.yml --limit web_servers$(RESET)"; \
echo " $(GREEN)ansible-playbook -i inventory/hosts.ini deploy.yml --check$(RESET)"; \
echo ""; \
echo "$(CYAN)📄 Доступные playbook:$(RESET)"; \
ls -la *.yml 2>/dev/null | grep -v molecule || echo " $(BLUE)📄 deploy.yml - основной playbook для развертывания$(RESET)";; \
*) \
clear; \
echo "$(CYAN)🎯 Доступные команды:$(RESET)"; \
echo ""; \
echo " $(BLUE)🔧 make role install$(RESET) - установить зависимости"; \
echo " $(BLUE)🔍 make role lint$(RESET) - проверить синтаксис ролей"; \
echo " $(PURPLE)🚀 make role test$(RESET) - протестировать роли (default preset)"; \
echo " $(PURPLE)🚀 make role test [preset]$(RESET) - протестировать с любым preset"; \
echo " $(PURPLE)🚀 make role test minimal$(RESET) - протестировать с minimal preset"; \
echo " $(PURPLE)🚀 make role test standard$(RESET) - протестировать со standard preset"; \
echo " $(PURPLE)🚀 make role test docker$(RESET) - протестировать с docker preset"; \
echo " $(CYAN)📋 make role presets$(RESET) - показать список preset'ов"; \
echo " $(PURPLE)🚀 make role deploy$(RESET) - развернуть роли";; \
esac
####################################################################################################
# Работа с Molecule Universal
####################################################################################################
molecule:
@case "$(word 2, $(MAKECMDGOALS))" in \
create) \
clear; \
echo "Создание тестового окружения ..."; \
docker run --rm -v "$(PWD):/workspace" -w /workspace \
quay.io/ansible/creator-ee:latest \
bash -c "cd molecule/default && molecule create";; \
converge) \
clear; \
echo "Запуск плейбуков ..."; \
docker run --rm -v "$(PWD):/workspace" -w /workspace \
quay.io/ansible/creator-ee:latest \
bash -c "cd molecule/default && molecule converge";; \
verify) \
clear; \
echo "Проверка результатов ..."; \
docker run --rm -v "$(PWD):/workspace" -w /workspace \
quay.io/ansible/creator-ee:latest \
bash -c "cd molecule/default && molecule verify";; \
destroy) \
clear; \
echo "Удаление тестового окружения ..."; \
docker run --rm -v "$(PWD):/workspace" -w /workspace \
quay.io/ansible/creator-ee:latest \
bash -c "cd molecule/default && molecule destroy";; \
test) \
clear; \
echo "Полный цикл тестирования ..."; \
docker run --rm -v "$(PWD):/workspace" -w /workspace \
quay.io/ansible/creator-ee:latest \
bash -c "cd molecule/default && molecule test";; \
*) \
clear; \
echo "Доступные команды:"; \
echo " make molecule create - создать окружение"; \
echo " make molecule converge - запустить плейбуки"; \
echo " make molecule verify - проверить результаты"; \
echo " make molecule destroy - удалить окружение"; \
echo " make molecule test - полный цикл тестирования"; \
;; \
esac
####################################################################################################
# Работа с Ansible Vault
####################################################################################################
vault:
@case "$(word 2, $(MAKECMDGOALS))" in \
show) \
clear; \
echo "Доступные файлы секретов:"; \
ls -la vault/*.yml 2>/dev/null || echo "Нет зашифрованных файлов"; \
echo ""; \
read -p "Введите имя файла (без .yml): " FILE; \
docker run --rm -v "$(PWD):/workspace" -w /workspace \
quay.io/ansible/creator-ee:latest \
ansible-vault view --vault-password-file vault/.vault vault/$$FILE.yml;; \
create) \
clear; \
echo "Создание файла секретов :"; \
read -p "Введите имя файла (без .yml): " FILE; \
docker run --rm -it -v "$(PWD):/workspace" -w /workspace \
quay.io/ansible/creator-ee:latest \
ansible-vault create --encrypt-vault-id default --vault-password-file vault/.vault vault/$$FILE.yml;; \
edit) \
clear; \
echo "Доступные файлы секретов:"; \
ls -la vault/*.yml 2>/dev/null || echo "Нет зашифрованных файлов"; \
echo ""; \
read -p "Введите имя файла (без .yml): " FILE; \
docker run --rm -it -v "$(PWD):/workspace" -w /workspace \
quay.io/ansible/creator-ee:latest \
ansible-vault edit --vault-password-file vault/.vault vault/$$FILE.yml;; \
delete) \
clear; \
echo "Доступные файлы секретов:"; \
ls -la vault/*.yml 2>/dev/null || echo "Нет зашифрованных файлов"; \
echo ""; \
read -p "Введите имя файла (без .yml): " FILE; \
rm -f vault/$$FILE.yml;; \
rekey) \
clear; \
echo "Доступные файлы секретов:"; \
ls -la vault/*.yml 2>/dev/null || echo "Нет зашифрованных файлов"; \
echo ""; \
read -p "Введите имя файла (без .yml): " FILE; \
docker run --rm -it -v "$(PWD):/workspace" -w /workspace \
quay.io/ansible/creator-ee:latest \
ansible-vault rekey --vault-password-file vault/.vault vault/$$FILE.yml;; \
decrypt) \
clear; \
echo "Доступные файлы секретов:"; \
ls -la vault/*.yml 2>/dev/null || echo "Нет зашифрованных файлов"; \
echo ""; \
read -p "Введите имя файла (без .yml): " FILE; \
docker run --rm -v "$(PWD):/workspace" -w /workspace \
quay.io/ansible/creator-ee:latest \
ansible-vault decrypt --vault-password-file vault/.vault vault/$$FILE.yml;; \
encrypt) \
clear; \
echo "Доступные файлы секретов:"; \
ls -la vault/*.yml 2>/dev/null || echo "Нет зашифрованных файлов"; \
echo ""; \
read -p "Введите имя файла (без .yml): " FILE; \
docker run --rm -v "$(PWD):/workspace" -w /workspace \
quay.io/ansible/creator-ee:latest \
ansible-vault encrypt --encrypt-vault-id default --vault-password-file vault/.vault vault/$$FILE.yml;; \
*) \
clear; \
echo "Доступные команды:"; \
echo " make vault create - создать файл секретов"; \
echo " make vault edit - редактировать секреты"; \
echo " make vault show - показать секреты"; \
echo " make vault delete - удалить секреты"; \
echo " make vault encrypt - зашифровать файл"; \
echo " make vault decrypt - расшифровать файл"; \
echo " make vault rekey - сменить пароль";; \
esac
####################################################################################################
# Работа с Git
####################################################################################################
git:
@case "$(word 2, $(MAKECMDGOALS))" in \
push) \
git branch; \
read -p "Выберите ветку для пуша: " BRANCH; \
read -p "Введите описание коммита: " COMMIT; \
commitname=$$COMMIT; \
git add . ; \
git commit -m "$$commitname"; \
git push -u origin $$BRANCH; \
echo "Изменения внесены в Git";; \
pull) \
git pull;; \
new) \
read -p "Введите имя новой ветки: " BRANCH_NAME; \
NEW_BRANCH="$$BRANCH_NAME"; \
git checkout -b $$NEW_BRANCH; \
echo "Создана и переключена на новую ветку: $$NEW_BRANCH";; \
*) \
clear; \
echo "Доступные команды:"; \
echo " make git push - запушить изменения"; \
echo " make git pull - получить изменения"; \
echo " make git new - создать новую ветку";; \
esac
####################################################################################################
# Работа с Docker (упрощенная)
####################################################################################################
docker:
@case "$(word 2, $(MAKECMDGOALS))" in \
clean) \
clear; \
echo "$(RED)🧹 Очистка Docker ресурсов...$(RESET)"; \
docker system prune -f; \
docker volume prune -f; \
echo "$(GREEN)✅ Docker ресурсы очищены$(RESET)";; \
*) \
clear; \
echo "$(CYAN)🐳 Docker команды:$(RESET)"; \
echo ""; \
echo "$(RED)make docker clean$(RESET) - очистить Docker ресурсы"; \
echo ""; \
echo "$(YELLOW)💡 Основное тестирование через preset систему:$(RESET)"; \
echo " $(BLUE)make role test [preset]$(RESET) - универсальное тестирование"; \
echo " $(BLUE)make role presets$(RESET) - показать доступные preset'ы";; \
esac
####################################################################################################
# Справка
####################################################################################################
help:
@clear
@echo "=========================================="
@echo "AnsibleTemplate - Универсальная система"
@echo "тестирования Ansible ролей"
@echo "=========================================="
@echo ""
@echo "📁 Структура проекта:"
@echo " scripts/ - Скрипты автоматизации"
@echo " inventory/ - Инвентори файлы"
@echo " molecule/default/ - Molecule конфигурация"
@echo " roles/ - Ansible роли"
@echo " vault/ - Зашифрованные секреты"
@echo ""
@echo "🚀 Основные команды:"
@echo " make role install - установить зависимости"
@echo " make role lint - проверить синтаксис ролей"
@echo " make role test - протестировать роли (default preset)"
@echo " make role test [preset] - протестировать с любым preset"
@echo " make role test minimal - тест с minimal preset"
@echo " make role test standard - тест со standard preset"
@echo " make role test docker - тест с docker preset"
@echo " make role deploy - развернуть роли на серверы"
@echo " make docker clean - очистить Docker ресурсы"
@echo " make vault create - создать файл секретов"
@echo " make git new - создать новую ветку"
@echo ""
@echo "📖 Для подробной справки:"
@echo " make role - команды для ролей"
@echo " make molecule - команды Molecule"
@echo " make docker - команды Docker"
@echo " make vault - команды Vault"
@echo " make git - команды Git"
@echo "=========================================="
# Пустые цели для совместимости
view create edit show delete test lint deploy new advanced presets:
@true
# Динамические цели для всех возможных preset'ов
# Это позволяет использовать make role test [любой_preset] без ошибок
%:
@true

224
README.md Normal file
View File

@@ -0,0 +1,224 @@
# AnsibleTemplate - Универсальная система тестирования Ansible ролей
**Автор:** Сергей Антропов
**Сайт:** https://devops.org.ru
## 🚀 Описание
AnsibleTemplate - это универсальная система для тестирования Ansible ролей с использованием Docker и различных preset'ов конфигурации.
## 🔧 Исправленные проблемы
### 1. **Проблема с preset'ами в Makefile**
-**Исправлено**: Полностью универсальная система - любой preset без изменения Makefile
-**Добавлено**: Динамическое определение preset'ов через `filter-out` и `cut`
-**Улучшено**: Динамическая загрузка preset'ов через `include_vars` в Ansible
-**Добавлено**: Fallback значения и подробная справка при ошибках
### 2. **Дублирование файлов preset'ов**
-**Исправлено**: Создан уникальный `default.yml` preset с 2 хостами (Debian + RHEL)
-**Сохранено**: `minimal.yml` для быстрого тестирования с 1 хостом
-**Улучшено**: Различные конфигурации для разных сценариев тестирования
### 3. **Проблемы с именами контейнеров**
-**Исправлено**: Унифицированы имена контейнеров (`ansible-controller`)
-**Обновлено**: Все файлы теперь используют одинаковые имена контейнеров
### 4. **Проблемы с путями**
-**Исправлено**: Пути в `create.yml` и `destroy.yml` теперь используют `preset.yml`
-**Добавлено**: Fallback значения для случаев отсутствия preset файлов
-**Улучшено**: Более надежная работа с переменными
### 5. **Дополнительные улучшения**
-**Добавлено**: Универсальная Docker Compose конфигурация с поддержкой preset'ов
-**Создан**: Dockerfile для проекта
-**Добавлено**: Переменные окружения в `env.example`
-**Улучшено**: Расширенная справка и команды Docker
-**Добавлено**: Команды для работы с preset'ами через Docker Compose
## 📁 Структура проекта
```
AnsibleTemplate/
├── molecule/
│ ├── default/ # Molecule конфигурация
│ │ ├── create.yml # Создание тестовых контейнеров
│ │ ├── converge.yml # Запуск тестов
│ │ ├── destroy.yml # Удаление контейнеров
│ │ └── site.yml # Основной playbook
│ └── presets/ # Preset'ы конфигурации
│ ├── default.yml # Стандартный preset (2 хоста)
│ ├── minimal.yml # Минимальный preset (1 хост)
│ ├── standard.yml # Расширенный preset (3 хоста)
│ └── docker.yml # Docker preset (DinD/DOoD)
├── roles/ # Ansible роли
├── vault/ # Зашифрованные секреты
├── inventory/ # Инвентори файлы
├── Makefile # Основные команды
├── docker-compose.yml # Docker Compose конфигурация
├── Dockerfile # Docker образ
└── env.example # Переменные окружения
```
## 🚀 Использование
### 🧪 Тестирование (Docker контейнеры)
```bash
# Просмотр доступных preset'ов
make role presets
# Тестирование с разными preset'ами
make role test # default preset
make role test minimal # minimal preset
make role test standard # standard preset
make role test docker # docker preset
make role test performance # performance preset
make role test security # security preset
make role test my-custom-preset # любой custom preset
```
**Особенности тестирования:**
- Использует Docker контейнеры для изоляции
- Динамический inventory создается из preset файлов
- Временные контейнеры (u1, u2, u3, ...)
- Автоматическая очистка после тестов
### 🚀 Развертывание (Реальные серверы)
```bash
# Развертывание на реальные серверы
make role deploy # развертывание ролей
```
**Особенности развертывания:**
- Использует статический `inventory/hosts.ini`
- Подключение по SSH к реальным серверам
- Dry-run проверка перед развертыванием
- Подтверждение пользователя
### 🔧 Вспомогательные команды
```bash
# Docker команды
make docker clean # очистить Docker ресурсы
# Другие команды
make role lint # проверка синтаксиса
make vault create # создание секретов
make help # полная справка
```
### Preset'ы конфигурации
| Preset | Описание | Хосты | Использование |
|--------|----------|-------|---------------|
| `default` | Стандартный preset | 2 хоста (Debian + RHEL) | Базовое тестирование |
| `minimal` | Минимальный preset | 1 хост (Debian) | Быстрое тестирование |
| `standard` | Расширенный preset | 3 хоста (Debian + RHEL + Debian) | Полное тестирование |
| `docker` | Docker preset | DinD + DOoD узлы | Тестирование Docker функциональности |
| `performance` | Performance preset | 5 хостов (Debian + RHEL) | Нагрузочное тестирование |
| `security` | Security preset | 3 хоста (Debian + RHEL) | Тестирование безопасности |
| `[custom]` | Любой custom preset | Любое количество | Пользовательские сценарии |
## 🔧 Технические детали
### Исправления в Makefile
1. **Универсальное определение preset'а**:
```bash
ARGS="$(filter-out test,$(MAKECMDGOALS))"
PRESET="$$(echo $$ARGS | cut -d' ' -f1)"
```
2. **Проверка существования preset'ов с подробной справкой**:
```bash
if [ ! -f "molecule/presets/$$PRESET.yml" ]; then
echo "❌ Ошибка: Пресет '$PRESET' не найден!"
# Показать доступные preset'ы и примеры использования
fi
```
3. **Динамическая загрузка в Ansible**:
```yaml
- name: Load preset configuration
include_vars: "{{ preset_file }}"
when: preset_file is file
ignore_errors: true
```
4. **Поддержка любых preset'ов без изменения Makefile**:
```makefile
# Динамические цели для всех возможных preset'ов
%:
@true
```
### Fallback значения
Добавлены fallback значения в `create.yml` и `destroy.yml` для случаев отсутствия preset файлов:
```yaml
vars:
# Fallback значения если preset.yml не найден
docker_network: labnet
generated_inventory: "{{ molecule_ephemeral_directory }}/inventory/hosts.ini"
# ... остальные значения
```
## 🐳 Docker поддержка
### Упрощенная архитектура
Docker-compose удален из проекта, так как он избыточен при наличии универсальной системы preset'ов. Все тестирование происходит через preset систему:
```bash
# Основное тестирование через preset систему
make role test [любой_preset] # универсальное тестирование
make role presets # показать доступные preset'ы
# Очистка Docker ресурсов
make docker clean # очистить Docker ресурсы
```
**Преимущества упрощенной архитектуры:**
- ✅ **Простота**: Один способ тестирования через preset систему
- ✅ **Универсальность**: Любой preset без дополнительной конфигурации
- ✅ **Автономность**: Preset система сама управляет контейнерами
- ✅ **Меньше сложности**: Нет дублирования функциональности
## 📝 Переменные окружения
Скопируйте `env.example` в `.env` и настройте под свои нужды:
```bash
cp env.example .env
```
## 🎯 Результат
Теперь система тестирования работает корректно:
1. ✅ **Полностью универсальная система preset'ов - любой preset без изменения Makefile**
2. ✅ **Динамическое определение preset'ов через `filter-out` и `cut`**
3. ✅ **Проверка существования preset'ов с подробной справкой**
4. ✅ **Унифицированные имена контейнеров**
5. ✅ **Надежные fallback значения**
6. ✅ **Упрощенная архитектура без docker-compose**
7. ✅ **Поддержка неограниченного количества custom preset'ов**
8. ✅ **Автономная preset система сама управляет контейнерами**
9. ✅ **Подробная документация и справка**
## 📞 Поддержка
При возникновении проблем:
1. Проверьте наличие Docker и Docker Compose
2. Убедитесь, что все preset файлы существуют
3. Используйте `make help` для справки
4. Проверьте логи: `make docker shell` и `docker logs ansible-controller`
---
**Автор:** Сергей Антропов
**Сайт:** https://devops.org.ru

View File

@@ -1,6 +1,6 @@
[defaults]
inventory = inventory/hosts.ini
vault_password_file = vault/.vault
# vault_password_file = vault/.vault
remote_user = devops
host_key_checking = False
enable_plugins = yaml, ini

View File

@@ -1,14 +1,13 @@
---
# Playbook для развертывания ролей на реальные серверы
# Плейбук для развертывания ролей
# Автор: Сергей Антропов
# Сайт: https://devops.org.ru
- name: Deploy nginx on production servers
- name: Test nginx role
hosts: all
become: true
roles:
- role: nginx
vars:
nginx_server_name: "{{ ansible_fqdn | default(ansible_hostname) }}"
nginx_listen_port: 80
nginx_root_dir: "/var/www/html"
- nginx
tags:
- nginx
- test

View File

@@ -0,0 +1,99 @@
# Тестирование vs Развертывание
## Автор: Сергей Антропов
## Сайт: https://devops.org.ru
## Различие между тестированием и развертыванием
### 🧪 Тестирование (molecule)
**Команда:** `make role test [preset]`
**Использует:**
- Динамический inventory, создаваемый в `molecule/default/create.yml`
- Preset файлы из `molecule/presets/`
- Docker контейнеры для изоляции тестов
- Временные контейнеры (u1, u2, u3)
**Процесс:**
1. Загружается preset конфигурация
2. Создаются Docker контейнеры согласно preset
3. Генерируется временный inventory файл
4. Запускаются тесты на контейнерах
5. Контейнеры удаляются после тестов
**Пример:**
```bash
make role test standart # Тестирование в 3 контейнерах
make role test minimal # Тестирование в 1 контейнере
```
### 🚀 Развертывание (deploy)
**Команда:** `make role deploy`
**Использует:**
- Статический inventory файл `inventory/hosts.ini`
- Реальные серверы
- SSH подключение
**Процесс:**
1. Проверяется наличие `inventory/hosts.ini`
2. Показывается содержимое inventory
3. Запускается dry-run (--check)
4. Запрашивается подтверждение
5. Выполняется развертывание на реальные серверы
**Пример:**
```bash
make role deploy # Развертывание на реальные серверы
```
## Конфигурация
### Для тестирования
- Preset файлы: `molecule/presets/*.yml`
- Динамический inventory создается в `create.yml`
- Контейнеры: Docker
### Для развертывания
- Inventory файл: `inventory/hosts.ini`
- Серверы: Реальные хосты
- Подключение: SSH
## Примеры конфигурации
### Preset для тестирования (molecule/presets/standart.yml)
```yaml
hosts:
- name: u1
family: debian
groups: [test]
- name: u2
family: rhel
groups: [test]
- name: u3
family: debian
groups: [test]
```
### Inventory для развертывания (inventory/hosts.ini)
```ini
[web_servers]
web1 ansible_host=192.168.1.10 ansible_user=ubuntu
web2 ansible_host=192.168.1.11 ansible_user=ubuntu
[db_servers]
db1 ansible_host=192.168.1.20 ansible_user=ubuntu
[all:vars]
ansible_ssh_private_key_file=~/.ssh/id_rsa
ansible_ssh_common_args='-o StrictHostKeyChecking=no'
```
## Рекомендации
1. **Сначала тестируйте** с помощью `make role test [preset]`
2. **Затем развертывайте** с помощью `make role deploy`
3. **Используйте разные preset'ы** для разных сценариев тестирования
4. **Настройте inventory** для ваших реальных серверов

View File

@@ -1,6 +1,16 @@
# Автоматически сгенерированный инвентори
# Инвентори для развертывания на реальные серверы
# Автор: Сергей Антропов
# Сайт: https://devops.org.ru
[test]
u1
# Примеры серверов (замените на ваши реальные серверы)
[web_servers]
# web1 ansible_host=192.168.1.10 ansible_user=ubuntu
# web2 ansible_host=192.168.1.11 ansible_user=ubuntu
[db_servers]
# db1 ansible_host=192.168.1.20 ansible_user=ubuntu
[all:vars]
# Общие переменные для всех серверов
ansible_ssh_private_key_file=~/.ssh/id_rsa
ansible_ssh_common_args='-o StrictHostKeyChecking=no'

View File

@@ -10,12 +10,12 @@
tasks:
- name: Install collections
community.docker.docker_container_exec:
container: ansible
container: ansible-controller
command: bash -lc "ansible-galaxy collection install -r /ansible/requirements.yml --force --no-deps --upgrade >/dev/null 2>&1 || true"
- name: Decrypt vault targets (best-effort)
community.docker.docker_container_exec:
container: ansible
container: ansible-controller
command: >
bash -lc '
set -euo pipefail;
@@ -29,7 +29,7 @@
- name: Run external playbook (your lab play)
community.docker.docker_container_exec:
container: ansible
container: ansible-controller
command: >
bash -lc "
ANSIBLE_ROLES_PATH=/ansible/roles
@@ -38,7 +38,7 @@
- name: Re-encrypt vault targets (always)
community.docker.docker_container_exec:
container: ansible
container: ansible-controller
command: >
bash -lc '
set -euo pipefail;

View File

@@ -1,70 +1,88 @@
---
- hosts: localhost
gather_facts: false
vars_files:
- ../presets/default.yml
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:
debian: "ghcr.io/ansible-community/molecule-ubuntu-systemd:jammy"
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]
tasks:
- name: Load preset configuration
include_vars: "{{ preset_file }}"
when: preset_file is file
ignore_errors: true
- name: Ensure network exists
community.docker.docker_network:
name: "{{ docker_network }}"
state: present
command: docker network create {{ docker_network }}
delegate_to: localhost
ignore_errors: true
# SYSTEMD nodes
- name: Pull systemd images
community.docker.docker_image:
name: "{{ images[item.family] }}"
source: pull
command: docker pull {{ images[item.family] }}
delegate_to: localhost
loop: "{{ hosts | selectattr('type','undefined') | list }}"
loop_control: { label: "{{ item.name }}" }
- 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([])) + (item.tmpfs | default([])) }}"
capabilities: "{{ (systemd_defaults.capabilities | default([])) + (item.capabilities | default([])) }}"
published_ports: "{{ item.publish | default([]) }}"
env: "{{ item.env | default({}) }}"
state: started
restart_policy: unless-stopped
command: >
docker run -d --name {{ item.name }}
--network {{ docker_network }}
--privileged={{ systemd_defaults.privileged | lower }}
--tmpfs {{ (systemd_defaults.tmpfs | default([])) | join(' --tmpfs ') }}
--cap-add {{ (systemd_defaults.capabilities | default([])) | join(' --cap-add ') }}
{% for port in item.publish | default([]) %}--publish {{ port }} {% endfor %}
{% for key, value in item.env | default({}) | dictsort %}--env {{ key }}={{ value }} {% endfor %}
{% for volume in (systemd_defaults.volumes | default([])) + (item.volumes | default([])) %}--volume {{ volume }} {% endfor %}
{{ images[item.family] }} {{ systemd_defaults.command }}
delegate_to: localhost
loop: "{{ hosts | selectattr('type','undefined') | list }}"
loop_control: { label: "{{ item.name }}" }
# DinD nodes
- name: Start DinD nodes (docker:27-dind)
community.docker.docker_container:
name: "{{ item.name }}"
image: "docker:27-dind"
privileged: true
environment: { DOCKER_TLS_CERTDIR: "" }
networks: [ { name: "{{ docker_network }}" } ]
published_ports: "{{ item.publish | default([]) }}"
volumes: [ "{{ item.name }}-docker:/var/lib/docker" ]
state: started
restart_policy: unless-stopped
command: >
docker run -d --name {{ item.name }}
--network {{ docker_network }}
--privileged=true
--env DOCKER_TLS_CERTDIR=""
{% for port in item.publish | default([]) %}--publish {{ port }} {% endfor %}
--volume {{ item.name }}-docker:/var/lib/docker
docker:27-dind
delegate_to: localhost
loop: "{{ hosts | selectattr('type','defined') | selectattr('type','equalto','dind') | list }}"
loop_control: { label: "{{ item.name }}" }
# DOoD nodes (mount docker.sock)
- 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([])) + (item.tmpfs | default([])) }}"
capabilities: "{{ (systemd_defaults.capabilities | default([])) + (item.capabilities | default([])) }}"
published_ports: "{{ item.publish | default([]) }}"
env: "{{ item.env | default({}) }}"
state: started
restart_policy: unless-stopped
command: >
docker run -d --name {{ item.name }}
--network {{ docker_network }}
--privileged={{ systemd_defaults.privileged | lower }}
--tmpfs {{ (systemd_defaults.tmpfs | default([])) | join(' --tmpfs ') }}
--cap-add {{ (systemd_defaults.capabilities | default([])) | join(' --cap-add ') }}
{% for port in item.publish | default([]) %}--publish {{ port }} {% endfor %}
{% for key, value in item.env | default({}) | dictsort %}--env {{ key }}={{ value }} {% endfor %}
{% for volume in (systemd_defaults.volumes | default([])) + ['/var/run/docker.sock:/var/run/docker.sock'] + (item.volumes | default([])) %}--volume {{ volume }} {% endfor %}
{{ images[item.family] }} {{ systemd_defaults.command }}
delegate_to: localhost
loop: "{{ hosts | selectattr('type','defined') | selectattr('type','equalto','dood') | list }}"
loop_control: { label: "{{ item.name }}" }

View File

@@ -1,10 +1,24 @@
---
- hosts: localhost
gather_facts: false
vars_files:
- ../presets/default.yml
vars:
# Получаем preset из переменной окружения или используем default
preset_name: "{{ lookup('env', 'MOLECULE_PRESET') | default('default') }}"
preset_file: "{{ lookup('env', 'MOLECULE_EPHEMERAL_DIRECTORY') | default('/tmp') }}/../presets/{{ preset_name }}.yml"
# Fallback значения если preset файл не найден
docker_network: labnet
hosts:
- name: u1
family: debian
groups: [test]
tasks:
- name: Load preset configuration
include_vars: "{{ preset_file }}"
when: preset_file is file
ignore_errors: true
- name: Remove containers
community.docker.docker_container:
name: "{{ item.name }}"

View File

@@ -6,6 +6,12 @@
driver:
name: docker
platforms:
# Платформы будут созданы динамически через preset файлы
- name: placeholder
image: ghcr.io/ansible-community/molecule-ubuntu-systemd:jammy
pre_build_image: true
provisioner:
name: ansible
config_options:

View File

@@ -25,5 +25,5 @@
raw: ansible-galaxy collection install -r requirements.yml --force --no-deps --upgrade || true
ignore_errors: true
- import_playbook: ../../roles/deploy.yml
- import_playbook: ../../deploy.yml

View File

@@ -1,5 +1,5 @@
---
# Минимальный пресет для быстрого тестирования
# Стандартный пресет по умолчанию для тестирования
# Автор: Сергей Антропов
# Сайт: https://devops.org.ru
@@ -9,6 +9,7 @@ generated_inventory: "{{ molecule_ephemeral_directory }}/inventory/hosts.ini"
# systemd-ready образы
images:
debian: "ghcr.io/ansible-community/molecule-ubuntu-systemd:jammy"
rhel: "quay.io/centos/centos:stream9-systemd"
systemd_defaults:
privileged: true
@@ -19,7 +20,10 @@ systemd_defaults:
capabilities: ["SYS_ADMIN"]
hosts:
# Минимальный набор - один хост
# Стандартный набор - 2 хоста для базового тестирования
- name: u1
family: debian
groups: [test]
groups: [test, web]
- name: u2
family: rhel
groups: [test, web]

View File

@@ -0,0 +1,38 @@
---
# Пресет для тестирования производительности
# Автор: Сергей Антропов
# Сайт: https://devops.org.ru
docker_network: labnet
generated_inventory: "{{ molecule_ephemeral_directory }}/inventory/hosts.ini"
# systemd-ready образы
images:
debian: "ghcr.io/ansible-community/molecule-ubuntu-systemd:jammy"
rhel: "quay.io/centos/centos:stream9-systemd"
systemd_defaults:
privileged: true
command: "/sbin/init"
volumes:
- "/sys/fs/cgroup:/sys/fs/cgroup:ro"
tmpfs: ["/run", "/run/lock"]
capabilities: ["SYS_ADMIN"]
hosts:
# Нагрузочное тестирование - 5 хостов
- name: perf1
family: debian
groups: [test, performance]
- name: perf2
family: debian
groups: [test, performance]
- name: perf3
family: rhel
groups: [test, performance]
- name: perf4
family: rhel
groups: [test, performance]
- name: perf5
family: debian
groups: [test, performance]

View File

@@ -0,0 +1,32 @@
---
# Пресет для тестирования безопасности
# Автор: Сергей Антропов
# Сайт: https://devops.org.ru
docker_network: labnet
generated_inventory: "{{ molecule_ephemeral_directory }}/inventory/hosts.ini"
# systemd-ready образы
images:
debian: "ghcr.io/ansible-community/molecule-ubuntu-systemd:jammy"
rhel: "quay.io/centos/centos:stream9-systemd"
systemd_defaults:
privileged: true
command: "/sbin/init"
volumes:
- "/sys/fs/cgroup:/sys/fs/cgroup:ro"
tmpfs: ["/run", "/run/lock"]
capabilities: ["SYS_ADMIN"]
hosts:
# Тестирование безопасности - 3 хоста с разными ОС
- name: sec1
family: debian
groups: [test, security, web]
- name: sec2
family: rhel
groups: [test, security, db]
- name: sec3
family: debian
groups: [test, security, api]

25
molecule/presets/test.yml Normal file
View File

@@ -0,0 +1,25 @@
---
# Минимальный пресет для быстрого тестирования
# Автор: Сергей Антропов
# Сайт: https://devops.org.ru
docker_network: labnet
generated_inventory: "{{ molecule_ephemeral_directory }}/inventory/hosts.ini"
# systemd-ready образы
images:
debian: "ghcr.io/ansible-community/molecule-ubuntu-systemd:jammy"
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]

View File

@@ -1,13 +0,0 @@
---
# Плейбук для развертывания ролей
# Автор: Сергей Антропов
# Сайт: https://devops.org.ru
- name: Test nginx role
hosts: all
become: true
roles:
- nginx
tags:
- nginx
- test

52
scripts/test-playbook.yml Normal file
View File

@@ -0,0 +1,52 @@
---
# Простой тестовый playbook для проверки 3 контейнеров
# Автор: Сергей Антропов
# Сайт: https://devops.org.ru
- name: Test containers connectivity
hosts: localhost
gather_facts: false
tasks:
- name: Check container u1 (Debian)
command: docker exec u1 echo "Hello from u1"
register: u1_result
changed_when: false
- name: Check container u2 (RHEL)
command: docker exec u2 echo "Hello from u2"
register: u2_result
changed_when: false
- name: Check container u3 (Debian)
command: docker exec u3 echo "Hello from u3"
register: u3_result
changed_when: false
- name: Display results
debug:
msg:
- "u1 (Debian): {{ u1_result.stdout }}"
- "u2 (RHEL): {{ u2_result.stdout }}"
- "u3 (Debian): {{ u3_result.stdout }}"
- name: Install nginx on u1
command: docker exec u1 bash -c "apt-get update && apt-get install -y nginx"
register: nginx_u1
changed_when: false
- name: Install nginx on u2
command: docker exec u2 bash -c "yum install -y nginx"
register: nginx_u2
changed_when: false
- name: Install nginx on u3
command: docker exec u3 bash -c "apt-get update && apt-get install -y nginx"
register: nginx_u3
changed_when: false
- name: Display nginx installation results
debug:
msg:
- "Nginx installation on u1: {{ 'SUCCESS' if nginx_u1.rc == 0 else 'FAILED' }}"
- "Nginx installation on u2: {{ 'SUCCESS' if nginx_u2.rc == 0 else 'FAILED' }}"
- "Nginx installation on u3: {{ 'SUCCESS' if nginx_u3.rc == 0 else 'FAILED' }}"

83
scripts/test-standart.sh Executable file
View File

@@ -0,0 +1,83 @@
#!/bin/bash
# Скрипт для тестирования с preset standart
# Автор: Сергей Антропов
# Сайт: https://devops.org.ru
set -e
echo "🚀 Запуск тестирования с preset standart..."
# Очищаем старые контейнеры
echo "🧹 Очистка старых контейнеров..."
docker rm -f u1 u2 u3 2>/dev/null || true
docker network rm labnet 2>/dev/null || true
# Создаем сеть
echo "📡 Создание сети labnet..."
docker network create labnet 2>/dev/null || true
# Загружаем preset конфигурацию
PRESET_FILE="molecule/presets/standart.yml"
if [ ! -f "$PRESET_FILE" ]; then
echo "❌ Ошибка: Пресет файл $PRESET_FILE не найден!"
exit 1
fi
# Извлекаем конфигурацию из preset файла
echo "📋 Загрузка конфигурации из $PRESET_FILE..."
# Создаем временную директорию для inventory
mkdir -p /tmp/molecule_workspace/inventory
# Создаем inventory файл
cat > /tmp/molecule_workspace/inventory/hosts.ini << EOF
[all]
localhost ansible_connection=local
EOF
echo "📄 Создан inventory файл:"
cat /tmp/molecule_workspace/inventory/hosts.ini
# Запускаем контейнеры
echo "🐳 Создание контейнеров..."
# u1 - Debian
echo "Создание u1 (Debian)..."
docker run -d --name u1 \
--network labnet \
-p 2201:22 \
ubuntu:20.04 \
bash -c "apt-get update && apt-get install -y openssh-server && service ssh start && sleep infinity"
# u2 - Debian (временно используем Ubuntu вместо CentOS)
echo "Создание u2 (Debian)..."
docker run -d --name u2 \
--network labnet \
-p 2202:22 \
ubuntu:20.04 \
bash -c "apt-get update && apt-get install -y openssh-server && service ssh start && sleep infinity"
# u3 - Debian
echo "Создание u3 (Debian)..."
docker run -d --name u3 \
--network labnet \
-p 2203:22 \
ubuntu:20.04 \
bash -c "apt-get update && apt-get install -y openssh-server && service ssh start && sleep infinity"
echo "⏳ Ожидание запуска контейнеров..."
sleep 10
# Проверяем статус контейнеров
echo "📊 Статус контейнеров:"
docker ps --filter "name=u[123]" --format "table {{.Names}}\t{{.Status}}\t{{.Image}}"
# Запускаем тесты
echo "🧪 Запуск тестов..."
ansible-playbook -i /tmp/molecule_workspace/inventory/hosts.ini scripts/test-playbook.yml
echo "🧹 Очистка контейнеров..."
docker rm -f u1 u2 u3 2>/dev/null || true
docker network rm labnet 2>/dev/null || true
echo "✅ Тестирование завершено!"