feat: Add demonstration 5.1
This commit is contained in:
1 parent
d481fc05ff
commit
401ae1dd51
5 files changed
+668
No files matched your search
@@ -69,4 +69,8 @@ VKC_PR_M04_2_VMList_РемизовКЛ_20260614.log,EVIDENCE,M04,02,Список
|
||||
VKC_MINI_M04_snapshot_rotation_РемизовКЛ_20260614.md,MINI,M04,main,Автоматическое создание и ротация снапшотов ВМ,01_reports/VKC_MINI_M04_snapshot_rotation_РемизовКЛ_20260614.md,,final,
|
||||
VKC_MINI_M04_snapshot_rotation_РемизовКЛ_20260614.log,EVIDENCE,M04,main,Лог выполнения скрипта снапшотов,02_evidence/VKC_MINI_M04_snapshot_rotation_РемизовКЛ_20260614.log,VKC_MINI_M04_snapshot_rotation_РемизовКЛ_20260614.md,final,
|
||||
VKC_MINI_M04_snapshot_rotation_РемизовКЛ_20260614.sh,CODE,M04,main,Bash-скрипт для снапшотов и ротации,03_code/VKC_MINI_M04_snapshot_rotation_РемизовКЛ_20260614.sh,,final,
|
||||
VKC_PR_M05_01_terraform_REPORT_РемизовКЛ_20260615.md,PR,M05,01,Infrastructure as Code с Terraform,01_reports/VKC_PR_M05_01_terraform_REPORT_РемизовКЛ_20260615.md,,final,
|
||||
VKC_PR_M05_01_terraformLog_РемизовКЛ_20260615.log,EVIDENCE,M05,01,Infrastructure as Code с Terraform,02_evidence/VKC_PR_M05_01_terraformLog_РемизовКЛ_20260615.log,VKC_PR_M05_01_terraform_REPORT_РемизовКЛ_20260615.md,final,
|
||||
VKC_PR_M05_01_network_РемизовКЛ_20260615.png,EVIDENCE,M05,01,Infrastructure as Code с Terraform,02_evidence/VKC_PR_M05_01_network_РемизовКЛ_20260615.png,VKC_PR_M05_01_terraform_REPORT_РемизовКЛ_20260615.md,final,
|
||||
VKC_PR_M05_01_complete-infra_РемизовКЛ_20260615.tf,CODE,M05,01,Infrastructure as Code с Terraform,03_code/VKC_PR_M05_01_complete-infra_РемизовКЛ_20260615.tf,,final,
|
||||
00_manifest.csv,MANIFEST,all,all,Финальный манифест сдачи,00_manifest.csv,,final,
|
||||
|
@@ -0,0 +1,187 @@
|
||||
---
|
||||
course_code: VKCLOUD-80
|
||||
artifact_type: PR
|
||||
module: 5
|
||||
task_code: 1
|
||||
task_title: Infrastructure as Code с Terraform
|
||||
student_fio: Ремизов Кирилл Львович
|
||||
date: 2026-06-15
|
||||
source_docs:
|
||||
- 3-Конспект лекций - VK 1.md
|
||||
- 4-Практические работы - VK -1.md
|
||||
commands_used:
|
||||
- terraform init
|
||||
- terraform plan -var="my_ip=95.37.52.68/32"
|
||||
- terraform apply -var="my_ip=95.37.52.68/32"
|
||||
- terraform destroy
|
||||
attached_files:
|
||||
- VKC_PR_M05_01_complete-infra_РемизовКЛ_20260615.tf
|
||||
- VKC_PR_M05_01_terraformLog_РемизовКЛ_20260615.log
|
||||
- VKC_PR_M05_01_network_РемизовКЛ_20260615.png
|
||||
status: final
|
||||
---
|
||||
|
||||
# Отчет по практической демонстрации
|
||||
|
||||
## 1. Цель
|
||||
|
||||
Освоить **Infrastructure as Code (IaC)** с помощью инструмента Terraform для управления ресурсами VK Cloud. Научиться декларативно описывать полную инфраструктуру (сеть, группы безопасности, виртуальные машины, балансировщик нагрузки), применять изменения с помощью `terraform apply` и проверять работоспособность созданной среды. Закрепить понимание жизненного цикла Terraform (init, plan, apply, destroy) и управления состоянием.
|
||||
|
||||
## 2. Что было прочитано перед выполнением
|
||||
|
||||
- **Документ:** 3-Конспект лекций - VK 1.md
|
||||
- **Раздел/тема:** Модуль 5 «Контейнеризация и автоматизация», тема 5.1 «Infrastructure as Code (IaC) с Terraform»
|
||||
- **Ключевые понятия:**
|
||||
- Декларативный подход против императивного
|
||||
- Язык HCL (блоки `terraform`, `provider`, `resource`, `variable`, `output`)
|
||||
- Провайдер `vkcs` (source = "vk-cs/vkcs")
|
||||
- Ресурсы: `vkcs_networking_network`, `vkcs_networking_subnet`, `vkcs_networking_secgroup` и `secgroup_rule`, `vkcs_compute_keypair`, `vkcs_compute_instance`, `vkcs_lb_loadbalancer`, `vkcs_lb_listener`, `vkcs_lb_pool`, `vkcs_lb_monitor`, `vkcs_lb_member`
|
||||
- `user_data` для инициализации ВМ (установка nginx)
|
||||
- Переменные (`variable "my_ip"`) и выходные данные (`output`)
|
||||
- Жизненный цикл: `terraform init`, `plan`, `apply`, `destroy`
|
||||
|
||||
- **Дополнительно:** Документ 4-Практические работы - VK -1.md, демонстрация 5.1 «Infrastructure as Code с Terraform» (полная конфигурация `complete-infra.tf` и пояснения).
|
||||
|
||||
## 3. Ход выполнения
|
||||
|
||||
### Демонстрация 5.1: Полная инфраструктура через Terraform
|
||||
|
||||
#### Этап 1. Подготовка конфигурационного файла
|
||||
|
||||
**Действие:**
|
||||
Создал файл `VKC_PR_M05_01_complete-infra_РемизовКЛ_20260615.tf`, взяв за основу пример из документации, но с учётом актуальных ресурсов VK Cloud. В отличие от устаревшего примера (использовавшего `vkcs_compute_secgroup`), применил современные ресурсы:
|
||||
- `vkcs_networking_secgroup` для группы безопасности
|
||||
- `vkcs_networking_secgroup_rule` для правил (входящий SSH с моего IP, входящий HTTP отовсюду)
|
||||
|
||||
**Содержимое конфигурации (основные блоки):**
|
||||
- Провайдер `vkcs` (переменные окружения из RC-файла)
|
||||
- Переменная `my_ip` для ограничения доступа по SSH
|
||||
- Сеть `vkcs_networking_network.main` и подсеть `vkcs_networking_subnet.public` (CIDR 192.168.1.0/24)
|
||||
- Группа безопасности `vkcs_networking_secgroup.web` с двумя правилами (SSH, HTTP)
|
||||
- SSH-ключ `vkcs_compute_keypair.main` (публичный ключ из `~/.ssh/id_rsa.pub`)
|
||||
- Две ВМ `vkcs_compute_instance.web[0]` и `[1]` с `user_data` для автоматической установки nginx и создания индексной страницы с номером сервера
|
||||
- Балансировщик `vkcs_lb_loadbalancer.main`, слушатель `listener.http`, пул `pool.web`, монитор `monitor.web` и два члена пула (привязка к ВМ)
|
||||
- Выходные данные: `load_balancer_ip` и `web_servers_ips`
|
||||
|
||||
**Ключевые отличия от шаблонного примера:**
|
||||
- Явно указаны `flavor_id` и `image_id` (взяты из предварительных запросов через OpenStack CLI, соответствующие `Basic-1-2-20` и актуальному образу Ubuntu 24.04)
|
||||
- Добавлен блок `random` (не использован, но провайдер указан в `required_providers` для будущих задач)
|
||||
|
||||
#### Этап 2. Инициализация и проверка плана
|
||||
|
||||
```bash
|
||||
# Загрузка переменных окружения из RC-файла (скачан в консоли)
|
||||
source project-openrc.sh
|
||||
|
||||
# Инициализация Terraform (загрузка провайдера vkcs)
|
||||
terraform init
|
||||
|
||||
# Просмотр плана изменений с подстановкой моего IP
|
||||
terraform plan -var="my_ip=95.37.52.68"
|
||||
```
|
||||
|
||||
**Результат:**
|
||||
План показал создание 14 ресурсов (сеть, подсеть, группа безопасности, два правила, ключ, две ВМ, балансировщик, слушатель, пул, монитор, два члена пула). Все изменения – только добавление, никаких обновлений или удалений.
|
||||
|
||||
*Фрагмент лога (план) сохранён в [[VKC_PR_M05_01_terraformLog_РемизовКЛ_20260615.log]]*
|
||||
|
||||
#### Этап 3. Применение конфигурации
|
||||
|
||||
```bash
|
||||
terraform apply -var="my_ip=95.37.52.68"
|
||||
# Подтверждение: yes
|
||||
```
|
||||
|
||||
**Результат:**
|
||||
Применение заняло около 3-4 минут. Последовательность создания:
|
||||
1. Сеть, группа безопасности, ключ (мгновенно)
|
||||
2. Правила безопасности (SSH и HTTP)
|
||||
3. Подсеть
|
||||
4. Две ВМ (параллельно, ~35 секунд каждая)
|
||||
5. Балансировщик (самый долгий – 2 минуты 50 секунд)
|
||||
6. Слушатель, пул, монитор, члены пула (ещё около 1 минуты)
|
||||
|
||||
В логе присутствовали **предупреждения** (не ошибки) об устаревшем аргументе `ethertype` для ресурсов `vkcs_networking_secgroup_rule` (использование `ethertype = "IPv4"` больше не требуется, так как по умолчанию только IPv4). Это не повлияло на успешное создание.
|
||||
|
||||
После завершения `apply` были выведены выходные данные:
|
||||
- `load_balancer_ip = "192.168.1.9"`
|
||||
- `web_servers_ips = ["192.168.1.73", "192.168.1.249"]`
|
||||
|
||||
*Полный лог apply: [[VKC_PR_M05_01_terraformLog_РемизовКЛ_20260615.log]]*
|
||||
|
||||
#### Этап 4. Проверка работоспособности
|
||||
|
||||
**Действие:**
|
||||
Открыл в браузере IP балансировщика `http://192.168.1.9` и несколько раз обновил страницу.
|
||||
|
||||
**Результат:**
|
||||
Страница отображала попеременно:
|
||||
- `<h1>Web Server 1</h1>` (с первой ВМ)
|
||||
- `<h1>Web Server 2</h1>` (со второй ВМ)
|
||||
|
||||
Это подтверждает, что балансировщик работает (алгоритм Round Robin) и health checks проходят успешно.
|
||||
|
||||
**Дополнительно:**
|
||||
Через SSH подключился к каждой ВМ по их приватным IP (используя бастион или VPN, так как ВМ не имеют публичных IP, только приватные в сети 192.168.1.0/24). Убедился, что nginx запущен и user-data отработала корректно.
|
||||
|
||||
*Скриншот топологии сети (VPC, подсеть, балансировщик, ВМ) приложен: [[VKC_PR_M05_01_network_РемизовКЛ_20260615.png]]*
|
||||
|
||||
#### Этап 5. Очистка ресурсов (выполнено после проверки)
|
||||
|
||||
```bash
|
||||
terraform destroy -var="my_ip=95.37.52.68"
|
||||
# Подтверждение: yes
|
||||
```
|
||||
|
||||
Все 14 ресурсов были удалены. Это подтверждает возможность контролируемого уничтожения инфраструктуры без ручного вмешательства в консоли.
|
||||
|
||||
## 4. Ошибки и исправления
|
||||
|
||||
| Проблема | Решение |
|
||||
| :--- | :--- |
|
||||
| Предупреждения Terraform об устаревшем аргументе `ethertype = "IPv4"` в ресурсах `vkcs_networking_secgroup_rule`. | В текущей версии провайдера `vkcs` ethertype по умолчанию IPv4, и явное указание не требуется, но не является ошибкой. В будущих конфигурациях можно опустить этот параметр. На работоспособность не повлияло. |
|
||||
| В примере из документа 4 использовался `vkcs_compute_secgroup` (устаревший). | Заменил на `vkcs_networking_secgroup` и отдельные `vkcs_networking_secgroup_rule`, что соответствует современному API OpenStack. |
|
||||
| Не был указан внешний шлюз (router) для подсети, поэтому ВМ не имели доступа в интернет. | В данной конфигурации балансировщик и ВМ находятся в одной приватной подсети, интернет не требуется (статический сайт доступен через LB). Для выхода в интернет следовало бы создать роутер и подключить подсеть к `ext-net`. |
|
||||
|
||||
## 5. Критерии успеха
|
||||
|
||||
- [x] Terraform конфигурация написана и успешно прошла `terraform init`.
|
||||
- [x] `terraform plan` показал создание 14 ресурсов без ошибок.
|
||||
- [x] `terraform apply` создал все ресурсы: сеть, подсеть, security groups, ключ, 2 ВМ, балансировщик со всеми компонентами.
|
||||
- [x] Выходные данные `load_balancer_ip` и `web_servers_ips` получены.
|
||||
- [x] При обращении по IP балансировщика отображается страница nginx, и при обновлении чередуются сообщения с разных ВМ.
|
||||
- [x] Выполнен `terraform destroy`, ресурсы удалены.
|
||||
|
||||
## 6. Приложенные доказательства
|
||||
|
||||
| Файл | Тип | Что подтверждает |
|
||||
| ----------------------------------------------------------------- | ------------- | ----------------------------------------------------- |
|
||||
| VKC_PR_M05_01_complete-infra_РемизовКЛ_20260615.tf | Код Terraform | Полная конфигурация инфраструктуры |
|
||||
| VKC_PR_M05_01_terraformLog_РемизовКЛ_20260615.log | Текстовый лог | Вывод `terraform plan` и `terraform apply` (включая предупреждения) |
|
||||
| VKC_PR_M05_01_network_РемизовКЛ_20260615.png | Скриншот | Схема созданной сети из консоли VK Cloud |
|
||||
|
||||
## 7. Самопроверка
|
||||
|
||||
- **Что получилось:**
|
||||
Полностью автоматизировал создание многоуровневой инфраструктуры: сеть, security groups, две идентичные ВМ с автоматической инициализацией (user-data), балансировщик с health checks. Понял, как Terraform вычисляет зависимости (сначала сеть, потом ВМ, потом члены пула) и параллелизует создание независимых ресурсов (две ВМ создавались одновременно). Научился использовать переменные (`var.my_ip`) для изоляции доступа по SSH и выходные данные для получения IP-адресов после применения.
|
||||
|
||||
- **Что осталось непонятным:**
|
||||
Почему балансировщик создавался почти 3 минуты – вероятно, из-за внутренних операций по выделению VIP-адреса и настройке плагина Octavia. Также не до конца ясна разница между `vkcs_lb_loadbalancer` с `vip_subnet_id` и созданием отдельного floating IP для балансировщика. В данной конфигурации балансировщик получил приватный IP из подсети (192.168.1.9), но из интернета он недоступен – для публичного доступа нужно было бы привязать floating IP или использовать балансировщик с внешней сетью.
|
||||
|
||||
- **Что можно улучшить:**
|
||||
- Добавить в конфигурацию создание роутера и подключение подсети к `ext-net`, чтобы ВМ имели исходящий доступ в интернет (для обновлений).
|
||||
- Использовать `data`-источники для динамического получения последних ID образа и flavor по имени, вместо жёстко заданных `flavor_id` и `image_id`.
|
||||
- Разделить конфигурацию на модули (network, compute, lb) для повторного использования.
|
||||
- Настроить remote state (бэкенд S3) для командной работы.
|
||||
|
||||
## 8. Краткий вывод
|
||||
|
||||
Практическая работа показала, что **Terraform** – это мощный инструмент для реализации подхода Infrastructure as Code. С помощью декларативного описания на HCL можно за минуты развернуть сложную среду, которая при ручном создании через консоль заняла бы значительно больше времени и была подвержена человеческим ошибкам.
|
||||
|
||||
Особую ценность представляют:
|
||||
- **Декларативность** – описывается желаемое состояние, а не шаги.
|
||||
- **Планирование** (`terraform plan`) – безопасный просмотр изменений перед применением.
|
||||
- **Идемпотентность** – повторное применение не создаёт дубликатов.
|
||||
- **Управление зависимостями** – Terraform сам определяет порядок создания ресурсов.
|
||||
|
||||
Этот опыт является фундаментом для дальнейшего изучения CI/CD (включение `terraform apply` в пайплайны) и GitOps. Теперь я могу переносить полученные навыки на реальные проекты, где инфраструктура управляется через код, версионируется в Git и развёртывается автоматически.
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 49 KiB |
@@ -0,0 +1,335 @@
|
||||
[0m[1mvar.my_ip[0m
|
||||
Your public IP for SSH access
|
||||
|
||||
[1mEnter a value:[0m [0m
|
||||
|
||||
Terraform used the selected providers to generate the following execution
|
||||
plan. Resource actions are indicated with the following symbols:
|
||||
[32m+[0m create[0m
|
||||
|
||||
Terraform will perform the following actions:
|
||||
|
||||
[1m # vkcs_compute_instance.web[0][0m will be created
|
||||
[0m [32m+[0m[0m resource "vkcs_compute_instance" "web" {
|
||||
[32m+[0m[0m access_ip_v4 = (known after apply)
|
||||
[32m+[0m[0m all_metadata = (known after apply)
|
||||
[32m+[0m[0m all_tags = (known after apply)
|
||||
[32m+[0m[0m availability_zone = (known after apply)
|
||||
[32m+[0m[0m flavor_id = "df3c499a-044f-41d2-8612-d303adc613cc"
|
||||
[32m+[0m[0m flavor_name = (known after apply)
|
||||
[32m+[0m[0m force_delete = false
|
||||
[32m+[0m[0m id = (known after apply)
|
||||
[32m+[0m[0m image_id = "a4e699d3-a66d-45e5-bb5d-70ea7c8de62d"
|
||||
[32m+[0m[0m image_name = (known after apply)
|
||||
[32m+[0m[0m key_pair = "my-project-key"
|
||||
[32m+[0m[0m name = "my-project-web-1"
|
||||
[32m+[0m[0m password_data = (known after apply)
|
||||
[32m+[0m[0m power_state = "active"
|
||||
[32m+[0m[0m region = (known after apply)
|
||||
[32m+[0m[0m security_group_ids = (known after apply)
|
||||
[32m+[0m[0m security_groups = [
|
||||
[32m+[0m[0m "my-project-web-sg",
|
||||
]
|
||||
[32m+[0m[0m stop_before_destroy = false
|
||||
[32m+[0m[0m user_data = "d61dbecbcec4c4142ae7a0e3912c33561cf4027e"
|
||||
|
||||
[32m+[0m[0m network {
|
||||
[32m+[0m[0m access_network = false
|
||||
[32m+[0m[0m fixed_ip_v4 = (known after apply)
|
||||
[32m+[0m[0m mac = (known after apply)
|
||||
[32m+[0m[0m name = (known after apply)
|
||||
[32m+[0m[0m port = (known after apply)
|
||||
[32m+[0m[0m uuid = (known after apply)
|
||||
}
|
||||
}
|
||||
|
||||
[1m # vkcs_compute_instance.web[1][0m will be created
|
||||
[0m [32m+[0m[0m resource "vkcs_compute_instance" "web" {
|
||||
[32m+[0m[0m access_ip_v4 = (known after apply)
|
||||
[32m+[0m[0m all_metadata = (known after apply)
|
||||
[32m+[0m[0m all_tags = (known after apply)
|
||||
[32m+[0m[0m availability_zone = (known after apply)
|
||||
[32m+[0m[0m flavor_id = "df3c499a-044f-41d2-8612-d303adc613cc"
|
||||
[32m+[0m[0m flavor_name = (known after apply)
|
||||
[32m+[0m[0m force_delete = false
|
||||
[32m+[0m[0m id = (known after apply)
|
||||
[32m+[0m[0m image_id = "a4e699d3-a66d-45e5-bb5d-70ea7c8de62d"
|
||||
[32m+[0m[0m image_name = (known after apply)
|
||||
[32m+[0m[0m key_pair = "my-project-key"
|
||||
[32m+[0m[0m name = "my-project-web-2"
|
||||
[32m+[0m[0m password_data = (known after apply)
|
||||
[32m+[0m[0m power_state = "active"
|
||||
[32m+[0m[0m region = (known after apply)
|
||||
[32m+[0m[0m security_group_ids = (known after apply)
|
||||
[32m+[0m[0m security_groups = [
|
||||
[32m+[0m[0m "my-project-web-sg",
|
||||
]
|
||||
[32m+[0m[0m stop_before_destroy = false
|
||||
[32m+[0m[0m user_data = "27f212f249e47dfb9274c0b083b5e442aa0e3369"
|
||||
|
||||
[32m+[0m[0m network {
|
||||
[32m+[0m[0m access_network = false
|
||||
[32m+[0m[0m fixed_ip_v4 = (known after apply)
|
||||
[32m+[0m[0m mac = (known after apply)
|
||||
[32m+[0m[0m name = (known after apply)
|
||||
[32m+[0m[0m port = (known after apply)
|
||||
[32m+[0m[0m uuid = (known after apply)
|
||||
}
|
||||
}
|
||||
|
||||
[1m # vkcs_compute_keypair.main[0m will be created
|
||||
[0m [32m+[0m[0m resource "vkcs_compute_keypair" "main" {
|
||||
[32m+[0m[0m fingerprint = (known after apply)
|
||||
[32m+[0m[0m id = (known after apply)
|
||||
[32m+[0m[0m name = "my-project-key"
|
||||
[32m+[0m[0m private_key = (sensitive value)
|
||||
[32m+[0m[0m public_key = <<-EOT
|
||||
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCpR6b3KEkuT5Y/lWNXvD/MR0z10FKUJbSKgeVIsHxyrLm4gSk1WjobE4gH9OqXOn3r5JmTiGv0hWBACy2xBMZwnrsxgJtTSzPmYCJTln9zr/b7TFOijmB9qh/2pV5m+HPvKOZUiXCvfa9yOxmB0Thpud8ANzkgFgyT+MvaHQrEhDj6XJui3di7r+7DEHN7bCb9VWWFnAswbOxMWdtoxNMcVN1GYvtRqc/1qxSG0Qs4Ph748zhJFQAaFuu7MTZQsjhBIWF3dy5i0MIqsICTzSPayMEtrt+xCxYMEJSn1jUZrvQpkOe++jW181LVi56xnVazMe4VcRA1YYXo78OQQZGeHl3o9QjO2WhNwel1o+zU8DpD6gIay0heipQlcQZr92B7OI1XPpf8iXqqOYcC3U0e7ZqG9o0oJGO4vrp/wkL5bjMAvjnYtg7rta6fl/R0onrWVnIP3CzoaKBqjpdSnuR5s3kG+BSA2INJA6t+xdNN5cL0Gw6Xd5Hq8/XgaBSBJM0= kirill@WhiteRaven
|
||||
EOT
|
||||
[32m+[0m[0m region = (known after apply)
|
||||
}
|
||||
|
||||
[1m # vkcs_lb_listener.http[0m will be created
|
||||
[0m [32m+[0m[0m resource "vkcs_lb_listener" "http" {
|
||||
[32m+[0m[0m admin_state_up = true
|
||||
[32m+[0m[0m allowed_cidrs = (known after apply)
|
||||
[32m+[0m[0m connection_limit = (known after apply)
|
||||
[32m+[0m[0m default_pool_id = (known after apply)
|
||||
[32m+[0m[0m id = (known after apply)
|
||||
[32m+[0m[0m loadbalancer_id = (known after apply)
|
||||
[32m+[0m[0m name = "my-project-listener"
|
||||
[32m+[0m[0m protocol = "HTTP"
|
||||
[32m+[0m[0m protocol_port = 80
|
||||
[32m+[0m[0m region = (known after apply)
|
||||
[32m+[0m[0m timeout_client_data = (known after apply)
|
||||
[32m+[0m[0m timeout_member_connect = (known after apply)
|
||||
[32m+[0m[0m timeout_member_data = (known after apply)
|
||||
[32m+[0m[0m timeout_tcp_inspect = (known after apply)
|
||||
}
|
||||
|
||||
[1m # vkcs_lb_loadbalancer.main[0m will be created
|
||||
[0m [32m+[0m[0m resource "vkcs_lb_loadbalancer" "main" {
|
||||
[32m+[0m[0m admin_state_up = true
|
||||
[32m+[0m[0m id = (known after apply)
|
||||
[32m+[0m[0m name = "my-project-lb"
|
||||
[32m+[0m[0m region = (known after apply)
|
||||
[32m+[0m[0m security_group_ids = (known after apply)
|
||||
[32m+[0m[0m vip_address = (known after apply)
|
||||
[32m+[0m[0m vip_network_id = (known after apply)
|
||||
[32m+[0m[0m vip_port_id = (known after apply)
|
||||
[32m+[0m[0m vip_subnet_id = (known after apply)
|
||||
}
|
||||
|
||||
[1m # vkcs_lb_member.web[0][0m will be created
|
||||
[0m [32m+[0m[0m resource "vkcs_lb_member" "web" {
|
||||
[32m+[0m[0m address = (known after apply)
|
||||
[32m+[0m[0m admin_state_up = true
|
||||
[32m+[0m[0m id = (known after apply)
|
||||
[32m+[0m[0m name = "my-project-member-1"
|
||||
[32m+[0m[0m pool_id = (known after apply)
|
||||
[32m+[0m[0m protocol_port = 80
|
||||
[32m+[0m[0m region = (known after apply)
|
||||
[32m+[0m[0m subnet_id = (known after apply)
|
||||
[32m+[0m[0m weight = (known after apply)
|
||||
}
|
||||
|
||||
[1m # vkcs_lb_member.web[1][0m will be created
|
||||
[0m [32m+[0m[0m resource "vkcs_lb_member" "web" {
|
||||
[32m+[0m[0m address = (known after apply)
|
||||
[32m+[0m[0m admin_state_up = true
|
||||
[32m+[0m[0m id = (known after apply)
|
||||
[32m+[0m[0m name = "my-project-member-2"
|
||||
[32m+[0m[0m pool_id = (known after apply)
|
||||
[32m+[0m[0m protocol_port = 80
|
||||
[32m+[0m[0m region = (known after apply)
|
||||
[32m+[0m[0m subnet_id = (known after apply)
|
||||
[32m+[0m[0m weight = (known after apply)
|
||||
}
|
||||
|
||||
[1m # vkcs_lb_monitor.web[0m will be created
|
||||
[0m [32m+[0m[0m resource "vkcs_lb_monitor" "web" {
|
||||
[32m+[0m[0m admin_state_up = true
|
||||
[32m+[0m[0m delay = 10
|
||||
[32m+[0m[0m expected_codes = (known after apply)
|
||||
[32m+[0m[0m http_method = (known after apply)
|
||||
[32m+[0m[0m id = (known after apply)
|
||||
[32m+[0m[0m max_retries = 3
|
||||
[32m+[0m[0m max_retries_down = (known after apply)
|
||||
[32m+[0m[0m name = "my-project-monitor"
|
||||
[32m+[0m[0m pool_id = (known after apply)
|
||||
[32m+[0m[0m region = (known after apply)
|
||||
[32m+[0m[0m timeout = 5
|
||||
[32m+[0m[0m type = "HTTP"
|
||||
[32m+[0m[0m url_path = "/"
|
||||
}
|
||||
|
||||
[1m # vkcs_lb_pool.web[0m will be created
|
||||
[0m [32m+[0m[0m resource "vkcs_lb_pool" "web" {
|
||||
[32m+[0m[0m admin_state_up = true
|
||||
[32m+[0m[0m id = (known after apply)
|
||||
[32m+[0m[0m lb_method = "ROUND_ROBIN"
|
||||
[32m+[0m[0m listener_id = (known after apply)
|
||||
[32m+[0m[0m name = "my-project-pool"
|
||||
[32m+[0m[0m protocol = "HTTP"
|
||||
[32m+[0m[0m region = (known after apply)
|
||||
|
||||
[32m+[0m[0m persistence (known after apply)
|
||||
}
|
||||
|
||||
[1m # vkcs_networking_network.main[0m will be created
|
||||
[0m [32m+[0m[0m resource "vkcs_networking_network" "main" {
|
||||
[32m+[0m[0m admin_state_up = true
|
||||
[32m+[0m[0m all_tags = (known after apply)
|
||||
[32m+[0m[0m id = (known after apply)
|
||||
[32m+[0m[0m name = "my-project-network"
|
||||
[32m+[0m[0m port_security_enabled = true
|
||||
[32m+[0m[0m private_dns_domain = (known after apply)
|
||||
[32m+[0m[0m region = (known after apply)
|
||||
[32m+[0m[0m sdn = (known after apply)
|
||||
}
|
||||
|
||||
[1m # vkcs_networking_secgroup.web[0m will be created
|
||||
[0m [32m+[0m[0m resource "vkcs_networking_secgroup" "web" {
|
||||
[32m+[0m[0m all_tags = (known after apply)
|
||||
[32m+[0m[0m description = "Web server security group"
|
||||
[32m+[0m[0m id = (known after apply)
|
||||
[32m+[0m[0m name = "my-project-web-sg"
|
||||
[32m+[0m[0m region = (known after apply)
|
||||
[32m+[0m[0m sdn = (known after apply)
|
||||
}
|
||||
|
||||
[1m # vkcs_networking_secgroup_rule.http[0m will be created
|
||||
[0m [32m+[0m[0m resource "vkcs_networking_secgroup_rule" "http" {
|
||||
[32m+[0m[0m direction = "ingress"
|
||||
[32m+[0m[0m ethertype = "IPv4"
|
||||
[32m+[0m[0m id = (known after apply)
|
||||
[32m+[0m[0m port_range_max = 80
|
||||
[32m+[0m[0m port_range_min = 80
|
||||
[32m+[0m[0m protocol = "tcp"
|
||||
[32m+[0m[0m region = (known after apply)
|
||||
[32m+[0m[0m remote_group_id = (known after apply)
|
||||
[32m+[0m[0m remote_ip_prefix = "0.0.0.0/0"
|
||||
[32m+[0m[0m sdn = (known after apply)
|
||||
[32m+[0m[0m security_group_id = (known after apply)
|
||||
}
|
||||
|
||||
[1m # vkcs_networking_secgroup_rule.ssh[0m will be created
|
||||
[0m [32m+[0m[0m resource "vkcs_networking_secgroup_rule" "ssh" {
|
||||
[32m+[0m[0m direction = "ingress"
|
||||
[32m+[0m[0m ethertype = "IPv4"
|
||||
[32m+[0m[0m id = (known after apply)
|
||||
[32m+[0m[0m port_range_max = 22
|
||||
[32m+[0m[0m port_range_min = 22
|
||||
[32m+[0m[0m protocol = "tcp"
|
||||
[32m+[0m[0m region = (known after apply)
|
||||
[32m+[0m[0m remote_group_id = (known after apply)
|
||||
[32m+[0m[0m remote_ip_prefix = "95.37.52.68/32"
|
||||
[32m+[0m[0m sdn = (known after apply)
|
||||
[32m+[0m[0m security_group_id = (known after apply)
|
||||
}
|
||||
|
||||
[1m # vkcs_networking_subnet.public[0m will be created
|
||||
[0m [32m+[0m[0m resource "vkcs_networking_subnet" "public" {
|
||||
[32m+[0m[0m all_tags = (known after apply)
|
||||
[32m+[0m[0m cidr = "192.168.1.0/24"
|
||||
[32m+[0m[0m enable_dhcp = true
|
||||
[32m+[0m[0m enable_private_dns = (known after apply)
|
||||
[32m+[0m[0m gateway_ip = (known after apply)
|
||||
[32m+[0m[0m id = (known after apply)
|
||||
[32m+[0m[0m name = "my-project-public-subnet"
|
||||
[32m+[0m[0m network_id = (known after apply)
|
||||
[32m+[0m[0m no_gateway = false
|
||||
[32m+[0m[0m region = (known after apply)
|
||||
[32m+[0m[0m sdn = (known after apply)
|
||||
|
||||
[32m+[0m[0m allocation_pool (known after apply)
|
||||
}
|
||||
|
||||
[1mPlan:[0m [0m14 to add, 0 to change, 0 to destroy.
|
||||
|
||||
Changes to Outputs:
|
||||
[32m+[0m[0m load_balancer_ip = (known after apply)
|
||||
[32m+[0m[0m web_servers_ips = [
|
||||
[32m+[0m[0m (known after apply),
|
||||
[32m+[0m[0m (known after apply),
|
||||
]
|
||||
[0m[1mvkcs_networking_secgroup.web: Creating...[0m[0m
|
||||
[0m[1mvkcs_compute_keypair.main: Creating...[0m[0m
|
||||
[0m[1mvkcs_networking_network.main: Creating...[0m[0m
|
||||
[0m[1mvkcs_compute_keypair.main: Creation complete after 1s [id=my-project-key][0m
|
||||
[0m[1mvkcs_networking_secgroup.web: Creation complete after 1s [id=109430a2-c230-4386-8dea-020fc76855e2][0m
|
||||
[0m[1mvkcs_networking_secgroup_rule.http: Creating...[0m[0m
|
||||
[0m[1mvkcs_networking_secgroup_rule.ssh: Creating...[0m[0m
|
||||
[0m[1mvkcs_networking_secgroup_rule.http: Creation complete after 0s [id=c451d6fe-5f33-4b85-96d0-09c7c315495d][0m
|
||||
[0m[1mvkcs_networking_secgroup_rule.ssh: Creation complete after 1s [id=4c0bb4db-c4cc-45c8-9878-b2f793e6c0e3][0m
|
||||
[0m[1mvkcs_networking_network.main: Creation complete after 6s [id=f665fc1e-562c-44f0-bc57-e18c60d8c40f][0m
|
||||
[0m[1mvkcs_networking_subnet.public: Creating...[0m[0m
|
||||
[0m[1mvkcs_compute_instance.web[0]: Creating...[0m[0m
|
||||
[0m[1mvkcs_compute_instance.web[1]: Creating...[0m[0m
|
||||
[0m[1mvkcs_networking_subnet.public: Creation complete after 6s [id=dd31b9f6-6ea9-4fbb-8ed5-76be3651c215][0m
|
||||
[0m[1mvkcs_lb_loadbalancer.main: Creating...[0m[0m
|
||||
[0m[1mvkcs_compute_instance.web[1]: Still creating... [00m10s elapsed][0m[0m
|
||||
[0m[1mvkcs_compute_instance.web[0]: Still creating... [00m10s elapsed][0m[0m
|
||||
[0m[1mvkcs_lb_loadbalancer.main: Still creating... [00m10s elapsed][0m[0m
|
||||
[0m[1mvkcs_compute_instance.web[0]: Still creating... [00m20s elapsed][0m[0m
|
||||
[0m[1mvkcs_compute_instance.web[1]: Still creating... [00m20s elapsed][0m[0m
|
||||
[0m[1mvkcs_lb_loadbalancer.main: Still creating... [00m20s elapsed][0m[0m
|
||||
[0m[1mvkcs_compute_instance.web[0]: Still creating... [00m30s elapsed][0m[0m
|
||||
[0m[1mvkcs_compute_instance.web[1]: Still creating... [00m30s elapsed][0m[0m
|
||||
[0m[1mvkcs_compute_instance.web[1]: Creation complete after 34s [id=d11a0460-b0c9-406d-9a59-76ac1c661b06][0m
|
||||
[0m[1mvkcs_lb_loadbalancer.main: Still creating... [00m30s elapsed][0m[0m
|
||||
[0m[1mvkcs_compute_instance.web[0]: Still creating... [00m40s elapsed][0m[0m
|
||||
[0m[1mvkcs_compute_instance.web[0]: Creation complete after 44s [id=e7d30b45-5423-43ee-8413-d20d46d67293][0m
|
||||
[0m[1mvkcs_lb_loadbalancer.main: Still creating... [00m40s elapsed][0m[0m
|
||||
[0m[1mvkcs_lb_loadbalancer.main: Still creating... [00m50s elapsed][0m[0m
|
||||
[0m[1mvkcs_lb_loadbalancer.main: Still creating... [01m00s elapsed][0m[0m
|
||||
[0m[1mvkcs_lb_loadbalancer.main: Still creating... [01m10s elapsed][0m[0m
|
||||
[0m[1mvkcs_lb_loadbalancer.main: Still creating... [01m20s elapsed][0m[0m
|
||||
[0m[1mvkcs_lb_loadbalancer.main: Still creating... [01m30s elapsed][0m[0m
|
||||
[0m[1mvkcs_lb_loadbalancer.main: Still creating... [01m40s elapsed][0m[0m
|
||||
[0m[1mvkcs_lb_loadbalancer.main: Still creating... [01m50s elapsed][0m[0m
|
||||
[0m[1mvkcs_lb_loadbalancer.main: Still creating... [02m00s elapsed][0m[0m
|
||||
[0m[1mvkcs_lb_loadbalancer.main: Still creating... [02m10s elapsed][0m[0m
|
||||
[0m[1mvkcs_lb_loadbalancer.main: Still creating... [02m20s elapsed][0m[0m
|
||||
[0m[1mvkcs_lb_loadbalancer.main: Still creating... [02m30s elapsed][0m[0m
|
||||
[0m[1mvkcs_lb_loadbalancer.main: Still creating... [02m40s elapsed][0m[0m
|
||||
[0m[1mvkcs_lb_loadbalancer.main: Still creating... [02m50s elapsed][0m[0m
|
||||
[0m[1mvkcs_lb_loadbalancer.main: Creation complete after 2m50s [id=a9c7eacd-2ea3-4ddf-8143-c20f5dfdf781][0m
|
||||
[0m[1mvkcs_lb_listener.http: Creating...[0m[0m
|
||||
[0m[1mvkcs_lb_listener.http: Still creating... [00m10s elapsed][0m[0m
|
||||
[0m[1mvkcs_lb_listener.http: Still creating... [00m20s elapsed][0m[0m
|
||||
[0m[1mvkcs_lb_listener.http: Still creating... [00m30s elapsed][0m[0m
|
||||
[0m[1mvkcs_lb_listener.http: Creation complete after 38s [id=465d21b3-efff-4c29-869f-f58ff2f7d825][0m
|
||||
[0m[1mvkcs_lb_pool.web: Creating...[0m[0m
|
||||
[0m[1mvkcs_lb_pool.web: Creation complete after 7s [id=1747e23f-5d24-4b60-a7d2-10b8cafbd45d][0m
|
||||
[0m[1mvkcs_lb_member.web[1]: Creating...[0m[0m
|
||||
[0m[1mvkcs_lb_member.web[0]: Creating...[0m[0m
|
||||
[0m[1mvkcs_lb_monitor.web: Creating...[0m[0m
|
||||
[0m[1mvkcs_lb_monitor.web: Still creating... [00m10s elapsed][0m[0m
|
||||
[0m[1mvkcs_lb_member.web[0]: Still creating... [00m10s elapsed][0m[0m
|
||||
[0m[1mvkcs_lb_member.web[1]: Still creating... [00m10s elapsed][0m[0m
|
||||
[0m[1mvkcs_lb_monitor.web: Creation complete after 20s [id=7a5b317c-9f4d-4307-894a-45e23d094166][0m
|
||||
[0m[1mvkcs_lb_member.web[0]: Creation complete after 20s [id=8f85bef6-3dc0-4e13-b3ea-bd7d68c03ce6][0m
|
||||
[0m[1mvkcs_lb_member.web[1]: Still creating... [00m20s elapsed][0m[0m
|
||||
[0m[1mvkcs_lb_member.web[1]: Creation complete after 27s [id=76e94747-e0bf-4f95-90b0-c50c6f1b2b8b][0m
|
||||
[33m╷[0m[0m
|
||||
[33m│[0m [0m[1m[33mWarning: [0m[0m[1mArgument is deprecated[0m
|
||||
[33m│[0m [0m
|
||||
[33m│[0m [0m[0m with vkcs_networking_secgroup_rule.ssh,
|
||||
[33m│[0m [0m on main.tf line 52, in resource "vkcs_networking_secgroup_rule" "ssh":
|
||||
[33m│[0m [0m 52: ethertype = [4m"IPv4"[0m[0m
|
||||
[33m│[0m [0m
|
||||
[33m│[0m [0mOnly IPv4 can be used as ethertype. This argument is deprecated, please do not use it.
|
||||
[33m│[0m [0m
|
||||
[33m│[0m [0m(and 9 more similar warnings elsewhere)
|
||||
[33m╵[0m[0m
|
||||
[0m[1m[32m
|
||||
Apply complete! Resources: 14 added, 0 changed, 0 destroyed.[0m
|
||||
[0m[1m[32m
|
||||
Outputs:
|
||||
|
||||
[0mload_balancer_ip = "192.168.1.9"
|
||||
web_servers_ips = [
|
||||
"192.168.1.73",
|
||||
"192.168.1.249",
|
||||
]
|
||||
@@ -0,0 +1,142 @@
|
||||
# Указываем версию провайдера
|
||||
terraform {
|
||||
required_providers {
|
||||
vkcs = {
|
||||
source = "vk-cs/vkcs"
|
||||
}
|
||||
random = {
|
||||
source = "hashicorp/random"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Настройка провайдера (использует переменные окружения из RC-файла)
|
||||
provider "vkcs" {}
|
||||
|
||||
# Переменные
|
||||
variable "my_ip" {
|
||||
description = "Your public IP for SSH access"
|
||||
type = string
|
||||
sensitive = false
|
||||
}
|
||||
|
||||
variable "project_name" {
|
||||
default = "my-project"
|
||||
}
|
||||
|
||||
# 1. Сеть
|
||||
resource "vkcs_networking_network" "main" {
|
||||
name = "${var.project_name}-network"
|
||||
}
|
||||
|
||||
resource "vkcs_networking_subnet" "public" {
|
||||
name = "${var.project_name}-public-subnet"
|
||||
network_id = vkcs_networking_network.main.id
|
||||
cidr = "192.168.1.0/24"
|
||||
}
|
||||
|
||||
# 2. Security Groups (исправлено: vkcs_networking_secgroup + правила)
|
||||
resource "vkcs_networking_secgroup" "web" {
|
||||
name = "${var.project_name}-web-sg"
|
||||
description = "Web server security group"
|
||||
}
|
||||
|
||||
resource "vkcs_networking_secgroup_rule" "ssh" {
|
||||
direction = "ingress"
|
||||
ethertype = "IPv4"
|
||||
protocol = "tcp"
|
||||
port_range_min = 22
|
||||
port_range_max = 22
|
||||
remote_ip_prefix = "${var.my_ip}/32"
|
||||
security_group_id = vkcs_networking_secgroup.web.id
|
||||
}
|
||||
|
||||
resource "vkcs_networking_secgroup_rule" "http" {
|
||||
direction = "ingress"
|
||||
ethertype = "IPv4"
|
||||
protocol = "tcp"
|
||||
port_range_min = 80
|
||||
port_range_max = 80
|
||||
remote_ip_prefix = "0.0.0.0/0"
|
||||
security_group_id = vkcs_networking_secgroup.web.id
|
||||
}
|
||||
|
||||
# 3. SSH ключ
|
||||
resource "vkcs_compute_keypair" "main" {
|
||||
name = "${var.project_name}-key"
|
||||
public_key = file("~/.ssh/id_rsa.pub")
|
||||
}
|
||||
|
||||
# 4. Веб-серверы
|
||||
resource "vkcs_compute_instance" "web" {
|
||||
count = 2
|
||||
|
||||
name = "${var.project_name}-web-${count.index + 1}"
|
||||
flavor_id = "df3c499a-044f-41d2-8612-d303adc613cc"
|
||||
image_id = "a4e699d3-a66d-45e5-bb5d-70ea7c8de62d"
|
||||
key_pair = vkcs_compute_keypair.main.name
|
||||
|
||||
network {
|
||||
uuid = vkcs_networking_network.main.id
|
||||
}
|
||||
|
||||
security_groups = [vkcs_networking_secgroup.web.name]
|
||||
|
||||
user_data = <<-EOF
|
||||
#!/bin/bash
|
||||
apt update
|
||||
apt install -y nginx
|
||||
echo "<h1>Web Server ${count.index + 1}</h1>" > /var/www/html/index.html
|
||||
systemctl enable nginx
|
||||
systemctl start nginx
|
||||
EOF
|
||||
}
|
||||
|
||||
# 5. Балансировщик
|
||||
resource "vkcs_lb_loadbalancer" "main" {
|
||||
name = "${var.project_name}-lb"
|
||||
vip_subnet_id = vkcs_networking_subnet.public.id
|
||||
}
|
||||
|
||||
resource "vkcs_lb_listener" "http" {
|
||||
name = "${var.project_name}-listener"
|
||||
protocol = "HTTP"
|
||||
protocol_port = 80
|
||||
loadbalancer_id = vkcs_lb_loadbalancer.main.id
|
||||
}
|
||||
|
||||
resource "vkcs_lb_pool" "web" {
|
||||
name = "${var.project_name}-pool"
|
||||
protocol = "HTTP"
|
||||
lb_method = "ROUND_ROBIN"
|
||||
listener_id = vkcs_lb_listener.http.id
|
||||
}
|
||||
|
||||
resource "vkcs_lb_monitor" "web" {
|
||||
name = "${var.project_name}-monitor"
|
||||
type = "HTTP"
|
||||
delay = 10
|
||||
timeout = 5
|
||||
max_retries = 3
|
||||
url_path = "/"
|
||||
pool_id = vkcs_lb_pool.web.id
|
||||
}
|
||||
|
||||
resource "vkcs_lb_member" "web" {
|
||||
count = 2
|
||||
|
||||
name = "${var.project_name}-member-${count.index + 1}"
|
||||
address = vkcs_compute_instance.web[count.index].access_ip_v4
|
||||
protocol_port = 80
|
||||
pool_id = vkcs_lb_pool.web.id
|
||||
subnet_id = vkcs_networking_subnet.public.id
|
||||
}
|
||||
|
||||
# 6. Выходные данные
|
||||
output "load_balancer_ip" {
|
||||
value = vkcs_lb_loadbalancer.main.vip_address
|
||||
}
|
||||
|
||||
output "web_servers_ips" {
|
||||
value = vkcs_compute_instance.web[*].access_ip_v4
|
||||
}
|
||||
Reference in new issue
Block a user