- HOWTO_IMPLEMENT_NEW_CLOUD_SERVICE.md: rules for implementing new managed services (naming, params, map-fixed blocks, operations, subresources, validation, checklist) - HOWTO_ADD_NEW_SERVICE.md: how to add service to terraform provider pipeline - TEST_STAND/*/main.tf: version 5.0.57, api_endpoint -> lk-api-gateway-test - TEST_STAND/POSTGRES/resources.tf: rewritten for new map-fixed param structure
8.8 KiB
Инструкция по добавлению нового сервиса в Terraform-провайдер Nubes
1. Где прописывать
Единственная точка входа — devops/config/services_list.txt (или профильный profiles/{stand}/services_list.txt).
Формат строки:
{service_id} {service_name} # Описание (опционально)
Пример:
90 postgres # Управляемая база данных PostgreSQL
- service_id — число, ID сервиса из API Nubes (
/services/{id}) - service_name — snake_case, латиница. Будет использоваться как имя ресурса
nubes_{name}
Исключение сервиса — закомментировать строку #.
2. Что происходит после добавления в список
Пайплайн (3 шага):
services_list.txt
→ 01_generate_yamls.sh → запрос к API → resources_yaml/{id}_{name}.yaml
→ 02_generate_resources_and_docs_v2.sh → internal/resources_gen/{name}_resource.go + docs
→ 03_build_and_upload_provider.sh → сборка + S3
Никаких ручных правок YAML или сгенерированного Go-кода. Всё из API.
3. Структура YAML (что генерируется)
name: postgres # snake_case, из services_list.txt
service_id: 90 # ID сервиса
service_display_name: PostgreSQL # человекочитаемое имя
service_short_name: postgres # краткое имя из API
service_man: "описание..." # MAN-руководство (HTML)
lifecycle:
suspend_on_destroy_default: true # есть ли операция suspend
adopt_existing_on_create_default: false
outputs:
params: # выходные параметры (всегда одинаковые)
- code: state_params; type: map
- code: state_out; type: map
- code: vault_secrets; type: map; sensitive: true
- code: vault_url; type: string
...
operations:
- name: create # имя операции из API (snake_case)
id: 19 # svcOperationId
kind: instance # instance | subresource | action
action: create # create | modify | delete | suspend | ...
man: "руководство" # описание операции
params:
- id: 788 # svcOperationCfsParamId
code: clusterConfiguration
data_type: map-fixed
required: true
sort: 20
is_modifiable: true
4. Типы параметров (data_type)
| Тип | Пример | Когда использовать |
|---|---|---|
string |
resourceRealm, domain, dbName |
Имена, домены, UUID, строки |
integer > 0 |
resourceCPU, resourceMemory |
Числовые значения больше нуля |
integer >= 0 |
autoScaleTechWindow |
Числовые, допускающие 0 |
boolean |
enablePgPoolerMaster, allowNoSsl |
Флаги вкл/выкл |
uuid |
s3Uid, vdcUid |
Ссылки на другие сервисы (ref) |
map-fixed |
clusterConfiguration |
Сложные K8s-сервисы: JSON-объект с фиксированным набором полей |
array-map-fixed |
postgresConf |
Массив JSON-объектов (доп. конфигурации) |
json |
jsonEnv, jsonParameters |
Произвольный JSON |
map |
state_params |
Только в outputs |
yaml |
— | YAML-строка (редко) |
5. Виды операций (kind)
instance — управление жизненным циклом сервиса
| action | Terraform | Пример |
|---|---|---|
create |
resource "nubes_X" "Y" {} |
Создание сервиса |
delete |
terraform destroy |
Удаление |
modify |
изменение параметров → apply |
Модификация |
suspend |
suspend_on_destroy = true |
Остановка (без удаления) |
resume |
adopt_existing_on_create = true |
Запуск остановленного |
Правило: если у сервиса есть suspend И resume → suspend_on_destroy_default = true.
subresource — вложенные объекты
Стандартные subresource'ы:
- user →
nubes_{service}_user(create/delete)- Параметры:
username(string, required),role(string, required, value_list)
- Параметры:
- database →
nubes_{service}_database(create/delete)- Параметры:
dbName(string, required, regex),dbOwner(string, required)
- Параметры:
- topic → Kafka
- backup → S3, PostgreSQL
- vdc → vcOrg
Правило: subresource всегда ссылается на родительский ресурс через {service}_id.
action — разовые операции
| action | Когда |
|---|---|
reconcile |
Синхронизация состояния (у 20 сервисов) |
redeploy |
Переразвёртывание (приложения: flask, nodejs, lucee, ...) |
restart |
Перезапуск (postgres, mariadb, ...) |
recovery |
Восстановление из бэкапа |
Правило: action-ресурсы используют trigger-поле (run_id/nonce) для идемпотентности.
6. Валидация параметров (автоматически из API)
| Механизм | Параметров | Пример |
|---|---|---|
regex |
29 | dbName: ^[A-Za-z0-9]+$ |
value_list |
38 | role: [app_user, ddl_user] |
minlength/maxlength |
87/74 | username: min 2, max 62 |
minvalue/maxvalue |
— | resourceCPU > 0 |
default |
120 | deleteS3Bucket: true |
is_modifiable |
106 | Можно менять после create |
is_sensitive |
2 | vault_secrets |
7. Что запрещено
- ❌ Править сгенерированные YAML вручную — источник истины только API
- ❌ Править
internal/resources_gen/*.goвручную — перезапишется при следующей генерации - ❌ Использовать кириллицу в
service_name— только латиница, snake_case - ❌ Менять
embed.go— генерируется автоматически - ❌ Пропускать сервис через комментарий без причины — лучше явно указать причину в комментарии:
# 24 DEPRECATED ...
8. Быстрый старт: добавляем новый сервис
# 1. Добавить строку в services_list.txt
echo "200 my_new_service # Моя новая услуга" >> devops/config/services_list.txt
# 2. Сгенерировать YAML (test-стенд)
devops/01_generate_yamls.sh --profile devops/profiles/test
# 3. Сгенерировать Go-код + доки
devops/02_generate_resources_and_docs_v2.sh --profile devops/profiles/test
# 4. Проверить что появился файл
ls devops/profiles/test/generated/resources_yaml/200_my_new_service.yaml
ls devops/profiles/test/generated/go/200_my_new_service_resource.go
# 5. Собрать и задеплоить провайдер
devops/03_build_and_upload_provider.sh --profile devops/profiles/test
# 6. Написать тестовый манифест в TEST_STAND/my_new_service/main.tf
# 7. terraform init && terraform plan && terraform apply
9. Как писать тестовый манифест
Простой сервис (flat-параметры)
resource "nubes_s3bucket" "test" {
resource_name = "Мой бакет"
s3_user_uid = var.s3_uid
bucket_name = "test-bucket"
}
Сложный сервис (map-fixed)
resource "nubes_postgres" "test" {
resource_name = "pg-test"
cluster_configuration = jsonencode({
platform = "k8s-3.ext.nubes.ru"
instances = 1
memory = 512
cpu = 500
disk = "1"
})
startup_configuration = jsonencode({
appVersion = "17"
})
access_configuration = jsonencode({
needExternalAddressMaster = false
})
# ... остальные блоки
}
JSON-ключи внутри map-fixed — camelCase-версии старых плоских названий параметров. Точные имена полей смотри в сгенерированном YAML (поле code у параметров в operations.params) или в generated/docs/{service}_params_create.md.