Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added img/ansible_playbook_run_success.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/client_docker_ps.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/server_docker_ps.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/todo_app_browser.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions inventory.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[app]
client ansible_host=192.168.31.48 ansible_user=sheptunov_2

[db]
server ansible_host=192.168.31.110 ansible_user=sheptunov_3
13 changes: 13 additions & 0 deletions playbook.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
- hosts: db
become: yes
vars_files:
- vault.yml
roles:
- mysql

- hosts: app
become: yes
vars_files:
- vault.yml
roles:
- todo
109 changes: 109 additions & 0 deletions report.md
Original file line number Diff line number Diff line change
@@ -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.31.108`, пользователь `sheptunov_1`)
* **Хост приложения (Todo-app):** Linux B (`192.168.31.48`, пользователь `sheptunov_2`), далее `client` в Ansible.
* **Хост базы данных (MySQL):** Linux C (`192.168.31.110`, пользователь `sheptunov_3`), далее `server` в Ansible.

---

## 1. Подготовка окружения Ansible

1. **Создание структуры проекта:**
Проект Ansible был организован с использованием ролей (`mysql`, `todo`) для лучшей структуризации задач. Создан файл инвентаря (`inventory.ini`), основной плейбук (`playbook.yml`) и файл для хранения зашифрованных учетных данных (`vault.yml`).
*Структура папок представлена в `folder_structure.txt`.*

2. **Настройка инвентаря (`inventory.ini`):**
Хосты были разделены на группы `[app]` и `[db]` с указанием IP-адресов и пользователей для подключения Ansible.
```ini
# Содержимое inventory.ini
[app]
client ansible_host=192.168.31.48 ansible_user=sheptunov_2

[db]
server ansible_host=192.168.31.110 ansible_user=sheptunov_3
```

3. **Использование Ansible Vault (`vault.yml`):**
Для безопасного хранения паролей (для MySQL root и пользователя БД приложения) был создан и зашифрован файл `vault.yml`. Пароли в плейбуках и ролях были заменены на переменные из этого файла (например, `{{ mysql_root_password }}`).
*Файл `vault.yml` (зашифрованный) находится в корне проекта.*

4. **Настройка целевых хостов (Linux B, Linux C):**
* Настроен SSH-доступ по ключам с управляющего хоста (Linux A) на целевые хосты.
* Для пользователей `sheptunov_2` (на Linux B) и `sheptunov_3` (на 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` контейнера (на котором слушает приложение) пробрасывается на порт `3002` хоста.
* Переменные окружения для подключения к базе данных (`DB_HOST`, `DB_USER`, `DB_PASSWORD`, `DB_NAME`) передаются в контейнер. `DB_HOST` указывает на IP-адрес хоста `server` (`192.168.31.110`), а `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):** Успешно запущен, порт `3002` доступен извне.
* **Веб-приложение:** Приложение Todo-app доступно в браузере по адресу `http://192.168.31.48:3002`. Функциональность создания, редактирования и удаления задач проверена и работает корректно, что подтверждает успешное подключение к базе данных 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 для защиты чувствительных данных и настройка файрвола для ограничения доступа. Задание выполнено в полном объеме.
25 changes: 25 additions & 0 deletions roles/mysql/tasks/main.yaml
Original file line number Diff line number Diff line change
@@ -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
25 changes: 25 additions & 0 deletions roles/todo/tasks/main.yaml
Original file line number Diff line number Diff line change
@@ -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:
- "3002:80"
env:
DB_HOST: 192.168.31.110
DB_USER: root
DB_PASSWORD: "{{ app_db_password }}"
DB_NAME: todos