# tf_registry — Архитектура и рабочий процесс ## Что такое этот реестр Собственный реестр Terraform-провайдеров по протоколу HashiCorp Provider Registry Protocol. Позволяет публиковать и распространять кастомные Terraform-провайдеры без HashiCorp Registry. **Текущий URL:** `https://go-registry.containerk8s.dev.nubes.ru` --- ## Как это работает ### Загрузка провайдера (пользователь) ```hcl terraform { required_providers { nubes = { source = "go-registry.containerk8s.dev.nubes.ru/nubes-test/nubes" version = "5.1.16" } } } ``` Terraform сам делает: 1. `GET /.well-known/terraform.json` → узнаёт API-путь 2. `GET /v1/providers/nubes-test/nubes/versions` → список версий и платформ 3. `GET /v1/providers/.../download/linux/amd64` → JSON с URL для скачивания 4. Скачивает zip, проверяет SHA256, проверяет GPG-подпись 5. Всё — провайдер установлен Никакой аутентификации не нужно. --- ## S3-структура Все данные хранятся в S3 (`terraform-registry`). Никакой БД нет. ``` {префикс}/{namespace}/{name}/{version}/ ├── terraform-provider-{name}_{ver}_{os}_{arch}.zip — бинарник провайдера ├── terraform-provider-{name}_{ver}_SHA256SUMS — контрольные суммы └── terraform-provider-{name}_{ver}_SHA256SUMS.sig — GPG-подпись сумм docs/{namespace}/{name}/{version}/ ├── index.html — документация провайдера └── ... — любые статические файлы ``` **Важно:** префикс (первая часть пути в S3) сейчас — `registry.kube5s.ru` (временный хардкод). Планируется либо сменить на свой домен, либо убрать префикс совсем. --- ## GPG-подпись ### Зачем Terraform требует, чтобы SHA256SUMS были подписаны GPG. Это гарантирует, что провайдер не подменён. ### Как работает 1. **Приватный ключ** — хранится у того, кто заливает провайдер (`secrets/private_key.asc`) 2. **Публичный ключ** — вшит в код реестра (`gpg_key.go` → `/v1/providers/.../download` отдаёт его) 3. Terraform при `init` сверяет подпись SHA256SUMS с публичным ключом ### Текущие ключи | Key ID | Роль | |---|---| | `3EC4673EB798238A` | Основной (текущий) | | `CB3A0DF161ECC416` | Legacy (старый) | Оба отдаются в `signing_keys.gpg_public_keys` — Terraform пробует каждый. --- ## Как залить новый провайдер ### Скрипт `build-provider.sh` Находится в `server/build-provider.sh`. Делает: 1. Компилирует Go-провайдер под linux/windows/darwin × amd64 2. Упаковывает в zip 3. Генерирует SHA256SUMS 4. Импортирует приватный GPG-ключ из `secrets/private_key.asc` 5. Подписывает SHA256SUMS 6. Заливает zip + SHA256SUMS + .sig в S3 ### Требования ```bash # Переменные окружения S3_ENDPOINT=s3.msk-1.ngcloud.ru S3_ACCESS_KEY=... S3_SECRET_KEY=... S3_BUCKET=terraform-registry # GPG secrets/private_key.asc # приватный ключ для подписи # Исходники провайдера universal_rebuild/ # директория с Go-кодом провайдера ``` ### Запуск ```bash VERSION=5.1.17 ./server/build-provider.sh ``` --- ## Документация Эндпоинт `/docs/{ns}/{name}/{ver}/...` отдаёт статику из S3: ``` docs/{ns}/{name}/{ver}/index.html ``` Работает как статический веб-сервер: HTML, CSS, JS, изображения — всё, что положишь в `docs/` в S3. Логика поиска (1:1 с Go-кодом): 1. Точный путь (`docs/ns/name/ver/style.css`) 2. Если нет расширения — `{путь}/index.html` 3. Fallback — `docs/ns/name/ver/index.html` --- ## Эндпоинты | Метод | URL | Ответ | |---|---|---| | GET | `/` | HTML с версией | | GET | `/.well-known/terraform.json` | `{"providers.v1":"/v1/providers/"}` | | GET | `/v1/providers/{ns}/{name}/versions` | JSON: id, versions[], warnings | | GET | `/v1/providers/{ns}/{name}/{ver}/download/{os}/{arch}` | JSON: download_url, shasum, GPG ключи | | GET | `/v1/proxy?bucket=...&key=...` | Стриминг файла из S3 | | GET | `/docs/{ns}/{name}/{ver}/...` | Статика из S3 | | GET | `/healthz`, `/readyz` | `"ok"` 200 | --- ## CI/CD ```bash # Сборка образа docker build -t gitea.services.ngcloud.ru/nail/tf_registry:latest . # Пуш в Gitea Docker Registry docker push gitea.services.ngcloud.ru/nail/tf_registry:latest # Редеплой — через UI modify (меняет только CPU/memory/replicas, подхватывает :latest) ``` --- ## Платформы Детектятся по имени zip-файла: - `_darwin_amd64.zip` → macOS Intel - `_linux_amd64.zip` → Linux - `_windows_amd64.zip` → Windows --- ## Текущие проблемы 1. **S3_PREFIX** — хардкод `registry.kube5s.ru` (TODO в коде) 2. **modify** — нельзя менять `jsonEnv` в UI (надо просить devops) 3. **Домен** — `go-registry` вместо `registry` (можно пересоздать)