diff --git a/README.md b/README.md index 8511e6bd..22a80d49 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,8 @@ +# Дипломная работа по профессии «Системный администратор» - Tarkov Viktor -# Дипломная работа по профессии «Системный администратор» +
+ +Задание Содержание ========== @@ -16,13 +19,20 @@ * [Как правильно задавать вопросы дипломному руководителю](#Как-правильно-задавать-вопросы-дипломному-руководителю) --------- + ## Задача -Ключевая задача — разработать отказоустойчивую инфраструктуру для сайта, включающую мониторинг, сбор логов и резервное копирование основных данных. Инфраструктура должна размещаться в [Yandex Cloud](https://cloud.yandex.com/). +Ключевая задача — разработать отказоустойчивую инфраструктуру для сайта, включающую мониторинг, сбор логов и резервное копирование основных данных. Инфраструктура должна размещаться в [Yandex Cloud](https://cloud.yandex.com/) и отвечать минимальным стандартам безопасности: запрещается выкладывать токен от облака в git. Используйте [инструкцию](https://cloud.yandex.ru/docs/tutorials/infrastructure-management/terraform-quickstart#get-credentials). + +**Перед началом работы над дипломным заданием изучите [Инструкция по экономии облачных ресурсов](https://github.com/netology-code/devops-materials/blob/master/cloudwork.MD).** ## Инфраструктура -Для развёртки инфраструктуры используйте Terraform и Ansible. +Для развёртки инфраструктуры используйте Terraform и Ansible. -Параметры виртуальной машины (ВМ) подбирайте по потребностям сервисов, которые будут на ней работать. +Не используйте для ansible inventory ip-адреса! Вместо этого используйте fqdn имена виртуальных машин в зоне ".ru-central1.internal". Пример: example.ru-central1.internal - для этого достаточно при создании ВМ указать name=example, hostname=examle !! + +Важно: используйте по-возможности **минимальные конфигурации ВМ**:2 ядра 20% Intel ice lake, 2-4Гб памяти, 10hdd, прерываемая. + +**Так как прерываемая ВМ проработает не больше 24ч, перед сдачей работы на проверку дипломному руководителю сделайте ваши ВМ постоянно работающими.** Ознакомьтесь со всеми пунктами из этой секции, не беритесь сразу выполнять задание, не дочитав до конца. Пункты взаимосвязаны и могут влиять друг на друга. @@ -31,21 +41,25 @@ Используйте набор статичных файлов для сайта. Можно переиспользовать сайт из домашнего задания. -Создайте [Target Group](https://cloud.yandex.com/docs/application-load-balancer/concepts/target-group), включите в неё две созданных ВМ. +Виртуальные машины не должны обладать внешним Ip-адресом, те находится во внутренней сети. Доступ к ВМ по ssh через бастион-сервер. Доступ к web-порту ВМ через балансировщик yandex cloud. + +Настройка балансировщика: -Создайте [Backend Group](https://cloud.yandex.com/docs/application-load-balancer/concepts/backend-group), настройте backends на target group, ранее созданную. Настройте healthcheck на корень (/) и порт 80, протокол HTTP. +1. Создайте [Target Group](https://cloud.yandex.com/docs/application-load-balancer/concepts/target-group), включите в неё две созданных ВМ. -Создайте [HTTP router](https://cloud.yandex.com/docs/application-load-balancer/concepts/http-router). Путь укажите — /, backend group — созданную ранее. +2. Создайте [Backend Group](https://cloud.yandex.com/docs/application-load-balancer/concepts/backend-group), настройте backends на target group, ранее созданную. Настройте healthcheck на корень (/) и порт 80, протокол HTTP. -Создайте [Application load balancer](https://cloud.yandex.com/en/docs/application-load-balancer/) для распределения трафика на веб-сервера, созданные ранее. Укажите HTTP router, созданный ранее, задайте listener тип auto, порт 80. +3. Создайте [HTTP router](https://cloud.yandex.com/docs/application-load-balancer/concepts/http-router). Путь укажите — /, backend group — созданную ранее. + +4. Создайте [Application load balancer](https://cloud.yandex.com/en/docs/application-load-balancer/) для распределения трафика на веб-сервера, созданные ранее. Укажите HTTP router, созданный ранее, задайте listener тип auto, порт 80. Протестируйте сайт `curl -v <публичный IP балансера>:80` ### Мониторинг -Создайте ВМ, разверните на ней Prometheus. На каждую ВМ из веб-серверов установите Node Exporter и [Nginx Log Exporter](https://github.com/martin-helmich/prometheus-nginxlog-exporter). Настройте Prometheus на сбор метрик с этих exporter. +Создайте ВМ, разверните на ней Zabbix. На каждую ВМ установите Zabbix Agent, настройте агенты на отправление метрик в Zabbix. -Создайте ВМ, установите туда Grafana. Настройте её на взаимодействие с ранее развернутым Prometheus. Настройте дешборды с отображением метрик, минимальный набор — Utilization, Saturation, Errors для CPU, RAM, диски, сеть, http_response_count_total, http_response_size_bytes. Добавьте необходимые [tresholds](https://grafana.com/docs/grafana/latest/panels/thresholds/) на соответствующие графики. +Настройте дешборды с отображением метрик, минимальный набор — по принципу USE (Utilization, Saturation, Errors) для CPU, RAM, диски, сеть, http запросов к веб-серверам. Добавьте необходимые tresholds на соответствующие графики. ### Логи Cоздайте ВМ, разверните на ней Elasticsearch. Установите filebeat в ВМ к веб-серверам, настройте на отправку access.log, error.log nginx в Elasticsearch. @@ -53,11 +67,13 @@ Cоздайте ВМ, разверните на ней Elasticsearch. Устан Создайте ВМ, разверните на ней Kibana, сконфигурируйте соединение с Elasticsearch. ### Сеть -Разверните один VPC. Сервера web, Prometheus, Elasticsearch поместите в приватные подсети. Сервера Grafana, Kibana, application load balancer определите в публичную подсеть. +Разверните один VPC. Сервера web, Elasticsearch поместите в приватные подсети. Сервера Zabbix, Kibana, application load balancer определите в публичную подсеть. Настройте [Security Groups](https://cloud.yandex.com/docs/vpc/concepts/security-groups) соответствующих сервисов на входящий трафик только к нужным портам. -Настройте ВМ с публичным адресом, в которой будет открыт только один порт — ssh. Настройте все security groups на разрешение входящего ssh из этой security group. Эта вм будет реализовывать концепцию bastion host. Потом можно будет подключаться по ssh ко всем хостам через этот хост. +Настройте ВМ с публичным адресом, в которой будет открыт только один порт — ssh. Эта вм будет реализовывать концепцию [bastion host]( https://cloud.yandex.ru/docs/tutorials/routing/bastion) . Синоним "bastion host" - "Jump host". Подключение ansible к серверам web и Elasticsearch через данный bastion host можно сделать с помощью [ProxyCommand](https://docs.ansible.com/ansible/latest/network/user_guide/network_debug_troubleshooting.html#network-delegate-to-vs-proxycommand) . Допускается установка и запуск ansible непосредственно на bastion host.(Этот вариант легче в настройке) + +Исходящий доступ в интернет для ВМ внутреннего контура через [NAT-шлюз](https://yandex.cloud/ru/docs/vpc/operations/create-nat-gateway). ### Резервное копирование Создайте snapshot дисков всех ВМ. Ограничьте время жизни snaphot в неделю. Сами snaphot настройте на ежедневное копирование. @@ -65,11 +81,10 @@ Cоздайте ВМ, разверните на ней Elasticsearch. Устан ### Дополнительно Не входит в минимальные требования. -1. Для Prometheus можно реализовать альтернативный способ хранения данных — в базе данных PpostgreSQL. Используйте [Yandex Managed Service for PostgreSQL](https://cloud.yandex.com/en-ru/services/managed-postgresql). Разверните кластер из двух нод с автоматическим failover. Воспользуйтесь адаптером с https://github.com/CrunchyData/postgresql-prometheus-adapter для настройки отправки данных из Prometheus в новую БД. +1. Для Zabbix можно реализовать разделение компонент - frontend, server, database. Frontend отдельной ВМ поместите в публичную подсеть, назначте публичный IP. Server поместите в приватную подсеть, настройте security group на разрешение трафика между frontend и server. Для Database используйте [Yandex Managed Service for PostgreSQL](https://cloud.yandex.com/en-ru/services/managed-postgresql). Разверните кластер из двух нод с автоматическим failover. 2. Вместо конкретных ВМ, которые входят в target group, можно создать [Instance Group](https://cloud.yandex.com/en/docs/compute/concepts/instance-groups/), для которой настройте следующие правила автоматического горизонтального масштабирования: минимальное количество ВМ на зону — 1, максимальный размер группы — 3. -3. Можно добавить в Grafana оповещения с помощью Grafana alerts. Как вариант, можно также установить Alertmanager в ВМ к Prometheus, настроить оповещения через него. -4. В Elasticsearch добавьте мониторинг логов самого себя, Kibana, Prometheus, Grafana через filebeat. Можно использовать logstash тоже. -5. Воспользуйтесь Yandex Certificate Manager, выпустите сертификат для сайта, если есть доменное имя. Перенастройте работу балансера на HTTPS, при этом нацелен он будет на HTTP веб-серверов. +3. В Elasticsearch добавьте мониторинг логов самого себя, Kibana, Zabbix, через filebeat. Можно использовать logstash тоже. +4. Воспользуйтесь Yandex Certificate Manager, выпустите сертификат для сайта, если есть доменное имя. Перенастройте работу балансера на HTTPS, при этом нацелен он будет на HTTP веб-серверов. ## Выполнение работы На этом этапе вы непосредственно выполняете работу. При этом вы можете консультироваться с руководителем по поводу вопросов, требующих уточнения. @@ -80,7 +95,7 @@ Cоздайте ВМ, разверните на ней Elasticsearch. Устан ## Критерии сдачи 1. Инфраструктура отвечает минимальным требованиям, описанным в [Задаче](#Задача). -2. Предоставлен доступ ко всем ресурсам, у которых предполагается веб-страница (сайт, Kibana, Grafanа). +2. Предоставлен доступ ко всем ресурсам, у которых предполагается веб-страница (сайт, Kibana, Zabbix). 3. Для ресурсов, к которым предоставить доступ проблематично, предоставлены скриншоты, команды, stdout, stderr, подтверждающие работу ресурса. 4. Работа оформлена в отдельном репозитории в GitHub или в [Google Docs](https://docs.google.com/), разрешён доступ по ссылке. 5. Код размещён в репозитории в GitHub. @@ -97,3 +112,268 @@ Cоздайте ВМ, разверните на ней Elasticsearch. Устан 1. Вопросы вида «Ничего не работает. Не запускается. Всё сломалось». Дипломный руководитель не сможет ответить на такой вопрос без дополнительных уточнений. Цените своё время и время других. 2. Откладывание выполнения дипломной работы на последний момент. 3. Ожидание моментального ответа на свой вопрос. Дипломные руководители — работающие инженеры, которые занимаются, кроме преподавания, своими проектами. Их время ограничено, поэтому постарайтесь задавать правильные вопросы, чтобы получать быстрые ответы :) + +
+ + +## I. Подготовка и установка TERRAFORM, ANSIBLE. + +### a) Terraform + +```python +wget https://hashicorp-releases.yandexcloud.net/terraform/1.14.0-alpha20250911/terraform_1.14.0-alpha20250911_linux_amd64.zip +wget https://hashicorp-releases.yandexcloud.net/terraform/1.14.0-alpha20250911/terraform_1.14.0-alpha20250911_SHA256SUMS +sha256sum -c --ignore-missing terraform_1.14.0-alpha20250911_SHA256SUMS +sudo unzip terraform_1.14.0-alpha20250911_linux_amd64.zip -d /usr/local/bin +terraform version +``` +![1](img/1.png) + +```python +nano ~/.terraformrc +``` +![2](img/2.png) + +```python +ssh-keygen -t ed25519 +cat ~/.ssh/id_ed25519.pub +``` + +```python +nano ~/meta.yaml +``` +![3](img/3.png) + +Создание `playbook Terraform` с провайдером. +```python +nano ~/providers.tf +``` +![4](img/4.png) + +```python +terraform init +``` +![5](img/5.png) + +### b) Ansible + +```python +mkdir .ansible/ +cd .ansible/ +sudo apt install ansible +ansible --version +``` +![6](img/6.png) + +Создание `ansible.cfg` +```python +sudo nano ansible.cfg +``` +![7](img/7.png) + +--------- + +## II. Настройки для развёртывания инфраструктуры с помощью TERRAFORM. + +### a) Сайт. Серверы Nginx. + +Создаются: + +```python +sudo nano ...tf +``` + +- [main.tf](https://github.com/stimul2520/sys43-diplom/blob/d6028295258290d8e62d48ff6c6203ad85766dec/terraform/main.tf), в котором описывается создание 2 ВМ с nginx. +- [target.tf](https://github.com/stimul2520/sys43-diplom/blob/d6028295258290d8e62d48ff6c6203ad85766dec/terraform/target.tf), создание целевых групп. +- [backend.tf](https://github.com/stimul2520/sys43-diplom/blob/d6028295258290d8e62d48ff6c6203ad85766dec/terraform/backend.tf), группы бэкендов. +- [router.tf](https://github.com/stimul2520/sys43-diplom/blob/c7c91766226b32fe9b269c78dc0fadeb7ebe8bbd/terraform/router.tf), HTTP роутер. +- [balancer.tf](https://github.com/stimul2520/sys43-diplom/blob/c7c91766226b32fe9b269c78dc0fadeb7ebe8bbd/terraform/balancer.tf), Application Load Balancer. + +### b) Мониторинг. Zabbix. + +Создание ВМ, развертывание на ней Zabbix. На каждую ВМ установка Zabbix Agent, настройка агентов на отправление метрик в Zabbix. + +- [zabbix.tf](https://github.com/stimul2520/sys43-diplom/blob/c7c91766226b32fe9b269c78dc0fadeb7ebe8bbd/terraform/zabbix.tf) + +### с) Логи. Elasticsearch, Kibana. + +1. Cоздание ВМ, развертывание на ней Elasticsearch. +2. Создание ВМ, развертывание на ней Kibana, конфигурация соединение с Elasticsearch. + +- [elastic.tf](https://github.com/stimul2520/sys43-diplom/blob/c7c91766226b32fe9b269c78dc0fadeb7ebe8bbd/terraform/elastic.tf) +- [kibana.tf](https://github.com/stimul2520/sys43-diplom/blob/c7c91766226b32fe9b269c78dc0fadeb7ebe8bbd/terraform/kibana.tf) + +### d) Сеть. + +1. Развертывание одного VPC. +2. Сервера web, Elasticsearch помещаются в приватные подсети. +3. Сервера Zabbix, Kibana, application load balancer определяются в публичную подсеть. +4. Настройка Security Groups соответствующих сервисов на входящий трафик только к нужным портам. +5. Настройка ВМ с публичным адресом, в которой будет открыт только один порт — ssh. Эта вм будет реализовывать концепцию bastion host . + +- [network.tf](https://github.com/stimul2520/sys43-diplom/blob/c7c91766226b32fe9b269c78dc0fadeb7ebe8bbd/terraform/network.tf) +- [security.tf](https://github.com/stimul2520/sys43-diplom/blob/c7c91766226b32fe9b269c78dc0fadeb7ebe8bbd/terraform/security.tf) +- [bastion.tf](https://github.com/stimul2520/sys43-diplom/blob/c7c91766226b32fe9b269c78dc0fadeb7ebe8bbd/terraform/bastion.tf) + +### e) Резервное копирование. + +1. Создание snapshot дисков всех ВМ. +2. Ограничение времени жизни snaphot в неделю. Сами snaphot настраиваются на ежедневное копирование. + +- [snapshot.tf](https://github.com/stimul2520/sys43-diplom/blob/697163b8fc84499b376548a5ec29d4e951159fde/terraform/snapshot.tf) + +### f) Вывод информации в консоль по созданию ВМ. + +- [outputs.tf](https://github.com/stimul2520/sys43-diplom/blob/c7c91766226b32fe9b269c78dc0fadeb7ebe8bbd/terraform/outputs.tf) + +--------- + +## III. Поднятие облачной инфраструктуры с помощью TERRAFORM. + +```python +terraform plan +terraform apply +``` +![10](img/10.png) +![11](img/11.png) +![12](img/12.png) +![13](img/13.png) +![14](img/14.png) +![15](img/15.png) + +--------- + +## IV. Настройки для развёртывания инфраструктуры с помощью ANSIBLE. + +Создание и настройка [hosts](https://github.com/stimul2520/sys43-diplom/blob/18ed5aea0366f84a3538636637f92b8d08c40173/ansible/hosts), [ansible.cfg](https://github.com/stimul2520/sys43-diplom/blob/18ed5aea0366f84a3538636637f92b8d08c40173/ansible/ansible.cfg). + +```python +cd .ansible/ +sudo nano hosts +sudo nano ansible.cfg +``` + +Проверка доступности хостов: +```python +sudo ansible all -m ping --list-hosts +ansible all -m ping +``` +![16](img/16.png) +![17](img/17.png) +![18](img/18.png) + +Создание, запуск ansible-playbooks и сопутствующих конфиг файлов. + +1. Nginx. +- [ngx1.html](https://github.com/stimul2520/sys43-diplom/blob/8c291abcbf88bf50f157887d514af1c6d74a5a6b/ansible/ngx1.html) +- [ngx2.html](https://github.com/stimul2520/sys43-diplom/blob/8c291abcbf88bf50f157887d514af1c6d74a5a6b/ansible/ngx2.html) +- [nginx-playbook.yaml](https://github.com/stimul2520/sys43-diplom/blob/8c291abcbf88bf50f157887d514af1c6d74a5a6b/ansible/nginx-playbook.yaml) + +![19](img/19.png) +![20](img/20.png) + +2. Elasticsearch (https://mirror.yandex.ru/mirrors/elastic/7/pool/main/e/elasticsearch/elasticsearch-7.17.1-amd64.deb) +- [elastic-conf.yaml](https://github.com/stimul2520/sys43-diplom/blob/8c291abcbf88bf50f157887d514af1c6d74a5a6b/ansible/elastic-conf.yaml) +- [elastic-play.yaml](https://github.com/stimul2520/sys43-diplom/blob/8c291abcbf88bf50f157887d514af1c6d74a5a6b/ansible/elastic-play.yaml) + +![21](img/21.png) + +3. Kibana (https://mirror.yandex.ru/mirrors/elastic/7/pool/main/k/kibana/kibana-7.17.1-amd64.deb) +- [kibana.j2](https://github.com/stimul2520/sys43-diplom/blob/8c291abcbf88bf50f157887d514af1c6d74a5a6b/ansible/kibana.j2) +- [kibana-play.yaml](https://github.com/stimul2520/sys43-diplom/blob/8c291abcbf88bf50f157887d514af1c6d74a5a6b/ansible/kibana-play.yaml) + +![22](img/22.png) + +4. Filebeat с настройкой на отправку access.log, error.log nginx в Elasticsearch (https://mirror.yandex.ru/mirrors/elastic/7/pool/main/f/filebeat/filebeat-7.17.1-amd64.deb) +- [filebeat.j2](https://github.com/stimul2520/sys43-diplom/blob/8c291abcbf88bf50f157887d514af1c6d74a5a6b/ansible/filebeat.j2) +- [filebeat-play.yaml](https://github.com/stimul2520/sys43-diplom/blob/8c291abcbf88bf50f157887d514af1c6d74a5a6b/ansible/filebeat-play.yaml) + +![23](img/23.png) + +5. Zabbix. Zabbix-agent. +- [zabbix-playbook.yaml](https://github.com/stimul2520/sys43-diplom/blob/8c291abcbf88bf50f157887d514af1c6d74a5a6b/ansible/zabbix-playbook.yaml) +- [zabbix-agent-playbook.yaml](https://github.com/stimul2520/sys43-diplom/blob/8c291abcbf88bf50f157887d514af1c6d74a5a6b/ansible/zabbix-agent-playbook.yaml) + +![24](img/24.png) +![25](img/25.png) +![26](img/26.png) +![27](img/27.png) + +--------- + +## V. Проверка и настройка ресурсов. + +### a) Сайт. Серверы Nginx. + +`curl -v <публичный IP балансера>:80` + +```python +curl -v 158.160.179.54:80 +``` +![30](img/30.png) + +```python +http://158.160.179.54 +``` + +После каждого запроса по внешнему адресу балансировщика поочередно открывается вэб-страница Nginx, при этом по сути сервис идентичен. + +![31](img/31.png) +![32](img/32.png) + +### b) Мониторинг. Zabbix. + +```python +http://158.160.120.30/zabbix +``` +![33](img/33.png) +![34](img/34.png) +![35](img/35.png) +![36](img/36.png) +![37](img/37.png) +![38](img/38.png) + +```python +log: Admin +pass: zabbix +``` +![39](img/39.png) +![40](img/40.png) + +Добавление хостов: + +![41](img/41.png) + +Настройка Templates, Items: + +![42](img/42.png) +![43](img/43.png) + +Настройка дешбордов и отражение в виде графиков: + +![44](img/44.png) +![45](img/45.png) + +### с) Логи. Elasticsearch, Kibana, Filebeat. + +Запуск Kibana: + +```python +http://89.169.141.42:5601 +``` +![46](img/46.png) + +Создание Index pattern: + +![47](img/47.png) +![48](img/48.png) + +Проверка отправки логов: + +![49](img/49.png) + +### d) Резервное копирование. + +![50](img/50.png) + +--------- diff --git a/ansible/ansible.cfg b/ansible/ansible.cfg new file mode 100644 index 00000000..db88dc2e --- /dev/null +++ b/ansible/ansible.cfg @@ -0,0 +1,9 @@ +[defaults] +inventory = /home/diploma1/.ansible/hosts +host_key_checking = false +remote_user = diploma1 +private_key_file = ~/.ssh/id_ed25519 +pipelining = True + +[privilege_escalation] +become = True diff --git a/ansible/elastic-conf.yaml b/ansible/elastic-conf.yaml new file mode 100644 index 00000000..296d3f8b --- /dev/null +++ b/ansible/elastic-conf.yaml @@ -0,0 +1,101 @@ +# ======================== Elasticsearch Configuration ========================= +# +# NOTE: Elasticsearch comes with reasonable defaults for most settings. +# Before you set out to tweak and tune the configuration, make sure you +# understand what are you trying to accomplish and the consequences. +# +# The primary way of configuring a node is via this file. This template lists +# the most important settings you may want to configure for a production cluster. +# +# Please consult the documentation for further information on configuration options: +# https://www.elastic.co/guide/en/elasticsearch/reference/index.html +# +# ---------------------------------- Cluster ----------------------------------- +# +# Use a descriptive name for your cluster: +# +cluster.name: diploma1 +# +# ------------------------------------ Node ------------------------------------ +# +# Use a descriptive name for the node: +# +node.name: node-1 +# +# Add custom attributes to the node: +# +#node.attr.rack: r1 +# +# ----------------------------------- Paths ------------------------------------ +# +# Path to directory where to store the data (separate multiple locations by comma): +# +path.data: /var/lib/elasticsearch +# +# Path to log files: +# +path.logs: /var/log/elasticsearch +# +# ----------------------------------- Memory ----------------------------------- +# +# Lock the memory on startup: +# +#bootstrap.memory_lock: true +# +# Make sure that the heap size is set to about half the memory available +# on the system and that the owner of the process is allowed to use this +# limit. +# +# Elasticsearch performs poorly when the system is swapping the memory. +# +# ---------------------------------- Network ----------------------------------- +# +# By default Elasticsearch is only accessible on localhost. Set a different +# address here to expose this node on the network: +# +#network.host: 0.0.0.0 +# +# By default Elasticsearch listens for HTTP traffic on the first free port it +# finds starting at 9200. Set a specific HTTP port here: +# +#http.port: 9200 +# +# For more information, consult the network module documentation. +# +# --------------------------------- Discovery ---------------------------------- +# +# Pass an initial list of hosts to perform discovery when this node is started: +# The default list of hosts is ["127.0.0.1", "[::1]"] +# +discovery.seed_hosts: ["127.0.0.1", "[::1]"] +# +# Bootstrap the cluster using an initial set of master-eligible nodes: +# +#cluster.initial_master_nodes: ["node-1", "node-2"] +# +# For more information, consult the discovery and cluster formation module documentation. +# +# ---------------------------------- Various ----------------------------------- +# +# Require explicit names when deleting indices: +# +#action.destructive_requires_name: true +# +# ---------------------------------- Security ---------------------------------- +# +# *** WARNING *** +# +# Elasticsearch security features are not enabled by default. +# These features are free, but require configuration changes to enable them. +# This means that users don’t have to provide credentials and can get full access +# to the cluster. Network connections are also not encrypted. +# +# To protect your data, we strongly encourage you to enable the Elasticsearch security features. +# Refer to the following documentation for instructions. +# +# https://www.elastic.co/guide/en/elasticsearch/reference/7.16/configuring-stack-security.html +network.host: 127.0.0.1 +http.host: 0.0.0.0 +http.port: 9200 +discovery.type: single-node + diff --git a/ansible/elastic-play.yaml b/ansible/elastic-play.yaml new file mode 100644 index 00000000..3376a78d --- /dev/null +++ b/ansible/elastic-play.yaml @@ -0,0 +1,25 @@ +--- +- name: 1 install Elastic + hosts: elasticsearch + become: yes + gather_facts: true + + tasks: + - name: Установка elasticsearch + apt: + deb: "https://mirror.yandex.ru/mirrors/elastic/7/pool/main/e/elasticsearch/elasticsearch-7.17.1-amd64.deb" + + - name: 2 copy elasticsearch + copy: + src: /home/diploma1/.ansible/elastic-conf.yaml + dest: /etc/elasticsearch/elasticsearch.yml + + - name: daemon_reload + systemd: + daemon_reload: true + + - name: 3 Перезапуск elasticsearch и добавляем в автозагрузку + service: + name: elasticsearch + state: restarted + enabled: yes diff --git a/ansible/filebeat-play.yaml b/ansible/filebeat-play.yaml new file mode 100644 index 00000000..0c3751ec --- /dev/null +++ b/ansible/filebeat-play.yaml @@ -0,0 +1,27 @@ +--- +- name: 1 installFilebeat + hosts: nginx-web + become: yes + gather_facts: true + vars: + kibana_host: 192.168.40.30:5601 + elastic_host: 192.168.10.30:9200 + tasks: + - name: 2 Устанавливаем filebeat + apt: + deb: "https://mirror.yandex.ru/mirrors/elastic/7/pool/main/f/filebeat/filebeat-7.17.1-amd64.deb" + + - name: 3 copy file filebeat + template: + src: /home/diploma1/.ansible/filebeat.j2 + dest: /etc/filebeat/filebeat.yml + + - name: daemon_reload + systemd: + daemon_reload: true + + - name: 4 Перезапускаем filebeat и добавляем в автозагрузку + service: + name: filebeat + state: restarted + enabled: yes diff --git a/ansible/filebeat.j2 b/ansible/filebeat.j2 new file mode 100644 index 00000000..87da4eef --- /dev/null +++ b/ansible/filebeat.j2 @@ -0,0 +1,30 @@ +#=========================== Filebeat inputs ============================= + +filebeat.inputs: +- type: log + enabled: true + paths: + - /var/log/nginx/access.log + - /var/log/nginx/error.log + +#============================= Filebeat modules =============================== + +filebeat.config.modules: + path: ${path.config}/modules.d/*.yml + reload.enabled: false + +#==================== Elasticsearch template setting ========================== + +setup.template.settings: + index.number_of_shards: 1 + +#============================== Kibana ===================================== + +setup.kibana: + host: "{{kibana_host}}" + +#-------------------------- Elasticsearch output ------------------------------ + +output.elasticsearch: + hosts: ["{{elastic_host}}"] + diff --git a/ansible/hosts b/ansible/hosts new file mode 100644 index 00000000..f25220e8 --- /dev/null +++ b/ansible/hosts @@ -0,0 +1,24 @@ +[nginx-web] +nginx-1 ansible_ssh_user=diploma1 ansible_sudo_pass=*** +nginx-2 ansible_ssh_user=diploma1 ansible_sudo_pass=*** + +[zabbix] +zabbix ansible_ssh_user=diploma1 ansible_sudo_pass=*** + +[elasticsearch] +elasticsearch + +[kibana] +kibana + +[nginx-web:vars] +ansible_ssh_common_args='-o ProxyCommand="ssh -W %h:%p -q diploma1@46.21.244.219"' + +[zabbix:vars] +ansible_ssh_common_args='-o ProxyCommand="ssh -W %h:%p -q diploma1@46.21.244.219"' + +[elasticsearch:vars] +ansible_ssh_common_args='-o ProxyCommand="ssh -W %h:%p -q diploma1@46.21.244.219"' + +[kibana:vars] +ansible_ssh_common_args='-o ProxyCommand="ssh -W %h:%p -q diploma1@46.21.244.219"' diff --git a/ansible/kibana-play.yaml b/ansible/kibana-play.yaml new file mode 100644 index 00000000..c597ec4b --- /dev/null +++ b/ansible/kibana-play.yaml @@ -0,0 +1,26 @@ +--- +- name: 1 install Kibana + hosts: kibana + become: yes + vars: + elastic_httphost: 192.168.10.30:9200 + tasks: + + - name: 2 Установка пакета kibana + apt: + deb: "https://mirror.yandex.ru/mirrors/elastic/7/pool/main/k/kibana/kibana-7.17.1-amd64.deb" + + - name: 3 copy file kibana + template: + src: /home/diploma1/.ansible/kibana.j2 + dest: /etc/kibana/kibana.yml + + - name: daemon_reload + systemd: + daemon_reload: true + + - name: 4 Перезапускаем kibana и добавляем в автозагрузку + service: + name: kibana + state: restarted + enabled: yes diff --git a/ansible/kibana.j2 b/ansible/kibana.j2 new file mode 100644 index 00000000..e89a1fc5 --- /dev/null +++ b/ansible/kibana.j2 @@ -0,0 +1,3 @@ +server.port: 5601 +server.host: "0.0.0.0" +elasticsearch.hosts: ["http://{{elastic_httphost}}"] diff --git a/ansible/nginx-playbook.yaml b/ansible/nginx-playbook.yaml new file mode 100644 index 00000000..330c683d --- /dev/null +++ b/ansible/nginx-playbook.yaml @@ -0,0 +1,50 @@ +--- +- name: test + hosts: nginx-web + become: yes + + tasks: + - name: update пакетов + apt: + force_apt_get: true + upgrade: dist + update_cache: yes + become: true + + - name: install nginx + apt: + name: nginx + state: latest + update_cache: yes + +- name: copy ngx1.html на первый сервер + hosts: nginx-1 + become: yes + + tasks: + - name: copy index_new.html + ansible.builtin.copy: + src: /home/diploma1/.ansible/ngx1.html + dest: /var/www/html/index.html + owner: root + group: sudo + mode: "0644" + +- name: copy ngx2.html на второй сервер + hosts: nginx-2 + become: yes + + tasks: + - name: copy index_new.html + ansible.builtin.copy: + src: /home/diploma1/.ansible/ngx2.html + dest: /var/www/html/index.html + owner: root + group: sudo + mode: "0644" + + handlers: + - name: reload nginx + systemd: + name: nginx + state: reloaded diff --git a/ansible/ngx1.html b/ansible/ngx1.html new file mode 100644 index 00000000..42284b65 --- /dev/null +++ b/ansible/ngx1.html @@ -0,0 +1,18 @@ + + + + +Dyplom project System administration + + + +

Добро пожаловать на nginx-1

+

Tarkov Viktor

+

SYS-43

+ + diff --git a/ansible/ngx2.html b/ansible/ngx2.html new file mode 100644 index 00000000..4ed3f941 --- /dev/null +++ b/ansible/ngx2.html @@ -0,0 +1,24 @@ + + + + +Welcome to nginx! + + + +

Page generated by

+

SYS-43
TARKOV VIKTOR

+

Hello, world!.

+
+ +

-------------------------------------------------------------

+

nginx-2

+ + diff --git a/ansible/zabbix-agent-playbook.yaml b/ansible/zabbix-agent-playbook.yaml new file mode 100644 index 00000000..6bc6876c --- /dev/null +++ b/ansible/zabbix-agent-playbook.yaml @@ -0,0 +1,37 @@ +--- + +- name: install zabbix-agent + hosts: all + become: true + + tasks: + - name: apt update + apt: + upgrade: yes + update_cache: yes + + - name: download zabbix-agent + get_url: + url: https://repo.zabbix.com/zabbix/7.4/release/ubuntu/pool/main/z/zabbix-release/zabbix-release_latest_7.4+ubuntu24.04_all.deb + dest: /tmp/zabbix-release_latest_7.4+ubuntu24.04_all.deb + + - name: dpkg -i zabbix-agent + apt: + deb: /tmp/zabbix-release_latest_7.4+ubuntu24.04_all.deb + + - name: apt update + apt: + update_cache: yes + + - name: apt install zabbix-agent + apt: + name: zabbix-agent + + - name: ip replacement in zabbix_agentd.conf + shell: | + sed -i 's/Server=127.0.0.1/Server=192.168.40.20/g' /etc/zabbix/zabbix_agentd.conf + + - name: restart and enable zabbix-agent + shell: | + systemctl restart zabbix-agent + systemctl enable zabbix-agent diff --git a/ansible/zabbix-playbook.yaml b/ansible/zabbix-playbook.yaml new file mode 100644 index 00000000..ee76d6da --- /dev/null +++ b/ansible/zabbix-playbook.yaml @@ -0,0 +1,51 @@ +--- + +- name: install zabbix + hosts: zabbix + become: true + + tasks: + - name: apt update + apt: + update_cache: yes + + - name: install postgresql + apt: + name: postgresql + state: latest + + - name: download zabbix + get_url: + url: https://repo.zabbix.com/zabbix/7.4/release/ubuntu/pool/main/z/zabbix-release/zabbix-release_latest_7.4+ubuntu24.04_all.deb + dest: /tmp/zabbix-release_latest_7.4+ubuntu24.04_all.deb + mode: 0644 + + - name: dpkg -i zabbix + apt: + deb: /tmp/zabbix-release_latest_7.4+ubuntu24.04_all.deb + + - name: apt update + apt: + update_cache: yes + + - name: install zabbix-server-pgsql zabbix-frontend-php php8.3-pgsql zabbix-apache-conf zabbix-sql-scripts zabbix-agent + apt: + name: + - zabbix-frontend-php + - php8.3-pgsql + - zabbix-apache-conf + - zabbix-sql-scripts + - zabbix-agent + state: latest + + - name: create user and initial database zabbix, import initial schema and data, configure DBPassword + shell: | + sudo -u postgres psql -c "CREATE USER zabbix WITH PASSWORD '7949';" + sudo -u postgres psql -c "CREATE DATABASE zabbix OWNER zabbix;" + zcat /usr/share/zabbix-sql-scripts/postgresql/server.sql.gz | sudo -u zabbix psql zabbix + sudo sed -i 's/# DBPassword=/DBPassword=7949/g' /etc/zabbix/zabbix_server.conf + + - name: start Zabbix server and agent processes + shell: | + systemctl restart zabbix-server apache2 + systemctl enable zabbix-server apache2 diff --git a/img/1.png b/img/1.png new file mode 100644 index 00000000..9c7b7872 Binary files /dev/null and b/img/1.png differ diff --git a/img/10.png b/img/10.png new file mode 100644 index 00000000..dc91204a Binary files /dev/null and b/img/10.png differ diff --git a/img/11.png b/img/11.png new file mode 100644 index 00000000..8338810f Binary files /dev/null and b/img/11.png differ diff --git a/img/12.png b/img/12.png new file mode 100644 index 00000000..341064a9 Binary files /dev/null and b/img/12.png differ diff --git a/img/13.png b/img/13.png new file mode 100644 index 00000000..427a4c0f Binary files /dev/null and b/img/13.png differ diff --git a/img/14.png b/img/14.png new file mode 100644 index 00000000..c2ffc4b8 Binary files /dev/null and b/img/14.png differ diff --git a/img/15.png b/img/15.png new file mode 100644 index 00000000..d688454d Binary files /dev/null and b/img/15.png differ diff --git a/img/16.png b/img/16.png new file mode 100644 index 00000000..5d7e339e Binary files /dev/null and b/img/16.png differ diff --git a/img/17.png b/img/17.png new file mode 100644 index 00000000..17b3ec94 Binary files /dev/null and b/img/17.png differ diff --git a/img/18.png b/img/18.png new file mode 100644 index 00000000..f6bd9ae5 Binary files /dev/null and b/img/18.png differ diff --git a/img/19.png b/img/19.png new file mode 100644 index 00000000..73203274 Binary files /dev/null and b/img/19.png differ diff --git a/img/2.png b/img/2.png new file mode 100644 index 00000000..39537b49 Binary files /dev/null and b/img/2.png differ diff --git a/img/20.png b/img/20.png new file mode 100644 index 00000000..f928cb12 Binary files /dev/null and b/img/20.png differ diff --git a/img/21.png b/img/21.png new file mode 100644 index 00000000..3670f3ec Binary files /dev/null and b/img/21.png differ diff --git a/img/22.png b/img/22.png new file mode 100644 index 00000000..ff1fafbd Binary files /dev/null and b/img/22.png differ diff --git a/img/23.png b/img/23.png new file mode 100644 index 00000000..8e201664 Binary files /dev/null and b/img/23.png differ diff --git a/img/24.png b/img/24.png new file mode 100644 index 00000000..dbcf0d20 Binary files /dev/null and b/img/24.png differ diff --git a/img/25.png b/img/25.png new file mode 100644 index 00000000..ec592bd6 Binary files /dev/null and b/img/25.png differ diff --git a/img/26.png b/img/26.png new file mode 100644 index 00000000..003baec7 Binary files /dev/null and b/img/26.png differ diff --git a/img/27.png b/img/27.png new file mode 100644 index 00000000..ff64b0a0 Binary files /dev/null and b/img/27.png differ diff --git a/img/28.png b/img/28.png new file mode 100644 index 00000000..ae88b377 Binary files /dev/null and b/img/28.png differ diff --git a/img/3.png b/img/3.png new file mode 100644 index 00000000..c6446dd3 Binary files /dev/null and b/img/3.png differ diff --git a/img/30.png b/img/30.png new file mode 100644 index 00000000..a47c91e6 Binary files /dev/null and b/img/30.png differ diff --git a/img/31.png b/img/31.png new file mode 100644 index 00000000..2e0d56c4 Binary files /dev/null and b/img/31.png differ diff --git a/img/32.png b/img/32.png new file mode 100644 index 00000000..d1ab2b2e Binary files /dev/null and b/img/32.png differ diff --git a/img/33.png b/img/33.png new file mode 100644 index 00000000..85639469 Binary files /dev/null and b/img/33.png differ diff --git a/img/34.png b/img/34.png new file mode 100644 index 00000000..12048b85 Binary files /dev/null and b/img/34.png differ diff --git a/img/35.png b/img/35.png new file mode 100644 index 00000000..3bdf5cb0 Binary files /dev/null and b/img/35.png differ diff --git a/img/36.png b/img/36.png new file mode 100644 index 00000000..7d4943d8 Binary files /dev/null and b/img/36.png differ diff --git a/img/37.png b/img/37.png new file mode 100644 index 00000000..a1700489 Binary files /dev/null and b/img/37.png differ diff --git a/img/38.png b/img/38.png new file mode 100644 index 00000000..bc41e466 Binary files /dev/null and b/img/38.png differ diff --git a/img/39.png b/img/39.png new file mode 100644 index 00000000..6aa35f1f Binary files /dev/null and b/img/39.png differ diff --git a/img/4.png b/img/4.png new file mode 100644 index 00000000..3bcf7c94 Binary files /dev/null and b/img/4.png differ diff --git a/img/40.png b/img/40.png new file mode 100644 index 00000000..b7abc892 Binary files /dev/null and b/img/40.png differ diff --git a/img/41.png b/img/41.png new file mode 100644 index 00000000..a7c9835a Binary files /dev/null and b/img/41.png differ diff --git a/img/42.png b/img/42.png new file mode 100644 index 00000000..f11db534 Binary files /dev/null and b/img/42.png differ diff --git a/img/43.png b/img/43.png new file mode 100644 index 00000000..6ea6fa72 Binary files /dev/null and b/img/43.png differ diff --git a/img/44.png b/img/44.png new file mode 100644 index 00000000..c6a8d588 Binary files /dev/null and b/img/44.png differ diff --git a/img/45.png b/img/45.png new file mode 100644 index 00000000..17c24fec Binary files /dev/null and b/img/45.png differ diff --git a/img/46.png b/img/46.png new file mode 100644 index 00000000..8aab488f Binary files /dev/null and b/img/46.png differ diff --git a/img/47.png b/img/47.png new file mode 100644 index 00000000..1df510dd Binary files /dev/null and b/img/47.png differ diff --git a/img/48.png b/img/48.png new file mode 100644 index 00000000..eddc7f9d Binary files /dev/null and b/img/48.png differ diff --git a/img/49.png b/img/49.png new file mode 100644 index 00000000..680ce750 Binary files /dev/null and b/img/49.png differ diff --git a/img/5.png b/img/5.png new file mode 100644 index 00000000..1b2c1480 Binary files /dev/null and b/img/5.png differ diff --git a/img/50.png b/img/50.png new file mode 100644 index 00000000..5bf23d3b Binary files /dev/null and b/img/50.png differ diff --git a/img/6.png b/img/6.png new file mode 100644 index 00000000..8004aa9b Binary files /dev/null and b/img/6.png differ diff --git a/img/7.png b/img/7.png new file mode 100644 index 00000000..5311068e Binary files /dev/null and b/img/7.png differ diff --git a/terraform/backend.tf b/terraform/backend.tf new file mode 100644 index 00000000..202964a2 --- /dev/null +++ b/terraform/backend.tf @@ -0,0 +1,29 @@ +# backend-group + +resource "yandex_alb_backend_group" "ngx-backend" { + name = "ngx-backend" + session_affinity { + connection { + source_ip = false + } + } + http_backend { + name = "http-backend" + weight = 1 + port = 80 + target_group_ids = ["${yandex_alb_target_group.target-web.id}"] + load_balancing_config { + panic_threshold = 90 + } + + healthcheck { + timeout = "10s" + interval = "2s" + healthy_threshold = 10 + unhealthy_threshold = 15 + http_healthcheck { + path = "/" + } + } + } +} diff --git a/terraform/balancer.tf b/terraform/balancer.tf new file mode 100644 index 00000000..c5a3636b --- /dev/null +++ b/terraform/balancer.tf @@ -0,0 +1,39 @@ +resource "yandex_alb_load_balancer" "alb-lb" { + name = "alb-lb" + + network_id = yandex_vpc_network.bastion-network.id + + security_group_ids = [ yandex_vpc_security_group.alb-security.id, + yandex_vpc_security_group.egress-security.id, + yandex_vpc_security_group.alb-vm-security.id, + yandex_vpc_security_group.external-ssh-security.id, + yandex_vpc_security_group.internal-ssh-security.id + ] + + allocation_policy { + location { + zone_id = "ru-central1-a" + subnet_id = yandex_vpc_subnet.bastion-external-segment.id + } + } + + + listener { + name = "alb-listener" + + endpoint { + address { + external_ipv4_address { + } + } + ports = [ 80 ] + } + + http { + handler { + http_router_id = yandex_alb_http_router.ngx-router.id + + } + } + } +} diff --git a/terraform/bastion.tf b/terraform/bastion.tf new file mode 100644 index 00000000..4f5c6515 --- /dev/null +++ b/terraform/bastion.tf @@ -0,0 +1,45 @@ +# Bastion + +resource "yandex_compute_instance" "bastion" { + + name = "bastion" + hostname = "bastion" + zone = "ru-central1-a" + allow_stopping_for_update = false + + resources { + core_fraction = 20 + cores = 2 + memory = 2 + } + + boot_disk { + initialize_params { + image_id = "fd8ichtldff870fce62q" + size = 10 + } + } + + network_interface { + subnet_id = yandex_vpc_subnet.bastion-external-segment.id + + security_group_ids = [ + yandex_vpc_security_group.external-ssh-security.id, + yandex_vpc_security_group.internal-ssh-security.id, + yandex_vpc_security_group.zabbix-security.id, + yandex_vpc_security_group.egress-security.id + ] + + nat = true + ip_address = "192.168.40.10" + } + + metadata = { + user-data = "${file("./meta.yaml")}" + } + + scheduling_policy { + preemptible = false + } + +} diff --git a/terraform/elastic.tf b/terraform/elastic.tf new file mode 100644 index 00000000..81e7fa1c --- /dev/null +++ b/terraform/elastic.tf @@ -0,0 +1,43 @@ +resource "yandex_compute_instance" "elasticsearch" { + + name = "elasticsearch" + hostname = "elasticsearch" + zone = "ru-central1-a" + allow_stopping_for_update = false + + resources { + core_fraction = 20 + cores = 2 + memory = 2 + } + + boot_disk { + initialize_params { + image_id = "fd8ichtldff870fce62q" + size = 10 + } + } + + network_interface { + subnet_id = yandex_vpc_subnet.bastion-internal-segment.id + + security_group_ids = [ + yandex_vpc_security_group.internal-ssh-security.id, + yandex_vpc_security_group.external-ssh-security.id, + yandex_vpc_security_group.zabbix-security.id, + yandex_vpc_security_group.elastic-security.id, + yandex_vpc_security_group.egress-security.id + ] + nat = false + ip_address = "192.168.10.30" + } + + metadata = { + user-data = "${file("./meta.yaml")}" + } + + scheduling_policy { + preemptible = false + } + +} diff --git a/terraform/kibana.tf b/terraform/kibana.tf new file mode 100644 index 00000000..d32c673c --- /dev/null +++ b/terraform/kibana.tf @@ -0,0 +1,44 @@ +resource "yandex_compute_instance" "kibana" { + + name = "kibana" + hostname = "kibana" + zone = "ru-central1-a" + allow_stopping_for_update = false + + resources { + core_fraction = 20 + cores = 2 + memory = 2 + } + + boot_disk { + initialize_params { + image_id = "fd8ichtldff870fce62q" + size = 10 + } + } + + network_interface { + subnet_id = yandex_vpc_subnet.bastion-external-segment.id + + security_group_ids = [ + yandex_vpc_security_group.internal-ssh-security.id, + yandex_vpc_security_group.external-ssh-security.id, + yandex_vpc_security_group.zabbix-security.id, + yandex_vpc_security_group.kibana-security.id, + yandex_vpc_security_group.egress-security.id + ] + + nat = true + ip_address = "192.168.40.30" + } + + metadata = { + user-data = "${file("./meta.yaml")}" + } + + scheduling_policy { + preemptible = false + } + +} diff --git a/terraform/main.tf b/terraform/main.tf new file mode 100644 index 00000000..36e30faf --- /dev/null +++ b/terraform/main.tf @@ -0,0 +1,89 @@ +# nginx 1 + +resource "yandex_compute_instance" "nginx-1" { + name = "nginx-1" + hostname = "nginx-1" + zone = "ru-central1-a" + allow_stopping_for_update = false + + resources { + core_fraction = 20 + cores = 2 + memory = 2 + } + + boot_disk { + initialize_params { + image_id = "fd8ichtldff870fce62q" + size = 10 + } + } + + network_interface { + subnet_id = yandex_vpc_subnet.bastion-internal-segment.id + security_group_ids = [ + yandex_vpc_security_group.internal-ssh-security.id, + yandex_vpc_security_group.alb-vm-security.id, + yandex_vpc_security_group.zabbix-security.id, + yandex_vpc_security_group.egress-security.id + ] + + + nat = false + ip_address = "192.168.10.10" + } + + metadata = { + user-data = "${file("./meta.yaml")}" + } + + scheduling_policy { + preemptible = true + } + +} + + +# nginx 2 + +resource "yandex_compute_instance" "nginx-2" { + name = "nginx-2" + hostname = "nginx-2" + zone = "ru-central1-a" + allow_stopping_for_update = false + + resources { + core_fraction = 20 + cores = 2 + memory = 2 + } + + boot_disk { + initialize_params { + image_id = "fd8ichtldff870fce62q" + size = 10 + } + } + + network_interface { + subnet_id = yandex_vpc_subnet.bastion-internal-segment.id + security_group_ids = [ + yandex_vpc_security_group.internal-ssh-security.id, + yandex_vpc_security_group.alb-vm-security.id, + yandex_vpc_security_group.zabbix-security.id, + yandex_vpc_security_group.egress-security.id + ] + + + nat = false + ip_address = "192.168.10.20" + } + + metadata = { + user-data = "${file("./meta.yaml")}" + } + + scheduling_policy { + preemptible = true + } +} diff --git a/terraform/network.tf b/terraform/network.tf new file mode 100644 index 00000000..c6082051 --- /dev/null +++ b/terraform/network.tf @@ -0,0 +1,41 @@ +## Network + +# External Network + +resource "yandex_vpc_network" "bastion-network" { + name = "bastion-network" +} + +# Subnet #1. External (Внешняя подсеть) + +resource "yandex_vpc_subnet" "bastion-external-segment" { + name = "bastion-external-segment" + zone = "ru-central1-a" + network_id = yandex_vpc_network.bastion-network.id + v4_cidr_blocks = ["192.168.40.0/24"] +} + +# Subnet #2. Internal (Внутренняя подсеть) + +resource "yandex_vpc_subnet" "bastion-internal-segment" { + name = "bastion-internal-segment" + zone = "ru-central1-a" + network_id = yandex_vpc_network.bastion-network.id + v4_cidr_blocks = ["192.168.10.0/24"] + route_table_id = yandex_vpc_route_table.rt.id +} + +resource "yandex_vpc_gateway" "nat_gateway" { + name = "nat-gateway" + shared_egress_gateway {} +} + +resource "yandex_vpc_route_table" "rt" { + name = "rt" + network_id = yandex_vpc_network.bastion-network.id + + static_route { + destination_prefix = "0.0.0.0/0" + gateway_id = yandex_vpc_gateway.nat_gateway.id + } +} diff --git a/terraform/outputs.tf b/terraform/outputs.tf new file mode 100644 index 00000000..e8df8103 --- /dev/null +++ b/terraform/outputs.tf @@ -0,0 +1,50 @@ +# Bastion-host + +output "bastion_nat" { + value = yandex_compute_instance.bastion.network_interface.0.nat_ip_address +} +output "bastion" { + value = yandex_compute_instance.bastion.network_interface.0.ip_address +} + +# web-1 + +output "nginx-1" { + value = yandex_compute_instance.nginx-1.network_interface.0.ip_address +} + +# web-2 + +output "nginx-2" { + value = yandex_compute_instance.nginx-2.network_interface.0.ip_address +} + +# kibana-server + +output "kibana-nat" { + value = yandex_compute_instance.kibana.network_interface.0.nat_ip_address +} +output "kibana" { + value = yandex_compute_instance.kibana.network_interface.0.ip_address +} + +# zabbix-server + +output "zabbix_nat" { + value = yandex_compute_instance.zabbix.network_interface.0.nat_ip_address +} +output "zabbix" { + value = yandex_compute_instance.zabbix.network_interface.0.ip_address +} + +# elasticsearch-server + +output "elasticsearch" { + value = yandex_compute_instance.elasticsearch.network_interface.0.ip_address +} + +# balancer + +output "load_balancer_pub" { + value = yandex_alb_load_balancer.alb-lb.listener[0].endpoint[0].address[0].external_ipv4_address +} diff --git a/terraform/router.tf b/terraform/router.tf new file mode 100644 index 00000000..b95f5997 --- /dev/null +++ b/terraform/router.tf @@ -0,0 +1,21 @@ +## HTTP router + +resource "yandex_alb_http_router" "ngx-router" { + name = "ngx-router" +} + +resource "yandex_alb_virtual_host" "vt-host" { + name = "vt-host" + http_router_id = yandex_alb_http_router.ngx-router.id + + route { + name = "my-route" + + http_route { + http_route_action { + backend_group_id = yandex_alb_backend_group.ngx-backend.id # ID созданной ранее backend группы + timeout = "60s" + } + } + } +} diff --git a/terraform/security.tf b/terraform/security.tf new file mode 100644 index 00000000..d5df8b90 --- /dev/null +++ b/terraform/security.tf @@ -0,0 +1,219 @@ +# External ssh (Внешний) + +resource "yandex_vpc_security_group" "external-ssh-security" { + name = "external-ssh-security" + description = "external ssh-security" + network_id = yandex_vpc_network.bastion-network.id + + ingress { + description = "Input TCP 22" + protocol = "TCP" + v4_cidr_blocks = ["0.0.0.0/0"] + port = 22 + } + + ingress { + description = "Input TCP SSH (internal-ssh-security) 22 port" + protocol = "TCP" + security_group_id = yandex_vpc_security_group.internal-ssh-security.id + port = 22 + } + + egress { + description = "Output all" + protocol = "ANY" + v4_cidr_blocks = ["0.0.0.0/0"] + from_port = 0 + to_port = 65535 + } + + egress { + description = "Output TCP 22 local SSH (internal-ssh-security)" + protocol = "TCP" + port = 22 + security_group_id = yandex_vpc_security_group.internal-ssh-security.id + } + +} + +# Internal ssh (Внутренний) + +resource "yandex_vpc_security_group" "internal-ssh-security" { + + name = "internal-ssh-security" + description = "Internal ssh" + network_id = yandex_vpc_network.bastion-network.id + + ingress { + description = "Input TCP 22" + protocol = "TCP" + v4_cidr_blocks = ["192.168.10.0/24"] + port = 22 + } + + egress { + description = "Output TCP 22 port" + v4_cidr_blocks = ["192.168.10.0/24"] + protocol = "TCP" + port = 22 + } + + egress { + description = "Output 22 port" + protocol = "ANY" + v4_cidr_blocks = ["0.0.0.0/0"] + from_port = 0 + to_port = 65535 + } + +} + +# Balancer Input (На балансировщик внутренний) + +resource "yandex_vpc_security_group" "alb-security" { + name = "alb-security" + network_id = yandex_vpc_network.bastion-network.id + + ingress { + protocol = "TCP" + v4_cidr_blocks = ["0.0.0.0/0"] + port = 80 + } + + ingress { + description = "healthchecks" + protocol = "TCP" + predefined_target = "loadbalancer_healthchecks" + port = 30080 + } +} + +# Balancer into Web-servers (От балансировщика на ngx-серверы) + +resource "yandex_vpc_security_group" "alb-vm-security" { + name = "alb-vm-security" + network_id = yandex_vpc_network.bastion-network.id + + ingress { + protocol = "TCP" + security_group_id = yandex_vpc_security_group.alb-security.id + port = 80 + } + + ingress { + description = "ssh" + protocol = "TCP" + v4_cidr_blocks = ["0.0.0.0/0"] + port = 22 + } + +} + +# All Output (Разрешен весь исх.трафик) + +resource "yandex_vpc_security_group" "egress-security" { + name = "egress-security" + network_id = yandex_vpc_network.bastion-network.id + + egress { + protocol = "ANY" + v4_cidr_blocks = ["0.0.0.0/0"] + from_port = 0 + to_port = 65535 + } +} + +# Zabbix agent Security group + +resource "yandex_vpc_security_group" "zabbix-security" { + name = "zabbix-security" + network_id = yandex_vpc_network.bastion-network.id + + ingress { + protocol = "TCP" + security_group_id = yandex_vpc_security_group.zabbix-server-security.id + from_port = 10050 + to_port = 10051 + } + + egress { + protocol = "TCP" + security_group_id = yandex_vpc_security_group.zabbix-server-security.id + from_port = 10050 + to_port = 10051 + } +} + +# Zabbix server Security group + +resource "yandex_vpc_security_group" "zabbix-server-security" { + name = "zabbix-server-security" + network_id = yandex_vpc_network.bastion-network.id + + ingress { + protocol = "TCP" + v4_cidr_blocks = ["0.0.0.0/0"] + port = 80 + } + + ingress { + protocol = "TCP" + v4_cidr_blocks = yandex_vpc_subnet.bastion-external-segment.v4_cidr_blocks + from_port = 10050 + to_port = 10052 + } + + ingress { + protocol = "TCP" + v4_cidr_blocks = yandex_vpc_subnet.bastion-internal-segment.v4_cidr_blocks + from_port = 10050 + to_port = 10051 + } + +} + +# Elasticsearch server security group + +resource "yandex_vpc_security_group" "elastic-security" { + name = "elastic-security" + network_id = yandex_vpc_network.bastion-network.id + + ingress { + protocol = "TCP" + v4_cidr_blocks = yandex_vpc_subnet.bastion-internal-segment.v4_cidr_blocks + port = 9200 + } + + ingress { + protocol = "TCP" + v4_cidr_blocks = yandex_vpc_subnet.bastion-external-segment.v4_cidr_blocks + port = 9200 + } + + ingress { + protocol = "TCP" + v4_cidr_blocks = yandex_vpc_subnet.bastion-internal-segment.v4_cidr_blocks + port = 9300 + } + + ingress { + protocol = "TCP" + v4_cidr_blocks = yandex_vpc_subnet.bastion-external-segment.v4_cidr_blocks + port = 9300 + } + +} + +# Kibana server security group + +resource "yandex_vpc_security_group" "kibana-security" { + name = "kibana-security" + network_id = yandex_vpc_network.bastion-network.id + + ingress { + protocol = "TCP" + v4_cidr_blocks = ["0.0.0.0/0"] + port = 5601 + } + +} diff --git a/terraform/snapshot.tf b/terraform/snapshot.tf new file mode 100644 index 00000000..8bf220fe --- /dev/null +++ b/terraform/snapshot.tf @@ -0,0 +1,21 @@ +resource "yandex_compute_snapshot_schedule" "my-snapshot" { + name = "my-snapshot" + + schedule_policy { + expression = "0 22 * * *" + } + + snapshot_count = 7 + + snapshot_spec { + description = "daily-snapshot" + } + + disk_ids = [ + "${yandex_compute_instance.bastion.boot_disk.0.disk_id}", + "${yandex_compute_instance.nginx-1.boot_disk.0.disk_id}", + "${yandex_compute_instance.nginx-2.boot_disk.0.disk_id}", + "${yandex_compute_instance.zabbix.boot_disk.0.disk_id}", + "${yandex_compute_instance.elasticsearch.boot_disk.0.disk_id}", + "${yandex_compute_instance.kibana.boot_disk.0.disk_id}", ] +} diff --git a/terraform/target.tf b/terraform/target.tf new file mode 100644 index 00000000..e10946ef --- /dev/null +++ b/terraform/target.tf @@ -0,0 +1,15 @@ +#Target Groups + +resource "yandex_alb_target_group" "target-web" { + name = "target-web" + + target { + subnet_id = yandex_vpc_subnet.bastion-internal-segment.id + ip_address = yandex_compute_instance.nginx-1.network_interface.0.ip_address + } + + target { + subnet_id = yandex_vpc_subnet.bastion-internal-segment.id + ip_address = yandex_compute_instance.nginx-2.network_interface.0.ip_address + } +} diff --git a/terraform/zabbix.tf b/terraform/zabbix.tf new file mode 100644 index 00000000..f1b60315 --- /dev/null +++ b/terraform/zabbix.tf @@ -0,0 +1,43 @@ +resource "yandex_compute_instance" "zabbix" { + + name = "zabbix" + hostname = "zabbix" + zone = "ru-central1-a" + allow_stopping_for_update = false + + resources { + core_fraction = 20 + cores = 2 + memory = 2 + } + + boot_disk { + initialize_params { + image_id = "fd8ichtldff870fce62q" + size = 10 + } + } + + network_interface { + subnet_id = yandex_vpc_subnet.bastion-external-segment.id + + security_group_ids = [ + yandex_vpc_security_group.internal-ssh-security.id, + yandex_vpc_security_group.external-ssh-security.id, + yandex_vpc_security_group.zabbix-server-security.id, + yandex_vpc_security_group.egress-security.id + ] + + nat = true + ip_address = "192.168.40.20" + } + + metadata = { + user-data = "${file("./meta.yaml")}" + } + + scheduling_policy { + preemptible = false + } + +}