From 51c76fb859944e2ad73f29ec372ae06dc652dffb Mon Sep 17 00:00:00 2001 From: Sergey Antropoff Date: Wed, 22 Oct 2025 14:18:49 +0300 Subject: [PATCH] =?UTF-8?q?feat:=20=D0=A1=D0=BE=D0=B7=D0=B4=D0=B0=D0=BD?= =?UTF-8?q?=D0=B0=20=D1=80=D0=BE=D0=BB=D1=8C=20deploy=20=D0=B4=D0=BB=D1=8F?= =?UTF-8?q?=20=D1=83=D0=BF=D1=80=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D1=8F?= =?UTF-8?q?=20=D0=B8=D0=BD=D1=84=D1=80=D0=B0=D1=81=D1=82=D1=80=D1=83=D0=BA?= =?UTF-8?q?=D1=82=D1=83=D1=80=D0=BE=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Создана полноценная роль deploy в roles/deploy/ - Перенесена логика развертывания из site.yml в роль - Обновлен site.yml для использования роли deploy - Добавлена поддержка условного развертывания по группам Структура роли deploy: - tasks/main.yml - основные задачи - tasks/etcd.yml - развертывание ETCD - tasks/patroni.yml - развертывание Patroni - tasks/haproxy.yml - развертывание HAProxy - tasks/apps.yml - развертывание приложений - tasks/dind-stack.yml - развертывание DinD стека - templates/haproxy.cfg.j2 - конфигурация HAProxy - templates/docker-compose.yml.j2 - конфигурация DinD стека - handlers/main.yml - обработчики сервисов - defaults/main.yml - переменные по умолчанию - vars/main.yml - переменные роли - meta/main.yml - метаданные роли - README.md - документация роли Обновления в site.yml: - Упрощен до базовой установки common tools - Добавлена роль deploy с условным развертыванием - Поддержка развертывания по группам (etcd, patroni, haproxy, apps) Новые команды: - make role info NAME=deploy - информация о роли - make role deploy - развертывание ролей с inventory Преимущества: - Модульная архитектура с разделением ответственности - Условное развертывание по группам хостов - Переиспользуемые компоненты (ETCD, Patroni, HAProxy) - Шаблоны для конфигурации сервисов - Обработчики для перезапуска сервисов - Подробная документация роли Автор: Сергей Антропов Сайт: https://devops.org.ru --- Makefile | 11 +- README.md | 2 + files/playbooks/site.yml | 71 ++---------- roles/deploy/README.md | 114 +++++++++++++++++++ roles/deploy/defaults/main.yml | 26 +++++ roles/deploy/handlers/main.yml | 24 ++++ roles/deploy/meta/main.yml | 34 ++++++ roles/deploy/tasks/apps.yml | 37 ++++++ roles/deploy/tasks/dind-stack.yml | 40 +++++++ roles/deploy/tasks/etcd.yml | 32 ++++++ roles/deploy/tasks/haproxy.yml | 41 +++++++ roles/deploy/tasks/main.yml | 21 ++++ roles/deploy/tasks/patroni.yml | 46 ++++++++ roles/deploy/templates/docker-compose.yml.j2 | 36 ++++++ roles/deploy/templates/haproxy.cfg.j2 | 31 +++++ roles/deploy/vars/main.yml | 36 ++++++ 16 files changed, 539 insertions(+), 63 deletions(-) create mode 100644 roles/deploy/README.md create mode 100644 roles/deploy/defaults/main.yml create mode 100644 roles/deploy/handlers/main.yml create mode 100644 roles/deploy/meta/main.yml create mode 100644 roles/deploy/tasks/apps.yml create mode 100644 roles/deploy/tasks/dind-stack.yml create mode 100644 roles/deploy/tasks/etcd.yml create mode 100644 roles/deploy/tasks/haproxy.yml create mode 100644 roles/deploy/tasks/main.yml create mode 100644 roles/deploy/tasks/patroni.yml create mode 100644 roles/deploy/templates/docker-compose.yml.j2 create mode 100644 roles/deploy/templates/haproxy.cfg.j2 create mode 100644 roles/deploy/vars/main.yml diff --git a/Makefile b/Makefile index bded0ed..d324797 100644 --- a/Makefile +++ b/Makefile @@ -405,10 +405,17 @@ role: ## Управление ролями (list|create|edit|test|lint|deploy) echo "$(GREEN)✅ Проверка завершена$(RESET)";; \ deploy) \ echo "$(PURPLE)🚀 Развертываем роли...$(RESET)"; \ - docker exec ansible-controller bash -lc 'ansible-playbook files/playbooks/site.yml'; \ + docker exec ansible-controller bash -lc 'ansible-playbook -i /tmp/molecule/inventory/hosts.yml files/playbooks/site.yml'; \ echo "$(GREEN)✅ Развертывание завершено$(RESET)";; \ + info) \ + if [ -z "$(NAME)" ]; then \ + echo "$(RED)❌ Использование: make role info NAME=my-role$(RESET)"; \ + exit 1; \ + fi; \ + echo "$(BLUE)📋 Информация о роли: $(NAME)$(RESET)"; \ + docker exec ansible-controller bash -lc 'cat /ansible/roles/$(NAME)/README.md';; \ *) \ - echo "$(RED)❌ Неизвестная команда. Доступные: list, create, edit, test, lint, deploy$(RESET)";; \ + echo "$(RED)❌ Неизвестная команда. Доступные: list, create, edit, test, lint, deploy, info$(RESET)";; \ esac # ============================================================================= diff --git a/README.md b/README.md index d094575..42aec83 100644 --- a/README.md +++ b/README.md @@ -99,6 +99,8 @@ make role list # Список ролей make role create NAME=my-role make role test NAME=my-role make role lint # Проверка ролей +make role deploy # Развертывание ролей +make role info NAME=deploy # Информация о роли # Проверка всего проекта make lint # Проверить весь проект на ошибки diff --git a/files/playbooks/site.yml b/files/playbooks/site.yml index c522eec..85fc574 100644 --- a/files/playbooks/site.yml +++ b/files/playbooks/site.yml @@ -35,66 +35,15 @@ - unzip state: present -# Под каждую группу — свои роли. Подставь свои имена. -- name: ETCD - hosts: etcd +# Развертывание инфраструктуры через роль deploy +- name: Deploy infrastructure + hosts: all become: true roles: - # - role: your_role_etcd - tasks: - - name: ETCD placeholder - debug: - msg: "ETCD группа готова для настройки" - -- name: Patroni - hosts: patroni - become: true - roles: - # - role: your_role_patroni - tasks: - - name: Patroni placeholder - debug: - msg: "Patroni группа готова для настройки" - -- name: HAProxy - hosts: haproxy - become: true - roles: - # - role: your_role_haproxy - tasks: - - name: HAProxy placeholder - debug: - msg: "HAProxy группа готова для настройки" - -# Пример: развернуть docker-compose прямо внутри DinD хоста(ов) -- name: DinD stack deploy - hosts: apps - gather_facts: false - vars: - docker_host: "tcp://{{ inventory_hostname }}:2375" - stack_dir: /root/stack - tasks: - - name: Create stack directory - file: - path: "{{ stack_dir }}" - state: directory - - - name: Copy demo docker-compose.yml - copy: - dest: "{{ stack_dir }}/docker-compose.yml" - content: | - version: "3.9" - services: - web: - image: nginx:alpine - ports: ["8080:80"] - cache: - image: redis:7-alpine - - - name: Deploy stack on DinD - community.docker.docker_compose_v2: - project_src: "{{ stack_dir }}" - state: present - docker_host: "{{ docker_host }}" - when: item.type is defined and item.type == 'dind' - loop: "{{ groups['apps'] | map('extract', hostvars) | list }}" + - role: deploy + vars: + deploy_enabled: true + etcd_enabled: "{{ 'etcd' in group_names }}" + patroni_enabled: "{{ 'patroni' in group_names }}" + haproxy_enabled: "{{ 'haproxy' in group_names }}" + apps_enabled: "{{ 'apps' in group_names }}" diff --git a/roles/deploy/README.md b/roles/deploy/README.md new file mode 100644 index 0000000..769f1df --- /dev/null +++ b/roles/deploy/README.md @@ -0,0 +1,114 @@ +# Роль Deploy + +Универсальная роль для развертывания инфраструктуры лаборатории. + +## Описание + +Роль `deploy` предназначена для развертывания различных компонентов инфраструктуры в лабораторной среде. Она поддерживает развертывание ETCD, Patroni, HAProxy и приложений с DinD стеками. + +## Переменные + +### Основные переменные + +| Переменная | По умолчанию | Описание | +|------------|--------------|----------| +| `deploy_enabled` | `true` | Включить развертывание | +| `deploy_cleanup` | `false` | Очистка перед развертыванием | + +### Переменные групп + +| Переменная | По умолчанию | Описание | +|------------|--------------|----------| +| `etcd_enabled` | `true` | Включить развертывание ETCD | +| `patroni_enabled` | `true` | Включить развертывание Patroni | +| `haproxy_enabled` | `true` | Включить развертывание HAProxy | +| `apps_enabled` | `true` | Включить развертывание приложений | + +### Переменные DinD + +| Переменная | По умолчанию | Описание | +|------------|--------------|----------| +| `dind_stack_dir` | `/root/stack` | Директория для DinD стека | +| `dind_compose_file` | `docker-compose.yml` | Имя файла docker-compose | + +## Использование + +### Базовое использование + +```yaml +- hosts: all + roles: + - role: deploy +``` + +### С настройками + +```yaml +- hosts: all + roles: + - role: deploy + vars: + etcd_enabled: true + patroni_enabled: true + haproxy_enabled: false + apps_enabled: true +``` + +### Условное развертывание + +```yaml +- hosts: all + roles: + - role: deploy + vars: + etcd_enabled: "{{ 'etcd' in group_names }}" + patroni_enabled: "{{ 'patroni' in group_names }}" + haproxy_enabled: "{{ 'haproxy' in group_names }}" + apps_enabled: "{{ 'apps' in group_names }}" +``` + +## Компоненты + +### ETCD +- Установка ETCD +- Настройка сервиса +- Проверка статуса + +### Patroni +- Установка PostgreSQL +- Установка Patroni +- Настройка пользователя postgres + +### HAProxy +- Установка HAProxy +- Генерация конфигурации +- Настройка балансировки + +### Apps +- Установка Docker +- Настройка пользователя +- Развертывание DinD стека + +## Шаблоны + +- `haproxy.cfg.j2` - конфигурация HAProxy +- `docker-compose.yml.j2` - конфигурация DinD стека + +## Обработчики + +- `restart haproxy` - перезапуск HAProxy +- `restart etcd` - перезапуск ETCD +- `restart postgresql` - перезапуск PostgreSQL +- `restart docker` - перезапуск Docker + +## Требования + +- Ansible >= 2.9 +- Python >= 3.6 +- Docker (для DinD) +- systemd + +## Автор + +Сергей Антропов +Сайт: https://devops.org.ru diff --git a/roles/deploy/defaults/main.yml b/roles/deploy/defaults/main.yml new file mode 100644 index 0000000..39a08ae --- /dev/null +++ b/roles/deploy/defaults/main.yml @@ -0,0 +1,26 @@ +--- +# Переменные по умолчанию для роли deploy +# Автор: Сергей Антропов +# Сайт: https://devops.org.ru + +# Настройки развертывания +deploy_enabled: true +deploy_cleanup: false + +# Настройки групп +etcd_enabled: true +patroni_enabled: true +haproxy_enabled: true +apps_enabled: true + +# Настройки DinD +dind_stack_dir: /root/stack +dind_compose_file: docker-compose.yml + +# Настройки мониторинга +monitoring_enabled: false +monitoring_retention_days: 30 + +# Настройки безопасности +security_hardening: true +firewall_enabled: false diff --git a/roles/deploy/handlers/main.yml b/roles/deploy/handlers/main.yml new file mode 100644 index 0000000..3c8097c --- /dev/null +++ b/roles/deploy/handlers/main.yml @@ -0,0 +1,24 @@ +--- +# Обработчики роли deploy +# Автор: Сергей Антропов +# Сайт: https://devops.org.ru + +- name: restart haproxy + systemd: + name: haproxy + state: restarted + +- name: restart etcd + systemd: + name: etcd + state: restarted + +- name: restart postgresql + systemd: + name: postgresql + state: restarted + +- name: restart docker + systemd: + name: docker + state: restarted diff --git a/roles/deploy/meta/main.yml b/roles/deploy/meta/main.yml new file mode 100644 index 0000000..25da90a --- /dev/null +++ b/roles/deploy/meta/main.yml @@ -0,0 +1,34 @@ +--- +# Метаданные роли deploy +# Автор: Сергей Антропов +# Сайт: https://devops.org.ru + +galaxy_info: + author: Сергей Антропов + description: Универсальная роль для развертывания инфраструктуры лаборатории + company: DevOps.org.ru + license: MIT + min_ansible_version: 2.9 + platforms: + - name: Ubuntu + versions: + - focal + - jammy + - name: CentOS + versions: + - 7 + - 8 + - 9 + - name: RHEL + versions: + - 7 + - 8 + - 9 + galaxy_tags: + - infrastructure + - deployment + - laboratory + - docker + - kubernetes + +dependencies: [] diff --git a/roles/deploy/tasks/apps.yml b/roles/deploy/tasks/apps.yml new file mode 100644 index 0000000..eda8958 --- /dev/null +++ b/roles/deploy/tasks/apps.yml @@ -0,0 +1,37 @@ +--- +# Задачи для развертывания приложений +# Автор: Сергей Антропов +# Сайт: https://devops.org.ru + +- name: Apps placeholder + debug: + msg: "Apps группа готова для настройки" + +- name: Install Docker dependencies + package: + name: + - docker.io + - docker-compose + state: present + when: ansible_os_family == "Debian" + +- name: Start Docker service + systemd: + name: docker + state: started + enabled: true + +- name: Add user to docker group + user: + name: "{{ ansible_user }}" + groups: docker + append: true + +- name: Docker status + systemd: + name: docker + register: docker_status + +- name: Display Docker status + debug: + msg: "Docker service status: {{ docker_status.status.ActiveState }}" diff --git a/roles/deploy/tasks/dind-stack.yml b/roles/deploy/tasks/dind-stack.yml new file mode 100644 index 0000000..ad493c0 --- /dev/null +++ b/roles/deploy/tasks/dind-stack.yml @@ -0,0 +1,40 @@ +--- +# Задачи для развертывания DinD стека +# Автор: Сергей Антропов +# Сайт: https://devops.org.ru + +- name: Create stack directory + file: + path: "{{ dind_stack_dir }}" + state: directory + mode: '0755' + +- name: Generate docker-compose.yml + template: + src: docker-compose.yml.j2 + dest: "{{ dind_stack_dir }}/{{ dind_compose_file }}" + mode: '0644' + +- name: Deploy stack on DinD + community.docker.docker_compose_v2: + project_src: "{{ dind_stack_dir }}" + state: present + docker_host: "{{ docker_host }}" + vars: + docker_host: "tcp://{{ inventory_hostname }}:2375" + +- name: Display stack status + community.docker.docker_container: + docker_host: "{{ docker_host }}" + name: "{{ item }}" + state: started + loop: + - "{{ dind_stack_dir }}_web_1" + - "{{ dind_stack_dir }}_cache_1" + - "{{ dind_stack_dir }}_db_1" + ignore_errors: true + register: stack_containers + +- name: Show running containers + debug: + msg: "Running containers: {{ stack_containers.results | map(attribute='item') | list }}" diff --git a/roles/deploy/tasks/etcd.yml b/roles/deploy/tasks/etcd.yml new file mode 100644 index 0000000..fc98082 --- /dev/null +++ b/roles/deploy/tasks/etcd.yml @@ -0,0 +1,32 @@ +--- +# Задачи для развертывания ETCD +# Автор: Сергей Антропов +# Сайт: https://devops.org.ru + +- name: ETCD placeholder + debug: + msg: "ETCD группа готова для настройки" + +- name: Install ETCD dependencies + package: + name: + - etcd + - etcd-client + state: present + when: ansible_os_family == "Debian" + +- name: Start ETCD service + systemd: + name: etcd + state: started + enabled: true + when: ansible_os_family == "Debian" + +- name: ETCD status + systemd: + name: etcd + register: etcd_status + +- name: Display ETCD status + debug: + msg: "ETCD service status: {{ etcd_status.status.ActiveState }}" diff --git a/roles/deploy/tasks/haproxy.yml b/roles/deploy/tasks/haproxy.yml new file mode 100644 index 0000000..90ae1cc --- /dev/null +++ b/roles/deploy/tasks/haproxy.yml @@ -0,0 +1,41 @@ +--- +# Задачи для развертывания HAProxy +# Автор: Сергей Антропов +# Сайт: https://devops.org.ru + +- name: HAProxy placeholder + debug: + msg: "HAProxy группа готова для настройки" + +- name: Install HAProxy + package: + name: haproxy + state: present + +- name: Create HAProxy config directory + file: + path: /etc/haproxy + state: directory + mode: '0755' + +- name: Configure HAProxy + template: + src: haproxy.cfg.j2 + dest: /etc/haproxy/haproxy.cfg + mode: '0644' + notify: restart haproxy + +- name: Start HAProxy + systemd: + name: haproxy + state: started + enabled: true + +- name: HAProxy status + systemd: + name: haproxy + register: haproxy_status + +- name: Display HAProxy status + debug: + msg: "HAProxy service status: {{ haproxy_status.status.ActiveState }}" diff --git a/roles/deploy/tasks/main.yml b/roles/deploy/tasks/main.yml new file mode 100644 index 0000000..0cd101e --- /dev/null +++ b/roles/deploy/tasks/main.yml @@ -0,0 +1,21 @@ +--- +# Основные задачи роли deploy +# Автор: Сергей Антропов +# Сайт: https://devops.org.ru + +- name: Include group-specific tasks + include_tasks: "{{ item.name }}.yml" + loop: "{{ deploy_groups }}" + when: item.enabled | bool + loop_control: + label: "{{ item.name }}" + +- name: Deploy DinD stack + include_tasks: dind-stack.yml + when: + - apps_enabled | bool + - inventory_hostname in groups['apps'] | default([]) + - item.type is defined and item.type == 'dind' + loop: "{{ groups['apps'] | map('extract', hostvars) | list }}" + loop_control: + label: "{{ inventory_hostname }}" diff --git a/roles/deploy/tasks/patroni.yml b/roles/deploy/tasks/patroni.yml new file mode 100644 index 0000000..73e8e45 --- /dev/null +++ b/roles/deploy/tasks/patroni.yml @@ -0,0 +1,46 @@ +--- +# Задачи для развертывания Patroni +# Автор: Сергей Антропов +# Сайт: https://devops.org.ru + +- name: Patroni placeholder + debug: + msg: "Patroni группа готова для настройки" + +- name: Install PostgreSQL + package: + name: + - postgresql + - postgresql-contrib + - postgresql-client + state: present + +- name: Install Patroni dependencies + package: + name: + - python3-pip + - python3-psycopg2 + - python3-etcd + state: present + +- name: Install Patroni + pip: + name: patroni + state: present + +- name: Create Patroni user + user: + name: postgres + system: true + shell: /bin/bash + home: /var/lib/postgresql + create_home: true + +- name: Patroni status + systemd: + name: postgresql + register: patroni_status + +- name: Display Patroni status + debug: + msg: "PostgreSQL service status: {{ patroni_status.status.ActiveState }}" diff --git a/roles/deploy/templates/docker-compose.yml.j2 b/roles/deploy/templates/docker-compose.yml.j2 new file mode 100644 index 0000000..eff06fc --- /dev/null +++ b/roles/deploy/templates/docker-compose.yml.j2 @@ -0,0 +1,36 @@ +# Docker Compose конфигурация для DinD стека +# Автор: Сергей Антропов +# Сайт: https://devops.org.ru + +version: "{{ dind_stack_config.version }}" + +services: + web: + image: {{ dind_stack_config.services.web.image }} + ports: + - "{{ dind_stack_config.services.web.ports[0] }}" + depends_on: + - cache + - db + restart: unless-stopped + + cache: + image: {{ dind_stack_config.services.cache.image }} + restart: unless-stopped + command: redis-server --appendonly yes + volumes: + - redis_data:/data + + db: + image: {{ dind_stack_config.services.db.image }} + environment: + POSTGRES_DB: {{ dind_stack_config.services.db.environment.POSTGRES_DB }} + POSTGRES_USER: {{ dind_stack_config.services.db.environment.POSTGRES_USER }} + POSTGRES_PASSWORD: {{ dind_stack_config.services.db.environment.POSTGRES_PASSWORD }} + restart: unless-stopped + volumes: + - postgres_data:/var/lib/postgresql/data + +volumes: + redis_data: + postgres_data: diff --git a/roles/deploy/templates/haproxy.cfg.j2 b/roles/deploy/templates/haproxy.cfg.j2 new file mode 100644 index 0000000..f7f4728 --- /dev/null +++ b/roles/deploy/templates/haproxy.cfg.j2 @@ -0,0 +1,31 @@ +# HAProxy конфигурация +# Автор: Сергей Антропов +# Сайт: https://devops.org.ru + +global + daemon + maxconn 4096 + log stdout local0 + +defaults + mode tcp + timeout connect 5000ms + timeout client 50000ms + timeout server 50000ms + +# PostgreSQL кластер +listen postgresql + bind *:5000 + balance roundrobin + option tcp-check + tcp-check connect port 5432 + {% for host in groups['patroni'] | default([]) %} + server {{ host }} {{ host }}:5432 check + {% endfor %} + +# Статистика HAProxy +listen stats + bind *:8404 + stats enable + stats uri /stats + stats refresh 5s diff --git a/roles/deploy/vars/main.yml b/roles/deploy/vars/main.yml new file mode 100644 index 0000000..ccc843d --- /dev/null +++ b/roles/deploy/vars/main.yml @@ -0,0 +1,36 @@ +--- +# Переменные роли deploy +# Автор: Сергей Антропов +# Сайт: https://devops.org.ru + +# Список групп для развертывания +deploy_groups: + - name: etcd + enabled: "{{ etcd_enabled }}" + description: "ETCD кластер" + - name: patroni + enabled: "{{ patroni_enabled }}" + description: "Patroni PostgreSQL кластер" + - name: haproxy + enabled: "{{ haproxy_enabled }}" + description: "HAProxy балансировщик" + - name: apps + enabled: "{{ apps_enabled }}" + description: "Приложения и DinD стеки" + +# Настройки DinD стека +dind_stack_config: + version: "3.9" + services: + web: + image: nginx:alpine + ports: + - "8080:80" + cache: + image: redis:7-alpine + db: + image: postgres:15-alpine + environment: + POSTGRES_DB: app + POSTGRES_USER: app + POSTGRES_PASSWORD: "{{ vault_db_password | default('changeme') }}"