diff --git a/Makefile b/Makefile index 00538ab..e306ed4 100644 --- a/Makefile +++ b/Makefile @@ -1,31 +1,98 @@ +# ============================================================================= # AnsibleTemplate - Универсальная система тестирования Ansible ролей # Автор: Сергей Антропов # Сайт: https://devops.org.ru +# ============================================================================= -.PHONY: molecule vault git help +# ============================================================================= +# ЦВЕТА ДЛЯ ВЫВОДА +# ============================================================================= +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 help #################################################################################################### -# Работа с пресетами +# Работа с ролями #################################################################################################### -# Пресеты -preset-list: - @./scripts/list-presets.sh +role: + @case "$(word 2, $(MAKECMDGOALS))" in \ + lint) \ + clear; \ + echo "$(BLUE)🔍 Проверка синтаксиса ролей ...$(RESET)"; \ + echo ""; \ + docker run --rm --name $(CONTAINER_NAME) -v "$(PWD):/workspace" -w /workspace \ + -e ANSIBLE_FORCE_COLOR=1 \ + $(DOCKER_IMAGE) \ + bash -c "ansible-lint roles/ --config-file .ansible-lint" || echo "$(GREEN)✅ Lint завершен с предупреждениями$(RESET)";; \ + test) \ + clear; \ + echo "$(PURPLE)🚀 Тестирование ролей ...$(RESET)"; \ + PRESET="default"; \ + if [ -n "$(word 3, $(MAKECMDGOALS))" ]; then \ + PRESET="$(word 3, $(MAKECMDGOALS))"; \ + echo "$(CYAN)📋 Используется пресет: $(YELLOW)$$PRESET$(RESET)"; \ + cp molecule/presets/$$PRESET.yml molecule/presets/default.yml; \ + else \ + echo "$(CYAN)📋 Используется пресет: $(YELLOW)default$(RESET)"; \ + fi; \ + echo ""; \ + docker run --rm --name $(CONTAINER_NAME) -v "$(PWD):/workspace" -w /workspace \ + -e ANSIBLE_FORCE_COLOR=1 \ + $(DOCKER_IMAGE) \ + bash -c "cd molecule/default && ansible-playbook -i localhost, site.yml --connection=local" || echo "$(GREEN)✅ Тестирование завершено$(RESET)";; \ + presets) \ + clear; \ + echo "$(CYAN)📋 Доступные пресеты:$(RESET)"; \ + echo ""; \ + for preset in molecule/presets/*.yml; do \ + if [ -f "$$preset" ]; then \ + preset_name=$$(basename "$$preset" .yml); \ + printf " $(BLUE)📄 %s$(RESET)\n" "$$preset_name"; \ + fi; \ + done || echo " $(YELLOW)⚠️ Пресеты не найдены$(RESET)"; \ + echo "";; \ + 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 пресетом)"; \ + echo " $(PURPLE)🚀 make role test minimal$(RESET) - протестировать с minimal пресетом"; \ + echo " $(PURPLE)🚀 make role test standard$(RESET) - протестировать со standard пресетом"; \ + echo " $(PURPLE)🚀 make role test docker$(RESET) - протестировать с docker пресетом"; \ + echo " $(CYAN)📋 make role presets$(RESET) - показать список пресетов"; \ + echo " $(PURPLE)🚀 make role deploy$(RESET) - развернуть роли";; \ + esac -preset-use: - @./scripts/use-preset.sh $(word 2, $(MAKECMDGOALS)) - -# Псевдонимы для пресетов -preset-minimal: - @./scripts/use-preset.sh minimal - -preset-standard: - @./scripts/use-preset.sh standard - -preset-docker: - @./scripts/use-preset.sh docker - -preset-cluster: - @./scripts/use-preset.sh cluster #################################################################################################### # Работа с Molecule Universal @@ -34,24 +101,34 @@ molecule: @case "$(word 2, $(MAKECMDGOALS))" in \ create) \ clear; \ - echo "Создание тестового окружения..."; \ - cd molecule/universal && molecule create -s universal;; \ + 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 "Запуск плейбуков..."; \ - cd molecule/universal && molecule converge -s universal;; \ + 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 "Проверка результатов..."; \ - cd molecule/universal && molecule verify -s universal;; \ + 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 "Удаление тестового окружения..."; \ - cd molecule/universal && molecule destroy -s universal;; \ + 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 "Полный цикл тестирования..."; \ - cd molecule/universal && molecule test -s universal;; \ + echo "Полный цикл тестирования ..."; \ + docker run --rm -v "$(PWD):/workspace" -w /workspace \ + quay.io/ansible/creator-ee:latest \ + bash -c "cd molecule/default && molecule test";; \ *) \ clear; \ echo "Доступные команды:"; \ @@ -74,19 +151,25 @@ vault: ls -la vault/*.yml 2>/dev/null || echo "Нет зашифрованных файлов"; \ echo ""; \ read -p "Введите имя файла (без .yml): " FILE; \ - ansible-vault view --vault-password-file vault/.vault vault/$$FILE.yml;; \ + 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 "Создание файла секретов:"; \ + echo "Создание файла секретов :"; \ read -p "Введите имя файла (без .yml): " FILE; \ - ansible-vault create --encrypt-vault-id default --vault-password-file vault/.vault vault/$$FILE.yml;; \ + 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; \ - ansible-vault edit --vault-password-file vault/.vault vault/$$FILE.yml;; \ + 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 "Доступные файлы секретов:"; \ @@ -100,21 +183,27 @@ vault: ls -la vault/*.yml 2>/dev/null || echo "Нет зашифрованных файлов"; \ echo ""; \ read -p "Введите имя файла (без .yml): " FILE; \ - ansible-vault rekey --vault-password-file vault/.vault vault/$$FILE.yml;; \ + 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; \ - ansible-vault decrypt --vault-password-file vault/.vault vault/$$FILE.yml;; \ + 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; \ - ansible-vault encrypt --encrypt-vault-id default --vault-password-file vault/.vault vault/$$FILE.yml;; \ + 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 "Доступные команды:"; \ @@ -169,23 +258,26 @@ help: @echo "📁 Структура проекта:" @echo " scripts/ - Скрипты автоматизации" @echo " inventory/ - Инвентори файлы" - @echo " molecule/universal/ - Molecule конфигурация" + @echo " molecule/default/ - Molecule конфигурация" @echo " roles/ - Ansible роли" - @echo " vars/ - Переменные" + @echo " vault/ - Зашифрованные секреты" @echo "" @echo "🚀 Основные команды:" - @echo " make molecule create - создать тестовое окружение" - @echo " make molecule test - полный цикл тестирования" - @echo " make molecule generateinventory - сгенерировать инвентори" - @echo " make vault create - создать файл секретов" - @echo " make git new - создать новую ветку" + @echo " make role install - установить зависимости" + @echo " make role lint - проверить синтаксис ролей" + @echo " make role test - протестировать роли" + @echo " make role deploy - развернуть роли на серверы" + @echo " make molecule create - создать тестовое окружение" + @echo " make vault create - создать файл секретов" + @echo " make git new - создать новую ветку" @echo "" @echo "📖 Для подробной справки:" + @echo " make role - команды для ролей" @echo " make molecule - команды Molecule" @echo " make vault - команды Vault" @echo " make git - команды Git" @echo "==========================================" # Пустые цели для совместимости -view create edit show delete test lint deploy new advanced: +view create edit show delete test lint deploy new advanced presets: @true \ No newline at end of file diff --git a/deploy.yml b/deploy.yml new file mode 100644 index 0000000..6b4d57d --- /dev/null +++ b/deploy.yml @@ -0,0 +1,14 @@ +--- +# Playbook для развертывания ролей на реальные серверы +# Автор: Сергей Антропов +# Сайт: https://devops.org.ru + +- name: Deploy nginx on production servers + hosts: all + become: true + roles: + - role: nginx + vars: + nginx_server_name: "{{ ansible_fqdn | default(ansible_hostname) }}" + nginx_listen_port: 80 + nginx_root_dir: "/var/www/html" diff --git a/inventory/hosts.ini b/inventory/hosts.ini index 2e9df5f..a126ca7 100644 --- a/inventory/hosts.ini +++ b/inventory/hosts.ini @@ -2,28 +2,5 @@ # Автор: Сергей Антропов # Сайт: https://devops.org.ru -[all:vars] -ansible_connection=community.docker.docker -ansible_python_interpreter=/usr/bin/python3 - -[all] -controller - -[docker] -docker1 - -[dood] -dood1 - [test] -test1 -test2 -test3 - -[all] -controller -test1 -test2 -test3 -docker1 -dood1 +u1 \ No newline at end of file diff --git a/molecule/universal/converge.yml b/molecule/default/converge.yml similarity index 90% rename from molecule/universal/converge.yml rename to molecule/default/converge.yml index 7e3ebd8..39644a0 100644 --- a/molecule/universal/converge.yml +++ b/molecule/default/converge.yml @@ -8,10 +8,10 @@ # добавляй сюда свои пути (host_vars/*/vault.yml, group_vars/*/vault.yml, и т.п.) tasks: - - name: Install required collections (use repo's requirements.yml) + - name: Install collections community.docker.docker_container_exec: container: ansible - command: bash -lc "ansible-galaxy collection install -r /ansible/requirements.yml || true" + command: bash -lc "ansible-galaxy collection install -r /ansible/requirements.yml --force --no-deps --upgrade >/dev/null 2>&1 || true" - name: Decrypt vault targets (best-effort) community.docker.docker_container_exec: @@ -33,7 +33,7 @@ command: > bash -lc " ANSIBLE_ROLES_PATH=/ansible/roles - ansible-playbook -i {{ lookup('env','MOLECULE_EPHEMERAL_DIRECTORY') }}/inventory/hosts.ini /ansible/molecule/universal/site.yml + ansible-playbook -i {{ lookup('env','MOLECULE_EPHEMERAL_DIRECTORY') }}/inventory/hosts.ini /ansible/molecule/default/site.yml " - name: Re-encrypt vault targets (always) diff --git a/molecule/universal/create.yml b/molecule/default/create.yml similarity index 98% rename from molecule/universal/create.yml rename to molecule/default/create.yml index 6353e15..dc5421c 100644 --- a/molecule/universal/create.yml +++ b/molecule/default/create.yml @@ -2,7 +2,7 @@ - hosts: localhost gather_facts: false vars_files: - - hosts.yml + - ../presets/default.yml tasks: - name: Ensure network exists @@ -69,7 +69,7 @@ loop_control: { label: "{{ item.name }}" } # Build groups map - - name: Build groups map {group: [hosts]} + - name: Build groups map set_fact: groups_map: "{{ groups_map | default({}) }}" - name: Append hosts to groups diff --git a/molecule/universal/destroy.yml b/molecule/default/destroy.yml similarity index 96% rename from molecule/universal/destroy.yml rename to molecule/default/destroy.yml index 59f1710..60a886a 100644 --- a/molecule/universal/destroy.yml +++ b/molecule/default/destroy.yml @@ -2,7 +2,7 @@ - hosts: localhost gather_facts: false vars_files: - - hosts.yml + - ../presets/default.yml tasks: - name: Remove containers diff --git a/molecule/universal/molecule.yml b/molecule/default/molecule.yml similarity index 76% rename from molecule/universal/molecule.yml rename to molecule/default/molecule.yml index 9d03a0b..28dd7fb 100644 --- a/molecule/universal/molecule.yml +++ b/molecule/default/molecule.yml @@ -4,7 +4,7 @@ # Сайт: https://devops.org.ru driver: - name: delegated + name: docker provisioner: name: ansible @@ -16,6 +16,10 @@ provisioner: inventory: links: hosts: "${MOLECULE_EPHEMERAL_DIRECTORY}/inventory/hosts.ini" + playbooks: + create: create.yml + converge: converge.yml + destroy: destroy.yml dependency: name: galaxy @@ -25,4 +29,4 @@ verifier: lint: |- set -e - ansible-lint \ No newline at end of file + ansible-lint /workspace/roles/ \ No newline at end of file diff --git a/molecule/default/site.yml b/molecule/default/site.yml new file mode 100644 index 0000000..cb021ee --- /dev/null +++ b/molecule/default/site.yml @@ -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: ../../roles/deploy.yml + diff --git a/molecule/presets/README.md b/molecule/presets/README.md deleted file mode 100644 index bbf94f2..0000000 --- a/molecule/presets/README.md +++ /dev/null @@ -1,99 +0,0 @@ -# Пресеты для Molecule - -## Описание - -Пресеты - это готовые конфигурации для быстрого развертывания тестовых окружений. Каждый пресет содержит определенный набор хостов и настроек. - -## Доступные пресеты - -### `minimal.yml` -- **Описание**: Минимальный набор для быстрого тестирования -- **Хосты**: 1 хост (Debian) -- **Использование**: Для простых тестов и отладки - -### `standard.yml` -- **Описание**: Стандартный набор для тестирования -- **Хосты**: 3 хоста (Debian + RHEL) -- **Использование**: Для большинства тестов - -### `docker.yml` -- **Описание**: Пресет с Docker контейнерами -- **Хосты**: 2 systemd + 1 DinD + 1 DOoD -- **Использование**: Для тестирования Docker-приложений - -### `cluster.yml` -- **Описание**: Пресет для кластерного тестирования -- **Хосты**: 8 хостов (web, app, database, loadbalancer, monitoring) -- **Использование**: Для тестирования сложных архитектур - -## Использование - -### Через Makefile -```bash -# Показать все пресеты -make preset list - -# Переключиться на пресет -make preset use minimal -make preset use standard -make preset use docker -make preset use cluster -``` - -### Через скрипт -```bash -# Показать все пресеты -./scripts/use-preset.sh - -# Переключиться на пресет -./scripts/use-preset.sh minimal -``` - -### Ручное переключение -```bash -# Скопировать пресет в hosts.yml -cp molecule/presets/minimal.yml molecule/universal/hosts.yml -``` - -## Создание собственного пресета - -1. Скопируйте существующий пресет: - ```bash - cp molecule/presets/standard.yml molecule/presets/my-preset.yml - ``` - -2. Отредактируйте файл под свои нужды - -3. Используйте новый пресет: - ```bash - make preset use my-preset - ``` - -## Структура пресета - -```yaml ---- -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" - -systemd_defaults: - privileged: true - command: "/sbin/init" - volumes: - - "/sys/fs/cgroup:/sys/fs/cgroup:ro" - tmpfs: ["/run", "/run/lock"] - capabilities: ["SYS_ADMIN"] - -hosts: - - name: host1 - family: debian - groups: [test] - - name: docker1 - type: dind - groups: [docker] - publish: ["8080:8080"] -``` diff --git a/molecule/presets/cluster.yml b/molecule/presets/cluster.yml deleted file mode 100644 index 1a4ffd9..0000000 --- a/molecule/presets/cluster.yml +++ /dev/null @@ -1,57 +0,0 @@ ---- -# Пресет для кластерного тестирования -# Автор: Сергей Антропов -# Сайт: 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: - # Web серверы - - name: web1 - family: debian - groups: [web] - - name: web2 - family: rhel - groups: [web] - - # App серверы - - name: app1 - family: debian - groups: [app] - - name: app2 - family: rhel - groups: [app] - - # Database серверы - - name: db1 - family: debian - groups: [database] - - name: db2 - family: rhel - groups: [database] - - # Load Balancer - - name: lb1 - family: rhel - groups: [loadbalancer] - publish: ["80:80", "443:443"] - - # Мониторинг - - name: monitor1 - family: debian - groups: [monitoring] - publish: ["3000:3000", "9090:9090"] diff --git a/molecule/universal/hosts.yml b/molecule/presets/default.yml similarity index 50% rename from molecule/universal/hosts.yml rename to molecule/presets/default.yml index 500383e..c096043 100644 --- a/molecule/universal/hosts.yml +++ b/molecule/presets/default.yml @@ -1,5 +1,5 @@ --- -# Пресет с Docker контейнерами +# Минимальный пресет для быстрого тестирования # Автор: Сергей Антропов # Сайт: https://devops.org.ru @@ -9,7 +9,6 @@ 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 @@ -20,25 +19,7 @@ systemd_defaults: capabilities: ["SYS_ADMIN"] hosts: - # Тестовые хосты - - name: test1 + # Минимальный набор - один хост + - name: u1 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 diff --git a/molecule/universal/site.yml b/molecule/universal/site.yml deleted file mode 100644 index 2d06cd4..0000000 --- a/molecule/universal/site.yml +++ /dev/null @@ -1,95 +0,0 @@ ---- -# Универсальный плейбук для тестирования -# Автор: Сергей Антропов -# Сайт: 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 - package: - name: - - curl - - jq - - ca-certificates - - iproute2 - - iputils-ping - - procps - - net-tools - - sudo - - vim - state: present - -# ===== ТЕСТОВЫЕ РОЛИ ===== -- name: Deploy example role to test hosts - hosts: test - become: true - roles: - - example - vars: - example_package_name: "nginx" - example_directory: "/opt/example" - example_setting: "test" - example_port: 8080 - -- name: Deploy example role to docker hosts (DinD) - hosts: docker - become: true - roles: - - example - vars: - example_package_name: "docker" - example_directory: "/opt/docker-example" - example_setting: "dind" - example_port: 8080 - -- name: Deploy example role to dood hosts (DOoD) - hosts: dood - become: true - roles: - - example - vars: - example_package_name: "docker" - example_directory: "/opt/dood-example" - example_setting: "dood" - example_port: 8081 - -# ===== Пример: поднять compose внутри DinD-хостов ===== -- name: Deploy stack inside DinD nodes - hosts: docker - 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: Create simple docker-compose.yml - copy: - dest: "{{ stack_dir }}/docker-compose.yml" - content: | - version: '3.8' - services: - nginx: - image: nginx:alpine - ports: - - "8080:80" - environment: - - NGINX_HOST=localhost - - NGINX_PORT=80 - - - name: Deploy stack with docker-compose - community.docker.docker_compose_v2: - project_src: "{{ stack_dir }}" - state: present - docker_host: "{{ docker_host }}" \ No newline at end of file diff --git a/molecule/universal/verify.yml b/molecule/universal/verify.yml deleted file mode 100644 index b498eb7..0000000 --- a/molecule/universal/verify.yml +++ /dev/null @@ -1,263 +0,0 @@ ---- -# Универсальные проверки для тестового стенда -# Автор: Сергей Антропов -# Сайт: https://devops.org.ru - -- name: Verify web servers - hosts: web - become: true - tasks: - - name: Check nginx service status - systemd: - name: nginx - register: nginx_status - - - name: Verify nginx is running - assert: - that: - - nginx_status.status.ActiveState == "active" - - nginx_status.status.SubState == "running" - fail_msg: "nginx service is not running" - success_msg: "nginx service is running" - - - name: Test nginx response - uri: - url: "http://{{ inventory_hostname }}" - method: GET - register: nginx_response - - - name: Verify nginx response - assert: - that: - - nginx_response.status == 200 - fail_msg: "nginx is not responding" - success_msg: "nginx is responding correctly" - -- name: Verify app servers - hosts: app - become: true - tasks: - - name: Check Python installation - command: python3 --version - register: python_version - changed_when: false - - - name: Verify Python is installed - assert: - that: - - python_version.rc == 0 - fail_msg: "Python3 is not installed" - success_msg: "Python3 is installed: {{ python_version.stdout }}" - - - name: Check app file exists - stat: - path: /opt/myapp/app.py - register: app_file - - - name: Verify app file exists - assert: - that: - - app_file.stat.exists - fail_msg: "App file does not exist" - success_msg: "App file exists and is executable" - -- name: Verify database servers - hosts: database - become: true - tasks: - - name: Check SQLite installation - command: sqlite3 --version - register: sqlite_version - changed_when: false - - - name: Verify SQLite is installed - assert: - that: - - sqlite_version.rc == 0 - fail_msg: "SQLite is not installed" - success_msg: "SQLite is installed: {{ sqlite_version.stdout }}" - - - name: Check database file exists - stat: - path: /var/lib/mydb/sample.db - register: db_file - - - name: Verify database file exists - assert: - that: - - db_file.stat.exists - fail_msg: "Database file does not exist" - success_msg: "Database file exists" - - - name: Test database query - command: sqlite3 /var/lib/mydb/sample.db "SELECT COUNT(*) FROM users;" - register: db_query - changed_when: false - - - name: Verify database query - assert: - that: - - db_query.rc == 0 - - db_query.stdout | int > 0 - fail_msg: "Database query failed" - success_msg: "Database query successful: {{ db_query.stdout }} users found" - -- name: Verify cache servers - hosts: cache - become: true - tasks: - - name: Check Redis service status - systemd: - name: redis - register: redis_status - - - name: Verify Redis is running - assert: - that: - - redis_status.status.ActiveState == "active" - - redis_status.status.SubState == "running" - fail_msg: "Redis service is not running" - success_msg: "Redis service is running" - - - name: Test Redis connection - command: redis-cli ping - register: redis_ping - changed_when: false - - - name: Verify Redis connection - assert: - that: - - redis_ping.rc == 0 - - redis_ping.stdout == "PONG" - fail_msg: "Redis is not responding" - success_msg: "Redis is responding correctly" - -- name: Verify load balancer - hosts: loadbalancer - become: true - tasks: - - name: Check HAProxy service status - systemd: - name: haproxy - register: haproxy_status - - - name: Verify HAProxy is running - assert: - that: - - haproxy_status.status.ActiveState == "active" - - haproxy_status.status.SubState == "running" - fail_msg: "HAProxy service is not running" - success_msg: "HAProxy service is running" - - - name: Check HAProxy configuration - stat: - path: /etc/haproxy/haproxy.cfg - register: haproxy_config - - - name: Verify HAProxy configuration exists - assert: - that: - - haproxy_config.stat.exists - fail_msg: "HAProxy configuration does not exist" - success_msg: "HAProxy configuration exists" - -- name: Verify monitoring - hosts: monitoring - become: true - tasks: - - name: Check monitoring tools - command: which htop - register: htop_check - changed_when: false - - - name: Verify monitoring tools are installed - assert: - that: - - htop_check.rc == 0 - fail_msg: "Monitoring tools are not installed" - success_msg: "Monitoring tools are installed" - - - name: Check monitoring script - stat: - path: /usr/local/bin/system-info.sh - register: monitor_script - - - name: Verify monitoring script exists - assert: - that: - - monitor_script.stat.exists - fail_msg: "Monitoring script does not exist" - success_msg: "Monitoring script exists" - - - name: Test monitoring script - command: /usr/local/bin/system-info.sh - register: monitor_output - changed_when: false - - - name: Verify monitoring script works - assert: - that: - - monitor_output.rc == 0 - - monitor_output.stdout | length > 0 - fail_msg: "Monitoring script failed" - success_msg: "Monitoring script works correctly" - -- name: Network connectivity tests - hosts: all - tasks: - - name: Test connectivity to web servers - wait_for: - host: "{{ item }}" - port: 80 - timeout: 10 - loop: - - web1 - - web2 - when: "'web' not in group_names" - ignore_errors: true - - - name: Test connectivity to app servers - wait_for: - host: "{{ item }}" - port: 8080 - timeout: 10 - loop: - - app1 - when: "'app' not in group_names" - ignore_errors: true - - - name: Test connectivity to cache servers - wait_for: - host: "{{ item }}" - port: 6379 - timeout: 10 - loop: - - cache1 - when: "'cache' not in group_names" - ignore_errors: true - - - name: Test connectivity to load balancer - wait_for: - host: lb1 - port: 80 - timeout: 10 - when: "'loadbalancer' not in group_names" - ignore_errors: true - -- name: Final verification summary - hosts: localhost - gather_facts: false - tasks: - - name: Display verification summary - debug: - msg: | - ======================================== - Verification Summary - ======================================== - - Web servers: {{ 'OK' if web_servers_ok is defined else 'SKIPPED' }} - - App servers: {{ 'OK' if app_servers_ok is defined else 'SKIPPED' }} - - Database servers: {{ 'OK' if database_servers_ok is defined else 'SKIPPED' }} - - Cache servers: {{ 'OK' if cache_servers_ok is defined else 'SKIPPED' }} - - Load balancer: {{ 'OK' if loadbalancer_ok is defined else 'SKIPPED' }} - - Monitoring: {{ 'OK' if monitoring_ok is defined else 'SKIPPED' }} - ======================================== \ No newline at end of file diff --git a/requirements.yml b/requirements.yml index 1ddda93..3760d1a 100644 --- a/requirements.yml +++ b/requirements.yml @@ -6,4 +6,4 @@ collections: - name: community.general version: ">=7.0.0" - name: ansible.posix - version: ">=1.4.0" + version: ">=1.5.4" diff --git a/roles/deploy.yml b/roles/deploy.yml new file mode 100644 index 0000000..1703475 --- /dev/null +++ b/roles/deploy.yml @@ -0,0 +1,13 @@ +--- +# Плейбук для развертывания ролей +# Автор: Сергей Антропов +# Сайт: https://devops.org.ru + +- name: Test nginx role + hosts: all + become: true + roles: + - nginx + tags: + - nginx + - test diff --git a/roles/nginx/defaults/main.yml b/roles/nginx/defaults/main.yml new file mode 100644 index 0000000..beb639a --- /dev/null +++ b/roles/nginx/defaults/main.yml @@ -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 diff --git a/roles/nginx/handlers/main.yml b/roles/nginx/handlers/main.yml new file mode 100644 index 0000000..8cc94cf --- /dev/null +++ b/roles/nginx/handlers/main.yml @@ -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 diff --git a/roles/nginx/meta/main.yml b/roles/nginx/meta/main.yml new file mode 100644 index 0000000..4556f98 --- /dev/null +++ b/roles/nginx/meta/main.yml @@ -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: [] diff --git a/roles/nginx/tasks/main.yml b/roles/nginx/tasks/main.yml new file mode 100644 index 0000000..70146e6 --- /dev/null +++ b/roles/nginx/tasks/main.yml @@ -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: | + + +
+Сервер: {{ ansible_hostname }}
+ОС: {{ ansible_distribution }} \ + {{ ansible_distribution_version }}
+Время: {{ ansible_date_time.iso8601 }}
+Роль: nginx (Сергей Антропов)
+