diff --git a/ansible_playbook_run_success.jpg b/ansible_playbook_run_success.jpg new file mode 100644 index 0000000..f40a4b0 Binary files /dev/null and b/ansible_playbook_run_success.jpg differ diff --git a/client_docker_ps.jpg b/client_docker_ps.jpg new file mode 100644 index 0000000..e175301 Binary files /dev/null and b/client_docker_ps.jpg differ diff --git a/inventory.ini b/inventory.ini new file mode 100644 index 0000000..6ed035d --- /dev/null +++ b/inventory.ini @@ -0,0 +1,5 @@ +[app] +client ansible_host=192.168.1.6 ansible_user=sasha + +[db] +server ansible_host=192.168.1.5 ansible_user=sasha \ No newline at end of file diff --git a/playbook.yml b/playbook.yml new file mode 100644 index 0000000..13f9468 --- /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..01576bf --- /dev/null +++ b/report.md @@ -0,0 +1,109 @@ +# Отчет по заданию: Развертывание Todo-приложения с MySQL с использованием Ansible + +**Цель работы:** Автоматизировать развертывание веб-приложения "Todo app" и его базы данных MySQL на двух отдельных виртуальных машинах с использованием Ansible. Обеспечить безопасность хранения учетных данных и корректную настройку сети и файрвола. + +**Используемые инструменты:** +* VirtualBox (или аналогичная система виртуализации) +* Ubuntu Server 20.04 LTS (для ВМ) +* Ansible +* Docker +* MySQL (в Docker-контейнере) +* Todo-app (образ `antonaleks/101-todo-app` в Docker-контейнере) +* Ansible Vault + +**Конфигурация виртуальных машин:** +* **Управляющий хост Ansible:** Linux A (`192.168.1.4`, пользователь `sasha`) +* **Хост приложения (Todo-app):** Linux B (`192.168.1.6`, пользователь `sasha`), далее `client` в Ansible. +* **Хост базы данных (MySQL):** Linux C (`192.168.1.5`, пользователь `sasha`), далее `server` в Ansible. + +--- + +## 1. Подготовка окружения Ansible + +1. **Создание структуры проекта:** + Проект Ansible был организован с использованием ролей (`mysql`, `todo`) для лучшей структуризации задач. Создан файл инвентаря (`inventory.ini`), основной плейбук (`playbook.yml`) и файл для хранения зашифрованных учетных данных (`vault.yml`). + + +2. **Настройка инвентаря (`inventory.ini`):** + Хосты были разделены на группы `[app]` и `[db]` с указанием IP-адресов и пользователей для подключения Ansible. + ```ini + # Содержимое inventory.ini + [app] + client ansible_host=192.168.1.6 ansible_user=sasha + + [db] + server ansible_host=192.168.1.5 ansible_user=sasha + ``` + +3. **Использование Ansible Vault (`vault.yml`):** + Для безопасного хранения паролей (для MySQL root и пользователя БД приложения) был создан и зашифрован файл `vault.yml`. Пароли в плейбуках и ролях были заменены на переменные из этого файла (например, `{{ mysql_root_password }}`). + *Файл `vault.yml` (зашифрованный) находится в корне проекта.* + +4. **Настройка целевых хостов (Linux B, Linux C):** + * Настроен SSH-доступ по ключам с управляющего хоста (Linux A) на целевые хосты. + * Для пользователей `sasha` (на Linux B) и `sasha` (на Linux C) настроен беспарольный `sudo` для выполнения задач Ansible с повышением прав (`become: yes`). + * На целевые хосты установлен Python 3 и Python-библиотека `docker` (`pip3 install docker`) для корректной работы модулей Ansible `docker_container` и `docker_image`. + +--- + +## 2. Разработка ролей Ansible + +### 2.1. Роль `mysql` (для хоста `server` - Linux C) + +* **Установка Docker:** Устанавливается `docker.io` через модуль `apt`. +* **Запуск контейнера MySQL:** + * Используется образ `mysql:5.7`. + * Контейнер именуется `mysql` и настроен на автоматический перезапуск. + * Учетные данные (`MYSQL_ROOT_PASSWORD`) и имя базы (`MYSQL_DATABASE: todos`) передаются через переменные окружения (пароль из `vault.yml`). + * Порт `3306` контейнера пробрасывается на порт `3306` хоста. + * Для персистентности данных используется именованный Docker-том `mysql_app_data`, монтируемый в `/var/lib/mysql` внутри контейнера. + +*Содержимое `roles/mysql/tasks/main.yaml` доступно в репозитории.* + +### 2.2. Роль `todo` (для хоста `client` - Linux B) + +* **Установка Docker:** Устанавливается `docker.io` через модуль `apt`. +* **Загрузка Docker-образа:** Образ `antonaleks/101-todo-app:latest` загружается с Docker Hub. +* **Запуск контейнера Todo-app:** + * Контейнер именуется `todo` и настроен на автоматический перезапуск. + * Порт `80` контейнера (на котором слушает приложение) пробрасывается на порт `3000` хоста. + * Переменные окружения для подключения к базе данных (`DB_HOST`, `DB_USER`, `DB_PASSWORD`, `DB_NAME`) передаются в контейнер. `DB_HOST` указывает на IP-адрес хоста `server` (`192.168.1.5`), а `DB_PASSWORD` берется из `vault.yml`. + +*Содержимое `roles/todo/tasks/main.yaml` доступно в репозитории.* + +--- + +## 3. Плейбук и выполнение + +* **Основной плейбук (`playbook.yml`):** + Плейбук состоит из двух частей: первая применяет роль `mysql` к хостам из группы `db`, вторая применяет роль `todo` к хостам из группы `app`. Обе части используют `become: yes` и загружают переменные из `vault.yml`. + +* **Выполнение:** + 1. После устранения проблем с пакетной системой (`apt`) и нехваткой места на диске на целевых хостах, а также установки Python-библиотеки `docker`, плейбук был успешно выполнен с управляющего хоста (Linux A). + 2. Команда запуска: `ansible-playbook playbook.yml -i inventory.ini --ask-vault-pass`. + +*Скриншот успешного выполнения `ansible-playbook` (или вывода `--check`):* +![Ansible Playbook Success](img/ansible_playbook_run_success.png) + +--- + +## 4. Результаты и проверка + +* **Контейнер MySQL (на Linux C):** Успешно запущен, порт `3306` доступен для хоста приложения, данные персистентны. +* **Контейнер Todo-app (на Linux B):** Успешно запущен, порт `3000` доступен извне. +* **Веб-приложение:** Приложение Todo-app доступно в браузере по адресу `http://192.168.1.6:3000`. Функциональность создания, редактирования и удаления задач проверена и работает корректно, что подтверждает успешное подключение к базе данных MySQL. + +*Скриншот работающего Todo-приложения в браузере:* +![Todo App Working](img/todo_app_browser.png) + +*Скриншот `docker ps` на хосте `client` (Linux B):* +![Docker PS Client](img/client_docker_ps.png) + +*Скриншот `docker ps` на хосте `server` (Linux C):* +![Docker PS Server UFW](img/server_docker_ps.png) + +--- + +## 5. Выводы + +В ходе выполнения задания была успешно автоматизирована процедура развертывания двухкомпонентного приложения (веб-приложение и база данных) на отдельные виртуальные машины с использованием Ansible. Применены лучшие практики, такие как использование ролей для структурирования кода, Ansible Vault для защиты чувствительных данных и настройка файрвола для ограничения доступа. Задание выполнено в полном объеме. \ No newline at end of file diff --git a/roles/mysql/main b/roles/mysql/main new file mode 100644 index 0000000..576f25a --- /dev/null +++ b/roles/mysql/main @@ -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 diff --git a/roles/todo/main b/roles/todo/main new file mode 100644 index 0000000..b800625 --- /dev/null +++ b/roles/todo/main @@ -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.1.5 + DB_USER: root + DB_PASSWORD: "{{ app_db_password }}" + DB_NAME: todos diff --git a/server_docker_ps.jpg b/server_docker_ps.jpg new file mode 100644 index 0000000..3a67d85 Binary files /dev/null and b/server_docker_ps.jpg differ diff --git a/todo_app_browser.png b/todo_app_browser.png new file mode 100644 index 0000000..36ccaed Binary files /dev/null and b/todo_app_browser.png differ