Reputation: 24301
I use a CI system to compile terraform providers and bundle them into an image, but every time I run terraform init, I am getting the following error/failure.
│ Error: Failed to install provider
│
│ Error while installing rancher/rancher2 v1.13.0: the current package for
│ registry.terraform.io/rancher/rancher2 1.13.0 doesn't match any of the
│ checksums previously recorded in the dependency lock file
This message is repeated for all of the providers listed in my provider file, which looks like this:
terraform {
required_version = ">= 0.13"
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "2.55.0"
}
github = {
source = "integrations/github"
version = "4.8.0"
}
}
...snip...
}
The terraform hcl lock file is stored in the repo and it's only when the lock file exists in the repo that these errors appear and terraform init fails. What could be the cause?
Upvotes: 41
Views: 39456
Reputation: 3507
While the accepted answer is absolutely correct, the easiest way to handle this situation is to deploy pre-commit
and use a hook
like https://github.com/antonbabenko/pre-commit-terraform#terraform_providers_lock.
Upvotes: 1
Reputation: 21
Just to improve a bit what was already posted above, I've done the same fix either in my local machine but also in automation (Github actions), wrapping up this solution into a tiny bash script. Putting this script into a GH action would solve this problem in a wider way
#!/usr/bin/env bash
export PATH=$PATH:/usr/local/bin
function main() {
parse_args "$@"
generate_terraform_lock_command_by_option
fix_lock_file
}
function fix_lock_file() {
pushd "$DIR" >/dev/null || exit
if [[ "${RUNON}" != "automation" ]]; then
clean_terraform_local_state
fi
if [[ -f ".terraform.lock.hcl" ]]; then
echo "Removing terraform.lock file"
cat $LOCK_FILE
rm -f "$LOCK_FILE"
fi
terraform get
terraform providers lock -platform=$OS
if [[ "${RUNON}" != "automation" ]]; then
clean_terraform_local_state
fi
popd >/dev/null || exit
}
function generate_terraform_lock_command_by_option(){
local platform
case "$PLATFORM" in
windows)
platform="windows_amd64"
;;
linux)
platform="darwin_amd64"
;;
mac)
platform="linux_amd64"
;;
*)
echo "Invalid platform: $PLATFORM"
exit 1
;;
esac
OS="$platform"
echo "Selected platform set: $OS"
}
function clean_terraform_local_state() {
if [[ -f ".terraform.tfstate" ]]; then
echo "Removing terraform.tfstate file"
rm terraform.tfstate
fi
if [[ -f ".terraform.tfstate.backup" ]]; then
echo "Removing terraform.tfstate.backup file"
rm terraform.tfstate.backup
fi
if [[ -d ".terraform" ]]; then
echo "Removing .terraform metadata folder to avoid local state conflicts "
rm -rf .terraform
fi
}
# Parse command line arguments
function parse_args() {
for arg in "$@"; do
echo "argument received --> [$arg]"
echo
done
for i in "$@"; do
case $i in
-d=* | --dir=*)
DIR="${i#*=}"
shift
;;
-=p* | --platform*)
PLATFORM="${i#*=}"
shift
;;
-e=* | --env=*)
ENV="${i#*=}"
shift
;;
-r=* | --runon=*)
RUNON="${i#*=}"
shift
;;
*) fatal "Unknown option: '-${i}'" "See '${0} --help' for usage" ;;
esac
done
}
# Globals
declare DIR
declare ENV
declare RUNON
declare LOCK_FILE=".terraform.lock.hcl"
declare OS
declare PLATFORM
[[ ${BASH_SOURCE[0]} != "$0" ]] || main "$@"
I'm running it from my local as follows:
.fix-terraform-lock-file.sh --dir=infrastructure/terraform/web_static --env=prod --platform=mac --runon=local
Upvotes: 1
Reputation: 24301
The issue is that my local workstation is a Mac which uses the darwin platform, so all of the providers are downloaded for darwin and the hashes stored in the lockfile for that platform. When the CI system, which is running on Linux runs, it attempts to retrieve the providers listed in the lockfile, but the checksums don't match because they use a different platform.
The solution is to use the following command locally to generate a new terraform dependency lock file with all of the platforms for terraform, other systems running on different platforms will then be able to obey the dependency lock file.
terraform providers lock -platform=windows_amd64 -platform=darwin_amd64 -platform=linux_amd64
Upvotes: 68