Compare commits
9 Commits
lab
...
8f5a9c955c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8f5a9c955c | ||
|
|
91e7554d71 | ||
|
|
cef8290341 | ||
|
|
646d1bbd00 | ||
|
|
ee0e5b98a3 | ||
|
|
696e08aa35 | ||
|
|
60ee5e90a5 | ||
| c99df83bad | |||
| 0b981ca61e |
4
.gitignore
vendored
4
.gitignore
vendored
@@ -1,6 +1,10 @@
|
||||
# ---> Ansible
|
||||
*.retry
|
||||
|
||||
# ---> Vault (секретные файлы)
|
||||
vault/.vault
|
||||
vault/secrets/*.yml
|
||||
|
||||
# ---> Python
|
||||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
|
||||
@@ -1,89 +0,0 @@
|
||||
stages:
|
||||
- lint
|
||||
- test
|
||||
- deploy
|
||||
- notify
|
||||
|
||||
services:
|
||||
- name: docker:dind
|
||||
command: ["--tls=false"]
|
||||
|
||||
variables:
|
||||
DOCKER_IMAGE: "hub.cism-ms.ru/ansible/ansible:latest"
|
||||
DOCKER_TLS_CERTDIR: ""
|
||||
ANSIBLE_FORCE_COLOR: "true"
|
||||
|
||||
before_script:
|
||||
- echo "$CI_REGISTRY_PASSWORD" | docker login hub.cism-ms.ru -u "$CI_REGISTRY_USER" --password-stdin
|
||||
- docker pull $DOCKER_IMAGE
|
||||
- echo "Fixing directory permissions..."
|
||||
- chmod o-w $CI_PROJECT_DIR
|
||||
|
||||
lint:
|
||||
stage: lint
|
||||
script:
|
||||
- echo "Начинаем стейдж Lint"
|
||||
- echo "Распаковываем секреты..."
|
||||
- ansible-vault decrypt vars/secrets.yml --vault-password-file ./vault-password.txt
|
||||
- echo "Запускаем ansible-lint..."
|
||||
- ansible-lint roles/*
|
||||
- echo "Упаковываем секреты..."
|
||||
- ansible-vault encrypt vars/secrets.yml --encrypt-vault-id default --vault-password-file ./vault-password.txt
|
||||
allow_failure: false
|
||||
rules:
|
||||
- if: $CI_COMMIT_REF_NAME != "main" && $CI_COMMIT_REF_NAME != "master"
|
||||
|
||||
test:
|
||||
stage: test
|
||||
script:
|
||||
- echo "Распаковываем секреты..."
|
||||
- ansible-vault decrypt --vault-password-file ./vault-password.txt vars/secrets.yml
|
||||
- echo "Запускаем тесты через Молекулу..."
|
||||
- molecule test --parallel --destroy=always
|
||||
- echo "Упаковываем секреты..."
|
||||
- ansible-vault encrypt vars/secrets.yml --encrypt-vault-id default --vault-password-file ./vault-password.txt
|
||||
allow_failure: false
|
||||
rules:
|
||||
- if: $CI_COMMIT_REF_NAME != "main" && $CI_COMMIT_REF_NAME != "master"
|
||||
|
||||
deploy:
|
||||
stage: deploy
|
||||
script:
|
||||
- echo "Настраиваем SSH-ключ для доступа к серверам..."
|
||||
# Создаем директорию .ssh и настраиваем права доступа
|
||||
- mkdir -p ~/.ssh
|
||||
- chmod 700 ~/.ssh
|
||||
# Записываем SSH-ключ в файл ~/.ssh/id_rsa
|
||||
- echo "$SSH_PRIVATE_KEY" | tr -d '\r' > ~/.ssh/id_rsa
|
||||
- chmod 600 ~/.ssh/id_rsa
|
||||
# Запускаем основной пайплайн
|
||||
- echo "Распаковываем секреты..."
|
||||
- ansible-vault decrypt --vault-password-file ./vault-password.txt vars/secrets.yml
|
||||
- echo "Все ок. Деплоим в прод..."
|
||||
- ansible-playbook roles/deploy.yaml
|
||||
- echo "Упаковываем секреты..."
|
||||
- ansible-vault encrypt vars/secrets.yml --encrypt-vault-id default --vault-password-file ./vault-password.txt
|
||||
# Удаляем ключ
|
||||
- rm -rf ~/.ssh
|
||||
rules:
|
||||
- if: $CI_COMMIT_REF_NAME != "main" && $CI_COMMIT_REF_NAME != "master"
|
||||
when: manual
|
||||
|
||||
notify:
|
||||
stage: notify
|
||||
script:
|
||||
- |
|
||||
if [ "$CI_JOB_STATUS" == "success" ]; then
|
||||
MESSAGE="✅ Пайплайн успешно завершен!%0AПроект: $CI_PROJECT_NAME%0AВетка: $CI_COMMIT_REF_NAME%0AСтатус: $CI_JOB_STATUS"
|
||||
else
|
||||
MESSAGE="❌ Пайплайн завершен с ошибкой!%0AПроект: $CI_PROJECT_NAME%0AВетка: $CI_COMMIT_REF_NAME%0AСтатус: $CI_JOB_STATUS"
|
||||
fi
|
||||
# curl -s -X POST "https://api.telegram.org/bot$TELEGRAM_BOT_TOKEN/sendMessage" \
|
||||
# -d "chat_id=$TELEGRAM_CHAT_ID" \
|
||||
# -d "text=$MESSAGE"
|
||||
rules:
|
||||
- if: $CI_JOB_STATUS # Отправлять уведомление только после завершения пайплайна
|
||||
|
||||
after_script:
|
||||
- echo "Работа пайплайна завершена"
|
||||
|
||||
83
Dockerfile
83
Dockerfile
@@ -1,40 +1,57 @@
|
||||
# Используем готовый образ с Ansible
|
||||
FROM geerlingguy/docker-ubuntu2204-ansible:latest
|
||||
# =============================================================================
|
||||
# AnsibleTemplate - Dockerfile для тестирования
|
||||
# Автор: Сергей Антропов
|
||||
# Сайт: https://devops.org.ru
|
||||
# =============================================================================
|
||||
|
||||
# Добавляем метаданные
|
||||
LABEL maintainer="Сергей Антропов <sergey@antropoff.ru>"
|
||||
LABEL description="Этот Dockerfile создан для внедрения подхода IaC в Ansible."
|
||||
LABEL version="0.1"
|
||||
LABEL contact.website="https://devops.org.ru"
|
||||
FROM quay.io/ansible/creator-ee:latest
|
||||
|
||||
# Устанавливаем переменные окружения
|
||||
ENV PYTHONUNBUFFERED=1
|
||||
ENV EDITOR=nano
|
||||
|
||||
# Устанавливаем дополнительные зависимости Python для Molecule
|
||||
RUN pip install --upgrade pip && \
|
||||
pip install \
|
||||
molecule \
|
||||
molecule-docker \
|
||||
ansible-lint \
|
||||
yamllint \
|
||||
docker \
|
||||
&& rm -rf /root/.cache/pip
|
||||
|
||||
# Создаем рабочую директорию
|
||||
WORKDIR /ansible
|
||||
|
||||
# Копируем файлы проекта
|
||||
COPY . /ansible/
|
||||
|
||||
# Устанавливаем права на выполнение (если папка scripts существует)
|
||||
RUN if [ -d /ansible/scripts ]; then chmod +x /ansible/scripts/*.sh; fi
|
||||
|
||||
# Устанавливаем пользователя
|
||||
# Установка дополнительных зависимостей
|
||||
USER root
|
||||
|
||||
# Открываем порт для SSH
|
||||
EXPOSE 22
|
||||
# Обновление системы и установка необходимых пакетов
|
||||
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"]
|
||||
@@ -1,54 +0,0 @@
|
||||
# Сборка контейнера с systemd для удобного тестирования ролей Ansible через Molecule
|
||||
|
||||
# Используем официальный образ Fedora
|
||||
FROM quay.io/fedora/python-312
|
||||
|
||||
USER root
|
||||
|
||||
# Обновляем пакеты и устанавливаем systemd и необходимые пакеты
|
||||
RUN dnf update -y && \
|
||||
dnf install -y --nodocs --setopt=install_weak_deps=False \
|
||||
systemd rsync \
|
||||
git \
|
||||
openssh \
|
||||
gcc \
|
||||
libffi-devel \
|
||||
openssl-devel \
|
||||
make \
|
||||
sudo \
|
||||
openssh-clients \
|
||||
less \
|
||||
ca-certificates \
|
||||
curl \
|
||||
gnupg2 \
|
||||
nano \
|
||||
sshpass \
|
||||
redhat-lsb-core \
|
||||
&& dnf clean all && \
|
||||
rm -rf /var/cache/dnf /tmp/* /var/tmp/*
|
||||
|
||||
# Устанавливаем docker-compose
|
||||
RUN curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose && \
|
||||
chmod +x /usr/local/bin/docker-compose
|
||||
|
||||
# Устанавливаем Python пакеты для Ansible
|
||||
RUN pip install --upgrade pip && \
|
||||
pip install \
|
||||
ansible \
|
||||
ansible-vault \
|
||||
molecule \
|
||||
molecule-docker \
|
||||
ansible-lint \
|
||||
yamllint \
|
||||
docker \
|
||||
&& rm -rf /root/.cache/pip
|
||||
|
||||
# Настраиваем окружение для systemd
|
||||
ENV container=docker
|
||||
STOPSIGNAL SIGRTMIN+3
|
||||
|
||||
# Создаем необходимые директории для systemd
|
||||
VOLUME [ "/sys/fs/cgroup" ]
|
||||
|
||||
# Запускаем systemd при старте контейнера
|
||||
CMD ["/sbin/init"]
|
||||
@@ -1,62 +0,0 @@
|
||||
# Сборка контейнера с systemd для удобного тестирования ролей Ansible через Molecule
|
||||
|
||||
# Используем готовый образ с Ansible (более старый, но стабильный)
|
||||
FROM geerlingguy/docker-ubuntu2004-ansible:latest
|
||||
|
||||
# Устанавливаем переменные окружения
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
ENV container=docker
|
||||
|
||||
# Устанавливаем дополнительные пакеты для тестирования
|
||||
RUN apt-get update && \
|
||||
apt-get install -y --no-install-recommends \
|
||||
systemd \
|
||||
systemd-sysv \
|
||||
rsync \
|
||||
git \
|
||||
ssh \
|
||||
gcc \
|
||||
libffi-dev \
|
||||
libssl-dev \
|
||||
make \
|
||||
sudo \
|
||||
sshpass \
|
||||
openssh-client \
|
||||
nano \
|
||||
less \
|
||||
ca-certificates \
|
||||
curl \
|
||||
gnupg \
|
||||
lsb-release \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Устанавливаем Python пакеты для Ansible с обновлением зависимостей
|
||||
RUN pip install --upgrade pip && \
|
||||
pip install --upgrade \
|
||||
requests \
|
||||
PyYAML \
|
||||
ansible-core \
|
||||
&& pip install \
|
||||
ansible \
|
||||
"ansible-vault<4.0.0" \
|
||||
molecule \
|
||||
molecule-docker \
|
||||
ansible-lint \
|
||||
yamllint \
|
||||
docker \
|
||||
&& rm -rf /root/.cache/pip
|
||||
|
||||
# Устанавливаем docker-compose
|
||||
RUN curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose && \
|
||||
chmod +x /usr/local/bin/docker-compose
|
||||
|
||||
|
||||
# Указываем, что контейнер использует systemd в качестве init-системы
|
||||
ENV container=docker
|
||||
STOPSIGNAL SIGRTMIN+3
|
||||
|
||||
# Создаем необходимые директории для systemd
|
||||
VOLUME [ "/sys/fs/cgroup" ]
|
||||
|
||||
# Запускаем systemd при старте контейнера
|
||||
CMD ["/sbin/init"]
|
||||
808
Makefile
808
Makefile
@@ -1,157 +1,689 @@
|
||||
# =============================================================================
|
||||
# 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
|
||||
|
||||
# Глобальные переменные
|
||||
IMAGE ?= ansible
|
||||
TAG ?= 0.1
|
||||
REGISTRY ?= inecs/ansible
|
||||
# По умолчанию используем docker. Для локальной разработки используйте docker-compose
|
||||
RUN_MODE ?= docker
|
||||
PROJECT_NAME ?= ansible-template
|
||||
VERSION ?= 0.1.0
|
||||
AUTHOR ?= "Сергей Антропов"
|
||||
SITE ?= "https://devops.org.ru"
|
||||
DOCKER_IMAGE ?= inecs/ansible-controller:latest
|
||||
DOCKER_DIND_IMAGE ?= docker:27-dind
|
||||
CONTAINER_NAME ?= ansible-controller
|
||||
|
||||
# Определение команды RUN в зависимости от RUN_MODE
|
||||
ifeq ($(RUN_MODE), docker-compose)
|
||||
RUN = docker compose run --rm $(IMAGE)
|
||||
else ifeq ($(RUN_MODE), docker)
|
||||
RUN = docker run -it --rm \
|
||||
--name $(IMAGE) \
|
||||
-v $(PWD):/ansible \
|
||||
-v /var/run/docker.sock:/var/run/docker.sock \
|
||||
-v ~/.ssh/id_rsa:/root/.ssh/id_rsa:ro \
|
||||
-e ANSIBLE_VAULT_PASSWORD_FILE=/ansible/vault-password.txt \
|
||||
--privileged \
|
||||
--workdir /ansible \
|
||||
$(REGISTRY)/$(IMAGE)
|
||||
else
|
||||
$(error Invalid RUN_MODE. Use "docker-compose" or "docker")
|
||||
endif
|
||||
# Переменные для Docker Hub
|
||||
DOCKER_REGISTRY ?= inecs
|
||||
DOCKER_VERSION ?= latest
|
||||
DOCKER_IMAGES := ansible-controller alt-linux astra-linux redos rhel centos alma rocky
|
||||
|
||||
view create edit show delete test lint deploy new init build rebuild prune release images push pull shell:
|
||||
@true
|
||||
# Multi-arch поддержка
|
||||
DOCKER_PLATFORMS ?= linux/amd64,linux/arm64
|
||||
DOCKER_BUILDX_BUILDER ?= multiarch-builder
|
||||
|
||||
####################################################################################################
|
||||
# Инициализация новой роли
|
||||
####################################################################################################
|
||||
init:
|
||||
@echo "Шаг 1: Создание Docker-образа..."
|
||||
@make docker build
|
||||
@echo "Шаг 2: Создание Docker-образов для запуска Molecule..."
|
||||
@make docker images
|
||||
@echo "Шаг 3: Создание нового vault-файла с паролем..."
|
||||
@read -p "Введите пароль для vault: " VAULT_PASSWORD; \
|
||||
echo "$$VAULT_PASSWORD" > vault-password.txt; \
|
||||
make vault create
|
||||
@echo "Шаг 4: Создание нового брэнча в гите..."
|
||||
@make git new
|
||||
@echo "Шаг 5: Создание новой роли..."
|
||||
@make role new
|
||||
# Базовые образы и их теги
|
||||
BASE_IMAGES := altlinux/p9 astralinux/astra-1.7 redos/redos:9 registry.access.redhat.com/ubi8/ubi quay.io/centos/centos:stream9 almalinux:8 rockylinux:8
|
||||
|
||||
####################################################################################################
|
||||
# Управление контейнерами с помощью docker compose или docker run
|
||||
####################################################################################################
|
||||
docker:
|
||||
@case "$(word 2, $(MAKECMDGOALS))" in \
|
||||
build) \
|
||||
docker buildx create --use --name multiarch-builder --driver docker-container; \
|
||||
if [ "$(RUN_MODE)" = "docker-compose" ]; then \
|
||||
docker compose build $(c); \
|
||||
else \
|
||||
docker build -t $(REGISTRY)/$(IMAGE) .; \
|
||||
fi;; \
|
||||
rebuild) \
|
||||
docker buildx create --use --name multiarch-builder --driver docker-container; \
|
||||
if [ "$(RUN_MODE)" = "docker-compose" ]; then \
|
||||
docker compose build --no-cache $(c); \
|
||||
else \
|
||||
docker build --no-cache -t $(REGISTRY)/$(IMAGE) .; \
|
||||
fi;; \
|
||||
prune) \
|
||||
docker system prune -af;; \
|
||||
shell) \
|
||||
clear; \
|
||||
echo "Entering to Ansible container shell..."; \
|
||||
$(RUN) bash ;; \
|
||||
release) \
|
||||
docker buildx create --use --name multiarch-builder --driver docker-container; \
|
||||
docker login $(REGISTRY); \
|
||||
docker buildx build -t $(REGISTRY)/$(IMAGE):$(TAG) -t $(REGISTRY)/$(IMAGE):latest --platform linux/amd64,linux/arm64 --push .;; \
|
||||
images) \
|
||||
docker buildx create --use --name multiarch-builder --driver docker-container; \
|
||||
echo "Логинимся в Docker Hub..."; \
|
||||
docker login; \
|
||||
echo "Собираем и пушим основной Ansible образ..."; \
|
||||
docker buildx build -t $(REGISTRY)/$(IMAGE):$(TAG) -t $(REGISTRY)/$(IMAGE):latest --platform linux/amd64,linux/arm64 --push .; \
|
||||
echo "Собираем и пушим образ CentOS..."; \
|
||||
docker buildx build -t $(REGISTRY):centos --platform linux/amd64,linux/arm64 --push -f Dockerfile-CentOS .; \
|
||||
echo "Собираем и пушим образ Ubuntu..."; \
|
||||
docker buildx build -t $(REGISTRY):ubuntu --platform linux/amd64,linux/arm64 --push -f Dockerfile-Ubuntu .; \
|
||||
echo "Образы успешно опубликованы в Docker Hub: $(REGISTRY)";; \
|
||||
*) echo "Unknown action. Available actions: build, rebuild, prune, release";; \
|
||||
esac
|
||||
|
||||
####################################################################################################
|
||||
# Работа с ролью
|
||||
####################################################################################################
|
||||
vault:
|
||||
@case "$(word 2, $(MAKECMDGOALS))" in \
|
||||
show) $(RUN) bash -c "ansible-vault view --vault-password-file vault-password.txt vars/secrets.yml";; \
|
||||
create) $(RUN) bash -c "ansible-vault create --encrypt-vault-id default --vault-password-file vault-password.txt vars/secrets.yml";; \
|
||||
edit) $(RUN) bash -c "ansible-vault edit --vault-password-file vault-password.txt vars/secrets.yml";; \
|
||||
delete) $(RUN) bash -c "rm vars/secrets.yml";; \
|
||||
rekey) $(RUN) bash -c "ansible-vault rekey --vault-password-file vault-password.txt vars/secrets.yml";; \
|
||||
decrypt) $(RUN) bash -c "ansible-vault decrypt --vault-password-file vault-password.txt vars/secrets.yml";; \
|
||||
encrypt) $(RUN) bash -c "ansible-vault encrypt --encrypt-vault-id default --vault-password-file vault-password.txt vars/secrets.yml";; \
|
||||
*) echo "Unknown action";; \
|
||||
esac
|
||||
.PHONY: role vault git docker presets controller help
|
||||
|
||||
# =============================================================================
|
||||
# КОМАНДЫ ДЛЯ РАБОТЫ С РОЛЯМИ
|
||||
# =============================================================================
|
||||
role:
|
||||
@case "$(word 2, $(MAKECMDGOALS))" in \
|
||||
new) \
|
||||
clear; \
|
||||
echo "Введите название новой роли на английском:"; \
|
||||
read ROLE_NAME; \
|
||||
echo "Введите описание роли:"; \
|
||||
read ROLE_DESC; \
|
||||
cp -r default/ "roles/$${ROLE_NAME}"; \
|
||||
printf "\n- name: $${ROLE_DESC}" >> roles/deploy.yaml; \
|
||||
printf "\n import_playbook: $${ROLE_NAME}/deploy.yaml" >> roles/deploy.yaml; \
|
||||
printf '\n - ../../roles/%s' "$$ROLE_NAME" >> molecule/default/converge.yml; \
|
||||
printf "\n - $${ROLE_NAME}" >> roles/$$ROLE_NAME/deploy.yaml;; \
|
||||
lint) \
|
||||
clear; \
|
||||
echo "Check your role..."; \
|
||||
$(RUN) bash -c "ansible-vault decrypt --vault-password-file vault-password.txt vars/secrets.yml"; \
|
||||
$(RUN) bash -c "ansible-lint roles/*"; \
|
||||
$(RUN) bash -c "ansible-vault encrypt vars/secrets.yml --encrypt-vault-id default --vault-password-file vault-password.txt";; \
|
||||
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 "Running test roles..."; \
|
||||
$(RUN) bash -c "ansible-vault decrypt --vault-password-file vault-password.txt vars/secrets.yml"; \
|
||||
$(RUN) bash -c "docker login $(REGISTRY) && molecule test --parallel --destroy=always"; \
|
||||
$(RUN) bash -c "ansible-vault encrypt vars/secrets.yml --encrypt-vault-id default --vault-password-file vault-password.txt";; \
|
||||
echo "🚀 Тестирование ролей ..."; \
|
||||
PRESET="default"; \
|
||||
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, 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;; \
|
||||
deploy) \
|
||||
clear; \
|
||||
echo "Deploying roles to production..."; \
|
||||
$(RUN) bash -c "ansible-playbook roles/deploy.yaml";; \
|
||||
*) echo "Unknown action";; \
|
||||
echo "🚀 Развертывание ролей на реальные серверы..."; \
|
||||
echo ""; \
|
||||
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 "🚀 Запуск развертывания..."; \
|
||||
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;; \
|
||||
*) \
|
||||
echo "🎯 Доступные команды:"; \
|
||||
echo ""; \
|
||||
echo " 🚀 make role test [preset] - протестировать роли с preset'ом"; \
|
||||
echo " 💡 Примеры:"; \
|
||||
echo " make role test # с default preset"; \
|
||||
echo " make role test minimal # с minimal preset"; \
|
||||
echo " make role test etcd-patroni # с etcd-patroni preset"; \
|
||||
echo ""; \
|
||||
echo " 🚀 make role deploy - развернуть роли на реальные серверы"; \
|
||||
echo " 💡 Требует: inventory/hosts.ini"; \
|
||||
echo ""; \
|
||||
echo " 🔍 make role lint - проверить синтаксис ролей"; \
|
||||
echo " 💡 Использует: ansible-lint";; \
|
||||
esac
|
||||
|
||||
####################################################################################################
|
||||
# Работа с Git
|
||||
####################################################################################################
|
||||
# =============================================================================
|
||||
# КОМАНДЫ ДЛЯ РАБОТЫ С PRESET'АМИ
|
||||
# =============================================================================
|
||||
presets:
|
||||
@case "$(word 2, $(MAKECMDGOALS))" in \
|
||||
list) \
|
||||
echo "📋 Доступные пресеты:"; \
|
||||
echo ""; \
|
||||
preset_count=0; \
|
||||
for preset in molecule/presets/*.yml; do \
|
||||
if [ -f "$$preset" ]; then \
|
||||
preset_name=$$(basename "$$preset" .yml); \
|
||||
preset_desc=$$(grep -E "^#description:" "$$preset" | head -1 | sed 's/^#description: *//' || 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; \
|
||||
if [ $$preset_count -eq 0 ]; then \
|
||||
echo " ⚠️ Пресеты не найдены"; \
|
||||
fi;; \
|
||||
info) \
|
||||
if [ -z "$(PRESET)" ]; then \
|
||||
echo "❌ Ошибка: Укажите PRESET=имя_пресета"; \
|
||||
echo "💡 Пример: make presets info 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 ""; \
|
||||
echo "📄 Описание:"; \
|
||||
grep -E "^#description:" "molecule/presets/$(PRESET).yml" | head -1 | sed 's/^#description: *//' || echo "Описание отсутствует"; \
|
||||
echo ""; \
|
||||
echo "🏠 Хосты:"; \
|
||||
grep -E "^- name:" "molecule/presets/$(PRESET).yml" | sed 's/^- name: / - /' || echo "Хосты не найдены"; \
|
||||
echo ""; \
|
||||
echo "🌐 Сеть:"; \
|
||||
grep -E "^docker_network:" "molecule/presets/$(PRESET).yml" | sed 's/^docker_network: / - /' || echo "Сеть не указана"; \
|
||||
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 ""; \
|
||||
echo " 📋 make presets list - показать список всех preset'ов"; \
|
||||
echo " 💡 Показывает: название, описание, количество хостов"; \
|
||||
echo ""; \
|
||||
echo " 📄 make presets info - подробная информация о preset'е"; \
|
||||
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";; \
|
||||
esac
|
||||
|
||||
# =============================================================================
|
||||
# КОМАНДЫ ДЛЯ РАБОТЫ С VAULT
|
||||
# =============================================================================
|
||||
vault:
|
||||
@case "$(word 2, $(MAKECMDGOALS))" in \
|
||||
create) \
|
||||
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) \
|
||||
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;; \
|
||||
show) \
|
||||
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;; \
|
||||
delete) \
|
||||
echo "🔐 Удаление секретов..."; \
|
||||
ls -la vault/*.yml 2>/dev/null || echo "Нет зашифрованных файлов"; \
|
||||
echo ""; \
|
||||
read -p "Введите имя файла (без .yml): " FILE; \
|
||||
rm -f vault/$$FILE.yml;; \
|
||||
encrypt) \
|
||||
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;; \
|
||||
decrypt) \
|
||||
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;; \
|
||||
rekey) \
|
||||
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;; \
|
||||
check) \
|
||||
echo "🔍 Проверка vault файлов..."; \
|
||||
if [ ! -d "vault" ]; then \
|
||||
echo "❌ Директория vault не найдена"; \
|
||||
exit 1; \
|
||||
fi; \
|
||||
vault_files=$$(find vault -name "*.yml" -type f 2>/dev/null); \
|
||||
if [ -z "$$vault_files" ]; then \
|
||||
echo "⚠️ Vault файлы не найдены"; \
|
||||
exit 0; \
|
||||
fi; \
|
||||
echo "📋 Найденные vault файлы:"; \
|
||||
for file in $$vault_files; do \
|
||||
echo " 📄 $$file"; \
|
||||
done; \
|
||||
echo ""; \
|
||||
echo "🔍 Проверка структуры..."; \
|
||||
for file in $$vault_files; do \
|
||||
if grep -q "ANSIBLE_VAULT" "$$file"; then \
|
||||
echo " ✅ $$file - зашифрован"; \
|
||||
else \
|
||||
echo " ⚠️ $$file - не зашифрован"; \
|
||||
fi; \
|
||||
done;; \
|
||||
scan) \
|
||||
echo "🔍 Поиск секретов в проекте..."; \
|
||||
echo "📋 Поиск потенциальных секретов:"; \
|
||||
find . -name "*.yml" -o -name "*.yaml" | grep -v ".git" | while read file; do \
|
||||
if grep -qE "(password|secret|key|token|api_key)" "$$file" 2>/dev/null; then \
|
||||
echo " ⚠️ $$file - содержит потенциальные секреты"; \
|
||||
fi; \
|
||||
done; \
|
||||
echo ""; \
|
||||
echo "💡 Рекомендации:"; \
|
||||
echo " - Используйте ansible-vault для шифрования секретов"; \
|
||||
echo " - Не храните секреты в открытом виде"; \
|
||||
echo " - Регулярно проверяйте файлы на наличие секретов";; \
|
||||
*) \
|
||||
echo "🎯 Доступные команды:"; \
|
||||
echo ""; \
|
||||
echo " 🔐 make vault create - создать новый файл секретов"; \
|
||||
echo " 💡 Интерактивное создание зашифрованного файла"; \
|
||||
echo ""; \
|
||||
echo " ✏️ make vault edit - редактировать существующие секреты"; \
|
||||
echo " 💡 Открывает редактор для изменения секретов"; \
|
||||
echo ""; \
|
||||
echo " 👁️ make vault show - показать содержимое секретов"; \
|
||||
echo " 💡 Расшифровывает и показывает содержимое"; \
|
||||
echo ""; \
|
||||
echo " 🗑️ make vault delete - удалить файл секретов"; \
|
||||
echo " 💡 Безвозвратное удаление файла"; \
|
||||
echo ""; \
|
||||
echo " 🔒 make vault encrypt - зашифровать существующий файл"; \
|
||||
echo " 💡 Шифрует незашифрованный файл"; \
|
||||
echo ""; \
|
||||
echo " 🔓 make vault decrypt - расшифровать файл"; \
|
||||
echo " 💡 Создает незашифрованную копию"; \
|
||||
echo ""; \
|
||||
echo " 🔑 make vault rekey - сменить пароль шифрования"; \
|
||||
echo " 💡 Изменяет пароль для существующего файла"; \
|
||||
echo ""; \
|
||||
echo " ✅ make vault check - проверить vault файлы"; \
|
||||
echo " 💡 Проверяет структуру и статус файлов"; \
|
||||
echo ""; \
|
||||
echo " 🔍 make vault scan - поиск потенциальных секретов"; \
|
||||
echo " 💡 Сканирует проект на наличие незашифрованных секретов";; \
|
||||
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";; \
|
||||
echo "📤 Отправка изменений в репозиторий..."; \
|
||||
git add .; \
|
||||
git commit -m "Обновление проекта"; \
|
||||
git push origin main;; \
|
||||
pull) \
|
||||
git pull;; \
|
||||
echo "📥 Получение изменений из репозитория..."; \
|
||||
git pull origin main;; \
|
||||
new) \
|
||||
read -p "Введите имя новой ветки: " BRANCH_NAME; \
|
||||
NEW_BRANCH="$$BRANCH_NAME"; \
|
||||
git checkout -b $$NEW_BRANCH; \
|
||||
echo "Создана и переключена на новую ветку: $$NEW_BRANCH";; \
|
||||
*) echo "Unknown action. Available actions: push, pull, cluster-branch";; \
|
||||
echo "🌿 Создание новой ветки..."; \
|
||||
read -p "Введите имя ветки: " BRANCH; \
|
||||
git checkout -b "$$BRANCH"; \
|
||||
echo "✅ Ветка '$$BRANCH' создана";; \
|
||||
*) \
|
||||
echo "🎯 Доступные команды:"; \
|
||||
echo ""; \
|
||||
echo " 📤 make git push - отправить изменения в репозиторий"; \
|
||||
echo " 💡 Выполняет: git add . && git commit && git push"; \
|
||||
echo ""; \
|
||||
echo " 📥 make git pull - получить изменения из репозитория"; \
|
||||
echo " 💡 Выполняет: git pull origin main"; \
|
||||
echo ""; \
|
||||
echo " 🌿 make git new - создать новую ветку"; \
|
||||
echo " 💡 Интерактивно запрашивает имя ветки"; \
|
||||
echo " 💡 Выполняет: git checkout -b имя_ветки";; \
|
||||
esac
|
||||
|
||||
# =============================================================================
|
||||
# КОМАНДЫ ДЛЯ РАБОТЫ С DOCKER
|
||||
# =============================================================================
|
||||
docker:
|
||||
@case "$(word 2, $(MAKECMDGOALS))" in \
|
||||
prepare) \
|
||||
echo "🔧 Подготовка Docker образов для Docker Hub..."; \
|
||||
echo "📋 Registry: $(DOCKER_REGISTRY)"; \
|
||||
echo "📋 Version: $(DOCKER_VERSION)"; \
|
||||
echo "📋 Images: $(DOCKER_IMAGES)"; \
|
||||
echo ""; \
|
||||
echo "💡 Для работы с Docker Hub выполните:"; \
|
||||
echo " docker login - авторизация в Docker Hub"; \
|
||||
echo " make docker build - сборка образов"; \
|
||||
echo " make docker push - отправка в Docker Hub";; \
|
||||
build) \
|
||||
echo "🐳 Сборка Docker образов (multi-arch)..."; \
|
||||
echo "📋 Платформы: $(DOCKER_PLATFORMS)"; \
|
||||
echo "📋 Builder: $(DOCKER_BUILDX_BUILDER)"; \
|
||||
echo ""; \
|
||||
$(MAKE) docker-setup-builder; \
|
||||
for image in $(DOCKER_IMAGES); do \
|
||||
echo "🔨 Сборка $(DOCKER_REGISTRY)/$$image:$(DOCKER_VERSION)"; \
|
||||
$(MAKE) docker-build-image IMAGE=$$image; \
|
||||
done; \
|
||||
echo "✅ Образы собраны";; \
|
||||
push) \
|
||||
echo "📤 Отправка Docker образов в Docker Hub..."; \
|
||||
for image in $(DOCKER_IMAGES); do \
|
||||
echo "📤 Отправка $(DOCKER_REGISTRY)/$$image:$(DOCKER_VERSION)"; \
|
||||
docker push $(DOCKER_REGISTRY)/$$image:$(DOCKER_VERSION); \
|
||||
done; \
|
||||
echo "✅ Образы отправлены в Docker Hub";; \
|
||||
pull) \
|
||||
echo "📥 Загрузка Docker образов из Docker Hub..."; \
|
||||
for image in $(DOCKER_IMAGES); do \
|
||||
echo "📥 Загрузка $(DOCKER_REGISTRY)/$$image:$(DOCKER_VERSION)"; \
|
||||
docker pull $(DOCKER_REGISTRY)/$$image:$(DOCKER_VERSION) || echo "⚠️ Образ $$image не найден в Docker Hub"; \
|
||||
done; \
|
||||
echo "✅ Загрузка завершена";; \
|
||||
clean) \
|
||||
echo "🧹 Очистка Docker образов..."; \
|
||||
for image in $(DOCKER_IMAGES); do \
|
||||
echo "🗑️ Удаление $(DOCKER_REGISTRY)/$$image:$(DOCKER_VERSION)"; \
|
||||
docker rmi $(DOCKER_REGISTRY)/$$image:$(DOCKER_VERSION) 2>/dev/null || true; \
|
||||
done; \
|
||||
echo "✅ Образы очищены";; \
|
||||
info) \
|
||||
echo "📊 Информация об образах..."; \
|
||||
for image in $(DOCKER_IMAGES); do \
|
||||
if docker images | grep -q "$(DOCKER_REGISTRY)/$$image"; then \
|
||||
echo "📦 $(DOCKER_REGISTRY)/$$image:$(DOCKER_VERSION)"; \
|
||||
docker images | grep "$(DOCKER_REGISTRY)/$$image" | head -1; \
|
||||
fi; \
|
||||
done;; \
|
||||
update) \
|
||||
echo "🔄 Обновление всех образов..."; \
|
||||
$(MAKE) docker pull; \
|
||||
$(MAKE) docker build; \
|
||||
$(MAKE) docker push; \
|
||||
echo "✅ Все образы обновлены";; \
|
||||
purge) \
|
||||
echo "🧹 Полная очистка Docker..."; \
|
||||
echo "⚠️ ВНИМАНИЕ: Это удалит ВСЕ Docker данные!"; \
|
||||
echo ""; \
|
||||
read -p "Продолжить? (y/N): " confirm; \
|
||||
if [ "$$confirm" = "y" ] || [ "$$confirm" = "Y" ]; then \
|
||||
echo "🛑 Остановка всех контейнеров..."; \
|
||||
docker stop $$(docker ps -aq) 2>/dev/null || true; \
|
||||
echo "🗑️ Удаление всех контейнеров..."; \
|
||||
docker rm $$(docker ps -aq) 2>/dev/null || true; \
|
||||
echo "🗑️ Удаление всех образов..."; \
|
||||
docker rmi $$(docker images -aq) 2>/dev/null || true; \
|
||||
echo "🗑️ Удаление всех томов..."; \
|
||||
docker volume rm $$(docker volume ls -q) 2>/dev/null || true; \
|
||||
echo "🗑️ Удаление всех сетей..."; \
|
||||
docker network rm $$(docker network ls -q) 2>/dev/null || true; \
|
||||
echo "🧹 Очистка системы..."; \
|
||||
docker system prune -af --volumes; \
|
||||
echo "✅ Docker полностью очищен"; \
|
||||
else \
|
||||
echo "❌ Очистка отменена"; \
|
||||
fi;; \
|
||||
*) \
|
||||
echo "🎯 Доступные команды:"; \
|
||||
echo ""; \
|
||||
echo " 🔧 make docker prepare - подготовка к работе с Docker Hub"; \
|
||||
echo " 💡 Показывает: registry, version, список образов"; \
|
||||
echo " 💡 Рекомендует: docker login перед работой"; \
|
||||
echo ""; \
|
||||
echo " 🐳 make docker build - собрать все Docker образы (multi-arch)"; \
|
||||
echo " 💡 Собирает: ansible-controller, alt-linux, astra-linux, redos"; \
|
||||
echo " 💡 Собирает: rhel, centos, alma, rocky"; \
|
||||
echo " 💡 Платформы: $(DOCKER_PLATFORMS)"; \
|
||||
echo " 💡 Тегирует: inecs/образ:<tag> (автоматически извлекает теги)"; \
|
||||
echo " 💡 Отправляет: автоматически в Docker Hub"; \
|
||||
echo ""; \
|
||||
echo " 📤 make docker push - отправить образы в Docker Hub"; \
|
||||
echo " 💡 Требует: docker login"; \
|
||||
echo " 💡 Отправляет: все образы в registry inecs"; \
|
||||
echo ""; \
|
||||
echo " 📥 make docker pull - загрузить образы из Docker Hub"; \
|
||||
echo " 💡 Загружает: все образы из registry inecs"; \
|
||||
echo " 💡 Пропускает: отсутствующие образы"; \
|
||||
echo ""; \
|
||||
echo " 🧹 make docker clean - удалить локальные образы"; \
|
||||
echo " 💡 Удаляет: все образы inecs/*:latest"; \
|
||||
echo " 💡 Безопасно: игнорирует ошибки"; \
|
||||
echo ""; \
|
||||
echo " 📊 make docker info - информация о собранных образах"; \
|
||||
echo " 💡 Показывает: размер, дата создания, теги"; \
|
||||
echo ""; \
|
||||
echo " 🔄 make docker update - обновить все образы"; \
|
||||
echo " 💡 Выполняет: pull + build + push"; \
|
||||
echo " 💡 Полный цикл обновления"; \
|
||||
echo ""; \
|
||||
echo " 💥 make docker purge - ПОЛНАЯ очистка Docker"; \
|
||||
echo " ⚠️ УДАЛЯЕТ: все контейнеры, образы, тома, сети"; \
|
||||
echo " ⚠️ ОСТАНОВИТ: все запущенные контейнеры"; \
|
||||
echo " ⚠️ ТРЕБУЕТ: подтверждение пользователя"; \
|
||||
echo ""; \
|
||||
echo " 🔧 make docker-setup-builder - настройка multi-arch builder"; \
|
||||
echo " 💡 Создает: builder в контейнере (не в системе)"; \
|
||||
echo " 💡 Поддерживает: amd64 и arm64 архитектуры"; \
|
||||
echo ""; \
|
||||
echo " 🧹 make docker-clean-builder - очистка multi-arch builder"; \
|
||||
echo " 💡 Удаляет: builder контейнер"; \
|
||||
echo " 💡 Полезно: при проблемах со сборкой";; \
|
||||
esac
|
||||
|
||||
# =============================================================================
|
||||
# ВСПОМОГАТЕЛЬНЫЕ ФУНКЦИИ ДЛЯ DOCKER
|
||||
# =============================================================================
|
||||
|
||||
# Настройка multi-arch builder
|
||||
docker-setup-builder:
|
||||
@echo "🔧 Настройка multi-arch builder в контейнере..."; \
|
||||
if ! docker buildx ls | grep -q $(DOCKER_BUILDX_BUILDER); then \
|
||||
echo "📦 Создание builder $(DOCKER_BUILDX_BUILDER) в контейнере..."; \
|
||||
docker buildx create --name $(DOCKER_BUILDX_BUILDER) --driver docker-container --bootstrap --use; \
|
||||
echo "⏳ Ожидание запуска builder..."; \
|
||||
sleep 5; \
|
||||
else \
|
||||
echo "✅ Builder $(DOCKER_BUILDX_BUILDER) уже существует"; \
|
||||
docker buildx use $(DOCKER_BUILDX_BUILDER); \
|
||||
fi; \
|
||||
echo "🔍 Проверка статуса builder..."; \
|
||||
docker buildx inspect $(DOCKER_BUILDX_BUILDER) --bootstrap
|
||||
|
||||
# Извлечение тега из базового образа
|
||||
docker-get-base-tag:
|
||||
@if [ -z "$(IMAGE)" ]; then \
|
||||
echo "❌ Ошибка: IMAGE не указан"; \
|
||||
exit 1; \
|
||||
fi; \
|
||||
case "$(IMAGE)" in \
|
||||
alt-linux) \
|
||||
BASE_IMAGE="altlinux/p9"; \
|
||||
TAG=$$(docker inspect --format='{{index .RepoDigests 0}}' $$BASE_IMAGE 2>/dev/null | cut -d'@' -f1 | cut -d':' -f2 || echo "latest");; \
|
||||
astra-linux) \
|
||||
BASE_IMAGE="astralinux/astra-1.7"; \
|
||||
TAG=$$(docker inspect --format='{{index .RepoDigests 0}}' $$BASE_IMAGE 2>/dev/null | cut -d'@' -f1 | cut -d':' -f2 || echo "latest");; \
|
||||
redos) \
|
||||
BASE_IMAGE="redos/redos:9"; \
|
||||
TAG=$$(docker inspect --format='{{index .RepoDigests 0}}' $$BASE_IMAGE 2>/dev/null | cut -d'@' -f1 | cut -d':' -f2 || echo "latest");; \
|
||||
rhel) \
|
||||
BASE_IMAGE="registry.access.redhat.com/ubi8/ubi"; \
|
||||
TAG=$$(docker inspect --format='{{index .RepoDigests 0}}' $$BASE_IMAGE 2>/dev/null | cut -d'@' -f1 | cut -d':' -f2 || echo "latest");; \
|
||||
centos) \
|
||||
BASE_IMAGE="quay.io/centos/centos:stream9"; \
|
||||
TAG=$$(docker inspect --format='{{index .RepoDigests 0}}' $$BASE_IMAGE 2>/dev/null | cut -d'@' -f1 | cut -d':' -f2 || echo "latest");; \
|
||||
alma) \
|
||||
BASE_IMAGE="almalinux:8"; \
|
||||
TAG=$$(docker inspect --format='{{index .RepoDigests 0}}' $$BASE_IMAGE 2>/dev/null | cut -d'@' -f1 | cut -d':' -f2 || echo "latest");; \
|
||||
rocky) \
|
||||
BASE_IMAGE="rockylinux:8"; \
|
||||
TAG=$$(docker inspect --format='{{index .RepoDigests 0}}' $$BASE_IMAGE 2>/dev/null | cut -d'@' -f1 | cut -d':' -f2 || echo "latest");; \
|
||||
ansible-controller) \
|
||||
TAG="latest";; \
|
||||
*) \
|
||||
echo "❌ Неизвестный образ: $(IMAGE)"; \
|
||||
exit 1;; \
|
||||
esac; \
|
||||
echo "📋 Образ: $(IMAGE)"; \
|
||||
echo "📋 Базовый образ: $$BASE_IMAGE"; \
|
||||
echo "📋 Тег: $$TAG"; \
|
||||
echo "$$TAG"
|
||||
|
||||
# Сборка одного образа с multi-arch
|
||||
docker-build-image:
|
||||
@if [ -z "$(IMAGE)" ]; then \
|
||||
echo "❌ Ошибка: IMAGE не указан"; \
|
||||
exit 1; \
|
||||
fi; \
|
||||
TAG=$$($(MAKE) docker-get-base-tag IMAGE=$(IMAGE)); \
|
||||
echo "🔨 Сборка $(DOCKER_REGISTRY)/$(IMAGE):$$TAG"; \
|
||||
cd dockerfiles/$(IMAGE) && \
|
||||
docker buildx build \
|
||||
--platform $(DOCKER_PLATFORMS) \
|
||||
--tag $(DOCKER_REGISTRY)/$(IMAGE):$$TAG \
|
||||
--tag $(DOCKER_REGISTRY)/$(IMAGE):latest \
|
||||
--push \
|
||||
.; \
|
||||
echo "✅ $(IMAGE):$$TAG собран и отправлен"
|
||||
|
||||
# Очистка multi-arch builder
|
||||
docker-clean-builder:
|
||||
@echo "🧹 Очистка multi-arch builder..."; \
|
||||
if docker buildx ls | grep -q $(DOCKER_BUILDX_BUILDER); then \
|
||||
echo "🗑️ Удаление builder $(DOCKER_BUILDX_BUILDER)..."; \
|
||||
docker buildx rm $(DOCKER_BUILDX_BUILDER) || true; \
|
||||
echo "✅ Builder удален"; \
|
||||
else \
|
||||
echo "ℹ️ Builder $(DOCKER_BUILDX_BUILDER) не найден"; \
|
||||
fi
|
||||
|
||||
# =============================================================================
|
||||
# КОМАНДЫ ДЛЯ РАБОТЫ С ANSIBLE-CONTROLLER
|
||||
# =============================================================================
|
||||
controller:
|
||||
@case "$(word 2, $(MAKECMDGOALS))" in \
|
||||
build) \
|
||||
echo "🔨 Сборка ansible-controller (multi-arch)..."; \
|
||||
echo "📋 Платформы: $(DOCKER_PLATFORMS)"; \
|
||||
$(MAKE) docker-setup-builder; \
|
||||
cd dockerfiles/ansible-controller && \
|
||||
docker buildx build \
|
||||
--platform $(DOCKER_PLATFORMS) \
|
||||
--tag $(DOCKER_REGISTRY)/ansible-controller:$(DOCKER_VERSION) \
|
||||
--push \
|
||||
.; \
|
||||
echo "✅ ansible-controller собран и отправлен";; \
|
||||
run) \
|
||||
echo "🚀 Запуск ansible-controller..."; \
|
||||
cd dockerfiles/ansible-controller && docker-compose up -d; \
|
||||
echo "✅ ansible-controller запущен";; \
|
||||
stop) \
|
||||
echo "🛑 Остановка ansible-controller..."; \
|
||||
cd dockerfiles/ansible-controller && docker-compose down; \
|
||||
echo "✅ ansible-controller остановлен";; \
|
||||
*) \
|
||||
echo "🎯 Доступные команды:"; \
|
||||
echo ""; \
|
||||
echo " 🔨 make controller build - собрать ansible-controller (multi-arch)"; \
|
||||
echo " 💡 Собирает: inecs/ansible-controller:latest"; \
|
||||
echo " 💡 Платформы: $(DOCKER_PLATFORMS)"; \
|
||||
echo " 💡 Использует: dockerfiles/ansible-controller/Dockerfile"; \
|
||||
echo " 💡 Requirements: dockerfiles/ansible-controller/requirements.yml"; \
|
||||
echo ""; \
|
||||
echo " 🚀 make controller run - запустить ansible-controller"; \
|
||||
echo " 💡 Запускает: docker-compose up -d"; \
|
||||
echo " 💡 Использует: dockerfiles/ansible-controller/docker-compose.yml"; \
|
||||
echo ""; \
|
||||
echo " 🛑 make controller stop - остановить ansible-controller"; \
|
||||
echo " 💡 Останавливает: docker-compose down"; \
|
||||
echo " 💡 Удаляет: контейнеры и сети";; \
|
||||
esac
|
||||
|
||||
# =============================================================================
|
||||
# СПРАВКА
|
||||
# =============================================================================
|
||||
help:
|
||||
@echo "=========================================="
|
||||
@echo "AnsibleTemplate - Универсальная система"
|
||||
@echo "тестирования Ansible ролей"
|
||||
@echo "=========================================="
|
||||
@echo ""
|
||||
@echo "📁 Структура проекта:"
|
||||
@echo " scripts/ - Скрипты автоматизации"
|
||||
@echo " inventory/ - Инвентори файлы"
|
||||
@echo " molecule/default/ - Molecule конфигурация"
|
||||
@echo " roles/ - Ansible роли"
|
||||
@echo " vault/ - Зашифрованные секреты"
|
||||
@echo " dockerfiles/ - Docker образы для тестирования"
|
||||
@echo ""
|
||||
@echo "🚀 ОСНОВНЫЕ КОМАНДЫ:"
|
||||
@echo " make role lint - проверить синтаксис ролей"
|
||||
@echo " make role test [preset] - протестировать роли с preset'ом"
|
||||
@echo " make role deploy - развернуть роли на реальные серверы"
|
||||
@echo ""
|
||||
@echo "📋 PRESET'Ы (тестовые окружения):"
|
||||
@echo " make presets list - показать все доступные preset'ы"
|
||||
@echo " make presets info - подробная информация о preset'е"
|
||||
@echo " make presets test - запустить тест с preset'ом"
|
||||
@echo ""
|
||||
@echo "🐳 DOCKER ОБРАЗЫ:"
|
||||
@echo " make docker prepare - подготовка к работе с Docker Hub"
|
||||
@echo " make docker build - собрать все Docker образы"
|
||||
@echo " make docker push - отправить образы в Docker Hub"
|
||||
@echo " make docker pull - загрузить образы из Docker Hub"
|
||||
@echo " make docker clean - удалить локальные образы"
|
||||
@echo " make docker info - информация о собранных образах"
|
||||
@echo " make docker update - обновить все образы (pull + build + push)"
|
||||
@echo " make docker purge - ПОЛНАЯ очистка Docker (ОСТОРОЖНО!)"
|
||||
@echo ""
|
||||
@echo "🔐 VAULT (управление секретами):"
|
||||
@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 - сменить пароль шифрования"
|
||||
@echo " make vault check - проверить vault файлы"
|
||||
@echo " make vault scan - поиск потенциальных секретов"
|
||||
@echo ""
|
||||
@echo "🌿 GIT (управление версиями):"
|
||||
@echo " make git push - отправить изменения в репозиторий"
|
||||
@echo " make git pull - получить изменения из репозитория"
|
||||
@echo " make git new - создать новую ветку"
|
||||
@echo ""
|
||||
@echo "🎮 CONTROLLER (ansible-controller):"
|
||||
@echo " make controller build - собрать ansible-controller"
|
||||
@echo " make controller run - запустить ansible-controller"
|
||||
@echo " make controller stop - остановить ansible-controller"
|
||||
@echo ""
|
||||
@echo "💡 ПРИМЕРЫ ИСПОЛЬЗОВАНИЯ:"
|
||||
@echo " make presets list # показать все preset'ы"
|
||||
@echo " make presets test PRESET=etcd-patroni # тест с etcd-patroni"
|
||||
@echo " make role test minimal # быстрый тест"
|
||||
@echo " make docker build # собрать все образы"
|
||||
@echo " make docker purge # полная очистка Docker"
|
||||
@echo " make vault create # создать секреты"
|
||||
@echo ""
|
||||
@echo "📖 Подробная справка: make [команда]"
|
||||
@echo "=========================================="
|
||||
|
||||
# Пустые цели для совместимости
|
||||
view create edit show delete lint deploy new advanced list info test build push pull clean prepare update run stop purge:
|
||||
@true
|
||||
|
||||
347
Makefile.backup
Normal file
347
Makefile.backup
Normal 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
|
||||
262
README.md
262
README.md
@@ -1,62 +1,224 @@
|
||||
# AnsibleTemplate
|
||||
# AnsibleTemplate - Универсальная система тестирования Ansible ролей
|
||||
|
||||
Темплейт для создания, проверки и тестирование ролей Ansible с помощью контейнеров Docker.
|
||||
**Автор:** Сергей Антропов
|
||||
**Сайт:** https://devops.org.ru
|
||||
|
||||
### С чего начать?
|
||||
## 🚀 Описание
|
||||
|
||||
На вашей машине вам необходимо сбилдить образ, где будут запускаться все роли через docker-compose.
|
||||
AnsibleTemplate - это универсальная система для тестирования Ansible ролей с использованием Docker и различных preset'ов конфигурации.
|
||||
|
||||
Это можно сделать самостоятельно:
|
||||
## 🔧 Исправленные проблемы
|
||||
|
||||
- **make docker build** - создание контейнера
|
||||
- **make docker rebuild** - пересоздание контейнера, если были внесены изменения в Dockerfile
|
||||
- **make docker prune** - очистить систему от лишних образов
|
||||
- **make docker shell** - войти в контейнер Shell
|
||||
- **make docker release** - собирает образ контейнера и пушит его в докер реджистри
|
||||
- **make docker images** - собрать образы контейнеров с systemd, для удобного тестирования ролей
|
||||
- **make images** - собрать и запушить все образы (основной Ansible, CentOS, Ubuntu) в Docker Hub (inecs/ansible)
|
||||
### 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 хостом
|
||||
- ✅ **Улучшено**: Различные конфигурации для разных сценариев тестирования
|
||||
|
||||
- **make init** - которая создаст файл секретов с паролем. Сбилдит образ. И создаст новую роль.
|
||||
### 3. **Проблемы с именами контейнеров**
|
||||
- ✅ **Исправлено**: Унифицированы имена контейнеров (`ansible-controller`)
|
||||
- ✅ **Обновлено**: Все файлы теперь используют одинаковые имена контейнеров
|
||||
|
||||
### Работа с ролью
|
||||
- **make role new** - создать новую роль из шаблона. Название роли пишется на английском, описание роли на любом языке
|
||||
- **make role lint** - проверяет все роли в папке roles/* на наличие ошибок
|
||||
- **make role test** - позволяет тестировать роль, указанную в molecule/default/converge.yml
|
||||
сразу на двух контейнерах (RedHat и Ubuntu)
|
||||
- **make role deploy** - запускает роль в продакшен. Все хосты берет из файла inventory/hosts
|
||||
### 4. **Проблемы с путями**
|
||||
- ✅ **Исправлено**: Пути в `create.yml` и `destroy.yml` теперь используют `preset.yml`
|
||||
- ✅ **Добавлено**: Fallback значения для случаев отсутствия preset файлов
|
||||
- ✅ **Улучшено**: Более надежная работа с переменными
|
||||
|
||||
### Работа с файлом переменных
|
||||
### 5. **Дополнительные улучшения**
|
||||
- ✅ **Добавлено**: Универсальная Docker Compose конфигурация с поддержкой preset'ов
|
||||
- ✅ **Создан**: Dockerfile для проекта
|
||||
- ✅ **Добавлено**: Переменные окружения в `env.example`
|
||||
- ✅ **Улучшено**: Расширенная справка и команды Docker
|
||||
- ✅ **Добавлено**: Команды для работы с preset'ами через Docker Compose
|
||||
|
||||
Все переменные защищены через **Ansible-Vault** и находятся в папке vars/secrets.yml
|
||||
## 📁 Структура проекта
|
||||
|
||||
Для смены пароля измените его в файле **./vault-password.txt**
|
||||
|
||||
- **make vault create** - создать новый файл с учетом пароля в файле **./vault-password.txt**
|
||||
- **make vault delete** - удалить файл с переменными
|
||||
- **make vault edit** - отредактировать файл переменных
|
||||
- **make vault show** - показать содержимое файла переменных
|
||||
- **make vault rekey** - сменить пароль шифрования
|
||||
- **make vault encrypt** - зашифровать файл секретов
|
||||
- **make vault decrypt** - расшифровать файл секретов
|
||||
|
||||
### Работа с Git
|
||||
|
||||
- **make git push** - запушить изменения. С выбором ветки и вводом коммита.
|
||||
- **make git pull** - получить изменения из репы
|
||||
- **make git new** - создание нового брэнча имя cluster-branch_name для IaC подхода.
|
||||
|
||||
### Добавить свой образ контейнера для тестов
|
||||
|
||||
Что бы добавить или изменить докер-образы для тестирования ролей измените файл настроек молекулы
|
||||
molecule/default/molecule.yml
|
||||
```yaml
|
||||
- name: ubuntu-instance
|
||||
image: "your.docker-registry.com/your-image:latest"
|
||||
privileged: true
|
||||
pre_build_image: true
|
||||
volumes:
|
||||
- /sys/fs/cgroup:/sys/fs/cgroup:ro
|
||||
```
|
||||
Помните, что образ обязательно должен содержать python не ниже версии 3.12 и systemd для нормального тестирования ролей.
|
||||
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
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[defaults]
|
||||
inventory = inventory/hosts
|
||||
vault_password_file = vault-password.txt
|
||||
inventory = inventory/hosts.ini
|
||||
# vault_password_file = vault/.vault
|
||||
remote_user = devops
|
||||
host_key_checking = False
|
||||
enable_plugins = yaml, ini
|
||||
|
||||
51
cicd/.gitlab-ci.yml
Normal file
51
cicd/.gitlab-ci.yml
Normal file
@@ -0,0 +1,51 @@
|
||||
# GitLab CI для AnsibleTemplate
|
||||
# Автор: Сергей Антропов
|
||||
# Сайт: https://devops.org.ru
|
||||
|
||||
stages:
|
||||
- test
|
||||
- deploy
|
||||
|
||||
variables:
|
||||
DOCKER_IMAGE: "quay.io/ansible/creator-ee:latest"
|
||||
DOCKER_TLS_CERTDIR: ""
|
||||
ANSIBLE_FORCE_COLOR: "true"
|
||||
|
||||
before_script:
|
||||
- echo "Установка зависимостей..."
|
||||
- pip install molecule[docker] ansible-lint
|
||||
- ansible-galaxy collection install -r requirements.yml
|
||||
|
||||
# Тестирование с Molecule
|
||||
test:
|
||||
stage: test
|
||||
image: $DOCKER_IMAGE
|
||||
services:
|
||||
- docker:dind
|
||||
variables:
|
||||
DOCKER_TLS_CERTDIR: ""
|
||||
script:
|
||||
- echo "Запуск тестов Molecule..."
|
||||
- cd molecule/universal
|
||||
- molecule test -s universal
|
||||
artifacts:
|
||||
reports:
|
||||
junit: molecule/universal/.molecule/reports/junit.xml
|
||||
paths:
|
||||
- molecule/universal/.molecule/
|
||||
expire_in: 1 week
|
||||
only:
|
||||
- merge_requests
|
||||
- main
|
||||
- develop
|
||||
|
||||
# Деплой (если нужен)
|
||||
deploy:
|
||||
stage: deploy
|
||||
image: $DOCKER_IMAGE
|
||||
script:
|
||||
- echo "Деплой не настроен"
|
||||
- echo "Добавьте логику деплоя в этот job"
|
||||
when: manual
|
||||
only:
|
||||
- main
|
||||
53
cicd/azure-devops/azure-pipelines.yml
Normal file
53
cicd/azure-devops/azure-pipelines.yml
Normal file
@@ -0,0 +1,53 @@
|
||||
# Azure DevOps Pipeline для AnsibleTemplate
|
||||
# Автор: Сергей Антропов
|
||||
# Сайт: https://devops.org.ru
|
||||
|
||||
trigger:
|
||||
- main
|
||||
- develop
|
||||
|
||||
pool:
|
||||
vmImage: 'ubuntu-latest'
|
||||
|
||||
variables:
|
||||
ANSIBLE_FORCE_COLOR: 'true'
|
||||
DOCKER_TLS_CERTDIR: ''
|
||||
|
||||
stages:
|
||||
- stage: Test
|
||||
displayName: 'Test Stage'
|
||||
jobs:
|
||||
- job: TestJob
|
||||
displayName: 'Run Tests'
|
||||
steps:
|
||||
- task: UsePythonVersion@0
|
||||
inputs:
|
||||
versionSpec: '3.11'
|
||||
displayName: 'Use Python 3.11'
|
||||
|
||||
- script: |
|
||||
pip install --upgrade pip
|
||||
pip install molecule[docker] ansible-lint
|
||||
ansible-galaxy collection install -r requirements.yml
|
||||
displayName: 'Install Dependencies'
|
||||
|
||||
- script: |
|
||||
ansible-lint molecule/universal/
|
||||
displayName: 'Run Ansible Lint'
|
||||
|
||||
- script: |
|
||||
cd molecule/universal
|
||||
molecule test -s universal
|
||||
displayName: 'Run Molecule Tests'
|
||||
|
||||
- task: PublishTestResults@2
|
||||
inputs:
|
||||
testResultsFiles: 'molecule/universal/.molecule/reports/junit.xml'
|
||||
testRunTitle: 'Molecule Test Results'
|
||||
condition: always()
|
||||
|
||||
- task: PublishBuildArtifacts@1
|
||||
inputs:
|
||||
pathToPublish: 'molecule/universal/.molecule'
|
||||
artifactName: 'molecule-reports'
|
||||
condition: always()
|
||||
70
cicd/github/workflows.yml
Normal file
70
cicd/github/workflows.yml
Normal file
@@ -0,0 +1,70 @@
|
||||
# GitHub Actions Workflow для AnsibleTemplate
|
||||
# Автор: Сергей Антропов
|
||||
# Сайт: https://devops.org.ru
|
||||
|
||||
name: Ansible Testing
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main, develop ]
|
||||
pull_request:
|
||||
branches: [ main ]
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: '3.11'
|
||||
|
||||
- name: Install system dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y docker.io
|
||||
sudo systemctl start docker
|
||||
sudo usermod -aG docker $USER
|
||||
|
||||
- name: Install Python dependencies
|
||||
run: |
|
||||
pip install --upgrade pip
|
||||
pip install molecule[docker] ansible-lint
|
||||
ansible-galaxy collection install -r requirements.yml
|
||||
|
||||
- name: Run Molecule tests
|
||||
run: |
|
||||
cd molecule/universal
|
||||
molecule test -s universal
|
||||
|
||||
- name: Upload test results
|
||||
uses: actions/upload-artifact@v3
|
||||
if: always()
|
||||
with:
|
||||
name: molecule-reports
|
||||
path: molecule/universal/.molecule/
|
||||
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: '3.11'
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
pip install ansible-lint
|
||||
ansible-galaxy collection install -r requirements.yml
|
||||
|
||||
- name: Run Ansible Lint
|
||||
run: |
|
||||
ansible-lint molecule/universal/
|
||||
59
cicd/jenkins/Jenkinsfile
vendored
Normal file
59
cicd/jenkins/Jenkinsfile
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
// Jenkins Pipeline для AnsibleTemplate
|
||||
// Автор: Сергей Антропов
|
||||
// Сайт: https://devops.org.ru
|
||||
|
||||
pipeline {
|
||||
agent any
|
||||
|
||||
environment {
|
||||
ANSIBLE_FORCE_COLOR = 'true'
|
||||
DOCKER_TLS_CERTDIR = ''
|
||||
}
|
||||
|
||||
stages {
|
||||
stage('Checkout') {
|
||||
steps {
|
||||
checkout scm
|
||||
}
|
||||
}
|
||||
|
||||
stage('Install Dependencies') {
|
||||
steps {
|
||||
sh '''
|
||||
pip install --upgrade pip
|
||||
pip install molecule[docker] ansible-lint
|
||||
ansible-galaxy collection install -r requirements.yml
|
||||
'''
|
||||
}
|
||||
}
|
||||
|
||||
stage('Lint') {
|
||||
steps {
|
||||
sh 'ansible-lint molecule/universal/'
|
||||
}
|
||||
}
|
||||
|
||||
stage('Test') {
|
||||
steps {
|
||||
dir('molecule/universal') {
|
||||
sh 'molecule test -s universal'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
post {
|
||||
always {
|
||||
archiveArtifacts artifacts: 'molecule/universal/.molecule/**/*', allowEmptyArchive: true
|
||||
publishTestResults testResultsPattern: 'molecule/universal/.molecule/reports/junit.xml'
|
||||
}
|
||||
|
||||
success {
|
||||
echo 'Pipeline completed successfully!'
|
||||
}
|
||||
|
||||
failure {
|
||||
echo 'Pipeline failed!'
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
---
|
||||
- name: Deploy roles
|
||||
hosts: all
|
||||
become: true
|
||||
become_user: root
|
||||
become_method: ansible.builtin.sudo
|
||||
gather_facts: true
|
||||
vars_files:
|
||||
- ../../vars/secrets.yml
|
||||
roles:
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
- name: Пример таски
|
||||
debug:
|
||||
msg: "Привет! Я запустился на Debian/Ubuntu!"
|
||||
@@ -1,12 +0,0 @@
|
||||
---
|
||||
- name: "Определяем ОС"
|
||||
set_fact:
|
||||
os_family: "{{ ansible_facts['os_family'] }}"
|
||||
|
||||
- name: "Подключаем таски для RedHat совместимых"
|
||||
include_tasks: "redhat/main.yaml"
|
||||
when: os_family == "RedHat"
|
||||
|
||||
- name: "Подключаем таски для Debian/Ubuntu совместимых"
|
||||
include_tasks: "debian/main.yaml"
|
||||
when: os_family == "Debian"
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
- name: Пример таски
|
||||
debug:
|
||||
msg: "Привет! Я запустился на RedHat/CentOS/Fedora!"
|
||||
13
deploy.yml
Normal file
13
deploy.yml
Normal file
@@ -0,0 +1,13 @@
|
||||
---
|
||||
# Плейбук для развертывания ролей
|
||||
# Автор: Сергей Антропов
|
||||
# Сайт: https://devops.org.ru
|
||||
|
||||
- name: Test nginx role
|
||||
hosts: all
|
||||
become: true
|
||||
roles:
|
||||
- nginx
|
||||
tags:
|
||||
- nginx
|
||||
- test
|
||||
@@ -1,12 +0,0 @@
|
||||
services:
|
||||
ansible:
|
||||
image: inecs/ansible:latest
|
||||
container_name: ansible
|
||||
volumes:
|
||||
- .:/ansible
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
environment:
|
||||
- ANSIBLE_VAULT_PASSWORD_FILE=./vault-password.txt
|
||||
tty: true
|
||||
privileged: true
|
||||
working_dir: /ansible
|
||||
160
dockerfiles/README.md
Normal file
160
dockerfiles/README.md
Normal file
@@ -0,0 +1,160 @@
|
||||
# Docker образы для универсальной системы тестирования
|
||||
|
||||
## Обзор
|
||||
|
||||
Эта директория содержит Docker образы для различных операционных систем и компонентов, используемых в универсальной системе тестирования Ansible ролей.
|
||||
|
||||
## Структура
|
||||
|
||||
```
|
||||
dockerfiles/
|
||||
├── ansible-controller/ # Ansible контроллер с предустановленными коллекциями
|
||||
├── alt-linux/ # ALT Linux с systemd
|
||||
├── astra-linux/ # Astra Linux с systemd
|
||||
├── redos/ # RED OS с systemd
|
||||
├── Makefile # Команды для сборки образов
|
||||
└── README.md # Документация
|
||||
```
|
||||
|
||||
## Доступные образы
|
||||
|
||||
### ansible-controller
|
||||
- **Базовый образ:** `quay.io/ansible/creator-ee:latest`
|
||||
- **Описание:** Ansible контроллер с предустановленными коллекциями
|
||||
- **Компоненты:**
|
||||
- Ansible с коллекциями (community.docker, community.general, ansible.posix)
|
||||
- Docker CLI
|
||||
- kubectl
|
||||
- Helm
|
||||
- Kind
|
||||
- Istio CLI
|
||||
- Дополнительные роли (geerlingguy.docker, geerlingguy.kubernetes)
|
||||
|
||||
### alt-linux
|
||||
- **Базовый образ:** `altlinux/p9`
|
||||
- **Описание:** ALT Linux с systemd
|
||||
- **Компоненты:**
|
||||
- systemd
|
||||
- Docker
|
||||
- Docker Compose
|
||||
- Python3
|
||||
- Пользователь ansible
|
||||
|
||||
### astra-linux
|
||||
- **Базовый образ:** `astralinux/astra-1.7`
|
||||
- **Описание:** Astra Linux с systemd
|
||||
- **Компоненты:**
|
||||
- systemd
|
||||
- Docker
|
||||
- Docker Compose
|
||||
- Python3
|
||||
- Пользователь ansible
|
||||
|
||||
### redos
|
||||
- **Базовый образ:** `redos/redos:9`
|
||||
- **Описание:** RED OS с systemd
|
||||
- **Компоненты:**
|
||||
- systemd
|
||||
- Docker
|
||||
- Docker Compose
|
||||
- Python3
|
||||
- Пользователь ansible
|
||||
|
||||
## Использование
|
||||
|
||||
### Сборка всех образов
|
||||
```bash
|
||||
make docker-build
|
||||
```
|
||||
|
||||
### Сборка конкретного образа
|
||||
```bash
|
||||
make docker-build IMAGE=ansible-controller
|
||||
```
|
||||
|
||||
### Отправка образов в registry
|
||||
```bash
|
||||
make docker-push
|
||||
```
|
||||
|
||||
### Очистка образов
|
||||
```bash
|
||||
make docker-clean
|
||||
```
|
||||
|
||||
### Информация об образах
|
||||
```bash
|
||||
make docker-info
|
||||
```
|
||||
|
||||
## Настройка registry
|
||||
|
||||
По умолчанию образы собираются с тегом `localhost:5000/имя:latest`. Для изменения registry:
|
||||
|
||||
```bash
|
||||
make docker-build REGISTRY=my-registry.com
|
||||
make docker-push REGISTRY=my-registry.com
|
||||
```
|
||||
|
||||
## Использование в preset'ах
|
||||
|
||||
После сборки образов их можно использовать в preset'ах:
|
||||
|
||||
```yaml
|
||||
# molecule/presets/my-preset.yml
|
||||
images:
|
||||
debian: "ghcr.io/ansible-community/molecule-ubuntu-systemd:jammy"
|
||||
rhel: "quay.io/centos/centos:stream9-systemd"
|
||||
alt: "localhost:5000/alt-linux:latest"
|
||||
astra: "localhost:5000/astra-linux:latest"
|
||||
redos: "localhost:5000/redos:latest"
|
||||
|
||||
hosts:
|
||||
- name: alt-server
|
||||
family: alt
|
||||
groups: [servers]
|
||||
- name: astra-server
|
||||
family: astra
|
||||
groups: [servers]
|
||||
- name: redos-server
|
||||
family: redos
|
||||
groups: [servers]
|
||||
```
|
||||
|
||||
## Лучшие практики
|
||||
|
||||
### 1. Версионирование образов
|
||||
```bash
|
||||
make docker-build VERSION=v1.0.0
|
||||
```
|
||||
|
||||
### 2. Использование registry
|
||||
```bash
|
||||
make docker-push REGISTRY=my-registry.com VERSION=v1.0.0
|
||||
```
|
||||
|
||||
### 3. Очистка старых образов
|
||||
```bash
|
||||
make docker-clean
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Проблемы с сборкой
|
||||
1. Проверьте доступность базовых образов
|
||||
2. Убедитесь, что Docker запущен
|
||||
3. Проверьте права доступа к Docker
|
||||
|
||||
### Проблемы с registry
|
||||
1. Убедитесь, что registry доступен
|
||||
2. Проверьте аутентификацию
|
||||
3. Проверьте права на push
|
||||
|
||||
### Проблемы с образами
|
||||
1. Проверьте размер образов
|
||||
2. Убедитесь, что все зависимости установлены
|
||||
3. Проверьте совместимость с базовыми образами
|
||||
|
||||
## Заключение
|
||||
|
||||
Эти Docker образы предоставляют готовую среду для тестирования Ansible ролей на различных операционных системах. Используйте их в своих preset'ах для создания универсальной системы тестирования.
|
||||
51
dockerfiles/alma/Dockerfile
Normal file
51
dockerfiles/alma/Dockerfile
Normal file
@@ -0,0 +1,51 @@
|
||||
# AlmaLinux с systemd
|
||||
# Автор: Сергей Антропов
|
||||
# Сайт: https://devops.org.ru
|
||||
# https://hub.docker.com/_/almalinux
|
||||
|
||||
FROM almalinux:8
|
||||
|
||||
# Обновляем систему
|
||||
RUN dnf update -y && dnf upgrade -y
|
||||
|
||||
# Устанавливаем systemd и необходимые пакеты
|
||||
RUN dnf install -y \
|
||||
systemd \
|
||||
systemd-sysv \
|
||||
dbus \
|
||||
curl \
|
||||
wget \
|
||||
git \
|
||||
vim \
|
||||
nano \
|
||||
jq \
|
||||
python3 \
|
||||
python3-pip \
|
||||
&& dnf clean all
|
||||
|
||||
# Устанавливаем yq
|
||||
RUN wget -qO /usr/local/bin/yq https://github.com/mikefarah/yq/releases/latest/download/yq_linux_arm64 \
|
||||
&& chmod +x /usr/local/bin/yq
|
||||
|
||||
# Устанавливаем Docker
|
||||
RUN dnf install -y dnf-plugins-core \
|
||||
&& dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo \
|
||||
&& dnf install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
|
||||
|
||||
# Устанавливаем Docker Compose
|
||||
RUN curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose \
|
||||
&& chmod +x /usr/local/bin/docker-compose
|
||||
|
||||
# Настраиваем systemd
|
||||
RUN systemctl set-default multi-user.target
|
||||
|
||||
# Создаем пользователя для Ansible
|
||||
RUN useradd -m -s /bin/bash ansible \
|
||||
&& echo "ansible ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
|
||||
|
||||
# Переключаемся на пользователя ansible
|
||||
USER ansible
|
||||
WORKDIR /home/ansible
|
||||
|
||||
# Команда по умолчанию
|
||||
CMD ["/sbin/init"]
|
||||
56
dockerfiles/alt-linux/Dockerfile
Normal file
56
dockerfiles/alt-linux/Dockerfile
Normal file
@@ -0,0 +1,56 @@
|
||||
# ALT Linux с systemd
|
||||
# Автор: Сергей Антропов
|
||||
# Сайт: https://devops.org.ru
|
||||
# https://hub.docker.com/_/alt/tags
|
||||
|
||||
FROM alt:p9
|
||||
|
||||
# Обновляем систему
|
||||
RUN apt-get update && apt-get dist-upgrade -y
|
||||
|
||||
# Устанавливаем systemd и необходимые пакеты
|
||||
RUN apt-get install -y \
|
||||
systemd \
|
||||
dbus \
|
||||
curl \
|
||||
wget \
|
||||
git \
|
||||
vim-enhanced \
|
||||
nano \
|
||||
htop \
|
||||
tree \
|
||||
jq \
|
||||
python3 \
|
||||
&& apt-get clean
|
||||
|
||||
# Устанавливаем pip для Python 3.7
|
||||
RUN curl -sS https://bootstrap.pypa.io/pip/3.7/get-pip.py | python3
|
||||
|
||||
# Устанавливаем yq
|
||||
RUN wget -qO /usr/local/bin/yq https://github.com/mikefarah/yq/releases/latest/download/yq_linux_arm64 \
|
||||
&& chmod +x /usr/local/bin/yq
|
||||
|
||||
# Устанавливаем Docker вручную для ALT Linux
|
||||
RUN apt-get update && apt-get install -y \
|
||||
ca-certificates \
|
||||
curl \
|
||||
gnupg \
|
||||
&& apt-get clean
|
||||
|
||||
# Устанавливаем Docker Compose
|
||||
RUN curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose \
|
||||
&& chmod +x /usr/local/bin/docker-compose
|
||||
|
||||
# Настраиваем systemd
|
||||
RUN systemctl set-default multi-user.target
|
||||
|
||||
# Создаем пользователя для Ansible
|
||||
RUN useradd -m -s /bin/bash ansible \
|
||||
&& echo "ansible ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
|
||||
|
||||
# Переключаемся на пользователя ansible
|
||||
USER ansible
|
||||
WORKDIR /home/ansible
|
||||
|
||||
# Команда по умолчанию
|
||||
CMD ["/sbin/init"]
|
||||
89
dockerfiles/ansible-controller/Dockerfile
Normal file
89
dockerfiles/ansible-controller/Dockerfile
Normal file
@@ -0,0 +1,89 @@
|
||||
# Ansible Controller с предустановленными коллекциями
|
||||
# Автор: Сергей Антропов
|
||||
# Сайт: https://devops.org.ru
|
||||
|
||||
FROM ubuntu:22.04
|
||||
|
||||
# Обновляем систему
|
||||
RUN apt-get update && apt-get upgrade -y && apt-get clean
|
||||
|
||||
# Устанавливаем Python и Ansible
|
||||
RUN apt-get install -y \
|
||||
python3 \
|
||||
python3-pip \
|
||||
python3-venv \
|
||||
python3-dev \
|
||||
build-essential \
|
||||
&& apt-get clean
|
||||
|
||||
# Устанавливаем Ansible
|
||||
RUN pip3 install ansible ansible-core
|
||||
|
||||
# Устанавливаем дополнительные пакеты
|
||||
RUN apt-get install -y \
|
||||
curl \
|
||||
wget \
|
||||
git \
|
||||
vim \
|
||||
nano \
|
||||
htop \
|
||||
tree \
|
||||
jq \
|
||||
&& apt-get clean
|
||||
|
||||
# Устанавливаем yq
|
||||
RUN wget -qO /usr/local/bin/yq https://github.com/mikefarah/yq/releases/latest/download/yq_linux_arm64 \
|
||||
&& chmod +x /usr/local/bin/yq
|
||||
|
||||
# Устанавливаем Docker CLI
|
||||
RUN apt-get install -y docker.io docker-compose
|
||||
|
||||
# Устанавливаем kubectl
|
||||
RUN curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" \
|
||||
&& chmod +x kubectl \
|
||||
&& mv kubectl /usr/local/bin/
|
||||
|
||||
# Устанавливаем Helm
|
||||
RUN curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
|
||||
|
||||
# Устанавливаем Kind
|
||||
RUN curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.23.0/kind-linux-amd64 \
|
||||
&& chmod +x ./kind \
|
||||
&& mv ./kind /usr/local/bin/
|
||||
|
||||
# Устанавливаем Istio CLI
|
||||
RUN curl -L https://istio.io/downloadIstio | ISTIO_VERSION=1.22.1 sh - \
|
||||
&& mv istio-1.22.1/bin/istioctl /usr/local/bin/ \
|
||||
&& rm -rf istio-1.22.1
|
||||
|
||||
# Копируем requirements.yml
|
||||
COPY dockerfiles/ansible-controller/requirements.yml /tmp/requirements.yml
|
||||
|
||||
# Устанавливаем Ansible коллекции
|
||||
RUN ansible-galaxy collection install -r /tmp/requirements.yml
|
||||
|
||||
# Создаем пользователя ansible
|
||||
RUN useradd -m -s /bin/bash ansible \
|
||||
&& echo "ansible ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
|
||||
|
||||
# Создаем рабочую директорию
|
||||
WORKDIR /ansible
|
||||
|
||||
# Устанавливаем права
|
||||
RUN chown -R ansible:ansible /ansible
|
||||
|
||||
# Переключаемся на пользователя ansible
|
||||
USER ansible
|
||||
|
||||
# Устанавливаем дополнительные роли
|
||||
RUN ansible-galaxy install geerlingguy.docker \
|
||||
&& ansible-galaxy install geerlingguy.kubernetes
|
||||
|
||||
# Настройки для работы с Docker
|
||||
ENV DOCKER_HOST=unix:///var/run/docker.sock
|
||||
ENV ANSIBLE_FORCE_COLOR=1
|
||||
ENV ANSIBLE_STDOUT_CALLBACK=yaml
|
||||
ENV ANSIBLE_CALLBACKS_ENABLED=profile_tasks
|
||||
|
||||
# Команда по умолчанию
|
||||
CMD ["sleep", "infinity"]
|
||||
23
dockerfiles/ansible-controller/docker-compose.yml
Normal file
23
dockerfiles/ansible-controller/docker-compose.yml
Normal file
@@ -0,0 +1,23 @@
|
||||
version: "3.9"
|
||||
|
||||
services:
|
||||
ansible-controller:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
container_name: ansible-controller
|
||||
privileged: true
|
||||
command: sleep infinity
|
||||
environment:
|
||||
DOCKER_HOST: unix:///var/run/docker.sock
|
||||
ANSIBLE_VAULT_PASSWORD_FILE: /ansible/vault-password.txt
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
- .:/ansible
|
||||
working_dir: /ansible
|
||||
networks:
|
||||
- labnet
|
||||
|
||||
networks:
|
||||
labnet:
|
||||
external: true
|
||||
9
dockerfiles/ansible-controller/requirements.yml
Normal file
9
dockerfiles/ansible-controller/requirements.yml
Normal file
@@ -0,0 +1,9 @@
|
||||
---
|
||||
# Ansible Collections для Molecule Universal
|
||||
collections:
|
||||
- name: community.docker
|
||||
version: ">=3.0.0"
|
||||
- name: community.general
|
||||
version: ">=7.0.0"
|
||||
- name: ansible.posix
|
||||
version: ">=1.5.4"
|
||||
61
dockerfiles/astra-linux/Dockerfile
Normal file
61
dockerfiles/astra-linux/Dockerfile
Normal file
@@ -0,0 +1,61 @@
|
||||
# Astra Linux с systemd
|
||||
# Автор: Сергей Антропов
|
||||
# Сайт: https://devops.org.ru
|
||||
# https://registry.astralinux.ru/browse/library/
|
||||
|
||||
FROM registry.astralinux.ru/library/astra/ubi17:1.7.6.uu2
|
||||
|
||||
# Обновляем систему
|
||||
RUN apt-get update && apt-get dist-upgrade -y
|
||||
|
||||
# Устанавливаем systemd и необходимые пакеты
|
||||
RUN apt-get install -y \
|
||||
systemd \
|
||||
systemd-sysv \
|
||||
dbus \
|
||||
curl \
|
||||
wget \
|
||||
git \
|
||||
vim \
|
||||
nano \
|
||||
htop \
|
||||
tree \
|
||||
jq \
|
||||
python3 \
|
||||
python3-pip \
|
||||
&& apt-get clean
|
||||
|
||||
# Устанавливаем yq
|
||||
RUN wget -qO /usr/local/bin/yq https://github.com/mikefarah/yq/releases/latest/download/yq_linux_arm64 \
|
||||
&& chmod +x /usr/local/bin/yq
|
||||
|
||||
# Устанавливаем Docker вручную для AstraLinux
|
||||
RUN apt-get update && apt-get install -y \
|
||||
ca-certificates \
|
||||
curl \
|
||||
gnupg \
|
||||
lsb-release \
|
||||
&& mkdir -p /usr/share/keyrings \
|
||||
&& curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg \
|
||||
&& echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian buster stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null \
|
||||
&& apt-get update \
|
||||
&& apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin \
|
||||
&& apt-get clean
|
||||
|
||||
# Устанавливаем Docker Compose
|
||||
RUN curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose \
|
||||
&& chmod +x /usr/local/bin/docker-compose
|
||||
|
||||
# Настраиваем systemd
|
||||
RUN systemctl set-default multi-user.target
|
||||
|
||||
# Создаем пользователя для Ansible
|
||||
RUN useradd -m -s /bin/bash ansible \
|
||||
&& echo "ansible ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
|
||||
|
||||
# Переключаемся на пользователя ansible
|
||||
USER ansible
|
||||
WORKDIR /home/ansible
|
||||
|
||||
# Команда по умолчанию
|
||||
CMD ["/sbin/init"]
|
||||
48
dockerfiles/centos/Dockerfile
Normal file
48
dockerfiles/centos/Dockerfile
Normal file
@@ -0,0 +1,48 @@
|
||||
# CentOS с systemd
|
||||
# Автор: Сергей Антропов
|
||||
# Сайт: https://devops.org.ru
|
||||
|
||||
FROM quay.io/centos/centos:stream9
|
||||
|
||||
# Обновляем систему
|
||||
RUN dnf update -y && dnf upgrade -y
|
||||
|
||||
# Устанавливаем systemd и необходимые пакеты
|
||||
RUN dnf install -y --allowerasing \
|
||||
systemd \
|
||||
systemd-sysv \
|
||||
dbus \
|
||||
curl \
|
||||
wget \
|
||||
git \
|
||||
vim \
|
||||
nano \
|
||||
jq \
|
||||
python3 \
|
||||
python3-pip \
|
||||
&& dnf clean all
|
||||
|
||||
# Устанавливаем yq
|
||||
RUN wget -qO /usr/local/bin/yq https://github.com/mikefarah/yq/releases/latest/download/yq_linux_arm64 \
|
||||
&& chmod +x /usr/local/bin/yq
|
||||
|
||||
# Устанавливаем Docker
|
||||
RUN curl -fsSL https://get.docker.com | sh
|
||||
|
||||
# Устанавливаем Docker Compose
|
||||
RUN curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose \
|
||||
&& chmod +x /usr/local/bin/docker-compose
|
||||
|
||||
# Настраиваем systemd
|
||||
RUN systemctl set-default multi-user.target
|
||||
|
||||
# Создаем пользователя для Ansible
|
||||
RUN useradd -m -s /bin/bash ansible \
|
||||
&& echo "ansible ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
|
||||
|
||||
# Переключаемся на пользователя ansible
|
||||
USER ansible
|
||||
WORKDIR /home/ansible
|
||||
|
||||
# Команда по умолчанию
|
||||
CMD ["/sbin/init"]
|
||||
53
dockerfiles/redos/Dockerfile
Normal file
53
dockerfiles/redos/Dockerfile
Normal file
@@ -0,0 +1,53 @@
|
||||
# RED OS с systemd
|
||||
# Автор: Сергей Антропов
|
||||
# Сайт: https://devops.org.ru
|
||||
# https://registry.red-soft.ru/ubi7/ubi/tags
|
||||
# docker search registry.red-soft.ru/ubi7/ubi
|
||||
|
||||
FROM registry.red-soft.ru/ubi7/ubi
|
||||
|
||||
# Обновляем систему
|
||||
RUN dnf update -y && dnf upgrade -y
|
||||
|
||||
# Устанавливаем systemd и необходимые пакеты
|
||||
RUN dnf install -y \
|
||||
systemd \
|
||||
systemd-sysv \
|
||||
dbus \
|
||||
curl \
|
||||
wget \
|
||||
git \
|
||||
vim \
|
||||
nano \
|
||||
jq \
|
||||
python3 \
|
||||
python3-pip \
|
||||
&& dnf clean all
|
||||
|
||||
# Устанавливаем yq
|
||||
RUN wget -qO /usr/local/bin/yq https://github.com/mikefarah/yq/releases/latest/download/yq_linux_arm64 \
|
||||
&& chmod +x /usr/local/bin/yq
|
||||
|
||||
# Устанавливаем Docker вручную для RED OS
|
||||
RUN dnf install -y dnf-plugins-core \
|
||||
&& dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo \
|
||||
&& dnf install -y docker-ce docker-ce-cli containerd.io \
|
||||
&& dnf clean all
|
||||
|
||||
# Устанавливаем Docker Compose
|
||||
RUN curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose \
|
||||
&& chmod +x /usr/local/bin/docker-compose
|
||||
|
||||
# Настраиваем systemd
|
||||
RUN systemctl set-default multi-user.target
|
||||
|
||||
# Создаем пользователя для Ansible
|
||||
RUN useradd -m -s /bin/bash ansible \
|
||||
&& echo "ansible ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
|
||||
|
||||
# Переключаемся на пользователя ansible
|
||||
USER ansible
|
||||
WORKDIR /home/ansible
|
||||
|
||||
# Команда по умолчанию
|
||||
CMD ["/sbin/init"]
|
||||
48
dockerfiles/rhel/Dockerfile
Normal file
48
dockerfiles/rhel/Dockerfile
Normal file
@@ -0,0 +1,48 @@
|
||||
# RHEL с systemd
|
||||
# Автор: Сергей Антропов
|
||||
# Сайт: https://devops.org.ru
|
||||
|
||||
FROM registry.access.redhat.com/ubi8/ubi
|
||||
|
||||
# Обновляем систему
|
||||
RUN dnf update -y && dnf upgrade -y
|
||||
|
||||
# Устанавливаем systemd и необходимые пакеты
|
||||
RUN dnf install -y \
|
||||
systemd \
|
||||
systemd-sysv \
|
||||
dbus \
|
||||
curl \
|
||||
wget \
|
||||
git \
|
||||
vim \
|
||||
nano \
|
||||
jq \
|
||||
python3 \
|
||||
python3-pip \
|
||||
&& dnf clean all
|
||||
|
||||
# Устанавливаем yq
|
||||
RUN wget -qO /usr/local/bin/yq https://github.com/mikefarah/yq/releases/latest/download/yq_linux_arm64 \
|
||||
&& chmod +x /usr/local/bin/yq
|
||||
|
||||
# Устанавливаем Docker
|
||||
RUN curl -fsSL https://get.docker.com | sh
|
||||
|
||||
# Устанавливаем Docker Compose
|
||||
RUN curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose \
|
||||
&& chmod +x /usr/local/bin/docker-compose
|
||||
|
||||
# Настраиваем systemd
|
||||
RUN systemctl set-default multi-user.target
|
||||
|
||||
# Создаем пользователя для Ansible
|
||||
RUN useradd -m -s /bin/bash ansible \
|
||||
&& echo "ansible ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
|
||||
|
||||
# Переключаемся на пользователя ansible
|
||||
USER ansible
|
||||
WORKDIR /home/ansible
|
||||
|
||||
# Команда по умолчанию
|
||||
CMD ["/sbin/init"]
|
||||
50
dockerfiles/rocky/Dockerfile
Normal file
50
dockerfiles/rocky/Dockerfile
Normal file
@@ -0,0 +1,50 @@
|
||||
# Rocky Linux с systemd
|
||||
# Автор: Сергей Антропов
|
||||
# Сайт: https://devops.org.ru
|
||||
|
||||
FROM rockylinux:8
|
||||
|
||||
# Обновляем систему
|
||||
RUN dnf update -y && dnf upgrade -y
|
||||
|
||||
# Устанавливаем systemd и необходимые пакеты
|
||||
RUN dnf install -y \
|
||||
systemd \
|
||||
systemd-sysv \
|
||||
dbus \
|
||||
curl \
|
||||
wget \
|
||||
git \
|
||||
vim \
|
||||
nano \
|
||||
jq \
|
||||
python3 \
|
||||
python3-pip \
|
||||
&& dnf clean all
|
||||
|
||||
# Устанавливаем yq
|
||||
RUN wget -qO /usr/local/bin/yq https://github.com/mikefarah/yq/releases/latest/download/yq_linux_arm64 \
|
||||
&& chmod +x /usr/local/bin/yq
|
||||
|
||||
# Устанавливаем Docker
|
||||
RUN dnf install -y dnf-plugins-core \
|
||||
&& dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo \
|
||||
&& dnf install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
|
||||
|
||||
# Устанавливаем Docker Compose
|
||||
RUN curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose \
|
||||
&& chmod +x /usr/local/bin/docker-compose
|
||||
|
||||
# Настраиваем systemd
|
||||
RUN systemctl set-default multi-user.target
|
||||
|
||||
# Создаем пользователя для Ansible
|
||||
RUN useradd -m -s /bin/bash ansible \
|
||||
&& echo "ansible ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
|
||||
|
||||
# Переключаемся на пользователя ansible
|
||||
USER ansible
|
||||
WORKDIR /home/ansible
|
||||
|
||||
# Команда по умолчанию
|
||||
CMD ["/sbin/init"]
|
||||
424
docs/examples.md
Normal file
424
docs/examples.md
Normal file
@@ -0,0 +1,424 @@
|
||||
# Примеры использования универсальной системы тестирования
|
||||
|
||||
## Пример 1: Тестирование кластера etcd + PostgreSQL + Patroni
|
||||
|
||||
### Описание
|
||||
Этот пример демонстрирует тестирование высокодоступного кластера PostgreSQL с Patroni и etcd.
|
||||
|
||||
### Preset: etcd-patroni
|
||||
|
||||
```yaml
|
||||
# molecule/presets/etcd-patroni.yml
|
||||
hosts:
|
||||
# ETCD кластер (5 узлов для высокой доступности)
|
||||
- name: etcd1
|
||||
family: debian
|
||||
groups: [etcd, cluster]
|
||||
- name: etcd2
|
||||
family: rhel
|
||||
groups: [etcd, cluster]
|
||||
- name: etcd3
|
||||
family: debian
|
||||
groups: [etcd, cluster]
|
||||
- name: etcd4
|
||||
family: rhel
|
||||
groups: [etcd, cluster]
|
||||
- name: etcd5
|
||||
family: debian
|
||||
groups: [etcd, cluster]
|
||||
|
||||
# Patroni кластер (3 узла PostgreSQL)
|
||||
- name: patroni1
|
||||
family: rhel
|
||||
groups: [patroni, database, cluster]
|
||||
- name: patroni2
|
||||
family: debian
|
||||
groups: [patroni, database, cluster]
|
||||
- name: patroni3
|
||||
family: rhel
|
||||
groups: [patroni, database, cluster]
|
||||
|
||||
# HAProxy для балансировки
|
||||
- name: haproxy
|
||||
family: debian
|
||||
groups: [haproxy, loadbalancer]
|
||||
publish: ["5000:5000", "5001:5001"] # RW и RO порты
|
||||
|
||||
# DinD узел для тестирования Docker Compose внутри
|
||||
- name: app-dind
|
||||
type: dind
|
||||
groups: [apps, docker]
|
||||
publish: ["8080:8080"]
|
||||
```
|
||||
|
||||
### Запуск тестирования
|
||||
|
||||
```bash
|
||||
# Информация о preset'е
|
||||
make preset-info PRESET=etcd-patroni
|
||||
|
||||
# Тестирование с preset'ом
|
||||
make preset-test PRESET=etcd-patroni
|
||||
|
||||
# Или через role test
|
||||
make role test etcd-patroni
|
||||
```
|
||||
|
||||
### Проверка результатов
|
||||
|
||||
```bash
|
||||
# Проверить статус контейнеров
|
||||
make container-info
|
||||
|
||||
# Проверить vault файлы
|
||||
make vault-check
|
||||
```
|
||||
|
||||
## Пример 2: Нагрузочное тестирование
|
||||
|
||||
### Описание
|
||||
Этот пример демонстрирует тестирование под нагрузкой с множественными серверами и кэшем.
|
||||
|
||||
### Preset: performance
|
||||
|
||||
```yaml
|
||||
# molecule/presets/performance.yml
|
||||
hosts:
|
||||
# Основные серверы (5 узлов)
|
||||
- name: server1
|
||||
family: debian
|
||||
groups: [servers, web, app]
|
||||
- name: server2
|
||||
family: rhel
|
||||
groups: [servers, web, app]
|
||||
- name: server3
|
||||
family: debian
|
||||
groups: [servers, web, app]
|
||||
- name: server4
|
||||
family: rhel
|
||||
groups: [servers, web, app]
|
||||
- name: server5
|
||||
family: debian
|
||||
groups: [servers, web, app]
|
||||
|
||||
# База данных (3 узла)
|
||||
- name: db1
|
||||
family: rhel
|
||||
groups: [database, db]
|
||||
- name: db2
|
||||
family: debian
|
||||
groups: [database, db]
|
||||
- name: db3
|
||||
family: rhel
|
||||
groups: [database, db]
|
||||
|
||||
# Кэш (3 узла Redis)
|
||||
- name: cache1
|
||||
family: debian
|
||||
groups: [cache, redis]
|
||||
- name: cache2
|
||||
family: rhel
|
||||
groups: [cache, redis]
|
||||
- name: cache3
|
||||
family: debian
|
||||
groups: [cache, redis]
|
||||
|
||||
# Load balancer
|
||||
- name: lb1
|
||||
family: rhel
|
||||
groups: [loadbalancer, haproxy]
|
||||
publish: ["80:80", "443:443"]
|
||||
|
||||
# DinD узел для тестирования Docker Compose
|
||||
- name: compose-dind
|
||||
type: dind
|
||||
groups: [apps, docker]
|
||||
publish: ["8080:8080", "8081:8081"]
|
||||
```
|
||||
|
||||
### Запуск тестирования
|
||||
|
||||
```bash
|
||||
# Тестирование с performance preset'ом
|
||||
make role test performance
|
||||
|
||||
# Проверка статуса
|
||||
make container-info
|
||||
```
|
||||
|
||||
## Пример 3: Тестирование безопасности
|
||||
|
||||
### Описание
|
||||
Этот пример демонстрирует тестирование в безопасной среде с bastion хостами и изоляцией.
|
||||
|
||||
### Preset: security
|
||||
|
||||
```yaml
|
||||
# molecule/presets/security.yml
|
||||
hosts:
|
||||
# Bastion хосты (точки входа)
|
||||
- name: bastion1
|
||||
family: rhel
|
||||
groups: [bastion, security, jump]
|
||||
publish: ["2222:22"]
|
||||
- name: bastion2
|
||||
family: debian
|
||||
groups: [bastion, security, jump]
|
||||
publish: ["2223:22"]
|
||||
|
||||
# Внутренние серверы (без внешнего доступа)
|
||||
- name: internal1
|
||||
family: rhel
|
||||
groups: [internal, servers, app]
|
||||
- name: internal2
|
||||
family: debian
|
||||
groups: [internal, servers, app]
|
||||
- name: internal3
|
||||
family: rhel
|
||||
groups: [internal, servers, app]
|
||||
|
||||
# База данных (изолированная сеть)
|
||||
- name: db-secure1
|
||||
family: rhel
|
||||
groups: [database, secure, internal]
|
||||
- name: db-secure2
|
||||
family: debian
|
||||
groups: [database, secure, internal]
|
||||
|
||||
# Мониторинг и логирование
|
||||
- name: monitor1
|
||||
family: debian
|
||||
groups: [monitoring, security, logs]
|
||||
- name: monitor2
|
||||
family: rhel
|
||||
groups: [monitoring, security, logs]
|
||||
|
||||
# Firewall и сетевые компоненты
|
||||
- name: fw1
|
||||
family: rhel
|
||||
groups: [firewall, network, security]
|
||||
- name: fw2
|
||||
family: debian
|
||||
groups: [firewall, network, security]
|
||||
|
||||
# DOoD узел для тестирования Docker безопасности
|
||||
- name: docker-secure
|
||||
type: dood
|
||||
family: debian
|
||||
groups: [docker, security, apps]
|
||||
publish: ["8080:8080"]
|
||||
env:
|
||||
DOCKER_HOST: "unix:///var/run/docker.sock"
|
||||
```
|
||||
|
||||
### Запуск тестирования
|
||||
|
||||
```bash
|
||||
# Тестирование с security preset'ом
|
||||
make role test security
|
||||
|
||||
# Проверка безопасности
|
||||
make vault-check
|
||||
make vault-scan
|
||||
```
|
||||
|
||||
## Пример 4: Тестирование на разных ОС
|
||||
|
||||
### Описание
|
||||
Этот пример демонстрирует тестирование на различных операционных системах.
|
||||
|
||||
### Preset: multi-os
|
||||
|
||||
```yaml
|
||||
# molecule/presets/multi-os.yml
|
||||
hosts:
|
||||
# Debian/Ubuntu серверы
|
||||
- name: ubuntu1
|
||||
family: ubuntu
|
||||
groups: [ubuntu, servers, web]
|
||||
- name: debian1
|
||||
family: debian
|
||||
groups: [debian, servers, web]
|
||||
- name: ubuntu2
|
||||
family: ubuntu
|
||||
groups: [ubuntu, servers, app]
|
||||
- name: debian2
|
||||
family: debian
|
||||
groups: [debian, servers, app]
|
||||
|
||||
# RHEL/CentOS серверы
|
||||
- name: rhel1
|
||||
family: rhel
|
||||
groups: [rhel, servers, web]
|
||||
- name: centos1
|
||||
family: centos
|
||||
groups: [centos, servers, web]
|
||||
- name: rhel2
|
||||
family: rhel
|
||||
groups: [rhel, servers, app]
|
||||
- name: centos2
|
||||
family: centos
|
||||
groups: [centos, servers, app]
|
||||
|
||||
# База данных на разных ОС
|
||||
- name: db-ubuntu
|
||||
family: ubuntu
|
||||
groups: [database, ubuntu, db]
|
||||
- name: db-rhel
|
||||
family: rhel
|
||||
groups: [database, rhel, db]
|
||||
|
||||
# Load balancer
|
||||
- name: lb-mixed
|
||||
family: debian
|
||||
groups: [loadbalancer, haproxy]
|
||||
publish: ["80:80", "443:443"]
|
||||
|
||||
# DinD узел для тестирования Docker
|
||||
- name: docker-mixed
|
||||
type: dind
|
||||
groups: [docker, apps]
|
||||
publish: ["8080:8080"]
|
||||
```
|
||||
|
||||
### Запуск тестирования
|
||||
|
||||
```bash
|
||||
# Тестирование с multi-os preset'ом
|
||||
make role test multi-os
|
||||
|
||||
# Проверка типов контейнеров
|
||||
make container-types
|
||||
```
|
||||
|
||||
## Пример 5: Создание собственного preset'а
|
||||
|
||||
### Описание
|
||||
Этот пример демонстрирует создание собственного preset'а для специфических нужд.
|
||||
|
||||
### Создание preset'а
|
||||
|
||||
```bash
|
||||
# Создать новый preset
|
||||
cat > molecule/presets/my-custom.yml << 'EOF'
|
||||
---
|
||||
# Пресет для тестирования веб-приложения
|
||||
# Автор: Ваше имя
|
||||
# Сайт: https://your-site.com
|
||||
|
||||
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:
|
||||
# Веб-серверы
|
||||
- name: web1
|
||||
family: debian
|
||||
groups: [web, servers]
|
||||
publish: ["80:80", "443:443"]
|
||||
- name: web2
|
||||
family: rhel
|
||||
groups: [web, servers]
|
||||
publish: ["8080:80", "8443:443"]
|
||||
|
||||
# База данных
|
||||
- name: db1
|
||||
family: rhel
|
||||
groups: [database, db]
|
||||
- name: db2
|
||||
family: debian
|
||||
groups: [database, db]
|
||||
|
||||
# Кэш
|
||||
- name: cache1
|
||||
family: debian
|
||||
groups: [cache, redis]
|
||||
|
||||
# DinD узел для тестирования
|
||||
- name: app-dind
|
||||
type: dind
|
||||
groups: [apps, docker]
|
||||
publish: ["8080:8080"]
|
||||
EOF
|
||||
```
|
||||
|
||||
### Использование preset'а
|
||||
|
||||
```bash
|
||||
# Информация о preset'е
|
||||
make preset-info PRESET=my-custom
|
||||
|
||||
# Тестирование с preset'ом
|
||||
make preset-test PRESET=my-custom
|
||||
|
||||
# Или через role test
|
||||
make role test my-custom
|
||||
```
|
||||
|
||||
## Пример 6: Работа с Ansible Vault
|
||||
|
||||
### Создание vault файла
|
||||
|
||||
```bash
|
||||
# Создать файл секретов
|
||||
make vault create
|
||||
|
||||
# Ввести имя файла: secrets
|
||||
# Ввести содержимое:
|
||||
# ---
|
||||
# database_password: "super_secret_password"
|
||||
# api_key: "your_api_key_here"
|
||||
# ssl_cert: "your_ssl_certificate"
|
||||
```
|
||||
|
||||
### Использование в ролях
|
||||
|
||||
```yaml
|
||||
# roles/my-role/tasks/main.yml
|
||||
- name: Configure database
|
||||
template:
|
||||
src: database.conf.j2
|
||||
dest: /etc/database.conf
|
||||
vars:
|
||||
db_password: "{{ database_password }}"
|
||||
api_key: "{{ api_key }}"
|
||||
```
|
||||
|
||||
### Проверка безопасности
|
||||
|
||||
```bash
|
||||
# Проверить vault файлы
|
||||
make vault-check
|
||||
|
||||
# Найти потенциальные секреты
|
||||
make vault-scan
|
||||
```
|
||||
|
||||
## Заключение
|
||||
|
||||
Эти примеры демонстрируют различные способы использования универсальной системы тестирования Ansible ролей. Вы можете:
|
||||
|
||||
1. Использовать готовые preset'ы для быстрого тестирования
|
||||
2. Создавать собственные preset'ы для специфических нужд
|
||||
3. Комбинировать различные типы контейнеров
|
||||
4. Использовать Ansible Vault для безопасности
|
||||
5. Тестировать на различных операционных системах
|
||||
|
||||
Для получения дополнительной информации используйте:
|
||||
- `make help` - общая справка
|
||||
- `make preset-list` - список preset'ов
|
||||
- `make container-types` - типы контейнеров
|
||||
- `make vault` - команды Vault
|
||||
99
docs/testing-vs-deployment.md
Normal file
99
docs/testing-vs-deployment.md
Normal 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** для ваших реальных серверов
|
||||
281
docs/universal-testing.md
Normal file
281
docs/universal-testing.md
Normal file
@@ -0,0 +1,281 @@
|
||||
# Универсальная система тестирования Ansible ролей
|
||||
|
||||
## Обзор
|
||||
|
||||
Эта система предоставляет универсальную среду для тестирования и деплоя Ansible ролей с поддержкой различных типов контейнеров, автоматической генерации инвентаря и интеграции с Ansible Vault.
|
||||
|
||||
## Основные возможности
|
||||
|
||||
### 🐳 Типы контейнеров
|
||||
|
||||
#### Systemd контейнеры (по умолчанию)
|
||||
- Полная поддержка systemd сервисов
|
||||
- Работа как виртуальные машины
|
||||
- Подходит для тестирования ролей
|
||||
|
||||
#### DinD (Docker-in-Docker)
|
||||
- Изолированный Docker daemon
|
||||
- Подходит для тестирования Docker Compose
|
||||
- Полная изоляция от хостового Docker
|
||||
|
||||
#### DOoD (Docker-out-of-Docker)
|
||||
- Доступ к хостовому Docker daemon
|
||||
- Быстрое тестирование
|
||||
- Подходит для CI/CD
|
||||
|
||||
### 📋 Preset'ы
|
||||
|
||||
#### etcd-patroni
|
||||
- Кластер etcd (5 узлов)
|
||||
- Кластер PostgreSQL с Patroni (3 узла)
|
||||
- HAProxy для балансировки
|
||||
- DinD узел для тестирования
|
||||
|
||||
#### performance
|
||||
- 5 серверов приложений
|
||||
- 3 узла базы данных
|
||||
- 3 узла кэша Redis
|
||||
- Load balancer
|
||||
- DinD узел для тестирования
|
||||
|
||||
#### security
|
||||
- Bastion хосты
|
||||
- Внутренние серверы
|
||||
- Изолированная база данных
|
||||
- Мониторинг и логирование
|
||||
- Firewall компоненты
|
||||
- DOoD узел для тестирования
|
||||
|
||||
#### multi-os
|
||||
- Тестирование на разных ОС
|
||||
- Ubuntu, Debian, RHEL, CentOS
|
||||
- Смешанные конфигурации
|
||||
- DinD узел для тестирования
|
||||
|
||||
### 🔐 Ansible Vault интеграция
|
||||
|
||||
- Автоматическая расшифровка перед тестированием
|
||||
- Безопасное хранение секретов
|
||||
- Автоматическая повторная шифровка после тестирования
|
||||
- Поддержка множественных vault'ов
|
||||
|
||||
## Использование
|
||||
|
||||
### Базовые команды
|
||||
|
||||
```bash
|
||||
# Показать все preset'ы
|
||||
make preset-list
|
||||
|
||||
# Информация о preset'е
|
||||
make preset-info PRESET=etcd-patroni
|
||||
|
||||
# Тестирование с preset'ом
|
||||
make preset-test PRESET=etcd-patroni
|
||||
|
||||
# Типы контейнеров
|
||||
make container-types
|
||||
|
||||
# Информация о контейнерах
|
||||
make container-info
|
||||
|
||||
# Проверка vault файлов
|
||||
make vault-check
|
||||
|
||||
# Поиск секретов
|
||||
make vault-scan
|
||||
```
|
||||
|
||||
### Тестирование ролей
|
||||
|
||||
```bash
|
||||
# С default preset
|
||||
make role test
|
||||
|
||||
# С конкретным preset'ом
|
||||
make role test etcd-patroni
|
||||
make role test performance
|
||||
make role test security
|
||||
make role test multi-os
|
||||
```
|
||||
|
||||
### Работа с Ansible Vault
|
||||
|
||||
```bash
|
||||
# Создать файл секретов
|
||||
make vault create
|
||||
|
||||
# Редактировать секреты
|
||||
make vault edit
|
||||
|
||||
# Показать секреты
|
||||
make vault show
|
||||
|
||||
# Зашифровать файл
|
||||
make vault encrypt
|
||||
|
||||
# Расшифровать файл
|
||||
make vault decrypt
|
||||
```
|
||||
|
||||
## Структура проекта
|
||||
|
||||
```
|
||||
.
|
||||
├── molecule/
|
||||
│ ├── default/
|
||||
│ │ ├── create.yml # Создание контейнеров
|
||||
│ │ ├── destroy.yml # Удаление контейнеров
|
||||
│ │ ├── converge.yml # Запуск плейбуков
|
||||
│ │ └── verify.yml # Проверка результатов
|
||||
│ └── presets/
|
||||
│ ├── etcd-patroni.yml
|
||||
│ ├── performance.yml
|
||||
│ ├── security.yml
|
||||
│ └── multi-os.yml
|
||||
├── files/
|
||||
│ ├── requirements.yml
|
||||
│ └── playbooks/
|
||||
│ └── site.yml
|
||||
├── vault/
|
||||
│ └── secrets.yml
|
||||
└── Makefile
|
||||
```
|
||||
|
||||
## Создание собственных preset'ов
|
||||
|
||||
### Пример preset'а
|
||||
|
||||
```yaml
|
||||
---
|
||||
# Пресет для тестирования кластера etcd + PostgreSQL + Patroni
|
||||
# Автор: Сергей Антропов
|
||||
# Сайт: 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:
|
||||
# Systemd узлы
|
||||
- name: server1
|
||||
family: debian
|
||||
groups: [servers, web]
|
||||
publish: ["80:80"]
|
||||
|
||||
# DinD узел
|
||||
- name: app-dind
|
||||
type: dind
|
||||
groups: [apps, docker]
|
||||
publish: ["8080:8080"]
|
||||
|
||||
# DOoD узел
|
||||
- name: docker-secure
|
||||
type: dood
|
||||
family: debian
|
||||
groups: [docker, security]
|
||||
publish: ["8081:8081"]
|
||||
env:
|
||||
DOCKER_HOST: "unix:///var/run/docker.sock"
|
||||
```
|
||||
|
||||
### Параметры хостов
|
||||
|
||||
- `name` - имя хоста
|
||||
- `family` - семейство ОС (debian, rhel, ubuntu, centos)
|
||||
- `type` - тип контейнера (dind, dood)
|
||||
- `groups` - группы для инвентаря
|
||||
- `publish` - порты для публикации
|
||||
- `env` - переменные окружения
|
||||
- `volumes` - дополнительные тома
|
||||
- `capabilities` - дополнительные возможности
|
||||
|
||||
## Лучшие практики
|
||||
|
||||
### 1. Использование групп
|
||||
|
||||
```yaml
|
||||
hosts:
|
||||
- name: web1
|
||||
groups: [web, servers, production]
|
||||
- name: db1
|
||||
groups: [database, servers, production]
|
||||
```
|
||||
|
||||
### 2. Безопасность
|
||||
|
||||
```yaml
|
||||
# Используйте Ansible Vault для секретов
|
||||
vault_targets:
|
||||
- /ansible/vault/secrets.yml
|
||||
- /ansible/files/playbooks/group_vars/*/vault.yml
|
||||
- /ansible/files/playbooks/host_vars/*/vault.yml
|
||||
```
|
||||
|
||||
### 3. Тестирование
|
||||
|
||||
```yaml
|
||||
# Проверяйте различные сценарии
|
||||
- name: Test web servers
|
||||
hosts: web
|
||||
tasks:
|
||||
- name: Check nginx status
|
||||
systemd:
|
||||
name: nginx
|
||||
state: started
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Проблемы с контейнерами
|
||||
|
||||
```bash
|
||||
# Проверить статус контейнеров
|
||||
make container-info
|
||||
|
||||
# Очистить Docker ресурсы
|
||||
make docker clean
|
||||
```
|
||||
|
||||
### Проблемы с Vault
|
||||
|
||||
```bash
|
||||
# Проверить vault файлы
|
||||
make vault-check
|
||||
|
||||
# Найти потенциальные секреты
|
||||
make vault-scan
|
||||
```
|
||||
|
||||
### Проблемы с preset'ами
|
||||
|
||||
```bash
|
||||
# Показать все preset'ы
|
||||
make preset-list
|
||||
|
||||
# Информация о preset'е
|
||||
make preset-info PRESET=имя_пресета
|
||||
```
|
||||
|
||||
## Заключение
|
||||
|
||||
Универсальная система тестирования Ansible ролей предоставляет мощные инструменты для тестирования ролей в различных сценариях. Используйте preset'ы для быстрого создания тестовых сред, различные типы контейнеров для изоляции и Ansible Vault для безопасности.
|
||||
|
||||
Для получения дополнительной информации используйте:
|
||||
- `make help` - общая справка
|
||||
- `make role` - команды для ролей
|
||||
- `make molecule` - команды Molecule
|
||||
- `make vault` - команды Vault
|
||||
@@ -1 +0,0 @@
|
||||
[all]
|
||||
16
inventory/hosts.ini
Normal file
16
inventory/hosts.ini
Normal file
@@ -0,0 +1,16 @@
|
||||
# Инвентори для развертывания на реальные серверы
|
||||
# Автор: Сергей Антропов
|
||||
# Сайт: https://devops.org.ru
|
||||
|
||||
# Примеры серверов (замените на ваши реальные серверы)
|
||||
[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,6 +1,75 @@
|
||||
---
|
||||
- name: Converge
|
||||
hosts: all
|
||||
vars_files:
|
||||
- ../../vars/secrets.yml
|
||||
roles:
|
||||
- hosts: localhost
|
||||
gather_facts: false
|
||||
vars:
|
||||
# Получаем preset из переменной окружения или используем default
|
||||
preset_name: "{{ lookup('env', 'MOLECULE_PRESET') | default('default') }}"
|
||||
preset_file: "/workspace/molecule/presets/{{ preset_name }}.yml"
|
||||
|
||||
# перечисли файлы/глобы, которые нужно временно расшифровать
|
||||
vault_targets:
|
||||
- /ansible/vault/secrets.yml
|
||||
- /ansible/files/playbooks/group_vars/*/vault.yml
|
||||
- /ansible/files/playbooks/host_vars/*/vault.yml
|
||||
- /ansible/roles/**/vars/vault.yml
|
||||
|
||||
tasks:
|
||||
- name: Load preset configuration
|
||||
include_vars: "{{ preset_file }}"
|
||||
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 /ansible/requirements.yml --force --no-deps --upgrade >/dev/null 2>&1 || true"
|
||||
|
||||
- name: Preflight vault — normalize state (encrypt if plaintext, then decrypt)
|
||||
community.docker.docker_container_exec:
|
||||
container: ansible-controller
|
||||
command: >
|
||||
bash -lc '
|
||||
set -euo pipefail; shopt -s nullglob globstar;
|
||||
for p in {{ vault_targets | map('quote') | join(' ') }}; do
|
||||
for f in $p; do
|
||||
[ -f "$f" ] || continue;
|
||||
if head -n1 "$f" | grep -q "^\$ANSIBLE_VAULT;"; then
|
||||
echo "[vault] already encrypted: $f";
|
||||
else
|
||||
echo "[vault] plaintext -> encrypt: $f";
|
||||
ansible-vault encrypt --encrypt-vault-id default --vault-password-file /ansible/vault-password.txt "$f";
|
||||
fi
|
||||
echo "[vault] decrypt for run: $f";
|
||||
ansible-vault decrypt --vault-password-file /ansible/vault-password.txt "$f";
|
||||
done
|
||||
done
|
||||
'
|
||||
|
||||
- name: Run lab playbook
|
||||
community.docker.docker_container_exec:
|
||||
container: ansible-controller
|
||||
command: >
|
||||
bash -lc "
|
||||
ANSIBLE_ROLES_PATH=/ansible/roles
|
||||
ansible-playbook -i {{ lookup('env','MOLECULE_EPHEMERAL_DIRECTORY') }}/inventory/hosts.ini /ansible/files/playbooks/site.yml
|
||||
"
|
||||
|
||||
- name: Post-run — re-encrypt secrets
|
||||
community.docker.docker_container_exec:
|
||||
container: ansible-controller
|
||||
command: >
|
||||
bash -lc '
|
||||
set -euo pipefail; shopt -s nullglob globstar;
|
||||
for p in {{ vault_targets | map('quote') | join(' ') }}; do
|
||||
for f in $p; do
|
||||
[ -f "$f" ] || continue;
|
||||
if head -n1 "$f" | grep -q "^\$ANSIBLE_VAULT;"; then
|
||||
echo "[vault] ok (encrypted): $f";
|
||||
else
|
||||
echo "[vault] encrypt back: $f";
|
||||
ansible-vault encrypt --encrypt-vault-id default --vault-password-file /ansible/vault-password.txt "$f" || true;
|
||||
fi
|
||||
done
|
||||
done
|
||||
'
|
||||
ignore_errors: true
|
||||
165
molecule/default/create.yml
Normal file
165
molecule/default/create.yml
Normal file
@@ -0,0 +1,165 @@
|
||||
---
|
||||
- hosts: localhost
|
||||
gather_facts: false
|
||||
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"
|
||||
rhel: "quay.io/centos/centos:stream9-systemd"
|
||||
ubuntu: "ghcr.io/ansible-community/molecule-ubuntu-systemd:jammy"
|
||||
centos: "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:
|
||||
- name: u1
|
||||
family: debian
|
||||
groups: [test]
|
||||
|
||||
tasks:
|
||||
- name: Install required collections
|
||||
command: ansible-galaxy collection install -r /workspace/requirements.yml
|
||||
delegate_to: localhost
|
||||
ignore_errors: true
|
||||
register: collections_install
|
||||
changed_when: false
|
||||
run_once: true
|
||||
become: true
|
||||
vars:
|
||||
ansible_python_interpreter: /usr/bin/python3
|
||||
environment:
|
||||
ANSIBLE_COLLECTIONS_PATH: /usr/share/ansible/collections
|
||||
|
||||
- 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
|
||||
|
||||
# SYSTEMD nodes
|
||||
- name: Pull systemd images
|
||||
community.docker.docker_image:
|
||||
name: "{{ images[item.family] }}"
|
||||
source: pull
|
||||
loop: "{{ hosts | selectattr('type','undefined') | list }}"
|
||||
loop_control: { label: "{{ item.name }}" }
|
||||
when: item.family is defined and images[item.family] is defined
|
||||
|
||||
- name: Start systemd nodes
|
||||
community.docker.docker_container:
|
||||
name: "{{ item.name }}"
|
||||
image: "{{ images[item.family] }}"
|
||||
networks:
|
||||
- name: "{{ docker_network }}"
|
||||
privileged: "{{ systemd_defaults.privileged }}"
|
||||
command: "{{ systemd_defaults.command }}"
|
||||
volumes: "{{ systemd_defaults.volumes | default([]) + (item.volumes | default([])) }}"
|
||||
tmpfs: "{{ systemd_defaults.tmpfs | default([]) }}"
|
||||
capabilities: "{{ systemd_defaults.capabilities | default([]) }}"
|
||||
published_ports: "{{ item.publish | default([]) }}"
|
||||
environment: "{{ item.env | default({}) }}"
|
||||
state: started
|
||||
restart_policy: unless-stopped
|
||||
loop: "{{ hosts | selectattr('type','undefined') | list }}"
|
||||
loop_control: { label: "{{ item.name }}" }
|
||||
when: item.family is defined and images[item.family] is defined
|
||||
|
||||
# DinD nodes
|
||||
- name: Start DinD nodes (docker:27-dind)
|
||||
community.docker.docker_container:
|
||||
name: "{{ item.name }}"
|
||||
image: "docker:27-dind"
|
||||
networks:
|
||||
- name: "{{ docker_network }}"
|
||||
privileged: true
|
||||
environment:
|
||||
DOCKER_TLS_CERTDIR: ""
|
||||
published_ports: "{{ item.publish | default([]) }}"
|
||||
volumes: "{{ (item.volumes | default([])) + [item.name + '-docker:/var/lib/docker'] }}"
|
||||
state: started
|
||||
restart_policy: unless-stopped
|
||||
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([]) }}"
|
||||
capabilities: "{{ systemd_defaults.capabilities | default([]) }}"
|
||||
published_ports: "{{ item.publish | default([]) }}"
|
||||
environment: "{{ item.env | default({}) }}"
|
||||
state: started
|
||||
restart_policy: unless-stopped
|
||||
loop: "{{ hosts | selectattr('type','defined') | selectattr('type','equalto','dood') | list }}"
|
||||
loop_control: { label: "{{ item.name }}" }
|
||||
when: item.family is defined and images[item.family] is defined
|
||||
|
||||
# Build groups map
|
||||
- name: Initialize groups map
|
||||
set_fact:
|
||||
groups_map: {}
|
||||
|
||||
- name: Append hosts to groups
|
||||
set_fact:
|
||||
groups_map: "{{ groups_map | combine({ item_group: (groups_map[item_group] | default([])) + [item_name] }) }}"
|
||||
loop: "{{ hosts | subelements('groups', skip_missing=True) }}"
|
||||
loop_control:
|
||||
label: "{{ item.0.name }}"
|
||||
vars:
|
||||
item_name: "{{ item.0.name }}"
|
||||
item_group: "{{ item.1 }}"
|
||||
|
||||
# Render inventory
|
||||
- name: Render inventory ini
|
||||
set_fact:
|
||||
inv_content: |
|
||||
[all:vars]
|
||||
ansible_connection=community.docker.docker
|
||||
ansible_python_interpreter=/usr/bin/python3
|
||||
|
||||
{% for group, members in (groups_map | dictsort) %}
|
||||
[{{ group }}]
|
||||
{% for h in members %}{{ h }}
|
||||
{% endfor %}
|
||||
|
||||
{% endfor %}
|
||||
[all]
|
||||
{% for h in hosts %}{{ h.name }}
|
||||
{% endfor %}
|
||||
|
||||
- name: Write inventory file
|
||||
copy:
|
||||
dest: "{{ generated_inventory }}"
|
||||
content: "{{ inv_content }}"
|
||||
mode: "0644"
|
||||
|
||||
- name: Display inventory summary
|
||||
debug:
|
||||
msg: |
|
||||
📋 Inventory Summary:
|
||||
- Total hosts: {{ hosts | length }}
|
||||
- Groups: {{ groups_map.keys() | list | join(', ') }}
|
||||
- Systemd nodes: {{ hosts | selectattr('type','undefined') | list | length }}
|
||||
- DinD nodes: {{ hosts | selectattr('type','defined') | selectattr('type','equalto','dind') | list | length }}
|
||||
- DOoD nodes: {{ hosts | selectattr('type','defined') | selectattr('type','equalto','dood') | list | length }}
|
||||
@@ -1,8 +1,60 @@
|
||||
- name: Destroy containers on interrupt
|
||||
hosts: localhost
|
||||
---
|
||||
- hosts: localhost
|
||||
gather_facts: false
|
||||
vars:
|
||||
# Получаем preset из переменной окружения или используем default
|
||||
preset_name: "{{ lookup('env', 'MOLECULE_PRESET') | default('default') }}"
|
||||
preset_file: "/workspace/molecule/presets/{{ preset_name }}.yml"
|
||||
|
||||
# Fallback значения если preset файл не найден
|
||||
docker_network: labnet
|
||||
hosts:
|
||||
- name: u1
|
||||
family: debian
|
||||
groups: [test]
|
||||
|
||||
tasks:
|
||||
- name: Ensure containers are destroyed
|
||||
docker_container:
|
||||
- name: Load preset configuration
|
||||
include_vars: "{{ preset_file }}"
|
||||
when: preset_file is file
|
||||
ignore_errors: true
|
||||
|
||||
- name: Stop and remove containers
|
||||
community.docker.docker_container:
|
||||
name: "{{ item.name }}"
|
||||
state: absent
|
||||
loop: "{{ molecule_yml.platforms }}"
|
||||
force_kill: true
|
||||
loop: "{{ hosts }}"
|
||||
loop_control: { label: "{{ item.name }}" }
|
||||
ignore_errors: true
|
||||
|
||||
- name: Remove DinD volumes
|
||||
community.docker.docker_volume:
|
||||
name: "{{ item.name }}-docker"
|
||||
state: absent
|
||||
loop: "{{ hosts | selectattr('type','defined') | selectattr('type','equalto','dind') | list }}"
|
||||
loop_control: { label: "{{ item.name }}" }
|
||||
ignore_errors: true
|
||||
|
||||
- name: Remove custom volumes
|
||||
community.docker.docker_volume:
|
||||
name: "{{ item.volumes | default([]) | select('match', '^[^:]+$') | list }}"
|
||||
state: absent
|
||||
loop: "{{ hosts }}"
|
||||
loop_control: { label: "{{ item.name }}" }
|
||||
ignore_errors: true
|
||||
when: item.volumes is defined
|
||||
|
||||
- name: Remove network
|
||||
community.docker.docker_network:
|
||||
name: "{{ docker_network }}"
|
||||
state: absent
|
||||
ignore_errors: true
|
||||
|
||||
- name: Display cleanup summary
|
||||
debug:
|
||||
msg: |
|
||||
🧹 Cleanup Summary:
|
||||
- Removed containers: {{ hosts | length }}
|
||||
- Removed DinD volumes: {{ hosts | selectattr('type','defined') | selectattr('type','equalto','dind') | list | length }}
|
||||
- Network: {{ docker_network }}
|
||||
@@ -1,61 +1,38 @@
|
||||
---
|
||||
dependency:
|
||||
name: galaxy
|
||||
enabled: false
|
||||
options:
|
||||
requirements-file: requirements.yml
|
||||
# Универсальная конфигурация Molecule
|
||||
# Автор: Сергей Антропов
|
||||
# Сайт: https://devops.org.ru
|
||||
|
||||
driver:
|
||||
name: docker
|
||||
|
||||
platforms:
|
||||
- name: centos
|
||||
image: "inecs/ansible:centos"
|
||||
privileged: true
|
||||
# Платформы будут созданы динамически через preset файлы
|
||||
- name: placeholder
|
||||
image: ghcr.io/ansible-community/molecule-ubuntu-systemd:jammy
|
||||
pre_build_image: true
|
||||
volumes:
|
||||
- /sys/fs/cgroup:/sys/fs/cgroup:ro
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
tmpfs:
|
||||
- /tmp
|
||||
- /run
|
||||
- name: ubuntu
|
||||
image: "inecs/ansible:ubuntu"
|
||||
privileged: true
|
||||
pre_build_image: true
|
||||
volumes:
|
||||
- /sys/fs/cgroup:/sys/fs/cgroup:ro
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
tmpfs:
|
||||
- /tmp
|
||||
- /run
|
||||
|
||||
provisioner:
|
||||
name: ansible
|
||||
connection_options:
|
||||
ansible_connection: docker
|
||||
ansible_user: root
|
||||
config_options:
|
||||
defaults:
|
||||
stdout_callback: yaml
|
||||
env:
|
||||
ANSIBLE_PYTHON_INTERPRETER: /usr/bin/python3
|
||||
lint:
|
||||
name: ansible-lint
|
||||
ANSIBLE_STDOUT_CALLBACK: yaml
|
||||
inventory:
|
||||
links:
|
||||
hosts: "${MOLECULE_EPHEMERAL_DIRECTORY}/inventory/hosts.ini"
|
||||
playbooks:
|
||||
create: create.yml
|
||||
converge: converge.yml
|
||||
destroy: destroy.yml
|
||||
|
||||
dependency:
|
||||
name: galaxy
|
||||
|
||||
verifier:
|
||||
name: ansible
|
||||
|
||||
scenario:
|
||||
name: default
|
||||
test_sequence:
|
||||
- dependency
|
||||
- cleanup
|
||||
- destroy
|
||||
- syntax
|
||||
- create
|
||||
- prepare
|
||||
- converge
|
||||
- idempotence
|
||||
- side_effect
|
||||
- verify
|
||||
- cleanup
|
||||
- destroy
|
||||
|
||||
lint: |-
|
||||
set -e
|
||||
ansible-lint /workspace/roles/
|
||||
@@ -1,43 +0,0 @@
|
||||
- name: Prepare
|
||||
hosts: all
|
||||
tasks:
|
||||
- name: Detect OS family
|
||||
ansible.builtin.setup:
|
||||
gather_subset:
|
||||
- "min"
|
||||
|
||||
- name: Обновляем пакеты для работы с Ansible в RockyLinux (Centos/RedHat)
|
||||
when: ansible_facts['os_family'] == "RedHat"
|
||||
block:
|
||||
- name: Устанавливаем репозиторий AppStream (если его нет)
|
||||
ansible.builtin.raw: dnf config-manager --set-enabled appstream
|
||||
changed_when: false
|
||||
|
||||
- name: Установить rsync
|
||||
ansible.builtin.raw: dnf install -y rsync
|
||||
changed_when: false
|
||||
|
||||
- name: Устанавливаем Python 3.8
|
||||
ansible.builtin.raw: dnf install -y python38 python38-pip
|
||||
changed_when: false
|
||||
|
||||
- name: Обновляем символическую ссылку python3
|
||||
ansible.builtin.raw: alternatives --set python /usr/bin/python3.8
|
||||
changed_when: false
|
||||
# - name: Fix repository URLs
|
||||
# ansible.builtin.command:
|
||||
# cmd: sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-*
|
||||
# changed_when: false
|
||||
|
||||
# - name: Update baseurl
|
||||
# ansible.builtin.command:
|
||||
# cmd: sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-*
|
||||
# changed_when: false
|
||||
|
||||
# - name: Install required packages
|
||||
# ansible.builtin.yum:
|
||||
# name:
|
||||
# - epel-release
|
||||
# - python3
|
||||
# - python3-pip
|
||||
# state: present
|
||||
@@ -1,7 +0,0 @@
|
||||
---
|
||||
- name: Prepare
|
||||
hosts: all
|
||||
tasks:
|
||||
- name: Reun verify
|
||||
debug:
|
||||
msg: "Hello, Verify!"
|
||||
29
molecule/default/site.yml
Normal file
29
molecule/default/site.yml
Normal file
@@ -0,0 +1,29 @@
|
||||
---
|
||||
# Универсальный плейбук для тестирования
|
||||
# Автор: Сергей Антропов
|
||||
# Сайт: https://devops.org.ru
|
||||
|
||||
- name: Base deps
|
||||
hosts: all
|
||||
become: true
|
||||
tasks:
|
||||
- name: Update apt cache (Debian)
|
||||
apt:
|
||||
update_cache: true
|
||||
when: ansible_os_family == 'Debian'
|
||||
changed_when: false
|
||||
|
||||
- name: Common tools
|
||||
raw: dnf install -y curl jq ca-certificates iproute2 iputils procps-ng net-tools sudo vim || yum install -y curl jq ca-certificates iproute2 iputils procps-ng net-tools sudo vim || apt-get update && apt-get install -y curl jq ca-certificates iproute2 iputils-ping procps net-tools sudo vim || true
|
||||
ignore_errors: true
|
||||
|
||||
- name: Update ansible-lint
|
||||
raw: pip install --upgrade ansible-lint --quiet --no-warn-script-location || true
|
||||
ignore_errors: true
|
||||
|
||||
- name: Install ansible collections
|
||||
raw: ansible-galaxy collection install -r requirements.yml --force --no-deps --upgrade || true
|
||||
ignore_errors: true
|
||||
|
||||
- import_playbook: ../../deploy.yml
|
||||
|
||||
@@ -1,132 +1,122 @@
|
||||
---
|
||||
# Проверка работы systemd, docker и docker-compose в образах
|
||||
# Автор: Сергей Антропов
|
||||
# Сайт: https://devops.org.ru
|
||||
- hosts: localhost
|
||||
gather_facts: false
|
||||
vars:
|
||||
# Получаем preset из переменной окружения или используем default
|
||||
preset_name: "{{ lookup('env', 'MOLECULE_PRESET') | default('default') }}"
|
||||
preset_file: "/workspace/molecule/presets/{{ preset_name }}.yml"
|
||||
|
||||
# Fallback значения если preset файл не найден
|
||||
docker_network: labnet
|
||||
hosts:
|
||||
- name: u1
|
||||
family: debian
|
||||
groups: [test]
|
||||
|
||||
- name: Verify systemd, docker and docker-compose services
|
||||
hosts: all
|
||||
gather_facts: true
|
||||
tasks:
|
||||
- name: Display OS information
|
||||
debug:
|
||||
msg: "Тестирование на {{ ansible_distribution }} {{ ansible_distribution_version }}"
|
||||
- name: Load preset configuration
|
||||
include_vars: "{{ preset_file }}"
|
||||
when: preset_file is file
|
||||
ignore_errors: true
|
||||
|
||||
- name: Check if systemd is available and running
|
||||
systemd:
|
||||
name: systemd
|
||||
state: started
|
||||
# Проверка systemd узлов
|
||||
- name: Check systemd nodes status
|
||||
community.docker.docker_container_exec:
|
||||
container: "{{ item.name }}"
|
||||
command: systemctl is-system-running
|
||||
loop: "{{ hosts | selectattr('type','undefined') | list }}"
|
||||
loop_control: { label: "{{ item.name }}" }
|
||||
register: systemd_status
|
||||
failed_when: false
|
||||
ignore_errors: true
|
||||
|
||||
- name: Display systemd status
|
||||
- name: Display systemd nodes status
|
||||
debug:
|
||||
msg: "Systemd статус: {{ 'Доступен и запущен' if systemd_status is succeeded else 'Недоступен или не запущен' }}"
|
||||
msg: "Systemd node {{ item.0.name }}: {{ item.1.stdout | default('unknown') }}"
|
||||
loop: "{{ systemd_status.results | default([]) }}"
|
||||
when: systemd_status is defined
|
||||
|
||||
- name: Check systemd version
|
||||
command: systemd --version
|
||||
register: systemd_version
|
||||
failed_when: false
|
||||
changed_when: false
|
||||
# Проверка DinD узлов
|
||||
- name: Check DinD nodes docker daemon
|
||||
community.docker.docker_container_exec:
|
||||
container: "{{ item.name }}"
|
||||
command: docker version --format '{{.Server.Version}}'
|
||||
loop: "{{ hosts | selectattr('type','defined') | selectattr('type','equalto','dind') | list }}"
|
||||
loop_control: { label: "{{ item.name }}" }
|
||||
register: dind_status
|
||||
ignore_errors: true
|
||||
|
||||
- name: Display systemd version
|
||||
- name: Display DinD nodes status
|
||||
debug:
|
||||
msg: "Версия systemd: {{ systemd_version.stdout_lines[0] if systemd_version.stdout_lines else 'Не определена' }}"
|
||||
msg: "DinD node {{ item.0.name }}: Docker {{ item.1.stdout | default('not running') }}"
|
||||
loop: "{{ dind_status.results | default([]) }}"
|
||||
when: dind_status is defined
|
||||
|
||||
- name: Check if docker service exists
|
||||
stat:
|
||||
path: /usr/bin/docker
|
||||
register: docker_binary
|
||||
# Проверка DOoD узлов
|
||||
- name: Check DOoD nodes docker access
|
||||
community.docker.docker_container_exec:
|
||||
container: "{{ item.name }}"
|
||||
command: docker ps --format '{{.Names}}'
|
||||
loop: "{{ hosts | selectattr('type','defined') | selectattr('type','equalto','dood') | list }}"
|
||||
loop_control: { label: "{{ item.name }}" }
|
||||
register: dood_status
|
||||
ignore_errors: true
|
||||
|
||||
- name: Check if docker service exists (alternative path)
|
||||
stat:
|
||||
path: /usr/local/bin/docker
|
||||
register: docker_binary_alt
|
||||
|
||||
- name: Display docker binary status
|
||||
- name: Display DOoD nodes status
|
||||
debug:
|
||||
msg: "Docker binary: {{ 'Найден в /usr/bin/docker' if docker_binary.stat.exists else ('Найден в /usr/local/bin/docker' if docker_binary_alt.stat.exists else 'Не найден') }}"
|
||||
msg: "DOoD node {{ item.0.name }}: Can access {{ item.1.stdout_lines | length | default(0) }} containers"
|
||||
loop: "{{ dood_status.results | default([]) }}"
|
||||
when: dood_status is defined
|
||||
|
||||
- name: Check docker version
|
||||
command: docker --version
|
||||
register: docker_version
|
||||
failed_when: false
|
||||
changed_when: false
|
||||
# Проверка сетевого подключения
|
||||
- name: Test network connectivity between nodes
|
||||
community.docker.docker_container_exec:
|
||||
container: "{{ item.0.name }}"
|
||||
command: ping -c 1 {{ item.1.name }}
|
||||
loop: "{{ hosts | subelements(hosts, 'name') }}"
|
||||
loop_control: { label: "{{ item.0.name }} -> {{ item.1.name }}" }
|
||||
when: item.0.name != item.1.name
|
||||
register: ping_results
|
||||
ignore_errors: true
|
||||
|
||||
- name: Display docker version
|
||||
- name: Display network connectivity results
|
||||
debug:
|
||||
msg: "Версия Docker: {{ docker_version.stdout if docker_version.stdout else 'Docker не установлен' }}"
|
||||
msg: "Network test {{ item.0.name }} -> {{ item.1.name }}: {{ 'OK' if item.2.rc == 0 else 'FAILED' }}"
|
||||
loop: "{{ ping_results.results | default([]) }}"
|
||||
when: ping_results is defined
|
||||
|
||||
- name: Check if docker daemon is running
|
||||
command: docker info
|
||||
register: docker_info
|
||||
failed_when: false
|
||||
changed_when: false
|
||||
# Проверка портов
|
||||
- name: Check published ports
|
||||
community.docker.docker_container_exec:
|
||||
container: "{{ item.name }}"
|
||||
command: netstat -tlnp
|
||||
loop: "{{ hosts | selectattr('publish','defined') | list }}"
|
||||
loop_control: { label: "{{ item.name }}" }
|
||||
register: port_status
|
||||
ignore_errors: true
|
||||
|
||||
- name: Display docker daemon status
|
||||
- name: Display port status
|
||||
debug:
|
||||
msg: "Docker daemon: {{ 'Запущен' if docker_info is succeeded else 'Не запущен или недоступен' }}"
|
||||
msg: "Node {{ item.0.name }} ports: {{ item.1.stdout_lines | select('match', 'LISTEN') | list | length }} listening"
|
||||
loop: "{{ port_status.results | default([]) }}"
|
||||
when: port_status is defined
|
||||
|
||||
- name: Check if docker-compose binary exists
|
||||
stat:
|
||||
path: /usr/local/bin/docker-compose
|
||||
register: docker_compose_binary
|
||||
|
||||
- name: Check if docker-compose binary exists (alternative path)
|
||||
stat:
|
||||
path: /usr/bin/docker-compose
|
||||
register: docker_compose_binary_alt
|
||||
|
||||
- name: Check if docker compose plugin exists
|
||||
command: docker compose version
|
||||
register: docker_compose_plugin
|
||||
failed_when: false
|
||||
changed_when: false
|
||||
|
||||
- name: Display docker-compose status
|
||||
debug:
|
||||
msg: "Docker Compose: {{ 'Найден как binary' if docker_compose_binary.stat.exists or docker_compose_binary_alt.stat.exists else ('Найден как plugin' if docker_compose_plugin is succeeded else 'Не найден') }}"
|
||||
|
||||
- name: Display docker-compose version
|
||||
debug:
|
||||
msg: "Версия Docker Compose: {{ docker_compose_plugin.stdout if docker_compose_plugin is succeeded else 'Docker Compose не установлен' }}"
|
||||
|
||||
- name: Test docker functionality
|
||||
command: docker run --rm hello-world
|
||||
register: docker_test
|
||||
failed_when: false
|
||||
changed_when: false
|
||||
|
||||
- name: Display docker test result
|
||||
debug:
|
||||
msg: "Тест Docker: {{ 'Успешно' if docker_test is succeeded else 'Ошибка - ' + docker_test.stderr }}"
|
||||
|
||||
- name: Check systemd services status
|
||||
command: systemctl list-units --type=service --state=running
|
||||
register: running_services
|
||||
failed_when: false
|
||||
changed_when: false
|
||||
|
||||
- name: Display running services count
|
||||
debug:
|
||||
msg: "Количество запущенных сервисов: {{ running_services.stdout_lines | length }}"
|
||||
|
||||
- name: Check for docker-related systemd services
|
||||
command: systemctl list-units --type=service | grep -i docker
|
||||
register: docker_services
|
||||
failed_when: false
|
||||
changed_when: false
|
||||
|
||||
- name: Display docker services
|
||||
debug:
|
||||
msg: "Docker сервисы: {{ docker_services.stdout_lines if docker_services.stdout_lines else 'Не найдены' }}"
|
||||
|
||||
- name: Final summary
|
||||
# Проверка групп
|
||||
- name: Display inventory groups
|
||||
debug:
|
||||
msg: |
|
||||
========================================
|
||||
РЕЗУЛЬТАТЫ ПРОВЕРКИ ОБРАЗА {{ ansible_distribution }}:
|
||||
========================================
|
||||
Systemd: {{ '✓ Работает' if systemd_status is succeeded else '✗ Не работает' }}
|
||||
Docker: {{ '✓ Установлен и работает' if docker_info is succeeded else '✗ Не установлен или не работает' }}
|
||||
Docker Compose: {{ '✓ Доступен' if (docker_compose_binary.stat.exists or docker_compose_binary_alt.stat.exists or docker_compose_plugin is succeeded) else '✗ Недоступен' }}
|
||||
========================================
|
||||
📋 Inventory Groups:
|
||||
{% for group, members in (groups_map | default({}) | dictsort) %}
|
||||
- {{ group }}: {{ members | join(', ') }}
|
||||
{% endfor %}
|
||||
|
||||
# Финальная сводка
|
||||
- name: Display verification summary
|
||||
debug:
|
||||
msg: |
|
||||
✅ Verification Summary:
|
||||
- Total hosts: {{ hosts | length }}
|
||||
- Systemd nodes: {{ hosts | selectattr('type','undefined') | list | length }}
|
||||
- DinD nodes: {{ hosts | selectattr('type','defined') | selectattr('type','equalto','dind') | list | length }}
|
||||
- DOoD nodes: {{ hosts | selectattr('type','defined') | selectattr('type','equalto','dood') | list | length }}
|
||||
- Groups: {{ groups_map.keys() | list | join(', ') }}
|
||||
- Network: {{ docker_network }}
|
||||
|
||||
29
molecule/presets/default.yml
Normal file
29
molecule/presets/default.yml
Normal file
@@ -0,0 +1,29 @@
|
||||
---
|
||||
#description: Стандартный пресет по умолчанию для тестирования с 2 хостами (Debian + RHEL)
|
||||
# Автор: Сергей Антропов
|
||||
# Сайт: 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:
|
||||
# Стандартный набор - 2 хоста для базового тестирования
|
||||
- name: u1
|
||||
family: debian
|
||||
groups: [test, web]
|
||||
- name: u2
|
||||
family: rhel
|
||||
groups: [test, web]
|
||||
44
molecule/presets/docker-test.yml
Normal file
44
molecule/presets/docker-test.yml
Normal file
@@ -0,0 +1,44 @@
|
||||
---
|
||||
#description: Пресет с Docker контейнерами (DinD + DOoD) для тестирования Docker-задач
|
||||
# Автор: Сергей Антропов
|
||||
# Сайт: 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:
|
||||
# Тестовые хосты
|
||||
- name: test1
|
||||
family: debian
|
||||
groups: [test]
|
||||
- name: test2
|
||||
family: rhel
|
||||
groups: [test]
|
||||
|
||||
# DinD узел (Docker-in-Docker)
|
||||
- name: docker1
|
||||
type: dind
|
||||
groups: [docker]
|
||||
publish: ["8080:8080"]
|
||||
|
||||
# DOoD узел (Docker-out-of-Docker)
|
||||
- name: dood1
|
||||
type: dood
|
||||
family: debian
|
||||
groups: [dood]
|
||||
publish: ["8081:8081"]
|
||||
env:
|
||||
DOCKER_HOST: unix:///var/run/docker.sock
|
||||
62
molecule/presets/etcd-patroni.yml
Normal file
62
molecule/presets/etcd-patroni.yml
Normal file
@@ -0,0 +1,62 @@
|
||||
---
|
||||
#description: Пресет для тестирования кластера etcd + PostgreSQL + Patroni (9 хостов)
|
||||
# Автор: Сергей Антропов
|
||||
# Сайт: 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"]
|
||||
|
||||
# Описание кластера etcd + Patroni + HAProxy
|
||||
hosts:
|
||||
# ETCD кластер (5 узлов для высокой доступности)
|
||||
- name: etcd1
|
||||
family: debian
|
||||
groups: [etcd, cluster]
|
||||
- name: etcd2
|
||||
family: rhel
|
||||
groups: [etcd, cluster]
|
||||
- name: etcd3
|
||||
family: debian
|
||||
groups: [etcd, cluster]
|
||||
- name: etcd4
|
||||
family: rhel
|
||||
groups: [etcd, cluster]
|
||||
- name: etcd5
|
||||
family: debian
|
||||
groups: [etcd, cluster]
|
||||
|
||||
# Patroni кластер (3 узла PostgreSQL)
|
||||
- name: patroni1
|
||||
family: rhel
|
||||
groups: [patroni, database, cluster]
|
||||
- name: patroni2
|
||||
family: debian
|
||||
groups: [patroni, database, cluster]
|
||||
- name: patroni3
|
||||
family: rhel
|
||||
groups: [patroni, database, cluster]
|
||||
|
||||
# HAProxy для балансировки
|
||||
- name: haproxy
|
||||
family: debian
|
||||
groups: [haproxy, loadbalancer]
|
||||
publish: ["5000:5000", "5001:5001"] # RW и RO порты
|
||||
|
||||
# DinD узел для тестирования Docker Compose внутри
|
||||
- name: app-dind
|
||||
type: dind
|
||||
groups: [apps, docker]
|
||||
publish: ["8080:8080"]
|
||||
25
molecule/presets/minimal.yml
Normal file
25
molecule/presets/minimal.yml
Normal file
@@ -0,0 +1,25 @@
|
||||
---
|
||||
#description: Минимальный пресет для быстрого тестирования с 1 хостом (Debian)
|
||||
# Автор: Сергей Антропов
|
||||
# Сайт: 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]
|
||||
70
molecule/presets/multi-os.yml
Normal file
70
molecule/presets/multi-os.yml
Normal file
@@ -0,0 +1,70 @@
|
||||
---
|
||||
#description: Пресет для тестирования на разных ОС с 12 хостами (Debian + RHEL)
|
||||
# Автор: Сергей Антропов
|
||||
# Сайт: 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:
|
||||
# Debian серверы
|
||||
- name: debian1
|
||||
family: debian
|
||||
groups: [debian, servers, web]
|
||||
- name: debian2
|
||||
family: debian
|
||||
groups: [debian, servers, web]
|
||||
- name: debian3
|
||||
family: debian
|
||||
groups: [debian, servers, app]
|
||||
- name: debian4
|
||||
family: debian
|
||||
groups: [debian, servers, app]
|
||||
|
||||
# RHEL серверы
|
||||
- name: rhel1
|
||||
family: rhel
|
||||
groups: [rhel, servers, web]
|
||||
- name: rhel2
|
||||
family: rhel
|
||||
groups: [rhel, servers, web]
|
||||
- name: rhel3
|
||||
family: rhel
|
||||
groups: [rhel, servers, app]
|
||||
- name: rhel4
|
||||
family: rhel
|
||||
groups: [rhel, servers, app]
|
||||
|
||||
# База данных на разных ОС
|
||||
- name: db-debian
|
||||
family: debian
|
||||
groups: [database, debian, db]
|
||||
- name: db-rhel
|
||||
family: rhel
|
||||
groups: [database, rhel, db]
|
||||
|
||||
# Load balancer
|
||||
- name: lb-mixed
|
||||
family: debian
|
||||
groups: [loadbalancer, haproxy]
|
||||
publish: ["80:80", "443:443"]
|
||||
|
||||
# DinD узел для тестирования Docker
|
||||
- name: docker-mixed
|
||||
type: dind
|
||||
groups: [docker, apps]
|
||||
publish: ["8080:8080"]
|
||||
73
molecule/presets/performance.yml
Normal file
73
molecule/presets/performance.yml
Normal file
@@ -0,0 +1,73 @@
|
||||
---
|
||||
#description: Пресет для нагрузочного тестирования с 12 хостами (серверы + БД + кэш)
|
||||
# Автор: Сергей Антропов
|
||||
# Сайт: 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: server1
|
||||
family: debian
|
||||
groups: [servers, web, app]
|
||||
- name: server2
|
||||
family: rhel
|
||||
groups: [servers, web, app]
|
||||
- name: server3
|
||||
family: debian
|
||||
groups: [servers, web, app]
|
||||
- name: server4
|
||||
family: rhel
|
||||
groups: [servers, web, app]
|
||||
- name: server5
|
||||
family: debian
|
||||
groups: [servers, web, app]
|
||||
|
||||
# База данных (3 узла)
|
||||
- name: db1
|
||||
family: rhel
|
||||
groups: [database, db]
|
||||
- name: db2
|
||||
family: debian
|
||||
groups: [database, db]
|
||||
- name: db3
|
||||
family: rhel
|
||||
groups: [database, db]
|
||||
|
||||
# Кэш (3 узла Redis)
|
||||
- name: cache1
|
||||
family: debian
|
||||
groups: [cache, redis]
|
||||
- name: cache2
|
||||
family: rhel
|
||||
groups: [cache, redis]
|
||||
- name: cache3
|
||||
family: debian
|
||||
groups: [cache, redis]
|
||||
|
||||
# Load balancer
|
||||
- name: lb1
|
||||
family: rhel
|
||||
groups: [loadbalancer, haproxy]
|
||||
publish: ["80:80", "443:443"]
|
||||
|
||||
# DinD узел для тестирования Docker Compose
|
||||
- name: compose-dind
|
||||
type: dind
|
||||
groups: [apps, docker]
|
||||
publish: ["8080:8080", "8081:8081"]
|
||||
76
molecule/presets/security.yml
Normal file
76
molecule/presets/security.yml
Normal file
@@ -0,0 +1,76 @@
|
||||
---
|
||||
#description: Пресет для тестирования безопасности с 10 хостами (bastion + internal + monitoring)
|
||||
# Автор: Сергей Антропов
|
||||
# Сайт: 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:
|
||||
# Bastion хосты (точки входа)
|
||||
- name: bastion1
|
||||
family: rhel
|
||||
groups: [bastion, security, jump]
|
||||
publish: ["2222:22"]
|
||||
- name: bastion2
|
||||
family: debian
|
||||
groups: [bastion, security, jump]
|
||||
publish: ["2223:22"]
|
||||
|
||||
# Внутренние серверы (без внешнего доступа)
|
||||
- name: internal1
|
||||
family: rhel
|
||||
groups: [internal, servers, app]
|
||||
- name: internal2
|
||||
family: debian
|
||||
groups: [internal, servers, app]
|
||||
- name: internal3
|
||||
family: rhel
|
||||
groups: [internal, servers, app]
|
||||
|
||||
# База данных (изолированная сеть)
|
||||
- name: db-secure1
|
||||
family: rhel
|
||||
groups: [database, secure, internal]
|
||||
- name: db-secure2
|
||||
family: debian
|
||||
groups: [database, secure, internal]
|
||||
|
||||
# Мониторинг и логирование
|
||||
- name: monitor1
|
||||
family: debian
|
||||
groups: [monitoring, security, logs]
|
||||
- name: monitor2
|
||||
family: rhel
|
||||
groups: [monitoring, security, logs]
|
||||
|
||||
# Firewall и сетевые компоненты
|
||||
- name: fw1
|
||||
family: rhel
|
||||
groups: [firewall, network, security]
|
||||
- name: fw2
|
||||
family: debian
|
||||
groups: [firewall, network, security]
|
||||
|
||||
# DOoD узел для тестирования Docker безопасности
|
||||
- name: docker-secure
|
||||
type: dood
|
||||
family: debian
|
||||
groups: [docker, security, apps]
|
||||
publish: ["8080:8080"]
|
||||
env:
|
||||
DOCKER_HOST: "unix:///var/run/docker.sock"
|
||||
32
molecule/presets/standart.yml
Normal file
32
molecule/presets/standart.yml
Normal file
@@ -0,0 +1,32 @@
|
||||
---
|
||||
#description: Стандартный пресет для тестирования с 3 хостами (Debian + RHEL)
|
||||
# Автор: Сергей Антропов
|
||||
# Сайт: 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: u1
|
||||
family: debian
|
||||
groups: [test]
|
||||
- name: u2
|
||||
family: rhel
|
||||
groups: [test]
|
||||
- name: u3
|
||||
family: debian
|
||||
groups: [test]
|
||||
25
molecule/presets/test.yml
Normal file
25
molecule/presets/test.yml
Normal file
@@ -0,0 +1,25 @@
|
||||
---
|
||||
#description: Минимальный пресет для быстрого тестирования с 1 хостом (Debian)
|
||||
# Автор: Сергей Антропов
|
||||
# Сайт: 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]
|
||||
@@ -1,4 +1,9 @@
|
||||
---
|
||||
# Ansible Collections для Molecule Universal
|
||||
collections:
|
||||
- name: maxhoesel.proxmox
|
||||
version: 5.0.1
|
||||
- name: community.docker
|
||||
version: ">=3.0.0"
|
||||
- name: community.general
|
||||
version: ">=7.0.0"
|
||||
- name: ansible.posix
|
||||
version: ">=1.5.4"
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
---
|
||||
60
roles/nginx/defaults/main.yml
Normal file
60
roles/nginx/defaults/main.yml
Normal file
@@ -0,0 +1,60 @@
|
||||
---
|
||||
# Переменные по умолчанию для роли nginx
|
||||
# Автор: Сергей Антропов
|
||||
# Сайт: https://devops.org.ru
|
||||
|
||||
# Основные настройки nginx
|
||||
nginx_user: "nginx"
|
||||
nginx_worker_processes: "auto"
|
||||
nginx_worker_connections: 1024
|
||||
nginx_keepalive_timeout: 65
|
||||
|
||||
# Настройки сервера
|
||||
nginx_server_name: "{{ ansible_fqdn | default(ansible_hostname) }}"
|
||||
nginx_listen_port: 80
|
||||
nginx_root_dir: "/var/www/html"
|
||||
nginx_index_file: "index.html"
|
||||
|
||||
# Настройки логов
|
||||
nginx_access_log: "/var/log/nginx/access.log"
|
||||
nginx_error_log: "/var/log/nginx/error.log"
|
||||
|
||||
# Настройки безопасности
|
||||
nginx_server_tokens: "off"
|
||||
nginx_hide_version: true
|
||||
|
||||
# Настройки производительности
|
||||
nginx_sendfile: "on"
|
||||
nginx_tcp_nopush: "on"
|
||||
nginx_tcp_nodelay: "on"
|
||||
|
||||
# Настройки gzip
|
||||
nginx_gzip: true
|
||||
nginx_gzip_vary: "on"
|
||||
nginx_gzip_min_length: 1024
|
||||
nginx_gzip_types:
|
||||
- "text/plain"
|
||||
- "text/css"
|
||||
- "text/xml"
|
||||
- "text/javascript"
|
||||
- "application/javascript"
|
||||
- "application/xml+rss"
|
||||
- "application/json"
|
||||
|
||||
# Настройки для разных ОС
|
||||
nginx_packages:
|
||||
- nginx
|
||||
|
||||
# Дополнительные пакеты для Ubuntu/Debian
|
||||
nginx_ubuntu_packages:
|
||||
- nginx
|
||||
- nginx-common
|
||||
|
||||
# Дополнительные пакеты для RHEL/CentOS
|
||||
nginx_rhel_packages:
|
||||
- nginx
|
||||
- nginx-mod-http-geoip
|
||||
- nginx-mod-http-image-filter
|
||||
- nginx-mod-http-xslt-filter
|
||||
- nginx-mod-mail
|
||||
- nginx-mod-stream
|
||||
44
roles/nginx/handlers/main.yml
Normal file
44
roles/nginx/handlers/main.yml
Normal file
@@ -0,0 +1,44 @@
|
||||
---
|
||||
# Обработчики для роли nginx
|
||||
# Автор: Сергей Антропов
|
||||
# Сайт: https://devops.org.ru
|
||||
|
||||
- name: Restart nginx
|
||||
systemd:
|
||||
name: nginx
|
||||
state: restarted
|
||||
listen: restart nginx
|
||||
tags:
|
||||
- nginx
|
||||
- service
|
||||
- restart
|
||||
|
||||
- name: Reload nginx
|
||||
systemd:
|
||||
name: nginx
|
||||
state: reloaded
|
||||
listen: reload nginx
|
||||
tags:
|
||||
- nginx
|
||||
- service
|
||||
- reload
|
||||
|
||||
- name: Start nginx
|
||||
systemd:
|
||||
name: nginx
|
||||
state: started
|
||||
listen: start nginx
|
||||
tags:
|
||||
- nginx
|
||||
- service
|
||||
- start
|
||||
|
||||
- name: Stop nginx
|
||||
systemd:
|
||||
name: nginx
|
||||
state: stopped
|
||||
listen: stop nginx
|
||||
tags:
|
||||
- nginx
|
||||
- service
|
||||
- stop
|
||||
26
roles/nginx/meta/main.yml
Normal file
26
roles/nginx/meta/main.yml
Normal file
@@ -0,0 +1,26 @@
|
||||
---
|
||||
# Метаданные роли nginx
|
||||
# Автор: Сергей Антропов
|
||||
# Сайт: https://devops.org.ru
|
||||
|
||||
galaxy_info:
|
||||
author: Сергей Антропов
|
||||
description: Простая роль для установки и настройки nginx
|
||||
company: DevOps.org.ru
|
||||
license: MIT
|
||||
min_ansible_version: "2.9"
|
||||
platforms:
|
||||
- name: Ubuntu
|
||||
versions:
|
||||
- jammy
|
||||
- focal
|
||||
- name: EL
|
||||
versions:
|
||||
- all
|
||||
galaxy_tags:
|
||||
- web
|
||||
- nginx
|
||||
- http
|
||||
- server
|
||||
|
||||
dependencies: []
|
||||
196
roles/nginx/tasks/main.yml
Normal file
196
roles/nginx/tasks/main.yml
Normal file
@@ -0,0 +1,196 @@
|
||||
---
|
||||
# Основные задачи для роли nginx
|
||||
# Автор: Сергей Антропов
|
||||
# Сайт: https://devops.org.ru
|
||||
|
||||
- name: Установка nginx на Ubuntu/Debian
|
||||
apt:
|
||||
name: "{{ nginx_ubuntu_packages }}"
|
||||
state: present
|
||||
update_cache: true
|
||||
when: ansible_os_family == "Debian"
|
||||
tags:
|
||||
- nginx
|
||||
- install
|
||||
- debian
|
||||
|
||||
- name: Установка nginx на RHEL/CentOS
|
||||
yum:
|
||||
name: "{{ nginx_rhel_packages }}"
|
||||
state: present
|
||||
when: ansible_os_family == "RedHat"
|
||||
tags:
|
||||
- nginx
|
||||
- install
|
||||
- rhel
|
||||
|
||||
- name: Включение и запуск nginx на Ubuntu/Debian
|
||||
systemd:
|
||||
name: nginx
|
||||
enabled: true
|
||||
state: started
|
||||
when: ansible_os_family == "Debian"
|
||||
tags:
|
||||
- nginx
|
||||
- service
|
||||
- debian
|
||||
|
||||
- name: Включение и запуск nginx на RHEL/CentOS
|
||||
systemd:
|
||||
name: nginx
|
||||
enabled: true
|
||||
state: started
|
||||
when: ansible_os_family == "RedHat"
|
||||
tags:
|
||||
- nginx
|
||||
- service
|
||||
- rhel
|
||||
|
||||
- name: Создание директории для веб-контента
|
||||
file:
|
||||
path: "{{ nginx_root_dir }}"
|
||||
state: directory
|
||||
owner: "{{ nginx_user }}"
|
||||
group: "{{ nginx_user }}"
|
||||
mode: '0755'
|
||||
tags:
|
||||
- nginx
|
||||
- config
|
||||
- directories
|
||||
|
||||
- name: Создание тестовой страницы
|
||||
copy:
|
||||
content: |
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Nginx Test Page</title>
|
||||
<style>
|
||||
body { font-family: Arial, sans-serif; margin: 40px; }
|
||||
.container { max-width: 600px; margin: 0 auto; }
|
||||
h1 { color: #333; }
|
||||
.info { background: #f4f4f4; padding: 20px; border-radius: 5px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>Nginx работает!</h1>
|
||||
<div class="info">
|
||||
<p><strong>Сервер:</strong> {{ ansible_hostname }}</p>
|
||||
<p><strong>ОС:</strong> {{ ansible_distribution }} \
|
||||
{{ ansible_distribution_version }}</p>
|
||||
<p><strong>Время:</strong> {{ ansible_date_time.iso8601 }}</p>
|
||||
<p><strong>Роль:</strong> nginx (Сергей Антропов)</p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
dest: "{{ nginx_root_dir }}/{{ nginx_index_file }}"
|
||||
owner: "{{ nginx_user }}"
|
||||
group: "{{ nginx_user }}"
|
||||
mode: '0644'
|
||||
notify: restart nginx
|
||||
tags:
|
||||
- nginx
|
||||
- config
|
||||
- content
|
||||
|
||||
- name: Создание резервной копии конфигурации nginx
|
||||
copy:
|
||||
src: "{{ item }}"
|
||||
dest: "{{ item }}.backup"
|
||||
remote_src: true
|
||||
mode: '0644'
|
||||
owner: root
|
||||
group: root
|
||||
loop:
|
||||
- /etc/nginx/nginx.conf
|
||||
- /etc/nginx/sites-available/default
|
||||
ignore_errors: true
|
||||
when: ansible_os_family == "Debian"
|
||||
tags:
|
||||
- nginx
|
||||
- config
|
||||
- backup
|
||||
|
||||
- name: Создание резервной копии конфигурации nginx (RHEL)
|
||||
copy:
|
||||
src: "{{ item }}"
|
||||
dest: "{{ item }}.backup"
|
||||
remote_src: true
|
||||
mode: '0644'
|
||||
owner: root
|
||||
group: root
|
||||
loop:
|
||||
- /etc/nginx/nginx.conf
|
||||
- /etc/nginx/conf.d/default.conf
|
||||
ignore_errors: true
|
||||
when: ansible_os_family == "RedHat"
|
||||
tags:
|
||||
- nginx
|
||||
- config
|
||||
- backup
|
||||
|
||||
- name: Настройка основной конфигурации nginx
|
||||
template:
|
||||
src: nginx.conf.j2
|
||||
dest: /etc/nginx/nginx.conf
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0644'
|
||||
backup: true
|
||||
notify: restart nginx
|
||||
tags:
|
||||
- nginx
|
||||
- config
|
||||
- main
|
||||
|
||||
- name: Настройка виртуального хоста (Ubuntu/Debian)
|
||||
template:
|
||||
src: default.conf.j2
|
||||
dest: /etc/nginx/sites-available/default
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0644'
|
||||
backup: true
|
||||
when: ansible_os_family == "Debian"
|
||||
notify: restart nginx
|
||||
tags:
|
||||
- nginx
|
||||
- config
|
||||
- vhost
|
||||
- debian
|
||||
|
||||
- name: Настройка виртуального хоста (RHEL/CentOS)
|
||||
template:
|
||||
src: default.conf.j2
|
||||
dest: /etc/nginx/conf.d/default.conf
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0644'
|
||||
backup: true
|
||||
when: ansible_os_family == "RedHat"
|
||||
notify: restart nginx
|
||||
tags:
|
||||
- nginx
|
||||
- config
|
||||
- vhost
|
||||
- rhel
|
||||
|
||||
- name: Проверка конфигурации nginx
|
||||
command: nginx -t
|
||||
register: nginx_config_test
|
||||
changed_when: false
|
||||
tags:
|
||||
- nginx
|
||||
- config
|
||||
- test
|
||||
|
||||
- name: Показать результат проверки конфигурации
|
||||
debug:
|
||||
msg: "{{ nginx_config_test.stdout_lines }}"
|
||||
when: nginx_config_test.stdout_lines is defined
|
||||
tags:
|
||||
- nginx
|
||||
- config
|
||||
- test
|
||||
67
roles/nginx/templates/default.conf.j2
Normal file
67
roles/nginx/templates/default.conf.j2
Normal file
@@ -0,0 +1,67 @@
|
||||
# Конфигурация виртуального хоста nginx
|
||||
# Автор: Сергей Антропов
|
||||
# Сайт: https://devops.org.ru
|
||||
# Сгенерировано: {{ ansible_date_time.iso8601 }}
|
||||
|
||||
server {
|
||||
listen {{ nginx_listen_port }};
|
||||
server_name {{ nginx_server_name }};
|
||||
|
||||
# Настройки безопасности
|
||||
{% if nginx_hide_version %}
|
||||
server_tokens off;
|
||||
{% endif %}
|
||||
|
||||
# Корневая директория
|
||||
root {{ nginx_root_dir }};
|
||||
index {{ nginx_index_file }};
|
||||
|
||||
# Настройки логов для этого виртуального хоста
|
||||
access_log {{ nginx_access_log }};
|
||||
error_log {{ nginx_error_log }};
|
||||
|
||||
# Основная локация
|
||||
location / {
|
||||
try_files $uri $uri/ =404;
|
||||
}
|
||||
|
||||
# Настройки для статических файлов
|
||||
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
|
||||
expires 1y;
|
||||
add_header Cache-Control "public, immutable";
|
||||
}
|
||||
|
||||
# Настройки безопасности
|
||||
location ~ /\. {
|
||||
deny all;
|
||||
access_log off;
|
||||
log_not_found off;
|
||||
}
|
||||
|
||||
# Настройки для favicon
|
||||
location = /favicon.ico {
|
||||
log_not_found off;
|
||||
access_log off;
|
||||
}
|
||||
|
||||
# Настройки для robots.txt
|
||||
location = /robots.txt {
|
||||
log_not_found off;
|
||||
access_log off;
|
||||
}
|
||||
|
||||
# Настройки для health check
|
||||
location /health {
|
||||
access_log off;
|
||||
return 200 "healthy\n";
|
||||
add_header Content-Type text/plain;
|
||||
}
|
||||
|
||||
# Настройки для статуса nginx
|
||||
location /nginx_status {
|
||||
stub_status on;
|
||||
access_log off;
|
||||
allow 127.0.0.1;
|
||||
deny all;
|
||||
}
|
||||
}
|
||||
58
roles/nginx/templates/nginx.conf.j2
Normal file
58
roles/nginx/templates/nginx.conf.j2
Normal file
@@ -0,0 +1,58 @@
|
||||
# Основная конфигурация nginx
|
||||
# Автор: Сергей Антропов
|
||||
# Сайт: https://devops.org.ru
|
||||
# Сгенерировано: {{ ansible_date_time.iso8601 }}
|
||||
|
||||
user {{ nginx_user }};
|
||||
worker_processes {{ nginx_worker_processes }};
|
||||
|
||||
error_log {{ nginx_error_log }};
|
||||
pid /run/nginx.pid;
|
||||
|
||||
events {
|
||||
worker_connections {{ nginx_worker_connections }};
|
||||
}
|
||||
|
||||
http {
|
||||
# Основные настройки
|
||||
sendfile {{ nginx_sendfile }};
|
||||
tcp_nopush {{ nginx_tcp_nopush }};
|
||||
tcp_nodelay {{ nginx_tcp_nodelay }};
|
||||
keepalive_timeout {{ nginx_keepalive_timeout }};
|
||||
types_hash_max_size 2048;
|
||||
server_tokens {{ nginx_server_tokens }};
|
||||
|
||||
# Настройки MIME типов
|
||||
include /etc/nginx/mime.types;
|
||||
default_type application/octet-stream;
|
||||
|
||||
# Настройки логирования
|
||||
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
|
||||
'$status $body_bytes_sent "$http_referer" '
|
||||
'"$http_user_agent" "$http_x_forwarded_for"';
|
||||
|
||||
access_log {{ nginx_access_log }} main;
|
||||
|
||||
# Настройки gzip
|
||||
{% if nginx_gzip %}
|
||||
gzip {{ nginx_gzip_vary }};
|
||||
gzip_min_length {{ nginx_gzip_min_length }};
|
||||
gzip_types
|
||||
{% for gzip_type in nginx_gzip_types %}
|
||||
{{ gzip_type }}{% if not loop.last %} {% endif %}
|
||||
{% endfor %};
|
||||
{% endif %}
|
||||
|
||||
# Настройки безопасности
|
||||
{% if nginx_hide_version %}
|
||||
server_tokens off;
|
||||
{% endif %}
|
||||
|
||||
# Включение конфигураций виртуальных хостов
|
||||
{% if ansible_os_family == "Debian" %}
|
||||
include /etc/nginx/conf.d/*.conf;
|
||||
include /etc/nginx/sites-enabled/*;
|
||||
{% elif ansible_os_family == "RedHat" %}
|
||||
include /etc/nginx/conf.d/*.conf;
|
||||
{% endif %}
|
||||
}
|
||||
52
scripts/test-playbook.yml
Normal file
52
scripts/test-playbook.yml
Normal 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
83
scripts/test-standart.sh
Executable 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 "✅ Тестирование завершено!"
|
||||
@@ -1 +0,0 @@
|
||||
password123
|
||||
33
vault/secrets.yml
Normal file
33
vault/secrets.yml
Normal file
@@ -0,0 +1,33 @@
|
||||
---
|
||||
# Основные секреты для тестирования
|
||||
# Автор: Сергей Антропов
|
||||
# Сайт: https://devops.org.ru
|
||||
|
||||
# Пароли для баз данных
|
||||
database_passwords:
|
||||
root_password: "database-root-password"
|
||||
app_user_password: "database-app-password"
|
||||
monitoring_user_password: "monitoring-user-password"
|
||||
|
||||
# SSL сертификаты
|
||||
ssl_certificates:
|
||||
server_cert: |
|
||||
-----BEGIN CERTIFICATE-----
|
||||
# Server certificate content
|
||||
-----END CERTIFICATE-----
|
||||
server_key: |
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
# Server private key content
|
||||
-----END PRIVATE KEY-----
|
||||
|
||||
# API ключи
|
||||
api_keys:
|
||||
github_token: "ghp_example_token"
|
||||
dockerhub_token: "dckr_example_token"
|
||||
monitoring_api_key: "monitoring_api_key_example"
|
||||
|
||||
# Строки подключения
|
||||
database_connections:
|
||||
primary: "mysql://user:password@db1:3306/app"
|
||||
replica: "mysql://user:password@db2:3306/app"
|
||||
cache: "redis://cache1:6379/0"
|
||||
Reference in New Issue
Block a user