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

6.7 KiB
Raw Blame History

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.

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 менять не нужно — там уже есть переопределение:

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) — они и без этого образа не лезли в интернет, тут ничего не поменялось.