9.0 KiB
Terraform Registry — Полное описание
Этот документ — точка входа для нового чата/агента. Содержит всё необходимое для понимания, сопровождения и доработки реестра провайдера.
Что это такое
Кастомный Terraform Registry Server для провайдера nubes (облако Nubes / ngcloud.ru).
Когда разработчик пишет в своём .tf:
terraform {
required_providers {
nubes = {
source = "terra.k8c.ru/nubes/nubes"
version = "5.0.18"
}
}
}
...и выполняет terraform init, Terraform идёт к этому серверу за бинарниками провайдера.
Структура папки
REGISTRY/
├── server/ — Go-код HTTP-сервера реестра (АКТУАЛЬНЫЙ)
├── operator/ — Kubernetes Operator (CRD TerraformProviderRelease) + старая копия server-кода в cmd/registry/
├── k8s/ — Kubernetes манифесты деплоя (namespace, ingress, deployment, service, TLS)
├── registrykeys/ — Go-модуль с публичным GPG-ключом (для верификации провайдера)
├── charts/ — Helm chart для деплоя registry-server
└── scripts/
└── build-and-push-registry-server.sh — сборка Docker-образа и push в registry
Важно: server/ и operator/cmd/registry/ — дублирующийся код. Актуальный и полный — только server/main.go. В operator/cmd/registry/main.go нет health-эндпоинтов и не удалены darwin-платформы. При правках менять только server/.
Как работает registry-server
Реализованный протокол
Terraform Registry Protocol v1.
| Эндпоинт | Назначение |
|---|---|
GET /.well-known/terraform.json |
Discovery — говорит Terraform, где API реестра |
GET /v1/providers/{ns}/{name}/versions |
Список доступных версий и платформ |
GET /v1/providers/{ns}/{name}/{version}/download/{os}/{arch} |
URL для скачивания бинарника |
GET /v1/proxy?url=... |
Проксирование файлов из S3 (бинарники, SHA, GPG-сигнатура) |
GET /docs/{ns}/{name}/{version}/... |
Документация провайдера (статический HTML из S3) |
GET /healthz |
Health probe для Kubernetes |
GET /readyz |
Readiness probe для Kubernetes |
Как определяются версии
Сервер листит S3 bucket в поиске файлов вида:
<hostname>/<namespace>/<name>/<version>/terraform-provider-<name>_<version>_linux_amd64.zip
Из имён файлов парсит версию и платформы. Поддерживаемые платформы: linux_amd64, linux_arm64, windows_amd64.
Переменные окружения
| Переменная | Default | Назначение |
|---|---|---|
REGISTRY_HOSTNAME |
localhost:8080 |
Домен реестра (используется в URL ответов) |
S3_ENDPOINT |
— | Хост S3 без схемы, например s3.msk-1.ngcloud.ru |
S3_ACCESS_KEY |
— | S3 access key |
S3_SECRET_KEY |
— | S3 secret key |
S3_BUCKET |
terraform-registry |
Имя бакета |
S3_USE_SSL |
— | Если true — HTTPS (в коде Secure: true захардкожено) |
S3 структура бакета
terraform-registry/ ← бакет
└── terra.k8c.ru/
└── nubes/
└── nubes/
└── 5.0.18/
├── terraform-provider-nubes_5.0.18_linux_amd64.zip
├── terraform-provider-nubes_5.0.18_windows_amd64.zip
├── terraform-provider-nubes_5.0.18_SHA256SUMS
└── terraform-provider-nubes_5.0.18_SHA256SUMS.sig
docs/
└── nubes/
└── nubes/
└── 5.0.18/
└── index.html (и другие файлы документации)
GPG-ключ
Terraform верифицирует подпись провайдера через GPG.
- Публичный ключ встроен в
server/main.go(ASCII Armor, константа в коде). - Также хранится в
registrykeys/public_key.go(отдельный go-модуль). - Приватный ключ —
secrets/private_key.asc(НЕ в репо, gitignore).
При ротации ключей:
- Сгенерировать новую пару
gpg --gen-key - Обновить ASCII Armor в
server/main.go - Пересобрать и передеплоить Docker-образ
- Перезалить все артефакты провайдера, подписанные новым ключом
Деплой в Kubernetes
Кластер и namespace
- Namespace:
terra - Домен:
terra.k8c.ru(планируемая миграция →registry.nubes.ru, см.../docs/ops/DOMAIN_MIGRATION.md) - TLS: cert-manager с
letsencrypt-prodissuer — НЕ ТРОГАТЬ сертификат руками!
Что задеплоено
| Ресурс | Kind | Образ |
|---|---|---|
registry-server |
Deployment | naeel/terraform-registry-server:gpg-key-20260208 |
registry-server |
Service | ClusterIP :8080 |
registry-ingress |
Ingress | host: terra.k8c.ru |
Credentials S3 — из секрета s3-credentials (ключи access-key, secret-key).
Применение манифестов (только при смене конфигурации кластера)
kubectl apply -f k8s/operator/manifests/00-namespace.yaml
kubectl apply -f k8s/operator/manifests/00-rbac.yaml
kubectl apply -f k8s/operator/manifests/02-crd.yaml
kubectl apply -f k8s/operator/manifests/05-registry-server.yaml
Диагностика (read-only)
kubectl -n terra get pods,svc,ingress,deploy
kubectl -n terra logs -l app=registry-server --tail=50
kubectl -n terra get certificate registry-tls -o yaml
Сборка и публикация нового образа
Скрипт: scripts/build-and-push-registry-server.sh
cd REGISTRY
./scripts/build-and-push-registry-server.sh
Собирает Docker-образ из server/ и пушит в Docker Hub (naeel/terraform-registry-server:<tag>).
После push нужно обновить тег образа в operator/manifests/05-registry-server.yaml и применить kubectl apply.
Когда registry НЕ нужно трогать
Registry — stateless сервис. При выпуске новой версии провайдера (nubes) registry не меняется:
Новая версия провайдера:
1. go build → бинарники
2. devops/03_build_and_upload_provider.sh → бинарники в S3
3. devops/04_build_and_publish_docs.sh → документация в S3
✅ Registry автоматически начинает отдавать новую версию
❌ kubectl не нужен
❌ код registry не меняется
❌ Docker-образ не пересобирается
Registry пересобирается только если меняется сам сервер: новые эндпоинты, логика, ротация GPG-ключа.
Связь с основным репо провайдера
Этот код был перемещён из основного репо terraform/ в папку REGISTRY/ для последующего выноса в отдельный репозиторий. Код провайдера и код реестра полностью независимы — нет общих go-модулей, нет импортов друг друга.
Ограничения и правила работы
- Ручные правки
operator/cmd/registry/— не делать, это устаревшая копия. Актуальный код — толькоserver/. - Let's Encrypt cert-manager (
letsencrypt-prod) — не применятьkubectl applyна Ingress-ресурсы без именённой необходимости (риск бана от CA). - docker build — только с явного разрешения разработчика.
- kubectl — только read-only (
get,describe,logs) без разрешения. - S3 credentials — никогда не коммитить в репо. Только через секреты k8s или переменные окружения.