Terraform:无法安装提供程序,与依赖项锁定文件中的校验和不匹配



我使用CI系统编译terraform提供程序并将它们捆绑到一个映像中,但每次运行terraform init时,我都会收到以下错误/失败。

│ 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

对于我的提供者文件中列出的所有提供者,都会重复此消息,如下所示:

terraform {
required_version = ">= 0.13"
required_providers {
azurerm = {
source  = "hashicorp/azurerm"
version = "2.55.0"
}
github = {
source  = "integrations/github"
version = "4.8.0"
}
}
...snip...
}

terraform hcl锁文件存储在repo中,只有当锁文件存在于repo中时,才会出现这些错误,并且terraform init失败。原因可能是什么?

问题是,我的本地工作站是一台使用darwin平台的Mac,因此所有的提供程序都是为darwin下载的,哈希存储在该平台的锁定文件中。当运行在Linux上的CI系统运行时,它会尝试检索锁定文件中列出的提供程序,但校验和不匹配,因为它们使用不同的平台。

解决方案是在本地使用以下命令生成一个新的terraform依赖锁定文件,该文件与terraform的所有平台一起使用,然后在不同平台上运行的其他系统将能够遵守依赖锁定文件。

terraform providers lock -platform=windows_amd64 -platform=darwin_amd64 -platform=linux_amd64

为了稍微改进上面已经发布的内容,我在本地机器和自动化(Github操作(中都做了同样的修复,将这个解决方案封装到一个小的bash脚本中。将这个脚本放入GH操作将以更广泛的方式解决这个问题

#!/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 "$@"

我在本地运行它,如下所示:

.fix-terraform-lock-file.sh --dir=infrastructure/terraform/web_static --env=prod --platform=mac --runon=local

最新更新