diff --git a/img/ansible_playbook.png b/img/ansible_playbook.png new file mode 100644 index 0000000..494679e Binary files /dev/null and b/img/ansible_playbook.png differ diff --git a/img/client_docker_ps.png b/img/client_docker_ps.png new file mode 100644 index 0000000..ba2c13f Binary files /dev/null and b/img/client_docker_ps.png differ diff --git a/img/server_docker_ps.png b/img/server_docker_ps.png new file mode 100644 index 0000000..f1e6b1d Binary files /dev/null and b/img/server_docker_ps.png differ diff --git a/img/todo_list.png b/img/todo_list.png new file mode 100644 index 0000000..30115c3 Binary files /dev/null and b/img/todo_list.png differ diff --git a/inventory.ini b/inventory.ini new file mode 100644 index 0000000..509ed0f --- /dev/null +++ b/inventory.ini @@ -0,0 +1,5 @@ +[app] +client ansible_host=192.168.31.103 ansible_user=ismukhanova_2 + +[db] +server ansible_host=192.168.31.102 ansible_user=ismukhanova_3 \ No newline at end of file diff --git a/playbook.yml b/playbook.yml new file mode 100644 index 0000000..d903e64 --- /dev/null +++ b/playbook.yml @@ -0,0 +1,13 @@ +- hosts: db + become: yes + vars_files: + - vault.yml + roles: + - mysql + +- hosts: app + become: yes + vars_files: + - vault.yml + roles: + - todo \ No newline at end of file diff --git a/report.md b/report.md new file mode 100644 index 0000000..3d03229 --- /dev/null +++ b/report.md @@ -0,0 +1,106 @@ +# Отчет о выполненной работе: Автоматизация развертывания Todo-приложения и MySQL с помощью Ansible + +**Введение:** +Целью данной работы являлась автоматизация процесса установки и настройки веб-приложения "Todo app" и связанной с ним базы данных MySQL. Для этого использовались две предварительно сконфигурированные виртуальные машины и инструмент управления конфигурациями Ansible. + +**Использованные технологии и компоненты:** +* Виртуальные машины: Ubuntu Server 20.04 LTS +* Оркестрация конфигураций: Ansible +* Контейнеризация: Docker +* База данных: MySQL (версия 5.7, развернута в Docker-контейнере) +* Веб-приложение: Образ `antonaleks/101-todo-app` (развернуто в Docker-контейнере) +* Управление секретами: Ansible Vault + +**Инфраструктура и роли хостов:** +* **Управляющий узел Ansible:** Linux A (IP: `192.168.31.101`, пользователь: `ismukhanova_1`) +* **Сервер приложения (Todo-app):** Linux B (IP: `192.168.31.103`, пользователь: `ismukhanova_2`), именуемый `client` в конфигурации Ansible. +* **Сервер базы данных (MySQL):** Linux C (IP: `192.168.31.102`, пользователь: `ismukhanova_3`), именуемый `server` в конфигурации Ansible. + +--- + +### 1. Организация проекта Ansible и начальная настройка + +Проект Ansible был структурирован для обеспечения модульности и ясности. Ключевые компоненты включали: + +* **Файл инвентаря (`inventory.ini`):** Определены группы хостов `[app]` и `[db]`, с указанием IP-адресов и имен пользователей для SSH-подключений Ansible. + ```ini + # inventory.ini + [app] + client ansible_host=192.168.31.103 ansible_user=ismukhanova_2 + + [db] + server ansible_host=192.168.31.102 ansible_user=ismukhanova_3 + ``` +* **Ansible Vault (`vault.yml`):** Для хранения паролей (root-пароль MySQL и пароль пользователя базы данных для приложения) был применен Ansible Vault. Это позволило избежать включения чувствительной информации непосредственно в плейбуки, используя вместо этого переменные, такие как `{{ mysql_root_password }}`. Файл `vault.yml` находится в корневой директории проекта и зашифрован. +* **Подготовка целевых хостов:** + * Настроен безопасный SSH-доступ с управляющего узла (Linux A) на целевые машины (Linux B и C) с использованием ключей. + * Пользователям `ismukhanova_2` и `ismukhanova_3` на соответствующих хостах предоставлены права на выполнение `sudo` команд без пароля, что необходимо для задач Ansible, требующих повышения привилегий (`become: yes`). + * На хостах Linux B и C установлен Python 3 и соответствующая Python-библиотека `docker` для взаимодействия модулей Ansible `docker_container` и `docker_image` с Docker API. + +--- + +### 2. Конфигурация Ansible ролей + +Для разделения логики развертывания были созданы две основные роли: `mysql` и `todo`. + +#### 2.1. Роль `mysql` (для хоста `server` - Linux C) + +Отвечает за подготовку и запуск сервера базы данных MySQL: +* **Установка Docker:** Модуль `apt` используется для установки пакета `docker.io`. +* **Развертывание MySQL контейнера:** + * Запускается контейнер на основе образа `mysql:5.7`. + * Контейнеру присвоено имя `mysql` и настроена политика автоматического перезапуска. + * Переменные окружения `MYSQL_ROOT_PASSWORD` (из `vault.yml`) и `MYSQL_DATABASE` (установлено в `todos`) передаются для инициализации базы данных. + * Стандартный порт MySQL `3306` внутри контейнера пробрасывается на порт `3306` хостовой машины. + * Для обеспечения сохранности данных при перезапусках контейнера используется именованный Docker-том `mysql_app_data`, который монтируется в директорию `/var/lib/mysql` контейнера. + +*Файл с задачами `roles/mysql/tasks/main.yaml` содержит детальную имплементацию.* + +#### 2.2. Роль `todo` (для хоста `client` - Linux B) + +Предназначена для развертывания веб-приложения: +* **Установка Docker:** Аналогично роли `mysql`, устанавливается `docker.io`. +* **Загрузка образа приложения:** Docker-образ `antonaleks/101-todo-app:latest` извлекается с Docker Hub. +* **Запуск контейнера приложения:** + * Контейнеру присвоено имя `todo` и настроена политика автоматического перезапуска. + * Порт `80` внутри контейнера (на котором работает веб-сервер приложения) пробрасывается на порт `3000` хостовой машины. + * Необходимые для подключения к базе данных переменные окружения (`DB_HOST`, `DB_USER`, `DB_PASSWORD`, `DB_NAME`) конфигурируются для контейнера. Значение `DB_HOST` соответствует IP-адресу хоста `server` (`192.168.31.102`), а `DB_PASSWORD` извлекается из `vault.yml`. + +*Файл с задачами `roles/todo/tasks/main.yaml` содержит детальную имплементацию.* + +--- + +### 3. Исполнение плейбука Ansible + +* **Основной плейбук (`playbook.yml`):** + Оркестрация развертывания осуществляется через главный плейбук, который последовательно применяет роль `mysql` к хостам группы `[db]` и роль `todo` к хостам группы `[app]`. Для обеих операций используется повышение привилегий (`become: yes`) и загрузка переменных из файла `vault.yml`. + +* **Процесс выполнения:** + После предварительной отладки (включая решение проблем с пакетным менеджером `apt` на целевых хостах, освобождение дискового пространства и установку Python SDK для Docker), плейбук был успешно запущен с управляющего узла (Linux A) посредством команды: + `ansible-playbook playbook.yml -i inventory.ini --ask-vault-pass`. + +*Пример успешного вывода команды `ansible-playbook` (или `--check`):* +![Успешное выполнение Ansible плейбука](img/ansible_playbook.png) + +--- + +### 4. Верификация результатов + +* **Сервер MySQL (Linux C):** Контейнер `mysql` функционирует корректно, порт `3306` доступен для сервера приложений, и данные сохраняются персистентно. +* **Сервер Todo-app (Linux B):** Контейнер `todo` запущен, порт `3000` обслуживает запросы. +* **Доступность и функциональность приложения:** Веб-приложение Todo-app успешно открывается в браузере по адресу `http://192.168.31.103:3000`. Тестирование основных операций (создание, изменение, удаление задач) подтвердило корректное взаимодействие с базой данных MySQL. + +*Визуальное подтверждение работы Todo-приложения:* +![Работающее Todo-приложение](img/todo_list.png) + +*Статус Docker-контейнеров на хосте приложения (Linux B):* +![Docker PS на client](img/client_docker_ps.png) + +*Статус Docker-контейнеров на хосте базы данных (Linux C):* +![Docker PS на server](img/server_docker_ps.png) + +--- + +### 5. Итоги + +Задача по автоматизации развертывания двухкомпонентного приложения с использованием Ansible выполнена. Была создана структурированная конфигурация с применением ролей, обеспечена безопасность учетных данных через Ansible Vault. Несмотря на возникшие в процессе отладки сложности с пакетной системой и дисковым пространством на целевых ВМ, они были успешно устранены, что позволило достичь конечной цели – работающего и доступного веб-приложения, полностью развернутого автоматически. \ No newline at end of file diff --git a/roles/mysql/main.yaml b/roles/mysql/main.yaml new file mode 100644 index 0000000..6a42ca4 --- /dev/null +++ b/roles/mysql/main.yaml @@ -0,0 +1,25 @@ +- name: Установить Docker + apt: + name: docker.io + state: present + update_cache: yes + +- name: Запустить контейнер MySQL + docker_container: + name: mysql + image: mysql:5.7 + state: started + restart_policy: always + env: + MYSQL_ROOT_PASSWORD: "{{ mysql_root_password }}" + MYSQL_DATABASE: todos + ports: + - "3306:3306" + volumes: + - "mysql_app_data:/var/lib/mysql" + +- name: Разрешить входящий трафик на порт 3306 + ufw: + rule: allow + port: 3306 + proto: tcp \ No newline at end of file diff --git a/roles/todo/main.yaml b/roles/todo/main.yaml new file mode 100644 index 0000000..064a0b4 --- /dev/null +++ b/roles/todo/main.yaml @@ -0,0 +1,25 @@ +- name: Установить Docker + apt: + name: docker.io + state: present + update_cache: true + +- name: Загрузить Docker-образ todo-app из Docker Hub + docker_image: + name: antonaleks/101-todo-app + tag: latest + source: pull + +- name: Запустить контейнер todo-app + docker_container: + name: todo + image: antonaleks/101-todo-app:latest + state: started + restart_policy: always + ports: + - "3000:80" + env: + DB_HOST: 192.168.31.102 + DB_USER: root + DB_PASSWORD: "{{ app_db_password }}" + DB_NAME: todos \ No newline at end of file