From b1f681fb30d5441a02225ec9bfceb708fc0da735 Mon Sep 17 00:00:00 2001 From: Sergey Antropoff Date: Wed, 22 Oct 2025 14:57:11 +0300 Subject: [PATCH] =?UTF-8?q?feat:=20=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B0=20=D0=BF=D0=BE=D0=B4=D0=B4=D0=B5=D1=80=D0=B6?= =?UTF-8?q?=D0=BA=D0=B0=20=D1=83=D0=BD=D0=B8=D0=B2=D0=B5=D1=80=D1=81=D0=B0?= =?UTF-8?q?=D0=BB=D1=8C=D0=BD=D1=8B=D1=85=20=D1=80=D0=BE=D0=BB=D0=B5=D0=B9?= =?UTF-8?q?=20=D0=B4=D0=BB=D1=8F=20RHEL=20=D0=B8=20Debian?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Роли теперь создаются универсальными для RHEL и Debian семейств - Автоматическое создание OS-специфичных задач (debian.yml, redhat.yml) - Универсальные playbooks с поддержкой разных ОС - Обновлена документация с примерами и лучшими практиками Новые возможности: - Автоматическое определение ОС через ansible_os_family - OS-специфичные задачи в отдельных файлах - Универсальные playbooks с pre_tasks и post_tasks - Поддержка apt для Debian/Ubuntu и yum для RHEL/CentOS Структура универсальной роли: - tasks/main.yml - общая логика и включение OS-специфичных задач - tasks/debian.yml - задачи для Debian/Ubuntu (apt, systemd) - tasks/redhat.yml - задачи для RHEL/CentOS (yum, systemd) - playbooks/ - универсальные playbooks с поддержкой разных ОС Универсальные playbooks: - gather_facts: true - сбор информации об ОС - pre_tasks - отображение информации об ОС - post_tasks - проверка успешного развертывания - Переменные роли автоматически добавляются Документация: - Добавлен раздел 'Универсальные роли' в docs/roles.md - Примеры задач для Debian и RHEL семейств - Лучшие практики для универсальных ролей - Рекомендации по тестированию на разных ОС Преимущества: - Автоматическое создание универсальных ролей - Поддержка RHEL и Debian семейств из коробки - Лучшие практики встроены в шаблоны - Подробная документация с примерами - Приучение к написанию универсальных ролей Автор: Сергей Антропов Сайт: https://devops.org.ru --- Makefile | 52 +++++++++++++++++-- docs/roles.md | 136 ++++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 164 insertions(+), 24 deletions(-) diff --git a/Makefile b/Makefile index ecf2254..5439e55 100644 --- a/Makefile +++ b/Makefile @@ -380,10 +380,8 @@ role: ## Управление ролями (list|create|edit|test|lint|deploy) echo " debug:" >> $(ROLES_DIR)/$(NAME)/tasks/main.yml; \ echo " msg: \"Роль $(NAME) готова для настройки\"" >> $(ROLES_DIR)/$(NAME)/tasks/main.yml; \ echo "" >> $(ROLES_DIR)/$(NAME)/tasks/main.yml; \ - echo "- name: Install $(NAME) package" >> $(ROLES_DIR)/$(NAME)/tasks/main.yml; \ - echo " package:" >> $(ROLES_DIR)/$(NAME)/tasks/main.yml; \ - echo " name: \"{{ $(NAME)_package | default('$(ROLE_PACKAGE)') }}\"" >> $(ROLES_DIR)/$(NAME)/tasks/main.yml; \ - echo " state: present" >> $(ROLES_DIR)/$(NAME)/tasks/main.yml; \ + echo "- name: Include OS-specific tasks" >> $(ROLES_DIR)/$(NAME)/tasks/main.yml; \ + echo " include_tasks: \"{{ ansible_os_family | lower }}.yml\"" >> $(ROLES_DIR)/$(NAME)/tasks/main.yml; \ echo "" >> $(ROLES_DIR)/$(NAME)/tasks/main.yml; \ echo "- name: Start $(NAME) service" >> $(ROLES_DIR)/$(NAME)/tasks/main.yml; \ echo " systemd:" >> $(ROLES_DIR)/$(NAME)/tasks/main.yml; \ @@ -391,6 +389,37 @@ role: ## Управление ролями (list|create|edit|test|lint|deploy) echo " state: started" >> $(ROLES_DIR)/$(NAME)/tasks/main.yml; \ echo " enabled: true" >> $(ROLES_DIR)/$(NAME)/tasks/main.yml; \ echo " when: $(NAME)_service is defined" >> $(ROLES_DIR)/$(NAME)/tasks/main.yml; \ + echo "---" > $(ROLES_DIR)/$(NAME)/tasks/debian.yml; \ + echo "# Задачи для Debian/Ubuntu семейства" >> $(ROLES_DIR)/$(NAME)/tasks/debian.yml; \ + echo "# Автор: $(AUTHOR)" >> $(ROLES_DIR)/$(NAME)/tasks/debian.yml; \ + echo "# Сайт: $(SITE)" >> $(ROLES_DIR)/$(NAME)/tasks/debian.yml; \ + echo "" >> $(ROLES_DIR)/$(NAME)/tasks/debian.yml; \ + echo "- name: Update apt cache (Debian)" >> $(ROLES_DIR)/$(NAME)/tasks/debian.yml; \ + echo " apt:" >> $(ROLES_DIR)/$(NAME)/tasks/debian.yml; \ + echo " update_cache: true" >> $(ROLES_DIR)/$(NAME)/tasks/debian.yml; \ + echo " cache_valid_time: 3600" >> $(ROLES_DIR)/$(NAME)/tasks/debian.yml; \ + echo " when: ansible_os_family == 'Debian'" >> $(ROLES_DIR)/$(NAME)/tasks/debian.yml; \ + echo "" >> $(ROLES_DIR)/$(NAME)/tasks/debian.yml; \ + echo "- name: Install $(NAME) package (Debian)" >> $(ROLES_DIR)/$(NAME)/tasks/debian.yml; \ + echo " apt:" >> $(ROLES_DIR)/$(NAME)/tasks/debian.yml; \ + echo " name: \"{{ $(NAME)_package | default('$(ROLE_PACKAGE)') }}\"" >> $(ROLES_DIR)/$(NAME)/tasks/debian.yml; \ + echo " state: present" >> $(ROLES_DIR)/$(NAME)/tasks/debian.yml; \ + echo " when: ansible_os_family == 'Debian'" >> $(ROLES_DIR)/$(NAME)/tasks/debian.yml; \ + echo "---" > $(ROLES_DIR)/$(NAME)/tasks/redhat.yml; \ + echo "# Задачи для RHEL/CentOS семейства" >> $(ROLES_DIR)/$(NAME)/tasks/redhat.yml; \ + echo "# Автор: $(AUTHOR)" >> $(ROLES_DIR)/$(NAME)/tasks/redhat.yml; \ + echo "# Сайт: $(SITE)" >> $(ROLES_DIR)/$(NAME)/tasks/redhat.yml; \ + echo "" >> $(ROLES_DIR)/$(NAME)/tasks/redhat.yml; \ + echo "- name: Update yum cache (RHEL)" >> $(ROLES_DIR)/$(NAME)/tasks/redhat.yml; \ + echo " yum:" >> $(ROLES_DIR)/$(NAME)/tasks/redhat.yml; \ + echo " update_cache: true" >> $(ROLES_DIR)/$(NAME)/tasks/redhat.yml; \ + echo " when: ansible_os_family == 'RedHat'" >> $(ROLES_DIR)/$(NAME)/tasks/redhat.yml; \ + echo "" >> $(ROLES_DIR)/$(NAME)/tasks/redhat.yml; \ + echo "- name: Install $(NAME) package (RHEL)" >> $(ROLES_DIR)/$(NAME)/tasks/redhat.yml; \ + echo " yum:" >> $(ROLES_DIR)/$(NAME)/tasks/redhat.yml; \ + echo " name: \"{{ $(NAME)_package | default('$(ROLE_PACKAGE)') }}\"" >> $(ROLES_DIR)/$(NAME)/tasks/redhat.yml; \ + echo " state: present" >> $(ROLES_DIR)/$(NAME)/tasks/redhat.yml; \ + echo " when: ansible_os_family == 'RedHat'" >> $(ROLES_DIR)/$(NAME)/tasks/redhat.yml; \ echo "---" > $(ROLES_DIR)/$(NAME)/defaults/main.yml; \ echo "# Переменные по умолчанию для роли $(NAME)" >> $(ROLES_DIR)/$(NAME)/defaults/main.yml; \ echo "# Автор: $(AUTHOR)" >> $(ROLES_DIR)/$(NAME)/defaults/main.yml; \ @@ -500,8 +529,23 @@ role: ## Управление ролями (list|create|edit|test|lint|deploy) echo "- name: $$PLAYBOOK_NAME" >> $(ROLES_DIR)/$(NAME)/playbooks/$$PLAYBOOK_NAME.yml; \ echo " hosts: all" >> $(ROLES_DIR)/$(NAME)/playbooks/$$PLAYBOOK_NAME.yml; \ echo " become: true" >> $(ROLES_DIR)/$(NAME)/playbooks/$$PLAYBOOK_NAME.yml; \ + echo " gather_facts: true" >> $(ROLES_DIR)/$(NAME)/playbooks/$$PLAYBOOK_NAME.yml; \ + echo " vars:" >> $(ROLES_DIR)/$(NAME)/playbooks/$$PLAYBOOK_NAME.yml; \ + echo " # Переменные для роли $(NAME)" >> $(ROLES_DIR)/$(NAME)/playbooks/$$PLAYBOOK_NAME.yml; \ + echo " $(NAME)_enabled: true" >> $(ROLES_DIR)/$(NAME)/playbooks/$$PLAYBOOK_NAME.yml; \ + echo "" >> $(ROLES_DIR)/$(NAME)/playbooks/$$PLAYBOOK_NAME.yml; \ + echo " pre_tasks:" >> $(ROLES_DIR)/$(NAME)/playbooks/$$PLAYBOOK_NAME.yml; \ + echo " - name: Display OS information" >> $(ROLES_DIR)/$(NAME)/playbooks/$$PLAYBOOK_NAME.yml; \ + echo " debug:" >> $(ROLES_DIR)/$(NAME)/playbooks/$$PLAYBOOK_NAME.yml; \ + echo " msg: \"OS Family: {{ ansible_os_family }}, OS: {{ ansible_distribution }} {{ ansible_distribution_version }}\"" >> $(ROLES_DIR)/$(NAME)/playbooks/$$PLAYBOOK_NAME.yml; \ + echo "" >> $(ROLES_DIR)/$(NAME)/playbooks/$$PLAYBOOK_NAME.yml; \ echo " roles:" >> $(ROLES_DIR)/$(NAME)/playbooks/$$PLAYBOOK_NAME.yml; \ echo " - role: $(NAME)" >> $(ROLES_DIR)/$(NAME)/playbooks/$$PLAYBOOK_NAME.yml; \ + echo "" >> $(ROLES_DIR)/$(NAME)/playbooks/$$PLAYBOOK_NAME.yml; \ + echo " post_tasks:" >> $(ROLES_DIR)/$(NAME)/playbooks/$$PLAYBOOK_NAME.yml; \ + echo " - name: Verify $(NAME) installation" >> $(ROLES_DIR)/$(NAME)/playbooks/$$PLAYBOOK_NAME.yml; \ + echo " debug:" >> $(ROLES_DIR)/$(NAME)/playbooks/$$PLAYBOOK_NAME.yml; \ + echo " msg: \"$(NAME) successfully deployed on {{ inventory_hostname }}\"" >> $(ROLES_DIR)/$(NAME)/playbooks/$$PLAYBOOK_NAME.yml; \ echo "$(GREEN)✅ Playbook $$PLAYBOOK_NAME создан$(RESET)";; \ list) \ echo "$(CYAN)📋 Playbooks для роли $(NAME):$(RESET)"; \ diff --git a/docs/roles.md b/docs/roles.md index af8fc0b..b5cb2fc 100644 --- a/docs/roles.md +++ b/docs/roles.md @@ -16,14 +16,17 @@ make role create NAME=my-role 3. **Настраивается сервис** - имя сервиса для управления 4. **Выбираются платформы** - поддерживаемые ОС (ubuntu, centos, rhel) 5. **Указываются теги** - теги для Ansible Galaxy -6. **Создается структура роли** с папкой `playbooks/` +6. **Создается универсальная структура роли** с поддержкой RHEL и Debian семейств +7. **Создается папка `playbooks/`** для playbooks роли ### Структура созданной роли ``` roles/my-role/ ├── tasks/ -│ └── main.yml # Основные задачи +│ ├── main.yml # Основные задачи (универсальные) +│ ├── debian.yml # Задачи для Debian/Ubuntu +│ └── redhat.yml # Задачи для RHEL/CentOS ├── handlers/ │ └── main.yml # Обработчики ├── templates/ # Шаблоны Jinja2 @@ -39,6 +42,65 @@ roles/my-role/ └── (создаются через make role playbook) ``` +## Универсальные роли + +### Принцип работы + +Роли создаются **универсальными** для RHEL и Debian семейств: + +1. **`tasks/main.yml`** - содержит общую логику и включает OS-специфичные задачи +2. **`tasks/debian.yml`** - задачи для Debian/Ubuntu (apt, systemd) +3. **`tasks/redhat.yml`** - задачи для RHEL/CentOS (yum, systemd) + +### Автоматическое определение ОС + +```yaml +# tasks/main.yml +- name: Include OS-specific tasks + include_tasks: "{{ ansible_os_family | lower }}.yml" +``` + +**Поддерживаемые ОС:** +- **Debian семейство**: Ubuntu, Debian, Linux Mint +- **RHEL семейство**: CentOS, RHEL, Rocky Linux, AlmaLinux + +### Примеры задач + +#### Debian/Ubuntu (tasks/debian.yml) +```yaml +--- +# Задачи для Debian/Ubuntu семейства + +- name: Update apt cache (Debian) + apt: + update_cache: true + cache_valid_time: 3600 + when: ansible_os_family == 'Debian' + +- name: Install nginx package (Debian) + apt: + name: "{{ nginx_package | default('nginx') }}" + state: present + when: ansible_os_family == 'Debian' +``` + +#### RHEL/CentOS (tasks/redhat.yml) +```yaml +--- +# Задачи для RHEL/CentOS семейства + +- name: Update yum cache (RHEL) + yum: + update_cache: true + when: ansible_os_family == 'RedHat' + +- name: Install nginx package (RHEL) + yum: + name: "{{ nginx_package | default('nginx') }}" + state: present + when: ansible_os_family == 'RedHat' +``` + ## Управление playbooks роли ### Создание playbook @@ -60,10 +122,34 @@ make role playbook NAME=my-role - name: deploy hosts: all become: true + gather_facts: true + vars: + # Переменные для роли my-role + my_role_enabled: true + + pre_tasks: + - name: Display OS information + debug: + msg: "OS Family: {{ ansible_os_family }}, OS: {{ ansible_distribution }} {{ ansible_distribution_version }}" + roles: - role: my-role + + post_tasks: + - name: Verify my-role installation + debug: + msg: "my-role successfully deployed on {{ inventory_hostname }}" ``` +### Универсальные playbooks + +Playbooks создаются **универсальными** с поддержкой: + +1. **`gather_facts: true`** - сбор информации об ОС +2. **`pre_tasks`** - отображение информации об ОС +3. **`post_tasks`** - проверка успешного развертывания +4. **Переменные роли** - автоматически добавляются в `vars` + ### Список playbooks ```bash @@ -225,27 +311,37 @@ dependencies: [] ## Лучшие практики -### 1. Структура роли -- Используйте **tasks/main.yml** для основных задач -- Создавайте **отдельные файлы** для сложных задач -- Используйте **handlers** для перезапуска сервисов -- Храните **шаблоны** в templates/ -- Храните **статические файлы** в files/ +### 1. Универсальные роли +- **Всегда создавайте OS-специфичные задачи** в `debian.yml` и `redhat.yml` +- **Используйте `ansible_os_family`** для определения ОС +- **Тестируйте на разных платформах** (Ubuntu, CentOS, RHEL) +- **Используйте универсальные модули** когда возможно (package, systemd) -### 2. Переменные -- **defaults/main.yml** - значения по умолчанию -- **vars/main.yml** - внутренние переменные роли -- Используйте **префиксы** для переменных роли +### 2. Структура роли +- **`tasks/main.yml`** - общая логика и включение OS-специфичных задач +- **`tasks/debian.yml`** - задачи для Debian/Ubuntu (apt, systemd) +- **`tasks/redhat.yml`** - задачи для RHEL/CentOS (yum, systemd) +- **`handlers`** - для перезапуска сервисов +- **`templates`** - для конфигурационных файлов +- **`files`** - для статических файлов -### 3. Playbooks -- Создавайте **отдельные playbooks** для разных сценариев -- Используйте **переменные** для настройки -- Добавляйте **проверки** и **валидацию** +### 3. Переменные +- **`defaults/main.yml`** - значения по умолчанию +- **`vars/main.yml`** - внутренние переменные роли +- **Используйте префиксы** для переменных роли +- **Создавайте OS-специфичные переменные** при необходимости -### 4. Тестирование -- Используйте **make role test** для проверки -- Создавайте **тесты** в папке tests/ -- Проверяйте **разные платформы** +### 4. Playbooks +- **`gather_facts: true`** - всегда собирайте информацию об ОС +- **`pre_tasks`** - отображайте информацию об ОС +- **`post_tasks`** - проверяйте успешное развертывание +- **Используйте переменные** для настройки + +### 5. Тестирование +- **`make role test`** - проверка роли +- **Тестируйте на разных ОС** - Ubuntu, CentOS, RHEL +- **Создавайте тесты** в папке tests/ +- **Проверяйте идемпотентность** - повторный запуск не должен изменять систему ## Интеграция с лабораторией