# .terraform.lock.hcl: фиксация версий провайдеров _Основы Terraform · TerraformLab Knowledge Base_ **TL;DR:** Lockfile фиксирует точные версии провайдеров и их хеши, чтобы у тебя и у CI всегда стояла та же сборка. Создаётся при terraform init, обновляется через init -upgrade. Коммитится в git. ## Что такое lockfile `.terraform.lock.hcl`, это файл в корне проекта, в котором terraform записывает: «при текущей конфигурации я скачал AWS-провайдер версии 5.62.0 с такими-то хешами». Lockfile появляется после первого [[tf-init|terraform init]] и потом обновляется по правилам ниже. Назначение, детерминизм. Без lockfile два инженера или CI могут на одинаковом коде скачать разные минорные версии плагина и получить разный план. С lockfile все получают одну и ту же сборку, пока кто-то явно её не поднял. Пример содержимого: ```hcl provider "registry.terraform.io/hashicorp/aws" { version = "5.62.0" constraints = "~> 5.60" hashes = [ "h1:abc123...", "h1:def456...", "zh:0123...", "zh:4567...", ] } ``` - `version`, точная установленная версия. - `constraints`, выражение из `required_providers`. Lockfile его запоминает, чтобы при `init -upgrade` искать новую версию в рамках того же constraint. - `hashes`, два варианта хешей. `h1:`, хеш zip-архива целиком. `zh:`, хеш конкретного бинарника под платформу. ## Когда lockfile меняется - **Первый `terraform init`**, создаётся с нуля, версия = последняя подходящая под constraint. - **`terraform init` без флагов**, если в lockfile уже есть запись, terraform пытается её соблюсти. Если хеши не совпали, падает. - **`terraform init -upgrade`**, terraform идёт в registry за свежими версиями в рамках того же constraint, перезаписывает lockfile. - **Меняется блок `required_providers`**, добавили провайдер, поменяли constraint, поменяли source, следующий `init` дозапишет/перепишет соответствующие блоки. - **`terraform providers lock`**, целенаправленное обновление хешей под несколько платформ (см. Ниже). Никакая команда никогда не редактирует lockfile «случайно». Изменился файл, был один из этих сценариев. ## Multi-platform хеши Когда `init` выполняется на macOS, в lockfile попадают хеши бинарников под `darwin_arm64` или `darwin_amd64`. Когда тот же проект потом запустится в Linux-CI, terraform на этой платформе нужного хеша не найдёт и упадёт. Решение, заранее заложить хеши под все нужные платформы: ```bash terraform providers lock \ -platform=linux_amd64 \ -platform=linux_arm64 \ -platform=darwin_amd64 \ -platform=darwin_arm64 ``` Команда сходит в registry за hashes под каждую платформу и допишет их в lockfile. Достаточно одного запуска при заведении проекта или когда добавили новую платформу в команду. ## Коммитить или нет **Коммитить.** Lockfile, часть source-of-truth проекта, наравне с `.tf`-файлами. Без него теряется главное преимущество, повторяемость. В `.gitignore` пишут только `.terraform/` (кеш провайдеров), но не `.terraform.lock.hcl`. Распространённая ошибка новичков, добавить `*.lock` в gitignore и спрятать lockfile. После этого жалобы «у меня работает, в CI нет» становятся регулярными. ## Что делать при ошибке хешей Текст ошибки от `init`: ``` Error: Failed to install provider Error while installing hashicorp/aws v5.62.0: the local package for registry.terraform.io/hashicorp/aws 5.62.0 doesn't match any of the checksums previously recorded in the dependency lock file ``` Причины и решения: - **Запустился init на новой платформе.** Решение, `terraform providers lock -platform=...` (см. Выше), затем коммит обновлённого lockfile. - **Меняли версию провайдера, не сделав -upgrade.** Решение, `terraform init -upgrade`. - **Зеркало registry отдало другой бинарник.** Серьёзная ситуация, проверь, не подменили ли провайдера в корпоративном зеркале. ## Конфликт lockfile при merge Двое в одной ветке поменяли `required_providers`. Получили git-конфликт в `.terraform.lock.hcl`. Что делать: 1. Не пытайся вручную мерджить hash-блоки, они хрупкие. 2. Прими любую из версий (или `git checkout --ours/--theirs`). 3. Запусти `terraform init -upgrade`, он перепишет lockfile под текущий HCL. 4. Закомить результат. ## Подводные камни - **Lockfile не блокирует `init -upgrade` от мажоров.** Если в constraint стоит `>= 5.0` (без верхней границы), `-upgrade` спокойно поднимет тебе 6.x. Чтобы такого не было, пиши pessimistic-constraints `~> 5.60` (см. [tf-version-constraints](/terraform/kb/tf-version-constraints.md)). - **Lockfile не фиксирует модули.** Только провайдеры. Модули кешируются в `.terraform/modules/` без хешей, версии модулей приходится контролировать через [[tf-init-modules|version constraint в module-блоке]]. - **`.terraform.lock.hcl` редактируют только инструментом.** Руками не правят. Если очень нужно, удали и сделай `init -upgrade`. ## Команды ```bash terraform init ``` Создаёт lockfile при первом запуске; на последующих: проверяет, что хеши скачанного совпадают. ```bash terraform init -upgrade ``` Обновляет провайдеры в рамках constraints, перезаписывает lockfile. ```bash terraform providers lock -platform=linux_amd64 -platform=darwin_arm64 ``` Дописать хеши под несколько платформ. Нужно когда команда работает на разных ОС/архитектурах. ```bash rm .terraform.lock.hcl && terraform init ``` Сброс lockfile. Применять только когда понимаешь, что делаешь: после этого версия зафиксируется заново и может оказаться свежее ожидаемой. ## См. также - [terraform init: первая команда в любом проекте](/terraform/kb/tf-init.md) - [Version constraints в Terraform: required_version и провайдеры](/terraform/kb/tf-version-constraints.md) - [Блок provider: кому Terraform будет звонить](/terraform/kb/tf-provider-block.md) - [Как terraform init подтягивает модули](/terraform/kb/tf-init-modules.md)