27 KiB
AGENTS.md — руководство для ИИ-агентов по репозиторию tf_examples
Этот файл читается ИИ-агентами (GitHub Copilot, Claude, Cursor и др.), которые работают в этом репозитории — репозитории готовых примеров Terraform-провайдера Nubes.
Цель агента: помогать пользователю писать и проверять Terraform-конфигурацию
(main.tf, variables.tf, terraform.tfvars) для провайдера Nubes — правильно и без
выдуманных параметров, не выполняя при этом деплой. terraform plan и terraform apply
запускает только пользователь.
Главное правило: параметры не берутся из памяти модели — они сверяются со схемой ресурса (раздел 2) и с содержимым самих примеров (раздел 6).
0. Кому адресован этот файл
Файл написан для стороннего ИИ-агента, который не знает о предметной области ничего. Если ты такой агент — прочитай файл целиком, прежде чем советовать. Ниже объяснены: базовые понятия Terraform, что такое облако Nubes, как устроены примеры и как правильно помогать пользователю. Все утверждения о параметрах должны опираться на схему (раздел 2) или на содержимое примеров (раздел 6), а не на догадки.
0.1. Базовые понятия Terraform (с нуля)
- Terraform — инструмент «инфраструктура как код» (Infrastructure as Code). Пользователь описывает желаемое состояние облака в текстовых файлах, а Terraform приводит облако к этому состоянию. Ничего не делается руками в интерфейсе — всё описано в коде.
- HCL — язык этих файлов (расширение
.tf). Пример блока ресурса:resource "nubes_postgres" "main_pg" { … } # тип ресурса — nubes_postgres, локальное имя — main_pg - Провайдер — плагин, через который Terraform общается с конкретным облаком. Здесь это
провайдер Nubes; он скачивается автоматически при
terraform init. - Ресурс — объект в облаке (кластер БД, виртуальная машина, бакет и т.п.).
- Переменные объявляются блоком
variable "имя" { … }, а их значения задаются в файлеterraform.tfvars— это то, что заполняет пользователь под свою организацию. - Файл состояния (
terraform.tfstate) хранит соответствие «код ↔ реальные объекты». Его не редактируют вручную. - Команды:
terraform init(скачать провайдер),terraform plan(показать, что изменится, ничего не меняя),terraform apply(применить),terraform destroy(удалить). - Каждый пример — отдельный каталог с собственным состоянием; модули не используются.
0.2. Что такое Nubes
Nubes — облачная платформа, предоставляющая услуги «как сервис»: базы данных (PostgreSQL, MongoDB, Redis, MariaDB, ClickHouse), очереди (Kafka, RabbitMQ), Kubernetes («Штурвал»), виртуализацию VMware (vDC, Edge, виртуальные машины), объектное хранилище S3, готовые приложения (Node.js, Flask, Lucee и др.) и сеть (DNS, внешние IP, SNAT).
- Управляется через Личный кабинет (ЛК) и API. Terraform-провайдер Nubes — обёртка
над этим API: каждая услуга платформы представлена ресурсом
nubes_*. - Ресурсы бывают составными: например, кластер БД (
nubes_postgres) → база (nubes_postgres_database) → пользователь (nubes_postgres_user). Часть ресурсов — модификаторы уже существующих услуг (внешние IP, SNAT). - У ресурса есть операции (создание/удаление/изменение/остановка/запуск). Провайдер сам вызывает нужную операцию по командам Terraform.
- Значения, зависящие от организации (токен, кластер, IP-пространства, домены), задаёт пользователь; они берутся из ЛК.
0.3. Зачем эти примеры и как их используют
Пользователь клонирует репозиторий, копирует terraform.tfvars.example → terraform.tfvars,
заполняет значения из ЛК, затем выполняет terraform init / plan / apply. Пример — это
готовый каркас конфигурации; правки сводятся к значениям и, при необходимости, к именам
ресурсов. Задача агента — помогать на этих шагах, а не выполнять их вместо пользователя.
1. Что это за репозиторий
Здесь лежат законченные сценарии развёртывания инфраструктуры в облаке Nubes через Terraform. Репозиторий — эталонные примеры, на которые ссылается сайт документации.
| Папка | Что это | Состояние | Документация |
|---|---|---|---|
fullpipe_chain/ |
vDC → Edge → внешние IP → SNAT → vApp → ВМ → Штурвал (полная цепочка) | рекомендовано использовать — повторяет рабочую конфигурацию стенда | /nubes-dev/curated/pipeline/vdc_edge_ip_snat/ |
Maria_CRUD/ |
MariaDB + три приложения (Lucee/Flask/Node.js) + HTTP-проверка | проверен на TEST-стенде | /nubes-test/curated/mariadb/three_apps/ |
CRUD/ |
PostgreSQL + три приложения (Lucee/Flask/Node.js) | черновик (устаревшая схема, старый пин провайдера) — с оговорками | /nubes-test/curated/crud/three_apps/ |
modify_resources/ |
внешние IP на организации + SNAT на шлюзе (для уже существующих услуг) | черновик | — |
Что рекомендовать пользователю: fullpipe_chain (полный цикл) или Maria_CRUD
(проверенный CRUD-пример). Остальные папки — черновики от прошлых работ: могут содержать
неактуальные версии провайдера и работать некорректно. Не выдавай черновик за рабочий образец.
2. Источник правды о параметрах (схемы)
Параметры ресурсов НЕ берутся из памяти. Их берут из схемы:
| Источник | Что внутри |
|---|---|
| Страница ресурса на сайте доков | https://tf-docs.nodejsk8s.dev.nubes.ru/<stand>/<service>/ — таблица атрибутов = схема |
| Машиночитаемая схема (JSON) | https://tf-docs.nodejsk8s.dev.nubes.ru/<stand>/schema/<service>.json |
| Локально (если репозиторий внутри провайдера) | ../provider/resources_yaml/*.yaml и ../stack/<stand>/<service>/raw.json |
Структура raw.json / YAML-спеки (поля параметра): name (человеческое имя),
code (машинное имя в API), type (integer/string/map-fixed/…), required,
default, sub_params[], man (описание). Тип ресурса в HCL — это resource_type
(вида nubes_*); поля ресурса — create.params[].
Стенды: nubes-test (тест), nubes-dev (dev), nubes (prod).
3. Инвентарь ресурсов провайдера (nubes_*)
Если пользователь называет ресурс, которого нет в этом списке — его не существует
(например, nubes_instance, nubes_floating_ip — таких нет).
| Ресурс | resource_type |
|---|---|
| PostgreSQL | nubes_postgres, nubes_postgres_user, nubes_postgres_database |
| MongoDB | nubes_mongodb, nubes_mongodb_user, nubes_mongodb_backup |
| Redis | nubes_redis |
| MariaDB | nubes_mariadb, nubes_mariadb_user, nubes_mariadb_database |
| ClickHouse | nubes_clickhouse |
| Kafka | nubes_kafka, nubes_kafka_topic, nubes_kafka_user |
| RabbitMQ | nubes_rabbitmq |
| S3 | nubes_s3, nubes_s3bucket, nubes_s3_sub_user |
| Сеть | nubes_zones_v2, nubes_dnsrecord, nubes_vcexternalip |
| VMware / Cloud Director | nubes_vc_org, nubes_vc_vdc, nubes_vc_vdc_group, nubes_vc_nsxt, nubes_vc_nsxt_snat, nubes_vc_org_ip_allocation, nubes_vapp, nubes_vc_vm_v3 |
| Kubernetes (Штурвал) | nubes_k8s_sthutrval_cluster, nubes_vc_mgmt_sthutrval_cluster, nubes_k8s_velero, nubes_k8s_openbao |
| Приложения | nubes_nodejs, nubes_flask, nubes_lucee, nubes_nextcloud, nubes_gitea, nubes_harbor, nubes_superset, nubes_pgadmin, nubes_akhq, nubes_http |
| Прочее | nubes_llm_ai, nubes_valo_tenant, nubes_template, nubes_dummy |
Полный актуальный список — в provider/resources_yaml/ (у провайдера) или на сайте доков.
4. Структура примера и назначение файлов
tf_examples/<example>/
README.md # что делает пример, порядок запуска, что заполнить
main.tf # провайдер + объявление переменных
variables.tf # описания и типы переменных (где есть)
<ресурсы>.tf # ресурсы (например postgres.tf, vm.tf, resources.tf)
locals.tf # настраиваемые значения (имена, домены, git-ревизии)
terraform.tfvars.example # ШАБЛОН параметров; копируется в terraform.tfvars
terraform.tfvars # реальные значения — в .gitignore, НЕ коммитится
Ключевая мысль: пользователь копирует terraform.tfvars.example в terraform.tfvars и
заполняет. Всё, что «постоянное» (имена ресурсов, размеры), лежит в .tf/locals.tf;
все значения, зависящие от организации пользователя (токен, кластер, IP-пространства) —
в terraform.tfvars.
5. Конфигурация провайдера (одинакова во всех примерах)
terraform {
required_providers {
nubes = {
source = "tf-registry.containerk8s.services.ngcloud.ru/<stand>/nubes"
version = "<версия>"
}
}
}
provider "nubes" {
api_token = var.api_token # JWT из ЛК (ЛК → Профиль → Токены → «Технический»)
api_endpoint = "https://lk-api-gateway-<stand>.ngcloud.ru/api/v1/svc"
}
api_token— всегда изterraform.tfvars/secrets.auto.tfvars, никогда не в git.realm— ресурсная платформа (кластер Kubernetes), должна существовать в ЛК.api_endpoint— у тестового стенда...-test.ngcloud.ru, у прода — без суффикса.
6. Разбор примеров (что создаётся, что задаёт пользователь, грабли)
6.1. fullpipe_chain — полная цепочка (рекомендуемый)
Создаёт: vDC → Edge (AVI) → внешние IP на организации → SNAT → vApp → ВМ → кластер Штурвал. Организацию пользователь создаёт заранее в ЛК (Terraform её не создаёт и не удаляет).
Обязательные значения terraform.tfvars:
| Переменная | Где брать |
|---|---|
api_token |
ЛК → Профиль → Токены → «Технический» |
organization |
точное название услуги «Организация в Cloud Director» |
vdc_network_provider |
ЛК → создание vDC → «Сетевой провайдер» |
vdc_provider_vdc |
ЛК → создание vDC → «Provider VDC» (тот же ресурсный пул) |
vdc_storage_config |
JSON-массив: [{"name":"SATA","size":"200"}] (дисковая политика + ГБ) |
ip_space_name |
имя ipSpace из карточки организации |
vm_user_public_key |
содержимое ~/.ssh/id_ed25519.pub |
Порядок: terraform init → validate → plan (7 ресурсов) → apply.
Проверка: terraform output (UUID/имена услуг), ВМ — terraform output vm_state_flat
(externalConnect для SSH), Штурвал — shturval_state_params (kubernetesApiAddress, ingressAddress).
Кластер Штурвала создаётся десятки минут (operation_timeout = "60m").
destroy по умолчанию = «заморозка»: почти ничего не удаляется (см. раздел 10).
Полное удаление — осознанное: снять keep_on_destroy/suspend_on_destroy, порядок —
кластер → ВМ → vApp → count = 0 → SNAT → Edge → vDC.
6.2. Maria_CRUD — CRUD на MariaDB (проверенный)
Создаёт: кластер MariaDB 9.4.0, базу maria, пользователя cruduser (ALL PRIVILEGES),
три приложения (Lucee / Flask / Node.js) и контейнер HTTP-проверки (nubes_http).
Все приложения пишут в одну таблицу crud_items.
Обязательные terraform.tfvars: api_token, realm, mariadb_user_password (пароль БД).
Проверка работоспособности: curl .../readyz у HTTP-проверки → {"status":"ready","database":"connected"}.
Грабли (важно объяснять пользователю):
- логин БД — без
_(cruduser, неcrud_user):_ломает RFC 1123 в имени k8s-объекта; - креды берутся из подресурса
nubes_mariadb_user, а не изvault_secretsкластера (внутри одногоapplyvault_secretsещё пуст →Invalid index); retainбэкапа — в часах, минимум24;- версия MariaDB — только
8.4.0или9.4.0(можно только повышать); db_nameпользователя — JSON-массив:jsonencode([{ dbname = "maria" }]);registry_pathобраза — полный путь (<реестр>/<namespace>/<образ>:<тег>);adopt_existing_on_create— повторныйapplyусыновляет существующий инстанс (не падает).
6.3. CRUD — PostgreSQL + три приложения
Создаёт: PostgreSQL (nubes_postgres), пользователя и БД, приложения Lucee/Flask/Node.js.
Особенность: PostgreSQL не успевает отдать пароль до старта приложений — нужен
двойной terraform apply (или два этапа через *_git_revision). Домены приложений
задаются в locals.tf (должны быть уникальны). Папка — черновик (старая плоская схема,
старый пин провайдера): использовать осторожно, при вопросах сверяться с Maria_CRUD.
6.4. modify_resources — IP и SNAT на существующих услугах
Два ресурса для уже созданных в ЛК услуг: nubes_vc_org_ip_allocation (внешние IP
на организации) и nubes_vc_nsxt_snat (SNAT на шлюзе).
terraform.tfvars: api_token, organization, nsxt_uid (UUID шлюза Edge из карточки
услуги), ip_space_name, ip_count.
7. Секреты — жёсткое правило
api_token, пароли, ключи, приватные ключи никогда не попадают вterraform.tfvarsв репозитории и тем более в git.- Реальные значения — в локальном
secrets.auto.tfvars(Terraform загружает файлы*.auto.tfvarsавтоматически). Этот файл — в.gitignore. - Значения-заглушки (
<token>,eyJhbGciOi...,AAAA...) — это примеры; их заменяет пользователь на свои. - Если файл передаётся внешнему сервису/ЛЛМ — только без секретов.
8. Workflow агента (проверка/написание файла)
Когда просят «проверить/написать terraform.tfvars (или .tf) для X»:
- Определи ресурс и найди его схему (раздел 2):
resource_type+params[]. - Сверь каждое поле со схемой: имя (
code/name), тип,required. Пропуск обязательного поля — ошибка; поле не из схемы — ошибка/предупреждение. - Значения не выдумывай. Не подставляй «правдоподобные» имена кластеров, IP, UUID, домены — их даёт пользователь или ЛК.
- Проверь слои: провайдер-конфиг (
api_token/realm/api_endpoint), параметры ресурса, зависимости (например, база должна существовать до пользователя —depends_on). - Верни результат: исправленный файл целиком + список изменений + предупреждения.
plan/apply— пользователь. Агент не деплоит и не удаляет.
Дополнительно: проверить файл можно и через сервис — POST /<stand>/_api/file
({"content":"...","instruction":"..."} → {content, changes[], warnings[]}), см. раздел 11.
9. Типичные ошибки (реальные, встречаются в примерах)
- Секрет в
terraform.tfvars(api_token, пароли) вместоsecrets.auto.tfvars. realmне существует в ЛК → «Ресурсной платформы … нету в Личном кабинете» (при этом/resourceRealms/availableможет её показывать — доверяй ЛК, не API-списку).- Логин БД с
_(crud_user) → платформа падает на имени k8s-объекта. Только буквы/цифры. - Короткий
registry_path(без хоста реестра) → образ «не находится». s3_uid, которого нет на стенде →invalid input syntax for type uuid.- Домен занят (не уникален) → ошибка деплоя приложения.
- Пропущен
required-параметр (cluster_configurationи т.п.) →plan/applyпадает. - Опечатка в имени поля (
clusterConfigвместоclusterConfiguration) → поле игнорируется. - Эмодзи (4-байтовые) в MariaDB-примере →
Incorrect string value(частичная utf8mb3-таблица). - Асинхронные сбои платформы («Kubernetes cluster unreachable», IAM-сбои) — не всегда вина конфигурации: повтор команды обычно проходит.
10. Жизненный цикл ресурсов (что объяснять пользователю)
Провайдер управляет не только созданием, но и «судьбой» ресурса при удалении:
suspend_on_destroy = true—destroyне удаляет, а останавливает (данные сохраняются). Повторныйapplyусыновляет и размораживает.keep_on_destroy = true— ресурс приdestroyне трогается вовсе (например, Edge, SNAT, квота IP, пользователь/база внутри кластера).adopt_existing_on_create = true— если инстанс с таким именем уже есть, провайдер его усыновит, а не упадёт с «уже существует».- Организация в Cloud Director создаётся вручную в ЛК — Terraform её не создаёт и не удаляет.
Практический вывод: terraform destroy в этих примерах по умолчанию не удаляет данные —
это «заморозка». Полное удаление требует явно снять флаги и соблюсти порядок.
11. Карта документации и сервисов
- Ресурс на сайте доков:
https://tf-docs.nodejsk8s.dev.nubes.ru/<stand>/<service>/(таблица атрибутов = схема); например/nubes-test/postgres/. - Машиночитаемая схема:
…/<stand>/schema/<service>.json. - Готовые примеры (curated):
…/<stand>/curated/…— приоритетны (проверены на деплоях). - Стенды:
nubes-test,nubes-dev,nubes(prod). - Проверка файла через ЛЛМ:
POST /<stand>/_api/file({content, instruction}) →{content, changes, warnings}. - Справка по документации:
POST /<stand>/_api/assist(ответ по шаблону Роль/Задача/Контекст/Требования/Ограничения).
12. Чего агент делать НЕ должен
- Деплоить:
terraform apply/destroy— только пользователь. - Удалять/менять реальные ресурсы и состояние Terraform.
- Читать секреты из файлов пользователя и подставлять их в вывод.
- Выдумывать параметры, значения, домены, UUID без источника (схема/ЛК/пользователь).
- Навязывать свой workflow — помощь и проверка, а не «делай так, как я сказал».
13. Глоссарий
| Термин | Значение |
|---|---|
realm / ресурсная платформа |
кластер Kubernetes, в котором разворачивается ресурс |
resource_name |
имя услуги в ЛК; уникально внутри своего сервиса; используется для усыновления |
sizing_policy |
профиль ресурсов (TKG 4CPU 8RAM и т.п.) |
cluster_configuration |
размеры кластера: cpu (мили-ядра, 1000 = 1 vCPU), memory (МБ), replicas, disk (ГБ), shards |
ipSpace |
пул внешних IP организации |
vDC |
виртуальный датацентр (Cloud Director) |
Edge |
сетевой шлюз периметра (NSX-T), балансировщик AVI |
SNAT |
трансляция исходящего трафика через шлюз |
vApp |
виртуальный каталог; контейнер для ВМ |
suspend |
остановка ресурса с сохранением данных |
adopt |
«усыновление» уже существующего ресурса по имени |
| ЛК | Личный кабинет Nubes — веб-интерфейс управления услугами |
| услуга / инстанс | конкретный объект в облаке, созданный по ресурсу |
| операция | действие платформы над услугой: create/delete/modify/suspend/resume и др. |
resource_name |
имя услуги в ЛК; по нему провайдер находит и усыновляет объект |
startup_configuration |
параметры размещения (например resource_realm — кластер Kubernetes) |
access_configuration |
сетевой доступ: IP-списки, внешний IP |
backup_configuration |
резервное копирование: schedule (cron), retain (срок хранения) |
json_env |
переменные окружения приложения (JSON) |
git_revision |
версия кода приложения; смена значения → redeploy |
domain |
доменное имя приложения (полный суффикс платформа добавляет сама) |
| HCL | язык конфигурации Terraform (файлы .tf) |
terraform.tfvars |
файл значений переменных; в этом репозитории — в .gitignore |
terraform.tfstate |
файл состояния Terraform; хранит соответствие «код ↔ облако» |