Что такое lockfile
.terraform.lock.hcl, это файл в корне проекта, в котором terraform
записывает: «при текущей конфигурации я скачал AWS-провайдер версии
5.62.0 с такими-то хешами». Lockfile появляется после первого
[[tf-init|terraform init]] и потом обновляется по правилам ниже.
Назначение, детерминизм. Без lockfile два инженера или CI могут на одинаковом коде скачать разные минорные версии плагина и получить разный план. С lockfile все получают одну и ту же сборку, пока кто-то явно её не поднял.
Пример содержимого:
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 на этой платформе нужного
хеша не найдёт и упадёт.
Решение, заранее заложить хеши под все нужные платформы:
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. Что делать:
- Не пытайся вручную мерджить hash-блоки, они хрупкие.
- Прими любую из версий (или
git checkout --ours/--theirs). - Запусти
terraform init -upgrade, он перепишет lockfile под текущий HCL. - Закомить результат.
Подводные камни
- Lockfile не блокирует
init -upgradeот мажоров. Если в constraint стоит>= 5.0(без верхней границы),-upgradeспокойно поднимет тебе 6.x. Чтобы такого не было, пиши pessimistic-constraints~> 5.60(см. tf-version-constraints). - Lockfile не фиксирует модули. Только провайдеры. Модули
кешируются в
.terraform/modules/без хешей, версии модулей приходится контролировать через [[tf-init-modules|version constraint в module-блоке]]. .terraform.lock.hclредактируют только инструментом. Руками не правят. Если очень нужно, удали и сделайinit -upgrade.