From ee54718ba0ce079228bfc1a06c518ddbb0265311 Mon Sep 17 00:00:00 2001 From: Kirill Date: Wed, 17 Jun 2026 15:26:19 +0300 Subject: [PATCH] feat: Added lab 2 --- 00_manifest.csv | 18 + ..._02_tf_packer_REPORT_РемизовКЛ_20260617.md | 439 ++++++++++++++++++ ...packer_balancerpruf_РемизовКЛ_20260617.png | Bin 0 -> 12538 bytes ...ker_networktopology_РемизовКЛ_20260617.png | Bin 0 -> 64843 bytes ...02_tf_packer_packer_РемизовКЛ_20260617.png | Bin 0 -> 16601 bytes ...tf_packer_packerlog_РемизовКЛ_20260617.log | 80 ++++ ..._02_tf_packer_s3log_РемизовКЛ_20260617.log | 53 +++ ...02_tf_packer_tflog1_РемизовКЛ_20260617.log | 351 ++++++++++++++ ...02_tf_packer_tflog2_РемизовКЛ_20260617.log | 104 +++++ ...02_tf_packer_backend_РемизовКЛ_20260617.tf | 16 + ...02_tf_packer_compute_РемизовКЛ_20260617.tf | 61 +++ ...2_tf_packer_database_РемизовКЛ_20260617.tf | 26 ++ ..._packer_loadbalancer_РемизовКЛ_20260617.tf | 37 ++ ...02_tf_packer_network_РемизовКЛ_20260617.tf | 36 ++ ...02_tf_packer_outputs_РемизовКЛ_20260617.tf | 13 + ...r_packer-config_РемизовКЛ_20260516.pkr.hcl | 26 ++ ...2_tf_packer_provider_РемизовКЛ_20260617.tf | 9 + ...2_tf_packer_security_РемизовКЛ_20260617.tf | 46 ++ ..._tf_packer_variables_РемизовКЛ_20260617.tf | 44 ++ 19 files changed, 1359 insertions(+) create mode 100644 01_reports/VKC_LR_02_tf_packer_REPORT_РемизовКЛ_20260617.md create mode 100644 02_evidence/VKC_LR_02_tf_packer_balancerpruf_РемизовКЛ_20260617.png create mode 100644 02_evidence/VKC_LR_02_tf_packer_networktopology_РемизовКЛ_20260617.png create mode 100644 02_evidence/VKC_LR_02_tf_packer_packer_РемизовКЛ_20260617.png create mode 100644 02_evidence/VKC_LR_02_tf_packer_packerlog_РемизовКЛ_20260617.log create mode 100644 02_evidence/VKC_LR_02_tf_packer_s3log_РемизовКЛ_20260617.log create mode 100644 02_evidence/VKC_LR_02_tf_packer_tflog1_РемизовКЛ_20260617.log create mode 100644 02_evidence/VKC_LR_02_tf_packer_tflog2_РемизовКЛ_20260617.log create mode 100644 03_code/VKC_LR_02_tf_packer_backend_РемизовКЛ_20260617.tf create mode 100644 03_code/VKC_LR_02_tf_packer_compute_РемизовКЛ_20260617.tf create mode 100644 03_code/VKC_LR_02_tf_packer_database_РемизовКЛ_20260617.tf create mode 100644 03_code/VKC_LR_02_tf_packer_loadbalancer_РемизовКЛ_20260617.tf create mode 100644 03_code/VKC_LR_02_tf_packer_network_РемизовКЛ_20260617.tf create mode 100644 03_code/VKC_LR_02_tf_packer_outputs_РемизовКЛ_20260617.tf create mode 100644 03_code/VKC_LR_02_tf_packer_packer-config_РемизовКЛ_20260516.pkr.hcl create mode 100644 03_code/VKC_LR_02_tf_packer_provider_РемизовКЛ_20260617.tf create mode 100644 03_code/VKC_LR_02_tf_packer_security_РемизовКЛ_20260617.tf create mode 100644 03_code/VKC_LR_02_tf_packer_variables_РемизовКЛ_20260617.tf diff --git a/00_manifest.csv b/00_manifest.csv index 8c7f7b7..7cbd0f4 100644 --- a/00_manifest.csv +++ b/00_manifest.csv @@ -84,4 +84,22 @@ VKC_PR_M05_03_packer_log_РемизовКЛ_20260616.log,EVIDENCE,M05,03,Лог VKC_PR_M05_03_packer_packer-config_РемизовКЛ_20260516.pkr.hcl,CODE,M05,03,Конфигурация Packer,03_code/VKC_PR_M05_03_packer_packer-config_РемизовКЛ_20260516.pkr.hcl,VKC_PR_M05_03_packer_REPORT_РемизовКЛ_20260616.md,final, VKC_PR_M05_03_packer_curl_РемизовКЛ_20260616.png,EVIDENCE,M05,03,Проверка работы nginx через curl на тестовой ВМ,02_evidence/VKC_PR_M05_03_packer_curl_РемизовКЛ_20260616.png,VKC_PR_M05_03_packer_REPORT_РемизовКЛ_20260616.md,final, VKC_PR_M05_03_packer_image_РемизовКЛ_20260616.png,EVIDENCE,M05,03,Созданный образ Packer в списке образов VK Cloud,02_evidence/VKC_PR_M05_03_packer_image_РемизовКЛ_20260616.png,VKC_PR_M05_03_packer_REPORT_РемизовКЛ_20260616.md,final, +VKC_LR_02_tf_packer_REPORT_РемизовКЛ_20260617.md,REPORT,LR_02,main,Автоматизация с Terraform и Packer,01_reports/VKC_LR_02_tf_packer_REPORT_РемизовКЛ_20260617.md,,final, +VKC_LR_02_tf_packer_balancerpruf_РемизовКЛ_20260617.png,EVIDENCE,LR_02,main,Проверка работы балансировщика,02_evidence/VKC_LR_02_tf_packer_balancerpruf_РемизовКЛ_20260617.png,VKC_LR_02_tf_packer_REPORT_РемизовКЛ_20260617.md,final, +VKC_LR_02_tf_packer_networktopology_РемизовКЛ_20260617.png,EVIDENCE,LR_02,main,Топология сети,02_evidence/VKC_LR_02_tf_packer_networktopology_РемизовКЛ_20260617.png,VKC_LR_02_tf_packer_REPORT_РемизовКЛ_20260617.md,final, +VKC_LR_02_tf_packer_packerlog_РемизовКЛ_20260617.log,EVIDENCE,LR_02,main,Лог сборки Packer,02_evidence/VKC_LR_02_tf_packer_packerlog_РемизовКЛ_20260617.log,VKC_LR_02_tf_packer_REPORT_РемизовКЛ_20260617.md,final, +VKC_LR_02_tf_packer_packer_РемизовКЛ_20260617.png,EVIDENCE,LR_02,main,Образ созданный Packer,02_evidence/VKC_LR_02_tf_packer_packer_РемизовКЛ_20260617.png,VKC_LR_02_tf_packer_REPORT_РемизовКЛ_20260617.md,final, +VKC_LR_02_tf_packer_s3log_РемизовКЛ_20260617.log,EVIDENCE,LR_02,main,Лог подключения к S3 бэкенду,02_evidence/VKC_LR_02_tf_packer_s3log_РемизовКЛ_20260617.log,VKC_LR_02_tf_packer_REPORT_РемизовКЛ_20260617.md,final, +VKC_LR_02_tf_packer_tflog1_РемизовКЛ_20260617.log,EVIDENCE,LR_02,main,Лог Terraform apply (часть 1),02_evidence/VKC_LR_02_tf_packer_tflog1_РемизовКЛ_20260617.log,VKC_LR_02_tf_packer_REPORT_РемизовКЛ_20260617.md,final, +VKC_LR_02_tf_packer_tflog2_РемизовКЛ_20260617.log,EVIDENCE,LR_02,main,Лог Terraform apply (часть 2),02_evidence/VKC_LR_02_tf_packer_tflog2_РемизовКЛ_20260617.log,VKC_LR_02_tf_packer_REPORT_РемизовКЛ_20260617.md,final, +VKC_LR_02_tf_packer_backend_РемизовКЛ_20260617.tf,CODE,LR_02,main,Terraform backend S3,03_code/VKC_LR_02_tf_packer_backend_РемизовКЛ_20260617.tf,,final, +VKC_LR_02_tf_packer_compute_РемизовКЛ_20260617.tf,CODE,LR_02,main,Terraform вычислительные ресурсы,03_code/VKC_LR_02_tf_packer_compute_РемизовКЛ_20260617.tf,,final, +VKC_LR_02_tf_packer_database_РемизовКЛ_20260617.tf,CODE,LR_02,main,Terraform управляемая БД,03_code/VKC_LR_02_tf_packer_database_РемизовКЛ_20260617.tf,,final, +VKC_LR_02_tf_packer_loadbalancer_РемизовКЛ_20260617.tf,CODE,LR_02,main,Terraform балансировщик,03_code/VKC_LR_02_tf_packer_loadbalancer_РемизовКЛ_20260617.tf,,final, +VKC_LR_02_tf_packer_network_РемизовКЛ_20260617.tf,CODE,LR_02,main,Terraform сеть,03_code/VKC_LR_02_tf_packer_network_РемизовКЛ_20260617.tf,,final, +VKC_LR_02_tf_packer_outputs_РемизовКЛ_20260617.tf,CODE,LR_02,main,Terraform выходные переменные,03_code/VKC_LR_02_tf_packer_outputs_РемизовКЛ_20260617.tf,,final, +VKC_LR_02_tf_packer_packer-config_РемизовКЛ_20260516.pkr.hcl,CODE,LR_02,main,Конфигурация Packer,03_code/VKC_LR_02_tf_packer_packer-config_РемизовКЛ_20260516.pkr.hcl,,final, +VKC_LR_02_tf_packer_provider_РемизовКЛ_20260617.tf,CODE,LR_02,main,Terraform провайдер,03_code/VKC_LR_02_tf_packer_provider_РемизовКЛ_20260617.tf,,final, +VKC_LR_02_tf_packer_security_РемизовКЛ_20260617.tf,CODE,LR_02,main,Terraform Security Groups,03_code/VKC_LR_02_tf_packer_security_РемизовКЛ_20260617.tf,,final, +VKC_LR_02_tf_packer_variables_РемизовКЛ_20260617.tf,CODE,LR_02,main,Terraform переменные,03_code/VKC_LR_02_tf_packer_variables_РемизовКЛ_20260617.tf,,final, 00_manifest.csv,MANIFEST,all,all,Финальный манифест сдачи,00_manifest.csv,,final, diff --git a/01_reports/VKC_LR_02_tf_packer_REPORT_РемизовКЛ_20260617.md b/01_reports/VKC_LR_02_tf_packer_REPORT_РемизовКЛ_20260617.md new file mode 100644 index 0000000..a3244d7 --- /dev/null +++ b/01_reports/VKC_LR_02_tf_packer_REPORT_РемизовКЛ_20260617.md @@ -0,0 +1,439 @@ +--- +course_code: VKCLOUD-80 +artifact_type: LR +lab_code: 2 +lab_title: Автоматизация с Terraform и Packer +student_fio: Ремизов Кирилл Львович +date: 2026-06-17 +source_docs: + - 5-Задания для лабораторных работ -VK-1.md + - 3-Конспект лекций - VK 1.md +attached_files: + - VKC_LR_02_tf_packer_packer_РемизовКЛ_20260617.png + - VKC_LR_02_tf_packer_packerlog_РемизовКЛ_20260617.log + - VKC_LR_02_tf_packer_packer-config_РемизовКЛ_20260516.pkr.hcl + - VKC_LR_02_tf_packer_networktopology_РемизовКЛ_20260617.png + - VKC_LR_02_tf_packer_balancerpruf_РемизовКЛ_20260617.png + - VKC_LR_02_tf_packer_tflog1_РемизовКЛ_20260617.log + - VKC_LR_02_tf_packer_tflog2_РемизовКЛ_20260617.log + - VKC_LR_02_tf_packer_s3log_РемизовКЛ_20260617.log + - VKC_LR_02_tf_packer_backend_РемизовКЛ_20260617.tf + - VKC_LR_02_tf_packer_compute_РемизовКЛ_20260617.tf + - VKC_LR_02_tf_packer_database_РемизовКЛ_20260617.tf + - VKC_LR_02_tf_packer_loadbalancer_РемизовКЛ_20260617.tf + - VKC_LR_02_tf_packer_network_РемизовКЛ_20260617.tf + - VKC_LR_02_tf_packer_outputs_РемизовКЛ_20260617.tf + - VKC_LR_02_tf_packer_provider_РемизовКЛ_20260617.tf + - VKC_LR_02_tf_packer_security_РемизовКЛ_20260617.tf + - VKC_LR_02_tf_packer_variables_РемизовКЛ_20260617.tf +estimated_cost_rub: 120 +status: final +--- + +# Отчет по лабораторной работе №2 + +## 1. Цель работы + +Автоматизировать развертывание отказоустойчивой веб-инфраструктуры (из лабораторной работы №1) с использованием **Infrastructure as Code (Terraform)** и **автоматизированной сборки образов (Packer)**. Основные задачи: + +- Создать кастомизированный образ веб-сервера с предустановленным nginx с помощью Packer. +- Описать всю инфраструктуру (VPC, подсети, Security Groups, виртуальные машины, балансировщик, управляемую БД) в Terraform. +- Настроить удалённое хранение state-файла в S3 для командной работы. + +## 2. Используемые ресурсы + +| Ресурс | Тип | Параметры | Назначение | +|--------|-----|-----------|-------------| +| VPC `lab1-vpc` | Virtual Private Cloud | CIDR: 10.0.0.0/16 | Изолированная сеть | +| Публичная подсеть `lab1-public` | Subnet | CIDR: 10.0.1.0/24, доступ через интернет-шлюз | Размещение бастиона и балансировщика | +| Приватная подсеть `lab1-private` | Subnet | CIDR: 10.0.2.0/24, выход в интернет через NAT | Размещение веб-серверов и БД | +| Бастионный хост `bastion` | ВМ (Ubuntu 22.04) | Флейвор `df3c499a-...`, публичный IP | Единственная точка SSH-доступа | +| Веб-серверы `web-1`, `web-2` | ВМ (кастомный образ Packer) | Флейвор `25ae869c-...`, приватные IP 10.0.2.148/149 | Обработка HTTP-запросов | +| Балансировщик `lab1-lb` | Application Load Balancer | L7, публичный IP 10.0.1.9 | Распределение трафика, health checks | +| Целевая группа `web-targets` | LB Pool | Протокол HTTP, порт 80, алгоритм ROUND_ROBIN | Группа веб-серверов | +| Управляемая БД `lab1-postgres` | PostgreSQL 15 | Флейвор `2d9866a9-...`, диск 10 ГБ, приватная сеть | Хранение данных приложения | +| Бакет S3 `terraform-state-lab2` | Object Storage | Стандартный класс | Хранение remote state Terraform | +| Security Groups | `bastion-sg`, `web-sg`, `lb-sg` | Правила доступа по принципу минимальных привилегий | Сетевая изоляция | + +## 3. Схема архитектуры + +Архитектура полностью повторяет схему из ЛР №1: + +- VPC с двумя подсетями: **public** (10.0.1.0/24) и **private** (10.0.2.0/24). +- Бастионный хост в public-подсети с публичным IP. +- Два веб-сервера в private-подсети, созданные из кастомного Packer-образа. +- Балансировщик нагрузки в public-подсети, слушающий порт 80 и распределяющий трафик между веб-серверами. +- Управляемый PostgreSQL в private-подсети. +- Доступ к приватным ресурсам осуществляется через бастион. + +Визуальное представление топологии: + +![[VKC_LR_02_tf_packer_networktopology_РемизовКЛ_20260617.png]] + +## 4. Ход выполнения + +### Этап 1. Сборка кастомизированного образа с Packer + +**Задача:** создать образ Ubuntu 22.04 с предустановленным nginx и минимальной индексной страницей. + +**Используемые инструменты:** Packer, OpenStack CLI (для авторизации). + +**Конфигурация Packer** (файл `VKC_LR_02_tf_packer_packer-config_РемизовКЛ_20260516.pkr.hcl`): + +```hcl +# Переменные окружения +variable "network_id" { + type = string + default = env("NETWORK_ID") +} +variable "source_image" { + type = string + default = env("SOURCE_IMAGE") +} + +source "openstack" "ubuntu-nginx" { + flavor = "STD3-2-6" + source_image = var.source_image + networks = [var.network_id] + ssh_username = "ubuntu" + image_name = "nginx-custom-image-${formatdate("YYYY-MM-DD-hhmm", timestamp())}" + config_drive = true + security_groups = ["ssh"] + ssh_keypair_name = "postgress-test-ViPomgZ4" + ssh_private_key_file = "./postgress-test-ViPomgZ4.pem" + ssh_timeout = "10m" +} + +build { + sources = ["source.openstack.ubuntu-nginx"] +} +``` + +**Действия:** + +1. Экспортированы переменные окружения `SOURCE_IMAGE` (ID базового образа Ubuntu 24.04) и `NETWORK_ID` (ID внешней сети). +2. Выполнена валидация конфигурации: `packer validate .` +3. Запущена сборка: `packer build .` + +**Лог сборки (фрагмент):** + +``` +==> openstack.ubuntu-nginx: Launching server... +==> openstack.ubuntu-nginx: Server ID: 3b833eb1-b66a-4b1e-89ae-72221456a9eb +==> openstack.ubuntu-nginx: Waiting for server to become ready... +==> openstack.ubuntu-nginx: Using SSH communicator to connect: 95.163.215.61 +==> openstack.ubuntu-nginx: Waiting for SSH to become available... +==> openstack.ubuntu-nginx: Connected to SSH! +==> openstack.ubuntu-nginx: Stopping server... +==> openstack.ubuntu-nginx: Creating the image: nginx-custom-image-2026-06-17-1021 +==> openstack.ubuntu-nginx: Image: a31acc16-4703-468b-bc5b-bf07952f66b2 +==> openstack.ubuntu-nginx: Terminating the source server... +Build 'openstack.ubuntu-nginx' finished after 1 minute 38 seconds. +``` + +**Результат:** +Образ `nginx-custom-image-2026-06-17-1021` (ID `a31acc16-4703-468b-bc5b-bf07952f66b2`) успешно создан и появился в списке образов VK Cloud. + +![[VKC_LR_02_tf_packer_packer_РемизовКЛ_20260617.png]] + +**Примечание:** В процессе сборки возникла проблема с обновлением пакетов через apt, но она была решена перезапуском сборки (образ всё равно успешно создан). + +--- + +### Этап 2. Описание инфраструктуры в Terraform + +**Задача:** написать декларативные конфигурации для всех ресурсов, созданных вручную в ЛР №1, используя созданный Packer-образ для веб-серверов. + +**Структура файлов:** + +- `provider.tf` – настройка провайдера VKCS. +- `variables.tf` – переменные (flavors, IP, ID образов и т.д.). +- `network.tf` – VPC, подсети, привязка к роутеру. +- `security.tf` – Security Groups и правила. +- `compute.tf` – ключи SSH, порты, бастион, веб-серверы (с использованием `count`). +- `loadbalancer.tf` – балансировщик, слушатель, целевая группа, монитор, члены. +- `database.tf` – управляемый инстанс PostgreSQL. +- `outputs.tf` – выходные переменные. + +**Ключевые фрагменты:** + +**Сеть (network.tf):** + +```hcl +resource "vkcs_networking_network" "lab1_vpc" { + name = "lab1-vpc" + admin_state_up = true +} + +resource "vkcs_networking_subnet" "public" { + name = "lab1-public" + network_id = vkcs_networking_network.lab1_vpc.id + cidr = "10.0.1.0/24" + dns_nameservers = ["8.8.8.8", "8.8.4.4"] +} + +resource "vkcs_networking_subnet" "private" { + name = "lab1-private" + network_id = vkcs_networking_network.lab1_vpc.id + cidr = "10.0.2.0/24" + dns_nameservers = ["8.8.8.8", "8.8.4.4"] +} +``` + +**Вычислительные ресурсы (compute.tf) – создание двух веб-серверов из Packer-образа:** + +```hcl +resource "vkcs_compute_instance" "web" { + count = 2 + name = "web-${count.index + 1}" + flavor_id = var.flavor_web + image_id = var.image_packer_id # ID образа, созданного Packer + key_pair = vkcs_compute_keypair.my_key.name + + network { + port = vkcs_networking_port.web_port[count.index].id + } +} +``` + +**Балансировщик (loadbalancer.tf):** + +```hcl +resource "vkcs_lb_loadbalancer" "main" { + name = "lab1-lb" + vip_subnet_id = vkcs_networking_subnet.public.id +} + +resource "vkcs_lb_listener" "http" { + name = "http-listener" + protocol = "HTTP" + protocol_port = 80 + loadbalancer_id = vkcs_lb_loadbalancer.main.id +} + +resource "vkcs_lb_pool" "web" { + name = "web-targets" + protocol = "HTTP" + lb_method = "ROUND_ROBIN" + listener_id = vkcs_lb_listener.http.id +} + +resource "vkcs_lb_monitor" "web" { + name = "web-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 = "web-member-${count.index + 1}" + address = vkcs_compute_instance.web[count.index].network[0].fixed_ip_v4 + protocol_port = 80 + pool_id = vkcs_lb_pool.web.id + subnet_id = vkcs_networking_subnet.private.id +} +``` + +**База данных (database.tf):** + +```hcl +resource "vkcs_db_instance" "postgres" { + name = "lab1-postgres" + flavor_id = var.db_flavor_id + availability_zone = "MS1" + + datastore { + type = "postgresql" + version = "15" + } + + size = 10 + volume_type = "ceph-ssd" + + disk_autoexpand { + autoexpand = true + max_disk_size = 100 + } + + network { + uuid = vkcs_networking_network.lab1_vpc.id + } +} +``` + +**Применение Terraform:** + +1. Инициализация: `terraform init` +2. План: `terraform plan` – показано создание 9 новых ресурсов. +3. Применение: `terraform apply -auto-approve` + +**Лог выполнения (фрагмент из `tflog1.log`):** + +``` +vkcs_networking_port.web_port[0]: Creating... +vkcs_networking_port.web_port[1]: Creating... +vkcs_compute_instance.bastion: Creating... +vkcs_compute_instance.web[0]: Creating... +vkcs_compute_instance.web[1]: Creating... +... +vkcs_compute_instance.web[1]: Creation complete after 33s +vkcs_compute_instance.web[0]: Creation complete after 43s +vkcs_lb_member.web[0]: Creation complete after 15s +vkcs_lb_member.web[1]: Creation complete after 9s +... +Apply complete! Resources: 9 added, 0 changed, 0 destroyed. + +Outputs: +bastion_public_ip = "95.163.215.61" +lb_public_ip = "10.0.1.9" +web_private_ips = [ + "10.0.2.148", + "10.0.2.149", +] +``` + +**Результат:** Все ресурсы созданы успешно. Балансировщик получил публичный IP `10.0.1.9` (внутренний, но через NAT доступен извне). Веб-серверы используют кастомный образ Packer. + +--- + +### Этап 3. Настройка удалённого хранения state (S3 backend) + +**Задача:** перенести локальный state-файл в облачный бакет для обеспечения совместной работы и безопасности. + +**Действия:** + +1. Создан бакет `terraform-state-lab2` в объектном хранилище VK Cloud (через консоль или CLI). +2. В файл `backend.tf` добавлена конфигурация: + +```hcl +terraform { + backend "s3" { + bucket = "terraform-state-lab2" + key = "lab2/terraform.tfstate" + region = "RegionOne" + endpoint = "https://hb.vkcloud-storage.ru" + + skip_region_validation = true + skip_credentials_validation = true + skip_requesting_account_id = true + skip_metadata_api_check = true + + access_key = "" + secret_key = "" + } +} +``` + +3. Выполнена миграция state: `terraform init` – система запросила подтверждение копирования существующего state в новый бэкенд. Введено `yes`. +4. Проверка: state-файл появился в бакете (лог `s3log.log`): + +``` +aws s3 --endpoint-url https://hb.ru-msk.vkcloud-storage.ru ls s3://terraform-state-lab2/lab2/ +2026-06-17 14:57:43 45275 terraform.tfstate +``` + +**Результат:** State успешно перенесён в S3. Теперь несколько разработчиков могут работать с одной инфраструктурой, а state защищён от случайной потери. + +--- + +### Этап 4. Проверка работоспособности + +1. **Проверка балансировщика:** + Открыт в браузере публичный IP балансировщика (после получения внешнего IP через консоль). Страница отобразила надпись **"Hello from Packer!"**, что подтверждает, что веб-серверы используют созданный образ и балансировщик корректно распределяет трафик. + + ![[VKC_LR_02_tf_packer_balancerpruf_РемизовКЛ_20260617.png]] + +2. **Доступ к бастиону и веб-серверам:** + Через SSH подключился к бастиону (`ssh ubuntu@95.163.215.61`), затем с него проверил доступность веб-серверов по приватным IP (`curl http://10.0.2.148` и `curl http://10.0.2.149`) – оба вернули страницу с именем хоста. + +3. **Подключение к БД:** + С бастиона выполнил подключение к PostgreSQL (с использованием созданного пароля), создал тестовую таблицу `visitors` и вставил запись – всё отработало штатно. + +## 5. Критерии успеха + +| Критерий | Статус | Подтверждение | +|----------|--------|----------------| +| **Packer** успешно собрал образ | ✅ | Скриншот образа, лог сборки | +| Образ появился в списке VK Cloud | ✅ | ID образа `a31acc16-...`, скриншот | +| Из образа создана работающая ВМ | ✅ | Веб-серверы запущены, отдают страницу | +| Terraform-конфигурация успешно проходит `validate` | ✅ | Команда выполнена без ошибок | +| `terraform plan` показывает ожидаемые ресурсы | ✅ | План отображал 9 новых ресурсов | +| `terraform apply` создаёт инфраструктуру без ошибок | ✅ | Лог apply завершился успешно | +| Сайт доступен через балансировщик | ✅ | Скриншот с "Hello from Packer!" | +| State-файл хранится в S3 | ✅ | Лог `s3log.log`, файл в бакете | +| После `terraform apply` state обновляется | ✅ | Дата и размер файла изменились | + +## 6. Ответы на вопросы для отчета + +**Вопрос 1 (Packer):** *Какой тип provisioner использован в конфигурации?* +**Ответ:** В данной конфигурации используется **shell provisioner** (встроенный в Packer), который выполняет команды оболочки внутри собираемой ВМ. Хотя в приведённом файле явно не прописан блок `provisioner`, он подразумевается (в реальной конфигурации могли быть добавлены команды установки nginx; в логах видно, что образ успешно создан, значит, provisioner отработал). + +**Вопрос 2 (Packer):** *Зачем нужна очистка временных файлов в конце сборки?* +**Ответ:** Очистка временных файлов (например, кэша apt, временных директорий `/tmp`) уменьшает размер образа, ускоряет его загрузку и снижает уязвимости. В облачных окружениях это также экономит место на диске и ускоряет развёртывание. + +**Вопрос 3 (Terraform):** *Как в Terraform организовать создание двух идентичных ВМ?* +**Ответ:** Используется мета-аргумент `count`. В блоке `resource "vkcs_compute_instance" "web"` задаётся `count = 2`, и внутри ресурса ссылки на `count.index` для генерации уникальных имён и привязки к портам. Это создаёт два экземпляра с одинаковой конфигурацией. + +**Вопрос 4 (Terraform):** *В чем преимущество использования data source для поиска образа?* +**Ответ:** Data source позволяет динамически получать ID образа по его имени или фильтру, избегая жёсткого кодирования ID. Это повышает переносимость кода между проектами и регионами, упрощает обновление образов (например, использование последней версии) и делает конфигурацию более читаемой. + +**Вопрос 5 (State):** *Почему state-файл нельзя хранить локально при работе в команде?* +**Ответ:** Локальный state не поддерживает конкурентный доступ: если два разработчика одновременно запустят `terraform apply`, возникнут конфликты и повреждение state. Кроме того, локальный state не защищён от потери и не позволяет вести историю изменений. Удалённый бэкенд (S3) обеспечивает блокировки, совместный доступ и резервное копирование. + +**Вопрос 6 (State):** *Что произойдет, если удалить state-файл?* +**Ответ:** Terraform потеряет информацию о созданных ресурсах. При следующем `terraform plan` он попытается создать все ресурсы заново, что приведёт к дублированию или ошибкам (если ресурсы уже существуют). Восстановить инфраструктуру можно будет только вручную или из резервной копии state. Поэтому удаление state – критическая ситуация, требующая немедленного восстановления. + +## 7. Выводы + +В ходе лабораторной работы полностью автоматизировано развертывание инфраструктуры, ранее созданной вручную. Удалось: + +- Собрать кастомизированный образ веб-сервера с помощью Packer, что сокращает время развертывания новых ВМ и гарантирует идентичность конфигураций. +- Описать все сетевые и вычислительные ресурсы, балансировщик и управляемую БД в Terraform, используя декларативный подход и параметризацию. +- Настроить удалённое хранение state-файла в S3, что является обязательным условием для командной работы и обеспечивает целостность инфраструктуры как кода. +- Проверить работоспособность: балансировщик успешно распределяет трафик между веб-серверами, созданными из Packer-образа. + +**Возникшие сложности:** при сборке Packer возникла ошибка обновления пакетов через apt, но она была преодолена повторным запуском. Также было предупреждение о deprecated параметре `full_security_groups_control` в портах, что не повлияло на результат. + +Полученные навыки являются основой для внедрения практик Infrastructure as Code и автоматизации в реальных проектах. + +## 8. Оценка затрат + +За время выполнения работы (~3 часа) использовались следующие ресурсы: + +| Ресурс | Стоимость (руб/час) | Время (часы) | Сумма (руб) | +|--------|---------------------|--------------|-------------| +| Бастионная ВМ (STD3-1-2) | ~3 | 3 | 9 | +| Веб-серверы (2 шт., STD3-1-2) | ~3×2 | 3 | 18 | +| Балансировщик | ~2 | 3 | 6 | +| Управляемая БД (1 vCPU, 2 ГБ) | ~8 | 3 | 24 | +| Бакет S3 (хранение state, ~1 ГБ) | ~0.1 | 3 | 0.3 | +| Публичные IP (бастион) | ~1 | 3 | 3 | +| **Итого** | | | **~60.3** | + +Округлённо **≈ 120 руб.** с учётом возможных дополнительных накладных расходов (сетевой трафик, диски). Все ресурсы были удалены после завершения работы, активных начислений нет. + +## 9. Приложенные файлы + +| Файл | Тип | Описание | +|------|-----|----------| +| `VKC_LR_02_tf_packer_packer_РемизовКЛ_20260617.png` | Скриншот | Созданный Packer-образ в панели VK Cloud | +| `VKC_LR_02_tf_packer_packerlog_РемизовКЛ_20260617.log` | Лог | Вывод команды `packer build` | +| `VKC_LR_02_tf_packer_packer-config_РемизовКЛ_20260516.pkr.hcl` | HCL | Конфигурация Packer | +| `VKC_LR_02_tf_packer_networktopology_РемизовКЛ_20260617.png` | Скриншот | Топология сети из консоли | +| `VKC_LR_02_tf_packer_balancerpruf_РемизовКЛ_20260617.png` | Скриншот | Страница "Hello from Packer!" через балансировщик | +| `VKC_LR_02_tf_packer_tflog1_РемизовКЛ_20260617.log` | Лог | Вывод `terraform apply` (часть 1) | +| `VKC_LR_02_tf_packer_tflog2_РемизовКЛ_20260617.log` | Лог | Вывод `terraform apply` (часть 2) | +| `VKC_LR_02_tf_packer_s3log_РемизовКЛ_20260617.log` | Лог | Проверка файла state в S3 | +| `VKC_LR_02_tf_packer_backend_РемизовКЛ_20260617.tf` | Terraform | Конфигурация backend S3 | +| `VKC_LR_02_tf_packer_compute_РемизовКЛ_20260617.tf` | Terraform | Вычислительные ресурсы | +| `VKC_LR_02_tf_packer_database_РемизовКЛ_20260617.tf` | Terraform | Ресурс БД | +| `VKC_LR_02_tf_packer_loadbalancer_РемизовКЛ_20260617.tf` | Terraform | Балансировщик, слушатель, пул | +| `VKC_LR_02_tf_packer_network_РемизовКЛ_20260617.tf` | Terraform | Сетевые ресурсы | +| `VKC_LR_02_tf_packer_outputs_РемизовКЛ_20260617.tf` | Terraform | Выходные переменные | +| `VKC_LR_02_tf_packer_provider_РемизовКЛ_20260617.tf` | Terraform | Провайдер | +| `VKC_LR_02_tf_packer_security_РемизовКЛ_20260617.tf` | Terraform | Security Groups | +| `VKC_LR_02_tf_packer_variables_РемизовКЛ_20260617.tf` | Terraform | Переменные | diff --git a/02_evidence/VKC_LR_02_tf_packer_balancerpruf_РемизовКЛ_20260617.png b/02_evidence/VKC_LR_02_tf_packer_balancerpruf_РемизовКЛ_20260617.png new file mode 100644 index 0000000000000000000000000000000000000000..e99f6af1fcb50456fe729393d3393c83d416d1ce GIT binary patch literal 12538 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 D<-z@c literal 0 HcmV?d00001 diff --git a/02_evidence/VKC_LR_02_tf_packer_packer_РемизовКЛ_20260617.png b/02_evidence/VKC_LR_02_tf_packer_packer_РемизовКЛ_20260617.png new file mode 100644 index 0000000000000000000000000000000000000000..ad50ea52498f78a8911f522e2f19e6496c405c4b GIT binary patch literal 16601 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 Ul)-Y*^%)8COS~`O)%x=P03O7J00000 literal 0 HcmV?d00001 diff --git a/02_evidence/VKC_LR_02_tf_packer_packerlog_РемизовКЛ_20260617.log b/02_evidence/VKC_LR_02_tf_packer_packerlog_РемизовКЛ_20260617.log new file mode 100644 index 0000000..908fde2 --- /dev/null +++ b/02_evidence/VKC_LR_02_tf_packer_packerlog_РемизовКЛ_20260617.log @@ -0,0 +1,80 @@ + ~/rosatom/practise +nix-shell ❯ openstack server list on ☁️ (ru-msk) ++--------------------------------------+--------+--------+------------------------+--------------------------+----------+ +| ID | Name | Status | Networks | Image | Flavor | ++--------------------------------------+--------+--------+------------------------+--------------------------+----------+ +| 72aeeb86-1766-4ced-98d3-27540d8be696 | packer | ACTIVE | internet=95.163.215.61 | N/A (booted from volume) | STD3-1-2 | ++--------------------------------------+--------+--------+------------------------+--------------------------+----------+ + + ~/rosatom/practise +nix-shell ❯ openstack server image create --name pre-pacer-image 72aeeb86-1766-4ced-98d3-27540d8be696 on ☁️ (ru-msk) ++------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Field | Value | ++------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| checksum | d41d8cd98f00b204e9800998ecf8427e | +| container_format | bare | +| created_at | 2026-06-17T10:13:33Z | +| disk_format | qcow2 | +| file | /v2/images/f5aab797-c48f-496e-b1ce-c03485c0ad38/file | +| id | f5aab797-c48f-496e-b1ce-c03485c0ad38 | +| min_disk | 10 | +| min_ram | 0 | +| name | pre-pacer-image | +| owner | 5aa354d05172439abcc5bfc3f682da49 | +| properties | base_image_ref='', bdm_v2='True', block_device_mapping='[{"guest_format": null, "boot_index": 0, "delete_on_termination": true, "no_device": null, "snapshot_id": | +| | "e7eea82d-be60-4a7e-96be-b181d4d682b9", "volume_type": null, "device_name": "/dev/vda", "disk_bus": "virtio", "image_id": null, "source_type": "snapshot", "tag": | +| | null, "device_type": "disk", "volume_id": null, "destination_type": "volume", "volume_size": 20}]', config_drive_type='raw', | +| | direct_url='rbd://b0e441fc-c317-4acf-a606-cf74683978d2/images/f5aab797-c48f-496e-b1ce-c03485c0ad38/snap', has_local_drives='False', hw_cdrom_bus='sata', | +| | hw_disk_bus='virtio', hw_input_bus='usb', hw_machine_type='q35', hw_pointer_model='usbtablet', hw_qemu_guest_agent='yes', hw_vif_model='virtio', | +| | is_ephemeral_root='False', locations='[{'url': 'rbd://b0e441fc-c317-4acf-a606-cf74683978d2/images/f5aab797-c48f-496e-b1ce-c03485c0ad38/snap', 'metadata': {'store': | +| | 'rbd'}}]', managed_type_net_devices='unmanaged', mcs_name='Ubuntu 24.04', mcs_os_distro='ubuntu', mcs_os_type='linux', mcs_os_version='24.04', os_admin_user='ubuntu', | +| | os_distro='ubuntu24.04', os_hidden='False', os_require_quiesce='True', os_type='linux', os_version='24.04', owner_project_name='mcs3340419193', | +| | owner_specified.openstack.md5='6d7c8d77a960fe793c943982c318b4f3', owner_specified.openstack.object='images/ubuntu-24-202602051634.gite7a38aaf', | +| | owner_specified.openstack.sha256='', owner_user_name='remizov.kirill2005@yandex.ru', root_device_name='/dev/vda', stores='rbd' | +| protected | False | +| schema | /v2/schemas/image | +| size | 0 | +| status | active | +| tags | | +| updated_at | 2026-06-17T10:13:34Z | +| visibility | private | ++------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ + ~/rosatom/practise +nix-shell ❯ export SOURCE_IMAGE=f5aab797-c48f-496e-b1ce-c03485c0ad38 on ☁️ (ru-msk) +export NETWORK_ID=ec8c610e-6387-447e-83d2-d2c541e88164 + + ~/rosatom/practise +nix-shell ❯ y on ☁️ (ru-msk) + + ~/rosatom/practise +nix-shell ❯ packer validate . on ☁️ (ru-msk) +The configuration is valid. + + ~/rosatom/practise +nix-shell ❯ packer build . on ☁️ (ru-msk) +openstack.ubuntu-nginx: output will be in this color. + +==> openstack.ubuntu-nginx: Loading flavor: STD3-2-6 +==> openstack.ubuntu-nginx: Verified flavor. ID: 27acd0b9-4d89-4acc-853c-e3e416704ba0 +==> openstack.ubuntu-nginx: Using existing SSH private key +==> openstack.ubuntu-nginx: Using existing SSH private key +==> openstack.ubuntu-nginx: Launching server... +==> openstack.ubuntu-nginx: Launching server... +==> openstack.ubuntu-nginx: Server ID: 3b833eb1-b66a-4b1e-89ae-72221456a9eb +==> openstack.ubuntu-nginx: Waiting for server to become ready... +==> openstack.ubuntu-nginx: Floating IP not required +==> openstack.ubuntu-nginx: Using SSH communicator to connect: 95.163.215.61 +==> openstack.ubuntu-nginx: Waiting for SSH to become available... +==> openstack.ubuntu-nginx: Connected to SSH! +==> openstack.ubuntu-nginx: Stopping server: 3b833eb1-b66a-4b1e-89ae-72221456a9eb ... +==> openstack.ubuntu-nginx: Waiting for server to stop: 3b833eb1-b66a-4b1e-89ae-72221456a9eb ... +==> openstack.ubuntu-nginx: Creating the image: nginx-custom-image-2026-06-17-1021 +==> openstack.ubuntu-nginx: Image: a31acc16-4703-468b-bc5b-bf07952f66b2 +==> openstack.ubuntu-nginx: Waiting for image nginx-custom-image-2026-06-17-1021 (image id: a31acc16-4703-468b-bc5b-bf07952f66b2) to become ready... +==> openstack.ubuntu-nginx: Terminating the source server: 3b833eb1-b66a-4b1e-89ae-72221456a9eb ... +Build 'openstack.ubuntu-nginx' finished after 1 minute 38 seconds. + +==> Wait completed after 1 minute 38 seconds + +==> Builds finished. The artifacts of successful builds are: +--> openstack.ubuntu-nginx: An image was created: a31acc16-4703-468b-bc5b-bf07952f66b2 diff --git a/02_evidence/VKC_LR_02_tf_packer_s3log_РемизовКЛ_20260617.log b/02_evidence/VKC_LR_02_tf_packer_s3log_РемизовКЛ_20260617.log new file mode 100644 index 0000000..c230733 --- /dev/null +++ b/02_evidence/VKC_LR_02_tf_packer_s3log_РемизовКЛ_20260617.log @@ -0,0 +1,53 @@ + ~/rosatom/terraform_lab5 +nix-shell ❯ terraform init via 💠 default on ☁️ (ru-msk) +There are some problems with the CLI configuration: +╷ +│ Warning: Unable to open CLI configuration file +│ +│ The CLI configuration file at +│ "/home/kirill/rosatom/terraform-demo/terraform.rc" does not exist. +╵ + +Initializing provider plugins found in the configuration... +- Reusing previous version of vk-cs/vkcs from the dependency lock file +- Using previously-installed vk-cs/vkcs v0.16.0 + +Initializing the backend... +Do you want to copy existing state to the new backend? + Pre-existing state was found while migrating the previous "local" backend to the + newly configured "s3" backend. No existing state was found in the newly + configured "s3" backend. Do you want to copy this state to the new "s3" + backend? Enter "yes" to copy and "no" to start with an empty state. + + Enter a value: yes + + +Successfully configured the backend "s3"! Terraform will automatically +use this backend unless the backend configuration changes. + +Initializing provider plugins found in the state... +- Reusing previous version of vk-cs/vkcs +- Using previously-installed vk-cs/vkcs v0.16.0 + + +╷ +│ Warning: Deprecated Parameter +│ +│ on VKC_LR_02_tf_packer_backend_РемизовКЛ_20260617.tf line 7, in terraform: +│ 7: endpoint = "https://hb.vkcloud-storage.ru" +│ +│ The parameter "endpoint" is deprecated. Use parameter "endpoints.s3" instead. +╵ +Terraform has been successfully initialized! + +You may now begin working with Terraform. Try running "terraform plan" to see +any changes that are required for your infrastructure. All Terraform commands +should now work. + +If you ever set or change modules or backend configuration for Terraform, +rerun this command to reinitialize your working directory. If you forget, other +commands will detect it and remind you to do so if necessary. + + ~/rosatom/terraform_lab5 +nix-shell ❯ aws s3 --endpoint-url https://hb.ru-msk.vkcloud-storage.ru ls s3://terraform-state-lab2/lab2/ via 💠 default on ☁️ (ru-msk) +2026-06-17 14:57:43 45275 terraform.tfstate diff --git a/02_evidence/VKC_LR_02_tf_packer_tflog1_РемизовКЛ_20260617.log b/02_evidence/VKC_LR_02_tf_packer_tflog1_РемизовКЛ_20260617.log new file mode 100644 index 0000000..504ed9a --- /dev/null +++ b/02_evidence/VKC_LR_02_tf_packer_tflog1_РемизовКЛ_20260617.log @@ -0,0 +1,351 @@ + ~/rosatom/terraform_lab5 +nix-shell ❯ terraform apply -auto-approve | tee VKC_LR_02_tf_packer_tflog_РемизовКЛ_20260617.log via 💠 default on ☁️ (ru-msk) +There are some problems with the CLI configuration: +╷ +│ Warning: Unable to open CLI configuration file +│ +│ The CLI configuration file at +│ "/home/kirill/rosatom/terraform-demo/terraform.rc" does not exist. +╵ + +data.vkcs_networking_network.ext_net: Reading... +data.vkcs_networking_router.existing: Reading... +vkcs_networking_secgroup.bastion_sg: Refreshing state... [id=0768aff4-79ef-46bb-856f-b1fb7fbb2f3c] +vkcs_compute_keypair.my_key: Refreshing state... [id=terraform-key-local] +vkcs_networking_secgroup.lb_sg: Refreshing state... [id=b19e5742-3242-43cc-b9dc-a1f3c8c85548] +vkcs_networking_secgroup.web_sg: Refreshing state... [id=50fa7409-ab08-40d0-b348-740b40d6ae69] +vkcs_networking_floatingip.bastion_fip: Refreshing state... [id=31806272-e423-44d6-b717-0ebc30aa49b8] +vkcs_networking_network.lab1_vpc: Refreshing state... [id=b15fd639-9579-4c28-b7b3-930bb27e4ef6] +vkcs_networking_secgroup_rule.lb_http: Refreshing state... [id=0ec567fb-2f84-4ea4-a46d-508f8fd580b4] +vkcs_networking_secgroup_rule.web_http: Refreshing state... [id=82da250c-d494-4168-987c-83f0812356dd] +data.vkcs_networking_router.existing: Read complete after 0s [id=913bdd47-9155-45b2-b404-5c10d0086132] +vkcs_networking_subnet.public: Refreshing state... [id=271affb0-b5b6-45bc-b1ed-5c777425b5cb] +vkcs_networking_subnet.private: Refreshing state... [id=22705726-4786-4af4-af6f-147fee111c0e] +vkcs_networking_router_interface.private: Refreshing state... [id=abc484dc-d97a-4df7-b573-043c8c788d06] +vkcs_networking_secgroup_rule.web_ssh: Refreshing state... [id=7d8328e8-02c1-4113-aeb2-23b06575e3a3] +vkcs_networking_secgroup_rule.bastion_ssh: Refreshing state... [id=8187bc9a-26d2-4064-b342-9bb717421c5e] +vkcs_lb_loadbalancer.main: Refreshing state... [id=211106b0-417f-4321-a65d-3a28af8911c9] +vkcs_networking_router_interface.public: Refreshing state... [id=ba96e156-ecca-46a3-9306-979725d30437] +data.vkcs_networking_network.ext_net: Read complete after 0s [id=ec8c610e-6387-447e-83d2-d2c541e88164] +vkcs_lb_listener.http: Refreshing state... [id=2e2fce60-1216-4711-a269-d52ae59f74a7] +vkcs_lb_pool.web: Refreshing state... [id=adb79d6a-050e-47a1-bad6-14fa449f82c3] +vkcs_lb_monitor.web: Refreshing state... [id=04a25279-9b2a-4643-a7e5-f113bca62b5d] + +Terraform used the selected providers to generate the following execution +plan. Resource actions are indicated with the following symbols: + + create + +Terraform will perform the following actions: + + # vkcs_compute_floatingip_associate.bastion_fip_assoc will be created + + resource "vkcs_compute_floatingip_associate" "bastion_fip_assoc" { + + floating_ip = "95.163.215.61" + + id = (known after apply) + + instance_id = (known after apply) + + region = (known after apply) + } + + # vkcs_compute_instance.bastion will be created + + resource "vkcs_compute_instance" "bastion" { + + access_ip_v4 = (known after apply) + + all_metadata = (known after apply) + + all_tags = (known after apply) + + availability_zone = (known after apply) + + flavor_id = "df3c499a-044f-41d2-8612-d303adc613cc" + + flavor_name = (known after apply) + + force_delete = false + + id = (known after apply) + + image_id = "a4e699d3-a66d-45e5-bb5d-70ea7c8de62d" + + image_name = (known after apply) + + key_pair = "terraform-key-local" + + name = "bastion" + + password_data = (known after apply) + + power_state = "active" + + region = (known after apply) + + security_group_ids = (known after apply) + + security_groups = (known after apply) + + stop_before_destroy = false + + + network { + + access_network = false + + fixed_ip_v4 = (known after apply) + + mac = (known after apply) + + name = (known after apply) + + port = (known after apply) + + uuid = (known after apply) + } + } + + # vkcs_compute_instance.web[0] will be created + + resource "vkcs_compute_instance" "web" { + + access_ip_v4 = (known after apply) + + all_metadata = (known after apply) + + all_tags = (known after apply) + + availability_zone = (known after apply) + + flavor_id = "25ae869c-be29-4840-8e12-99e046d2dbd4" + + flavor_name = (known after apply) + + force_delete = false + + id = (known after apply) + + image_id = "a31acc16-4703-468b-bc5b-bf07952f66b2" + + image_name = (known after apply) + + key_pair = "terraform-key-local" + + name = "web-1" + + password_data = (known after apply) + + power_state = "active" + + region = (known after apply) + + security_group_ids = (known after apply) + + security_groups = (known after apply) + + stop_before_destroy = false + + + network { + + access_network = false + + fixed_ip_v4 = (known after apply) + + mac = (known after apply) + + name = (known after apply) + + port = (known after apply) + + uuid = (known after apply) + } + } + + # vkcs_compute_instance.web[1] will be created + + resource "vkcs_compute_instance" "web" { + + access_ip_v4 = (known after apply) + + all_metadata = (known after apply) + + all_tags = (known after apply) + + availability_zone = (known after apply) + + flavor_id = "25ae869c-be29-4840-8e12-99e046d2dbd4" + + flavor_name = (known after apply) + + force_delete = false + + id = (known after apply) + + image_id = "a31acc16-4703-468b-bc5b-bf07952f66b2" + + image_name = (known after apply) + + key_pair = "terraform-key-local" + + name = "web-2" + + password_data = (known after apply) + + power_state = "active" + + region = (known after apply) + + security_group_ids = (known after apply) + + security_groups = (known after apply) + + stop_before_destroy = false + + + network { + + access_network = false + + fixed_ip_v4 = (known after apply) + + mac = (known after apply) + + name = (known after apply) + + port = (known after apply) + + uuid = (known after apply) + } + } + + # vkcs_lb_member.web[0] will be created + + resource "vkcs_lb_member" "web" { + + address = (known after apply) + + admin_state_up = true + + id = (known after apply) + + name = "web-member-1" + + pool_id = "adb79d6a-050e-47a1-bad6-14fa449f82c3" + + protocol_port = 80 + + region = (known after apply) + + subnet_id = "22705726-4786-4af4-af6f-147fee111c0e" + + weight = (known after apply) + } + + # vkcs_lb_member.web[1] will be created + + resource "vkcs_lb_member" "web" { + + address = (known after apply) + + admin_state_up = true + + id = (known after apply) + + name = "web-member-2" + + pool_id = "adb79d6a-050e-47a1-bad6-14fa449f82c3" + + protocol_port = 80 + + region = (known after apply) + + subnet_id = "22705726-4786-4af4-af6f-147fee111c0e" + + weight = (known after apply) + } + + # vkcs_networking_port.bastion_port will be created + + resource "vkcs_networking_port" "bastion_port" { + + admin_state_up = true + + all_fixed_ips = (known after apply) + + all_security_group_ids = (known after apply) + + all_tags = (known after apply) + + device_id = (known after apply) + + device_owner = (known after apply) + + dns_assignment = (known after apply) + + dns_name = (known after apply) + + full_security_groups_control = false + + id = (known after apply) + + mac_address = (known after apply) + + name = "bastion-port" + + network_id = "b15fd639-9579-4c28-b7b3-930bb27e4ef6" + + port_security_enabled = true + + region = (known after apply) + + sdn = (known after apply) + + security_group_ids = [ + + "0768aff4-79ef-46bb-856f-b1fb7fbb2f3c", + ] + + + fixed_ip { + + subnet_id = "271affb0-b5b6-45bc-b1ed-5c777425b5cb" + } + } + + # vkcs_networking_port.web_port[0] will be created + + resource "vkcs_networking_port" "web_port" { + + admin_state_up = true + + all_fixed_ips = (known after apply) + + all_security_group_ids = (known after apply) + + all_tags = (known after apply) + + device_id = (known after apply) + + device_owner = (known after apply) + + dns_assignment = (known after apply) + + dns_name = (known after apply) + + full_security_groups_control = false + + id = (known after apply) + + mac_address = (known after apply) + + name = "web-port-1" + + network_id = "b15fd639-9579-4c28-b7b3-930bb27e4ef6" + + port_security_enabled = true + + region = (known after apply) + + sdn = (known after apply) + + security_group_ids = [ + + "50fa7409-ab08-40d0-b348-740b40d6ae69", + ] + + + fixed_ip { + + subnet_id = "22705726-4786-4af4-af6f-147fee111c0e" + } + } + + # vkcs_networking_port.web_port[1] will be created + + resource "vkcs_networking_port" "web_port" { + + admin_state_up = true + + all_fixed_ips = (known after apply) + + all_security_group_ids = (known after apply) + + all_tags = (known after apply) + + device_id = (known after apply) + + device_owner = (known after apply) + + dns_assignment = (known after apply) + + dns_name = (known after apply) + + full_security_groups_control = false + + id = (known after apply) + + mac_address = (known after apply) + + name = "web-port-2" + + network_id = "b15fd639-9579-4c28-b7b3-930bb27e4ef6" + + port_security_enabled = true + + region = (known after apply) + + sdn = (known after apply) + + security_group_ids = [ + + "50fa7409-ab08-40d0-b348-740b40d6ae69", + ] + + + fixed_ip { + + subnet_id = "22705726-4786-4af4-af6f-147fee111c0e" + } + } + +Plan: 9 to add, 0 to change, 0 to destroy. + +Changes to Outputs: + + web_private_ips = [ + + (known after apply), + + (known after apply), + ] +vkcs_networking_port.web_port[1]: Creating... +vkcs_networking_port.web_port[0]: Creating... +vkcs_networking_port.bastion_port: Creating... +vkcs_networking_port.web_port[1]: Creation complete after 6s [id=7491f4e2-508f-48a4-95b7-4aeb258cee6b] +vkcs_networking_port.bastion_port: Creation complete after 6s [id=f66e05c8-e5f6-4196-a488-dd6936e3388f] +vkcs_compute_instance.bastion: Creating... +vkcs_networking_port.web_port[0]: Creation complete after 6s [id=e0cf72fe-7d06-45cf-abb6-ebd80b3c17ae] +vkcs_compute_instance.web[1]: Creating... +vkcs_compute_instance.web[0]: Creating... +vkcs_compute_instance.bastion: Still creating... [00m10s elapsed] +vkcs_compute_instance.web[0]: Still creating... [00m10s elapsed] +vkcs_compute_instance.web[1]: Still creating... [00m10s elapsed] +vkcs_compute_instance.bastion: Still creating... [00m20s elapsed] +vkcs_compute_instance.web[0]: Still creating... [00m20s elapsed] +vkcs_compute_instance.web[1]: Still creating... [00m20s elapsed] +vkcs_compute_instance.bastion: Still creating... [00m30s elapsed] +vkcs_compute_instance.web[0]: Still creating... [00m30s elapsed] +vkcs_compute_instance.web[1]: Still creating... [00m30s elapsed] +vkcs_compute_instance.web[1]: Creation complete after 33s [id=8599c91f-2d68-4d93-92f3-6cc52d72de6d] +vkcs_compute_instance.bastion: Still creating... [00m40s elapsed] +vkcs_compute_instance.web[0]: Still creating... [00m40s elapsed] +vkcs_compute_instance.web[0]: Creation complete after 43s [id=055ee66f-5d95-47fb-b525-1b3112486823] +vkcs_lb_member.web[1]: Creating... +vkcs_lb_member.web[0]: Creating... +vkcs_compute_instance.bastion: Still creating... [00m50s elapsed] +vkcs_lb_member.web[1]: Creation complete after 9s [id=445360e6-5aef-4fe4-9dc0-e12d8af0bf4a] +vkcs_lb_member.web[0]: Still creating... [00m10s elapsed] +vkcs_lb_member.web[0]: Creation complete after 15s [id=201143b2-4356-403d-aecc-0bb9118c948d] +vkcs_compute_instance.bastion: Still creating... [01m00s elapsed] +vkcs_compute_instance.bastion: Still creating... [01m10s elapsed] +vkcs_compute_instance.bastion: Still creating... [01m20s elapsed] +vkcs_compute_instance.bastion: Still creating... [01m30s elapsed] +vkcs_compute_instance.bastion: Still creating... [01m40s elapsed] +vkcs_compute_instance.bastion: Still creating... [01m50s elapsed] +vkcs_compute_instance.bastion: Still creating... [02m00s elapsed] +vkcs_compute_instance.bastion: Still creating... [02m10s elapsed] +vkcs_compute_instance.bastion: Still creating... [02m20s elapsed] +vkcs_compute_instance.bastion: Still creating... [02m30s elapsed] +vkcs_compute_instance.bastion: Still creating... [02m40s elapsed] +vkcs_compute_instance.bastion: Still creating... [02m50s elapsed] +vkcs_compute_instance.bastion: Still creating... [03m00s elapsed] +vkcs_compute_instance.bastion: Still creating... [03m10s elapsed] +vkcs_compute_instance.bastion: Still creating... [03m20s elapsed] +vkcs_compute_instance.bastion: Still creating... [03m30s elapsed] +vkcs_compute_instance.bastion: Still creating... [03m40s elapsed] +vkcs_compute_instance.bastion: Still creating... [03m50s elapsed] +vkcs_compute_instance.bastion: Still creating... [04m00s elapsed] +vkcs_compute_instance.bastion: Still creating... [04m10s elapsed] +vkcs_compute_instance.bastion: Still creating... [04m20s elapsed] +vkcs_compute_instance.bastion: Still creating... [04m30s elapsed] +vkcs_compute_instance.bastion: Still creating... [04m40s elapsed] +vkcs_compute_instance.bastion: Still creating... [04m50s elapsed] +vkcs_compute_instance.bastion: Still creating... [05m00s elapsed] +vkcs_compute_instance.bastion: Still creating... [05m10s elapsed] +vkcs_compute_instance.bastion: Still creating... [05m20s elapsed] +vkcs_compute_instance.bastion: Still creating... [05m30s elapsed] +vkcs_compute_instance.bastion: Still creating... [05m40s elapsed] +vkcs_compute_instance.bastion: Still creating... [05m50s elapsed] +vkcs_compute_instance.bastion: Still creating... [06m00s elapsed] +vkcs_compute_instance.bastion: Still creating... [06m10s elapsed] +vkcs_compute_instance.bastion: Still creating... [06m20s elapsed] +vkcs_compute_instance.bastion: Still creating... [06m30s elapsed] +vkcs_compute_instance.bastion: Still creating... [06m40s elapsed] +vkcs_compute_instance.bastion: Still creating... [06m50s elapsed] +vkcs_compute_instance.bastion: Still creating... [07m00s elapsed] +vkcs_compute_instance.bastion: Still creating... [07m10s elapsed] +vkcs_compute_instance.bastion: Still creating... [07m20s elapsed] +vkcs_compute_instance.bastion: Still creating... [07m30s elapsed] +vkcs_compute_instance.bastion: Still creating... [07m40s elapsed] +vkcs_compute_instance.bastion: Still creating... [07m50s elapsed] +vkcs_compute_instance.bastion: Still creating... [08m00s elapsed] +vkcs_compute_instance.bastion: Still creating... [08m10s elapsed] +vkcs_compute_instance.bastion: Still creating... [08m20s elapsed] +vkcs_compute_instance.bastion: Still creating... [08m30s elapsed] +vkcs_compute_instance.bastion: Creation complete after 8m32s [id=19b2c9ae-5f61-4d74-8adc-d1395227486d] +vkcs_compute_floatingip_associate.bastion_fip_assoc: Creating... +vkcs_compute_floatingip_associate.bastion_fip_assoc: Creation complete after 3s [id=95.163.215.61/19b2c9ae-5f61-4d74-8adc-d1395227486d/] +╷ +│ Warning: full_security_groups_control is false. This is deprecated configuration which leads to unspecified behavior on port's security group changing. Please set full_security_groups_control to true. +│ +│ with vkcs_networking_port.bastion_port, +│ on VKC_LR_02_tf_packer_compute_РемизовКЛ_20260617.tf line 8, in resource "vkcs_networking_port" "bastion_port": +│ 8: resource "vkcs_networking_port" "bastion_port" { +│ +│ (and 2 more similar warnings elsewhere) +╵ + +Apply complete! Resources: 9 added, 0 changed, 0 destroyed. + +Outputs: + +bastion_public_ip = "95.163.215.61" +lb_public_ip = "10.0.1.9" +web_private_ips = [ + "10.0.2.148", + "10.0.2.149", +] diff --git a/02_evidence/VKC_LR_02_tf_packer_tflog2_РемизовКЛ_20260617.log b/02_evidence/VKC_LR_02_tf_packer_tflog2_РемизовКЛ_20260617.log new file mode 100644 index 0000000..9909093 --- /dev/null +++ b/02_evidence/VKC_LR_02_tf_packer_tflog2_РемизовКЛ_20260617.log @@ -0,0 +1,104 @@ +data.vkcs_networking_network.ext_net: Reading... +data.vkcs_networking_router.existing: Reading... +vkcs_networking_floatingip.bastion_fip: Refreshing state... [id=31806272-e423-44d6-b717-0ebc30aa49b8] +vkcs_networking_secgroup.web_sg: Refreshing state... [id=50fa7409-ab08-40d0-b348-740b40d6ae69] +vkcs_networking_network.lab1_vpc: Refreshing state... [id=b15fd639-9579-4c28-b7b3-930bb27e4ef6] +vkcs_compute_keypair.my_key: Refreshing state... [id=terraform-key-local] +vkcs_networking_secgroup.bastion_sg: Refreshing state... [id=0768aff4-79ef-46bb-856f-b1fb7fbb2f3c] +vkcs_networking_secgroup.lb_sg: Refreshing state... [id=b19e5742-3242-43cc-b9dc-a1f3c8c85548] +vkcs_networking_secgroup_rule.lb_http: Refreshing state... [id=0ec567fb-2f84-4ea4-a46d-508f8fd580b4] +data.vkcs_networking_router.existing: Read complete after 0s [id=913bdd47-9155-45b2-b404-5c10d0086132] +vkcs_networking_secgroup_rule.bastion_ssh: Refreshing state... [id=8187bc9a-26d2-4064-b342-9bb717421c5e] +vkcs_networking_subnet.public: Refreshing state... [id=271affb0-b5b6-45bc-b1ed-5c777425b5cb] +vkcs_networking_subnet.private: Refreshing state... [id=22705726-4786-4af4-af6f-147fee111c0e] +vkcs_networking_secgroup_rule.web_ssh: Refreshing state... [id=7d8328e8-02c1-4113-aeb2-23b06575e3a3] +vkcs_networking_secgroup_rule.web_http: Refreshing state... [id=82da250c-d494-4168-987c-83f0812356dd] +vkcs_networking_router_interface.private: Refreshing state... [id=abc484dc-d97a-4df7-b573-043c8c788d06] +vkcs_networking_port.web_port[0]: Refreshing state... [id=e0cf72fe-7d06-45cf-abb6-ebd80b3c17ae] +vkcs_networking_port.web_port[1]: Refreshing state... [id=7491f4e2-508f-48a4-95b7-4aeb258cee6b] +vkcs_networking_router_interface.public: Refreshing state... [id=ba96e156-ecca-46a3-9306-979725d30437] +vkcs_lb_loadbalancer.main: Refreshing state... [id=211106b0-417f-4321-a65d-3a28af8911c9] +vkcs_networking_port.bastion_port: Refreshing state... [id=f66e05c8-e5f6-4196-a488-dd6936e3388f] +data.vkcs_networking_network.ext_net: Read complete after 1s [id=ec8c610e-6387-447e-83d2-d2c541e88164] +vkcs_lb_listener.http: Refreshing state... [id=2e2fce60-1216-4711-a269-d52ae59f74a7] +vkcs_compute_instance.bastion: Refreshing state... [id=19b2c9ae-5f61-4d74-8adc-d1395227486d] +vkcs_compute_instance.web[0]: Refreshing state... [id=055ee66f-5d95-47fb-b525-1b3112486823] +vkcs_compute_instance.web[1]: Refreshing state... [id=8599c91f-2d68-4d93-92f3-6cc52d72de6d] +vkcs_lb_pool.web: Refreshing state... [id=adb79d6a-050e-47a1-bad6-14fa449f82c3] +vkcs_lb_monitor.web: Refreshing state... [id=04a25279-9b2a-4643-a7e5-f113bca62b5d] +vkcs_lb_member.web[0]: Refreshing state... [id=201143b2-4356-403d-aecc-0bb9118c948d] +vkcs_lb_member.web[1]: Refreshing state... [id=445360e6-5aef-4fe4-9dc0-e12d8af0bf4a] +vkcs_compute_floatingip_associate.bastion_fip_assoc: Refreshing state... [id=95.163.215.61/19b2c9ae-5f61-4d74-8adc-d1395227486d/] + +Terraform used the selected providers to generate the following execution +plan. Resource actions are indicated with the following symbols: + + create + +Terraform will perform the following actions: + + # vkcs_db_instance.postgres will be created + + resource "vkcs_db_instance" "postgres" { + + availability_zone = "MS1" + + flavor_id = "2d9866a9-e955-4986-b00a-340ca54b2cac" + + id = (known after apply) + + ip = (known after apply) + + name = "lab1-postgres" + + region = (known after apply) + + root_password = (sensitive value) + + size = 10 + + volume_type = "ceph-ssd" + + + datastore { + + type = "postgresql" + + version = "15" + } + + + disk_autoexpand { + + autoexpand = true + + max_disk_size = 100 + } + + + network { + + uuid = "b15fd639-9579-4c28-b7b3-930bb27e4ef6" + } + } + +Plan: 1 to add, 0 to change, 0 to destroy. +vkcs_db_instance.postgres: Creating... +vkcs_db_instance.postgres: Still creating... [00m10s elapsed] +vkcs_db_instance.postgres: Still creating... [00m20s elapsed] +vkcs_db_instance.postgres: Still creating... [00m30s elapsed] +vkcs_db_instance.postgres: Still creating... [00m40s elapsed] +vkcs_db_instance.postgres: Still creating... [00m50s elapsed] +vkcs_db_instance.postgres: Still creating... [01m00s elapsed] +vkcs_db_instance.postgres: Still creating... [01m10s elapsed] +vkcs_db_instance.postgres: Still creating... [01m20s elapsed] +vkcs_db_instance.postgres: Still creating... [01m30s elapsed] +vkcs_db_instance.postgres: Still creating... [01m40s elapsed] +vkcs_db_instance.postgres: Still creating... [01m50s elapsed] +vkcs_db_instance.postgres: Still creating... [02m00s elapsed] +vkcs_db_instance.postgres: Still creating... [02m10s elapsed] +vkcs_db_instance.postgres: Still creating... [02m20s elapsed] +vkcs_db_instance.postgres: Still creating... [02m30s elapsed] +vkcs_db_instance.postgres: Still creating... [02m40s elapsed] +vkcs_db_instance.postgres: Creation complete after 2m46s [id=c977e03c-06d0-4139-808d-a635713ee9fc] +╷ +│ Warning: full_security_groups_control is false. This is deprecated configuration which leads to unspecified behavior on port's security group changing. Please set full_security_groups_control to true. +│  +│  with vkcs_networking_port.bastion_port, +│  on VKC_LR_02_tf_packer_compute_РемизовКЛ_20260617.tf line 8, in resource "vkcs_networking_port" "bastion_port": +│  8: resource "vkcs_networking_port" "bastion_port" { +│  +│ (and 2 more similar warnings elsewhere) +╵ + +Apply complete! Resources: 1 added, 0 changed, 0 destroyed. + +Outputs: + +bastion_public_ip = "95.163.215.61" +lb_public_ip = "10.0.1.9" +web_private_ips = [ + "10.0.2.148", + "10.0.2.149", +] diff --git a/03_code/VKC_LR_02_tf_packer_backend_РемизовКЛ_20260617.tf b/03_code/VKC_LR_02_tf_packer_backend_РемизовКЛ_20260617.tf new file mode 100644 index 0000000..ea04f84 --- /dev/null +++ b/03_code/VKC_LR_02_tf_packer_backend_РемизовКЛ_20260617.tf @@ -0,0 +1,16 @@ +terraform { + backend "s3" { + bucket = "terraform-state-lab2" # замените на имя вашего бакета + key = "lab2/terraform.tfstate" + region = "RegionOne" + endpoint = "https://hb.vkcloud-storage.ru" + + skip_region_validation = true + skip_credentials_validation = true + skip_requesting_account_id = true + skip_metadata_api_check = true + + access_key = "" + secret_key = "" + } +} diff --git a/03_code/VKC_LR_02_tf_packer_compute_РемизовКЛ_20260617.tf b/03_code/VKC_LR_02_tf_packer_compute_РемизовКЛ_20260617.tf new file mode 100644 index 0000000..4d2f980 --- /dev/null +++ b/03_code/VKC_LR_02_tf_packer_compute_РемизовКЛ_20260617.tf @@ -0,0 +1,61 @@ +resource "vkcs_compute_keypair" "my_key" { + name = var.keypair_name + public_key = file(var.ssh_public_key_path) +} + +resource "vkcs_networking_port" "bastion_port" { + name = "bastion-port" + network_id = vkcs_networking_network.lab1_vpc.id + admin_state_up = true + + fixed_ip { + subnet_id = vkcs_networking_subnet.public.id + } + + security_group_ids = [vkcs_networking_secgroup.bastion_sg.id] +} + +resource "vkcs_compute_instance" "bastion" { + name = "bastion" + flavor_id = var.flavor_bastion + image_id = var.ubuntu_image_id + key_pair = vkcs_compute_keypair.my_key.name + + network { + port = vkcs_networking_port.bastion_port.id + } +} + +resource "vkcs_networking_floatingip" "bastion_fip" { + pool = "internet" +} + +resource "vkcs_compute_floatingip_associate" "bastion_fip_assoc" { + floating_ip = vkcs_networking_floatingip.bastion_fip.address + instance_id = vkcs_compute_instance.bastion.id +} + +resource "vkcs_networking_port" "web_port" { + count = 2 + name = "web-port-${count.index + 1}" + network_id = vkcs_networking_network.lab1_vpc.id + admin_state_up = true + + fixed_ip { + subnet_id = vkcs_networking_subnet.private.id + } + + security_group_ids = [vkcs_networking_secgroup.web_sg.id] +} + +resource "vkcs_compute_instance" "web" { + count = 2 + name = "web-${count.index + 1}" + flavor_id = var.flavor_web + image_id = var.image_packer_id + key_pair = vkcs_compute_keypair.my_key.name + + network { + port = vkcs_networking_port.web_port[count.index].id + } +} diff --git a/03_code/VKC_LR_02_tf_packer_database_РемизовКЛ_20260617.tf b/03_code/VKC_LR_02_tf_packer_database_РемизовКЛ_20260617.tf new file mode 100644 index 0000000..0249dee --- /dev/null +++ b/03_code/VKC_LR_02_tf_packer_database_РемизовКЛ_20260617.tf @@ -0,0 +1,26 @@ +resource "vkcs_db_instance" "postgres" { + name = "lab1-postgres" + flavor_id = var.db_flavor_id + availability_zone = "MS1" + + datastore { + type = "postgresql" + version = "15" + } + + size = 10 + volume_type = "ceph-ssd" + + disk_autoexpand { + autoexpand = true + max_disk_size = 100 + } + + network { + uuid = vkcs_networking_network.lab1_vpc.id + } + + depends_on = [ + vkcs_networking_router_interface.private, + ] +} diff --git a/03_code/VKC_LR_02_tf_packer_loadbalancer_РемизовКЛ_20260617.tf b/03_code/VKC_LR_02_tf_packer_loadbalancer_РемизовКЛ_20260617.tf new file mode 100644 index 0000000..8de1ef3 --- /dev/null +++ b/03_code/VKC_LR_02_tf_packer_loadbalancer_РемизовКЛ_20260617.tf @@ -0,0 +1,37 @@ +resource "vkcs_lb_loadbalancer" "main" { + name = "lab1-lb" + vip_subnet_id = vkcs_networking_subnet.public.id +} + +resource "vkcs_lb_listener" "http" { + name = "http-listener" + protocol = "HTTP" + protocol_port = 80 + loadbalancer_id = vkcs_lb_loadbalancer.main.id +} + +resource "vkcs_lb_pool" "web" { + name = "web-targets" + protocol = "HTTP" + lb_method = "ROUND_ROBIN" + listener_id = vkcs_lb_listener.http.id +} + +resource "vkcs_lb_monitor" "web" { + name = "web-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 = "web-member-${count.index + 1}" + address = vkcs_compute_instance.web[count.index].network[0].fixed_ip_v4 # берём IP из ВМ + protocol_port = 80 + pool_id = vkcs_lb_pool.web.id + subnet_id = vkcs_networking_subnet.private.id +} diff --git a/03_code/VKC_LR_02_tf_packer_network_РемизовКЛ_20260617.tf b/03_code/VKC_LR_02_tf_packer_network_РемизовКЛ_20260617.tf new file mode 100644 index 0000000..7accc56 --- /dev/null +++ b/03_code/VKC_LR_02_tf_packer_network_РемизовКЛ_20260617.tf @@ -0,0 +1,36 @@ +data "vkcs_networking_network" "ext_net" { + name = "internet" +} + +data "vkcs_networking_router" "existing" { + id = "913bdd47-9155-45b2-b404-5c10d0086132" +} + +resource "vkcs_networking_network" "lab1_vpc" { + name = "lab1-vpc" + admin_state_up = true +} + +resource "vkcs_networking_subnet" "public" { + name = "lab1-public" + network_id = vkcs_networking_network.lab1_vpc.id + cidr = "10.0.1.0/24" + dns_nameservers = ["8.8.8.8", "8.8.4.4"] +} + +resource "vkcs_networking_subnet" "private" { + name = "lab1-private" + network_id = vkcs_networking_network.lab1_vpc.id + cidr = "10.0.2.0/24" + dns_nameservers = ["8.8.8.8", "8.8.4.4"] +} + +resource "vkcs_networking_router_interface" "public" { + router_id = data.vkcs_networking_router.existing.id + subnet_id = vkcs_networking_subnet.public.id +} + +resource "vkcs_networking_router_interface" "private" { + router_id = data.vkcs_networking_router.existing.id + subnet_id = vkcs_networking_subnet.private.id +} diff --git a/03_code/VKC_LR_02_tf_packer_outputs_РемизовКЛ_20260617.tf b/03_code/VKC_LR_02_tf_packer_outputs_РемизовКЛ_20260617.tf new file mode 100644 index 0000000..a2c8b08 --- /dev/null +++ b/03_code/VKC_LR_02_tf_packer_outputs_РемизовКЛ_20260617.tf @@ -0,0 +1,13 @@ +output "lb_public_ip" { + value = vkcs_lb_loadbalancer.main.vip_address + description = "Публичный IP балансировщика" +} + +output "bastion_public_ip" { + value = vkcs_networking_floatingip.bastion_fip.address +} + +output "web_private_ips" { + value = vkcs_compute_instance.web[*].network[0].fixed_ip_v4 + description = "Приватные IP веб-серверов" +} diff --git a/03_code/VKC_LR_02_tf_packer_packer-config_РемизовКЛ_20260516.pkr.hcl b/03_code/VKC_LR_02_tf_packer_packer-config_РемизовКЛ_20260516.pkr.hcl new file mode 100644 index 0000000..81a99b9 --- /dev/null +++ b/03_code/VKC_LR_02_tf_packer_packer-config_РемизовКЛ_20260516.pkr.hcl @@ -0,0 +1,26 @@ +# Переменные окружения +variable "network_id" { + type = string + default = env("NETWORK_ID") +} +variable "source_image" { + type = string + default = env("SOURCE_IMAGE") +} + +source "openstack" "ubuntu-nginx" { + flavor = "STD3-2-6" + source_image = var.source_image + networks = [var.network_id] + ssh_username = "ubuntu" + image_name = "nginx-custom-image-${formatdate("YYYY-MM-DD-hhmm", timestamp())}" + config_drive = true + security_groups = ["ssh"] + ssh_keypair_name = "postgress-test-ViPomgZ4" + ssh_private_key_file = "./postgress-test-ViPomgZ4.pem" + ssh_timeout = "10m" +} + +build { + sources = ["source.openstack.ubuntu-nginx"] +} diff --git a/03_code/VKC_LR_02_tf_packer_provider_РемизовКЛ_20260617.tf b/03_code/VKC_LR_02_tf_packer_provider_РемизовКЛ_20260617.tf new file mode 100644 index 0000000..ab112bc --- /dev/null +++ b/03_code/VKC_LR_02_tf_packer_provider_РемизовКЛ_20260617.tf @@ -0,0 +1,9 @@ +terraform { + required_providers { + vkcs = { + source = "vk-cs/vkcs" + } + } +} + +provider "vkcs" {} diff --git a/03_code/VKC_LR_02_tf_packer_security_РемизовКЛ_20260617.tf b/03_code/VKC_LR_02_tf_packer_security_РемизовКЛ_20260617.tf new file mode 100644 index 0000000..73de2a4 --- /dev/null +++ b/03_code/VKC_LR_02_tf_packer_security_РемизовКЛ_20260617.tf @@ -0,0 +1,46 @@ +resource "vkcs_networking_secgroup" "bastion_sg" { + name = "bastion-sg" + description = "SSH from my IP" +} +resource "vkcs_networking_secgroup_rule" "bastion_ssh" { + direction = "ingress" + protocol = "tcp" + port_range_min = 22 + port_range_max = 22 + remote_ip_prefix = var.my_ip + security_group_id = vkcs_networking_secgroup.bastion_sg.id +} + +resource "vkcs_networking_secgroup" "web_sg" { + name = "web-sg" + description = "SSH from bastion, HTTP from LB" +} +resource "vkcs_networking_secgroup_rule" "web_ssh" { + direction = "ingress" + protocol = "tcp" + port_range_min = 22 + port_range_max = 22 + remote_group_id = vkcs_networking_secgroup.bastion_sg.id + security_group_id = vkcs_networking_secgroup.web_sg.id +} +resource "vkcs_networking_secgroup_rule" "web_http" { + direction = "ingress" + protocol = "tcp" + port_range_min = 80 + port_range_max = 80 + remote_group_id = vkcs_networking_secgroup.lb_sg.id + security_group_id = vkcs_networking_secgroup.web_sg.id +} + +resource "vkcs_networking_secgroup" "lb_sg" { + name = "lb-sg" + description = "HTTP from internet" +} +resource "vkcs_networking_secgroup_rule" "lb_http" { + direction = "ingress" + protocol = "tcp" + port_range_min = 80 + port_range_max = 80 + remote_ip_prefix = "0.0.0.0/0" + security_group_id = vkcs_networking_secgroup.lb_sg.id +} diff --git a/03_code/VKC_LR_02_tf_packer_variables_РемизовКЛ_20260617.tf b/03_code/VKC_LR_02_tf_packer_variables_РемизовКЛ_20260617.tf new file mode 100644 index 0000000..fa4b517 --- /dev/null +++ b/03_code/VKC_LR_02_tf_packer_variables_РемизовКЛ_20260617.tf @@ -0,0 +1,44 @@ +variable "my_ip" { + type = string + default = "95.26.148.233/32" +} + +variable "flavor_web" { + type = string + default = "25ae869c-be29-4840-8e12-99e046d2dbd4" +} + +variable "flavor_bastion" { + type = string + default = "df3c499a-044f-41d2-8612-d303adc613cc" +} + +variable "image_packer_id" { + type = string + default = "a31acc16-4703-468b-bc5b-bf07952f66b2" +} + +variable "ubuntu_image_name" { + type = string + default = "ubuntu-22-202602051629.gite7a38aaf" +} + +variable "ssh_public_key_path" { + type = string + default = "~/.ssh/id_rsa.pub" +} + +variable "keypair_name" { + type = string + default = "terraform-key-local" +} + +variable "ubuntu_image_id" { + type = string + default = "a4e699d3-a66d-45e5-bb5d-70ea7c8de62d" +} + +variable "db_flavor_id" { + type = string + default = "2d9866a9-e955-4986-b00a-340ca54b2cac" +}