Files
tf_registry/REGISTRY_OVERVIEW.md
T

9.0 KiB
Raw Blame History

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).

При ротации ключей:

  1. Сгенерировать новую пару gpg --gen-key
  2. Обновить ASCII Armor в server/main.go
  3. Пересобрать и передеплоить Docker-образ
  4. Перезалить все артефакты провайдера, подписанные новым ключом

Деплой в Kubernetes

Кластер и namespace

  • Namespace: terra
  • Домен: terra.k8c.ru (планируемая миграция → registry.nubes.ru, см. ../docs/ops/DOMAIN_MIGRATION.md)
  • TLS: cert-manager с letsencrypt-prod issuer — НЕ ТРОГАТЬ сертификат руками!

Что задеплоено

Ресурс 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 или переменные окружения.