add: documentation
This commit is contained in:
@@ -0,0 +1,368 @@
|
||||
# Начало работы с Nubes Terraform
|
||||
|
||||
Это руководство поможет вам установить инструменты, настроить доступ и развернуть вашу первую инфраструктуру в облаке Nubes, используя Terraform.
|
||||
|
||||
## 0. Установка Terraform
|
||||
|
||||
Для работы с инфраструктурой как кодом (IaC) потребуется утилита Terraform (версии 1.0 или выше).
|
||||
|
||||
1. **Скачивание**:
|
||||
* Официальный сайт: [hashicorp.com/terraform/install](https://developer.hashicorp.com/terraform/install)
|
||||
* *Для пользователей из РФ (без VPN):* [Yandex Cloud Mirror](https://hashicorp-releases.yandexcloud.net/terraform/)
|
||||
2. **Установка**:
|
||||
* Распакуйте скачанный архив.
|
||||
* Поместите исполняемый файл (`terraform` или `terraform.exe`) в папку, доступную в переменной окружения `PATH`.
|
||||
3. **Проверка**:
|
||||
* Откройте терминал (PowerShell, CMD, Bash или Terminal в macOS).
|
||||
* Введите команду `terraform -version`. Вы должны увидеть номер версии.
|
||||
|
||||
## 1. Подготовка конфигурации
|
||||
|
||||
Создайте рабочую директорию для вашего проекта и создайте основной файл конфигурации `main.tf`.
|
||||
|
||||
```hcl title="main.tf"
|
||||
terraform {
|
||||
required_providers {
|
||||
nubes = {
|
||||
source = "terra.k8c.ru/nubes/nubes"
|
||||
version = "2.1.23" # Поставьте нужную вам версию провайдера
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
provider "nubes" {
|
||||
api_endpoint = "https://deck-api.ngcloud.ru/api/v1/index.cfm"
|
||||
api_token = var.api_token
|
||||
}
|
||||
|
||||
variable "api_token" {
|
||||
type = string
|
||||
sensitive = true
|
||||
}
|
||||
```
|
||||
|
||||
!!! info "TEST стенд (обязательные адреса)"
|
||||
Эта документация относится к TEST стенду.
|
||||
|
||||
- Личный кабинет: https://deck-test.ngcloud.ru/dashboard/
|
||||
- API endpoint: https://deck-api-test.ngcloud.ru/api/v1
|
||||
|
||||
!!! tip "Безопасность"
|
||||
Никогда не храните токен прямо в файле `main.tf`, если планируете загружать код в систему контроля версий (git). Используйте `variables.tf` или файл `terraform.tfvars`.
|
||||
|
||||
## 2. Получение API токена
|
||||
|
||||
Токен (Access Token) необходим провайдеру для авторизации ваших действий в облаке.
|
||||
|
||||
Если нет ТОКЕНА доступа или хотите создать новый -
|
||||
В Личном Кабинете - на странице Профиля пользователя https://deck.ngcloud.ru/authorization/profile
|
||||
во вкладке Токены - нажать "Выпустить тех-токен"
|
||||
Значение токена показывается только при его создании, надо его сохранить
|
||||
|
||||
Создайте файл `terraform.tfvars` и сохраните токен там:
|
||||
|
||||
```hcl title="terraform.tfvars"
|
||||
api_token = "eyJhbGciOiJ..." # Ваш длинный токен
|
||||
```
|
||||
|
||||
## 3. Описание ресурсов
|
||||
|
||||
Добавьте ресурсы, которые вы хотите создать, в файл `main.tf` или `resources.tf`.
|
||||
|
||||
Пример создания S3 бакета:
|
||||
|
||||
```hcl
|
||||
resource "nubes_s3bucket" "my_files" {
|
||||
resource_name = "bucket_0"
|
||||
bucket_name = "my-unique-bucket-name"
|
||||
s3_user_uid = "235e0546-..." # UID Корневой услуги S3
|
||||
}
|
||||
```
|
||||
|
||||
Или Postgres кластера:
|
||||
|
||||
```hcl
|
||||
resource "nubes_postgres" "db" {
|
||||
resource_name = "pg-tst0"
|
||||
resource_realm = "k8s-3.ext.nubes.ru" # Платформа развертывания
|
||||
s3_uid = "235e0546-..." # UUID услуги S3 для бэкапов
|
||||
|
||||
resource_c_p_u = 2000 # 2 vCPU (в милликорах)
|
||||
resource_memory = 4096 # 4 GB (в МБ)
|
||||
resource_disk = "20" # 20 GB
|
||||
resource_instances = 1
|
||||
}
|
||||
```
|
||||
|
||||
Подробные примеры конфигураций смотрите в разделе **Resources** документации.
|
||||
|
||||
## 4. Запуск
|
||||
|
||||
Теперь вы готовы применить конфигурацию:
|
||||
|
||||
1. **Инициализация**: `terraform init` (загружает плагин провайдера).
|
||||
2. **План**: `terraform plan` (показывает, что будет сделано).
|
||||
3. **Применение**: `terraform apply` (создает инфраструктуру).
|
||||
|
||||
## 5. Почему провайдер использует Suspend/Adopt
|
||||
|
||||
Для этой логики используются два флага.
|
||||
|
||||
- `suspend_on_destroy`
|
||||
- `adopt_existing_on_create`
|
||||
|
||||
### `suspend_on_destroy`
|
||||
|
||||
- `true` (по умолчанию)
|
||||
- при `terraform destroy` инстанс уходит в `Suspend`;
|
||||
- при удалении ресурса из манифеста — тоже `Suspend`.
|
||||
- `false`
|
||||
- Terraform удаляет ресурс только из state;
|
||||
- в облаке инстанс не меняется.
|
||||
|
||||
### `adopt_existing_on_create`
|
||||
|
||||
- `false` (по умолчанию)
|
||||
- если инстанс уже существует, Terraform вернёт ошибку.
|
||||
- `true`
|
||||
- Terraform может взять существующий инстанс под управление.
|
||||
|
||||
### Как это связано с `terraform import`
|
||||
|
||||
Это похоже на `terraform import`,
|
||||
но срабатывает в обычном `apply`.
|
||||
|
||||
- найден `running` → `adopt`;
|
||||
- найден `suspended` + обязательные параметры совпадают → `resume + adopt`.
|
||||
|
||||
### Важно
|
||||
|
||||
Один инстанс должен быть только в одном state.
|
||||
|
||||
Если подключить один инстанс
|
||||
к двум манифестам,
|
||||
получится конфликт управления:
|
||||
|
||||
- первый `apply` меняет ресурс;
|
||||
- второй `apply` откатывает
|
||||
или перезаписывает изменения.
|
||||
|
||||
---
|
||||
|
||||
Следующий шаг: изучите [Справочник по командам Terraform](terraform-basics.md) для уверенной работы.
|
||||
|
||||
## Примеры
|
||||
|
||||
### Lucee & Postgress
|
||||
|
||||
Lucee и NodeJS — это два отдельных UI для CRUD‑операций, оба работают с одной и той же таблицей в Postgres.
|
||||
|
||||
```hcl title="resources.tf"
|
||||
resource "nubes_postgres" "db2" {
|
||||
# Основной Postgres-кластер для демо.
|
||||
resource_name = "pg-tst0"
|
||||
s3_uid = "235e0546-..."
|
||||
resource_realm = "k8s-3.ext.nubes.ru" # Платформа развертывания
|
||||
resource_instances = 1
|
||||
resource_memory = 512
|
||||
resource_c_p_u = 500
|
||||
resource_disk = "1"
|
||||
app_version = "17"
|
||||
json_parameters = jsonencode({
|
||||
# Выключаем подробные логи подключений в демо.
|
||||
log_connections = "off"
|
||||
log_disconnections = "off"
|
||||
})
|
||||
enable_pg_pooler_master = false
|
||||
enable_pg_pooler_slave = false
|
||||
allow_no_s_s_l = false
|
||||
auto_scale = false
|
||||
auto_scale_percentage = 10
|
||||
auto_scale_tech_window = 0
|
||||
auto_scale_quota_gb = "1"
|
||||
need_external_address_master = false
|
||||
}
|
||||
|
||||
resource "nubes_lucee" "app1" {
|
||||
# Lucee UI, который читает/пишет в Postgres.
|
||||
resource_name = "lucy1"
|
||||
resource_realm = nubes_postgres.db2.resource_realm
|
||||
domain = "web03" # Пример домена приложения
|
||||
git_path = "https://gitea-naeel.giteak8s.services.ngcloud.ru/naeel/testlucee.git"
|
||||
|
||||
json_env = jsonencode({
|
||||
# JDBC datasource для Lucee.
|
||||
testds_class = "org.postgresql.Driver"
|
||||
testds_bundleName = "org.postgresql.jdbc"
|
||||
testds_bundleVersion = "42.6.0"
|
||||
testds_connectionString = "jdbc:postgresql://${nubes_postgres.db2.state_out_flat["internalConnect.master"]}:5432/postgres"
|
||||
testds_username = nubes_postgres.db2.vault_secrets["adminUser"]
|
||||
testds_password = nubes_postgres.db2.vault_secrets["adminPass"]
|
||||
testds_connectionLimit = "5"
|
||||
testds_liveTimeout = "15"
|
||||
testds_validate = "false"
|
||||
})
|
||||
|
||||
resource_c_p_u = 300
|
||||
resource_memory = 512
|
||||
resource_instances = 1
|
||||
app_version = "5.4"
|
||||
|
||||
depends_on = [nubes_postgres.db2]
|
||||
}
|
||||
|
||||
resource "nubes_nodejs" "app3" {
|
||||
# NodeJS демо, работающий с тем же Postgres.
|
||||
resource_name = "node_0"
|
||||
resource_realm = nubes_postgres.db2.resource_realm
|
||||
domain = "node"
|
||||
git_path = "https://gitea-naeel.giteak8s.services.ngcloud.ru/naeel/testnode.git"
|
||||
health_path = "/healthz"
|
||||
app_version = "23"
|
||||
|
||||
json_env = jsonencode({
|
||||
# Переменные подключения к Postgres.
|
||||
PGHOST = nubes_postgres.db2.state_out_flat["internalConnect.master"]
|
||||
PGPORT = "5432"
|
||||
PGUSER = nubes_postgres.db2.vault_secrets["adminUser"]
|
||||
PGPASSWORD = nubes_postgres.db2.vault_secrets["adminPass"]
|
||||
PGSSLMODE = "require"
|
||||
DATABASE_URL = format(
|
||||
"postgresql://%s:%s@%s:5432/postgres",
|
||||
nubes_postgres.db2.vault_secrets["adminUser"],
|
||||
nubes_postgres.db2.vault_secrets["adminPass"],
|
||||
nubes_postgres.db2.state_out_flat["internalConnect.master"]
|
||||
)
|
||||
})
|
||||
|
||||
resource_c_p_u = 300
|
||||
resource_memory = 256
|
||||
resource_instances = 1
|
||||
|
||||
depends_on = [nubes_postgres.db2]
|
||||
}
|
||||
```
|
||||
|
||||
### Пример (PROD_STAND/RABBIT)
|
||||
|
||||
Ниже полный пример `resources.tf` для RabbitMQ + Lucee UI + NodeJS воркера.
|
||||
|
||||
Комментарий: UI Lucee отправляет CRUD‑запросы в RabbitMQ, а применение изменений в Postgres выполняет отдельный воркер на NodeJS.
|
||||
Сервис Postgres должен быть запущен заранее. В данном примере используется Postgres из раздела https://terra.k8c.ru/docs/nubes/nubes/2.1.7/30_registry/guides/getting-started/#lucee-postgress
|
||||
|
||||
```hcl title="resources.tf"
|
||||
# RabbitMQ кластер для демо.
|
||||
resource "nubes_rabbitmq" "rb1" {
|
||||
resource_name = "rabbit_0"
|
||||
resource_realm = "k8s-3.ext.nubes.ru"
|
||||
resource_instances = 1
|
||||
resource_memory = 512
|
||||
resource_c_p_u = 500
|
||||
resource_disk = 5
|
||||
need_external_address_master = false
|
||||
need_external_address_slave = false
|
||||
}
|
||||
|
||||
# Lucee UI, который пишет в Rabbit и читает из Postgres.
|
||||
resource "nubes_lucee" "rabbit_ui" {
|
||||
resource_name = "rb-lucee-ui"
|
||||
resource_realm = "k8s-3.ext.nubes.ru"
|
||||
domain = "rb-ui"
|
||||
app_version = "5.4"
|
||||
git_path = "https://gitea-naeel.giteak8s.services.ngcloud.ru/naeel/rabbit-lsd"
|
||||
resource_c_p_u = 300
|
||||
resource_memory = 512
|
||||
resource_instances = 1
|
||||
|
||||
# Переменные окружения для datasource, Rabbit и UI.
|
||||
json_env = jsonencode({
|
||||
testds_bundleName = "org.postgresql.jdbc"
|
||||
testds_bundleVersion = "42.6.0"
|
||||
testds_class = "org.postgresql.Driver"
|
||||
testds_connectionLimit = "5"
|
||||
testds_connectionString = "jdbc:postgresql://${var.PGHOST}:5432/postgres"
|
||||
testds_liveTimeout = "15"
|
||||
testds_username = var.PGUSER
|
||||
testds_password = var.PGPASSWORD
|
||||
testds_validate = "false"
|
||||
PG_TABLE = "rabbit_messages"
|
||||
UI_LOG_TABLE = "rabbit_ui_log"
|
||||
RABBIT_HOST = try(nubes_rabbitmq.rb1.state_out_flat["internalConnect.master"], nubes_rabbitmq.rb1.state_out_flat["inernalConnect.master"])
|
||||
RABBIT_PORT = "5672"
|
||||
RABBIT_USER = nubes_rabbitmq.rb1.vault_secrets["adminUser"]
|
||||
RABBIT_PASSWORD = nubes_rabbitmq.rb1.vault_secrets["adminPass"]
|
||||
RABBIT_VHOST = "/"
|
||||
RABBIT_QUEUES = "crud_queue"
|
||||
RABBIT_DURABLE = "true"
|
||||
RABBIT_ADMIN_URL = "https://${nubes_rabbitmq.rb1.state_out_flat["externalConnect.admin.fqdn"]}/#/"
|
||||
NODEWORKER_URL = "https://nodeworker.nodejsk8s.services.ngcloud.ru/"
|
||||
})
|
||||
|
||||
depends_on = [nubes_rabbitmq.rb1]
|
||||
}
|
||||
|
||||
# NodeJS воркер, который переносит CRUD из очереди в Postgres.
|
||||
resource "nubes_nodejs" "rabbit_nodeworker" {
|
||||
resource_name = "nodeworker"
|
||||
resource_realm = "k8s-3.ext.nubes.ru"
|
||||
domain = "nodeworker"
|
||||
app_version = "23"
|
||||
git_path = "https://gitea-naeel.giteak8s.services.ngcloud.ru/naeel/rabbit-nodeworker.git"
|
||||
health_path = "/healthz"
|
||||
resource_c_p_u = 100
|
||||
resource_memory = 256
|
||||
resource_instances = 1
|
||||
|
||||
# Параметры подключения к Rabbit и Postgres.
|
||||
json_env = jsonencode({
|
||||
RABBIT_HOST = try(nubes_rabbitmq.rb1.state_out_flat["internalConnect.master"], nubes_rabbitmq.rb1.state_out_flat["inernalConnect.master"])
|
||||
RABBIT_PORT = "5672"
|
||||
RABBIT_USER = nubes_rabbitmq.rb1.vault_secrets["adminUser"]
|
||||
RABBIT_PASSWORD = nubes_rabbitmq.rb1.vault_secrets["adminPass"]
|
||||
RABBIT_VHOST = "/"
|
||||
RABBIT_QUEUES = "crud_queue"
|
||||
RABBIT_DURABLE = "true"
|
||||
RABBIT_PREFETCH = "1"
|
||||
REQUEUE_ON_ERROR = "true"
|
||||
PGHOST = var.PGHOST
|
||||
PGPORT = "5432"
|
||||
PGUSER = var.PGUSER
|
||||
PGPASSWORD = var.PGPASSWORD
|
||||
PGDATABASE = "postgres"
|
||||
PGSSLMODE = "require"
|
||||
PG_TABLE = "rabbit_messages"
|
||||
})
|
||||
|
||||
depends_on = [nubes_rabbitmq.rb1]
|
||||
}
|
||||
|
||||
# Ручной триггер redeploy для воркера.
|
||||
resource "nubes_nodejs_redeploy" "rabbit_nodeworker_redeploy" {
|
||||
nodejs_id = nubes_nodejs.rabbit_nodeworker.id
|
||||
resource_realm = "k8s-3.ext.nubes.ru"
|
||||
run_id = "redeploy-2026-02-23-011"
|
||||
}
|
||||
```
|
||||
|
||||
```hcl title="variables.tf"
|
||||
// Postgres уже запущен, значения берутся из UI Личного кабинета.
|
||||
variable "PGUSER" {
|
||||
type = string
|
||||
default = "postgres"
|
||||
}
|
||||
|
||||
variable "PGPASSWORD" {
|
||||
type = string
|
||||
default = "" # пароль укажите вручную, в примере не публикуем
|
||||
}
|
||||
|
||||
variable "PGHOST" {
|
||||
type = string
|
||||
default = "postgresqlk8s-master.<id>.svc.k8s-3.ext.nubes.ru" # оставьте префикс и суффикс, меняется только <id>
|
||||
}
|
||||
```
|
||||
|
||||
```hcl title="terraform.tfvars"
|
||||
# Инструкция по получению токена: раздел "Получение API токена"
|
||||
api_token = "eyJhbGciOiJ..."
|
||||
```
|
||||
Reference in New Issue
Block a user