Terraform Cloud拉取Google Artifact Registry镜像SHA偶现空值问题
解决Terraform Cloud中从Google Artifact Registry拉取镜像SHA偶为空的问题
问题背景
编写了脚本用于从Google Artifact Registry拉取最新镜像版本的SHA值,确保Terraform Cloud部署始终使用GCP镜像的最新版本。本地运行完全正常,但在Terraform Cloud中时常出现SHA为空的情况,无明显规律,成功率仅约50%。同时需要获取Terraform Cloud的详细日志定位问题根源。
原脚本实现
exec 2>/dev/null curl https://sdk.cloud.google.com > install.sh bash install.sh --disable-prompts --install-dir=./ >/dev/null PATH=$PATH:./google-cloud-sdk/bin printf '%s' "$GOOGLE_CREDENTIALS" > key.json gcloud auth activate-service-account --key-file=key.json SHA=$(gcloud artifacts docker images list us-docker.pkg.dev/$2/gcr.io/$1 --sort-by="~UPDATE_TIME" --limit=1 --format="value(format('{0}',version))") while [[ ! "$SHA" =~ ^sha256\:[0-9a-f]{64}$ ]]; do // do some processing here SHA=$(gcloud artifacts docker images list us-docker.pkg.dev/$2/gcr.io/$1 --sort-by="~UPDATE_TIME" --limit=1 --format="value(format('{0}',version))") sleep 5 done cat <<EOF { "sha": "$SHA" } EOF
Terraform调用配置
data "external" "lookup-codes-ol-svc-image-sha" { program = ["${path.module}/scripts/get-image-sha.sh","${local.lookup_codes_ol_svc_name}","${var.common_project_id}"] }
Cloud Run容器定义
containers { image = "gcr.io/${var.common_project_id}/${local.lookup_codes_ol_svc_name}@${data.external.lookup-codes-ol-svc-image-sha.result["sha"]}" }
排查步骤
获取Terraform Cloud详细日志:
- 进入对应工作区的运行记录,点击目标运行任务查看完整日志输出。
- 若默认日志信息不足,可在工作区的
Settings > General中开启Verbose Logging,重新触发运行后即可获取更详细的执行日志,便于定位脚本执行中的错误。
定位问题根源:
通过详细日志发现,Terraform Cloud的容器复用机制导致安装Google Cloud SDK时出现目录非空错误,初始添加简单检查和重试后成功率有所提升,但仍偶发SHA为空的情况。
最终优化方案
通过为SDK安装创建唯一目录、增强SHA获取的重试机制,解决了偶现的SHA为空问题,优化后的脚本如下:
datenum=$(expr $(date +%s) + 0) dirstring="$((datenum % 10000))dir" retries=5 while true; do res=$(mkdir $dirstring 2>&1) if echo "$res" | grep -Eq '^.{0}$'; then break fi sleep 5 datenum=$(expr $(date +%s) + 0) dirstring="$((datenum % 10000))dir" retries=$((retries - 1)) if [ $retries -eq 0 ]; then echo "Failed to create directory" exit 1 fi done curl https://sdk.cloud.google.com > install.sh bash install.sh --disable-prompts --install-dir=./$dirstring >/dev/null PATH=$PATH:./$dirstring/google-cloud-sdk/bin printf '%s' "$GOOGLE_CREDENTIALS" > key.json gcloud auth activate-service-account --key-file=key.json SHA=$(gcloud artifacts docker images list us-docker.pkg.dev/$2/gcr.io/$1 --sort-by="~UPDATE_TIME" --limit=1 --format="value(format('{0}',version))") retries=5 while true; do if echo "$SHA" | grep -Eq '^sha256\:[0-9a-f]{64}$'; then break fi sleep 5 SHA=$(gcloud artifacts docker images list us-docker.pkg.dev/$2/gcr.io/$1 --sort-by="~UPDATE_TIME" --limit=1 --format="value(format('{0}',version))") retries=$((retries - 1)) if [ $retries -eq 0 ]; then echo "Failed to get SHA for image us-docker.pkg.dev/$2/gcr.io/$1" exit 1 fi done cat <<EOF { "sha": "$SHA" } EOF
优化点说明
- 动态唯一目录:基于时间戳生成唯一目录名,避免Terraform Cloud容器复用导致的SDK安装目录冲突,并添加目录创建重试机制,确保目录创建成功。
- 增强SHA重试逻辑:设置固定重试次数,每次失败后等待5秒重试,直到获取到符合
sha256:[0-9a-f]{64}格式的SHA值,避免临时网络波动或GCP API响应异常导致的空值问题。
优化后的脚本已稳定运行一周,彻底解决了Terraform Cloud中偶现的SHA为空问题。
内容的提问来源于stack exchange,提问作者Chris Lyons
相关产品推荐
相关产品推荐

