terraform-contour-mirror/docker/offline-runner/README.md

66 lines
6.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Offline terraform/terragrunt runner
Образ `terraform/terragrunt:v9.11` из `cr.yandex/crp3ccidau046kdj8g9q` тянет провайдеры terraform (`kubernetes`, `vault`, `mongey/kafka`, `cyrilgdn/postgresql`, `cyrilgdn/rabbitmq`, `aminueza/minio`, `random`, `tls`) с `registry.terraform.io` при каждом `terraform init`. В закрытом контуре без доступа к этому хосту `init` виснет или падает.
Этот образ решает именно это: провайдеры зашиты внутрь как файловое зеркало, `terraform init` их больше никуда не тянет. Доступ к `cr.yandex` при этом всё ещё нужен — сам образ раннер тянет оттуда.
## Что внутри
Поверх `cr.yandex/crp3ccidau046kdj8g9q/terraform/terragrunt:v9.11` добавлено:
- `/opt/terraform/provider-mirror` — файловое зеркало (`terraform providers mirror`), собранное под `linux_amd64` по версиям из `required_providers` в `live/terragrunt.hcl`
- `/root/.terraformrc` с `provider_installation { filesystem_mirror {...} }`, указывающим terraform брать провайдеры оттуда, а не с `registry.terraform.io`
- `TF_CLI_CONFIG_FILE=/root/.terraformrc`
- `CHECKPOINT_DISABLE=1` — отключает фоновую проверку новой версии terraform на `checkpoint.hashicorp.com` (не блокирует прогон при недоступности, но незачем тратить время на таймаут)
`sops` уже был в базовом образе `v9.11` — отдельно решать не пришлось, шаг "Decrypt secret values" в workflow ничего с интернета не тянет ни в базовом, ни в этом образе.
## Проверено, не только собрано
`terraform init` реально прогонялся в контейнере с `docker run --network none` — все 8 провайдеров разрешились из локального зеркала, `Terraform has been successfully initialized!`. Не теория, а факт.
## Собрать и залить заново
Нужно, когда меняется набор/версии провайдеров в `live/terragrunt.hcl`, или обновляется базовый образ `terraform/terragrunt`.
```bash
cd docker/offline-runner
PUSH=true ./build.sh
```
`build.sh` сам:
1. качает `terraform/terragrunt:v9.11` под `linux/amd64` (с маком без этого флага уедет arm64, и джоба под упадёт `exec format error`)
2. пересобирает `provider-mirror/` через `terraform providers mirror -platform=linux_amd64` из `versions.tf` в этой же папке
3. собирает образ `cr.yandex/crp3ccidau046kdj8g9q/contour/terraform-terragrunt-offline:v9.11`
4. заливает его, если `PUSH=true`
Локальную папку `provider-mirror/` (около 75 MB бинарников) в git не кладём — она пересобирается заново каждый билд, коммитить туда нечего, кроме `Dockerfile`/`terraformrc`/`versions.tf`/`build.sh`.
**`versions.tf` в этой папке должен быть зеркалом `required_providers` из `live/terragrunt.hcl`.** Если там появится новый провайдер или сменится версия — сначала правится `live/terragrunt.hcl`, потом та же запись копируется сюда и гонится пересборка. Рассинхрон тихий: `terraform init` в офлайн-контуре просто не найдёт новый провайдер в зеркале и упадёт с ошибкой резолва версии, а не с понятным "provider not in mirror".
Текущий образ уже собран и залит: `cr.yandex/crp3ccidau046kdj8g9q/contour/terraform-terragrunt-offline:v9.11`, `linux/amd64`, digest `sha256:9beff996644afad1429f5568f1549501fcb1efe58df8dcd5882ea9dc5a8ffed4`.
## Как подключить в конкретном контуре
Ничего в `.gitea/workflows/terraform.yml` менять не нужно — там уже есть переопределение:
```yaml
image: ${{ vars.RUNNER_IMAGE || 'cr.yandex/crp3ccidau046kdj8g9q/terraform/terragrunt:v9.11' }}
```
В Gitea нужного контура (Settings → Actions → Variables) добавить репозиторную переменную:
```
RUNNER_IMAGE = cr.yandex/crp3ccidau046kdj8g9q/contour/terraform-terragrunt-offline:v9.11
```
`vars.*` в Gitea Actions — переменные конкретного репозитория в конкретном gitea-инстансе, они не синкаются вместе с содержимым ветки. Установка `RUNNER_IMAGE` в одном контуре не задевает остальные — у них как был, так и останется дефолтный образ, пока кто-то явно не пропишет то же самое там.
После этого прогоняется обычный `validate`/`plan`/`apply` — разницы в шагах нет, разница только в том, откуда `terraform init` берёт провайдеры.
## Что офлайн-образ не решает
- Доступ к `cr.yandex` всё равно нужен — и на пул этого образа раннером, и на пул образов приложений (`kafka-contour`, `camunda-contour`, `postgresql-contour` и так далее — их тянет flux/kubelet, не terraform, к этому образу отношения не имеет).
- Шаг "Configure module registry auth" в workflow настраивает `git config` на `gitlab.sarex.io` под внешние `terraform { source }` — в самом контуре все `source` локальные (`../../modules//...`), так что это безвредная команда без сети. Если когда-нибудь появится стек с внешним source на gitlab, для него нужен будет реальный доступ к `gitlab.sarex.io`, этот образ его не даст.
- S3-бэкенд стейта, providers kubernetes/vault/postgresql/kafka/rabbitmq/minio в рантайме ходят на локальные адреса контура (MinIO, Vault, кластер, VM) — они и без этого образа не лезли в интернет, тут ничего не поменялось.