对于 CI 模板和修复管道运行的替换验证脚本,Cloud Build 失败并出现错误 SUBSTITUTIONVARIABLENOT_DEFINED

已发表: 2025-11-29

Cloud Build 已成为许多开发人员和组织持续集成和部署工作流程中的关键工具。它与其他 Google Cloud Platform (GCP) 产品和可编写脚本的工作流程紧密集成,使其成为需要可定制和可扩展的 CI/CD 管道的团队的最爱。然而,与许多强大的工具一样,Cloud Build 也有其怪癖,尤其是在变量和参数化方面。最近许多开发人员遇到的一个令人沮丧的问题是SUBSTITUTION_VARIABLE_NOT_DEFINED错误。这个难以捉摸的问题可能会导致整个管道停止运行,影响开发速度并增加故障排除时间。

长话短说

如果您的 Cloud Build 管道失败并出现SUBSTITUTION_VARIABLE_NOT_DEFINED错误,则可能意味着您的构建触发器或配置文件中缺少所需的替换变量。当使用跨存储库共享的 CI 模板时,这种情况很常见。自定义变量验证脚本通过在运行时检查所有必需的变量来修复此问题,提供更清晰的反馈并防止错误的构建。该解决方法还提高了整体管道的稳健性并最大限度地减少了手动调试工作。

了解 SUBSTITUTION_VARIABLE_NOT_DEFINED 错误

当构建流程引用尚未在该构建上下文中定义的替换变量时,Cloud Build 会发出SUBSTITUTION_VARIABLE_NOT_DEFINED错误。这些替换变量允许您自定义构建步骤和模板,而无需将值直接硬编码到管道 YAML 中,从而提高可重用性和清晰度。

例如,常见的 Cloud Build 模板可能包括如下所示的构建步骤:

步骤:
- 名称:'gcr.io/cloud-builders/docker'
  参数:['build', '-t', '${_IMAGE_NAME}', '.']

这里, ${_IMAGE_NAME}是用户定义的替换变量。如果在触发构建时未提供此变量(可能通过触发器配置或命令行),Cloud Build 将立即失败并出现SUBSTITUTION_VARIABLE_NOT_DEFINED错误。

CI 模板实现的根本原因

当团队使用共享模板时,或者当不同的存储库通过集中式 YAML 配置搭载相同的 CI 逻辑时,这个问题变得特别麻烦。通常,每个存储库或构建触发器可能需要定义不同的变量,但强制一致性变得具有挑战性。许多团队假设替换变量是可选的,或者它有默认的后备,只有当该变量在需要它的构建上下文中不存在时才会遇到此错误。

可能出现此错误的情况:

  • 当触发器设置中忘记默认值时
  • 添加新模板但未记录或强制执行所有必需的变量时
  • 当开发人员跨环境(例如,登台、生产)克隆模板但省略特定变量定义时

实用的修复:替换验证脚本

为了解决这个问题并防止未来的中断,几个团队引入了预验证机制 - 一个嵌入式验证脚本,该脚本在管道开始时运行,以在执行任何关键步骤之前检查所需的替换变量。

该脚本扫描当前环境并尝试断言所有关键变量是否存在(有时是类型或模式)。如果缺少任何变量,它会提前停止执行并提供一个人类可读的缺少变量的列表。

下面是用 bash 编写的此类脚本的简化示例:

#!/bin/bash
设置-e

REQUIRED_VARS=(
  “_IMAGE_NAME”
  “_SERVICE_NAME”
)

对于“${REQUIRED_VARS[@]}”中的 VAR
做
  如果 [[ -z "${!VAR}" ]];然后
    echo“错误:未定义所需的替换变量 ${VAR}。”
    1号出口
  菲
完毕

echo“所有必需的替换变量都存在。”

通过将此步骤放在构建管道的顶部,团队可以及早发现错误,减少浪费的计算周期,并向其他开发人员提供更有用的反馈。

集成到云构建工作流程中

在实际工作流程中,验证 shell 脚本可以作为内联命令包含在内,也可以从安全位置(例如版本控制的 GCS 存储桶)中的共享脚本文件导入。这通常是 cloudbuild.yaml 文件中的第一步:

步骤:
- 名称:'gcr.io/cloud-builders/bash'
  入口点:'bash'
  参数:['-c', './validate_vars.sh']

这使团队能够:

  • 版本化他们的 CI 验证逻辑
  • 维护预期变量的单一事实来源
  • 减少涉及试错触发器编辑的嘈杂调试周期

增强的开发人员体验

该验证脚本的引入产生了立竿见影的效果:

  • 由于未被注意到的缺失变量而导致的管道故障更少
  • 更清晰的错误消息直接指向问题,而不是晦涩的日志。
  • 新开发人员可以更快地入职,他们可以重用现有的 CI 工作流程,而无需了解预期变量的完整知识。

随着时间的推移,一些团队扩展了验证器以允许可选变量并设置后备,从而为共享模板提供了更大的灵活性。其他人将其与 YAML 模式验证配对,以在运行时检查整个 cloudbuild.yaml 管道。

防止新项目中的错误

为了使未来的项目免受此问题的影响,建议遵循以下最佳实践:

  • 在存储库的 README 或 CI 指南中记录所有必需的替换变量
  • 在添加到 CI/CD 工作流程的每个新模板中使用验证脚本
  • 定义清晰的命名约定(例如,以 _ 开头的变量意味着需要自定义替换)。
  • 在适当的情况下在构建中设置默认值或通过脚本提供可选的变量逻辑。

最后的想法

尽管SUBSTITUTION_VARIABLE_NOT_DEFINED错误乍一看似乎无害,但它代表了 CI/CD 卫生和配置管理中更广泛的问题。将变量验证视为管道的一流组件可确保更强大的自动化实践、更少的损坏构建以及更快乐的开发人员。通过引入简单的验证脚本,许多团队能够简化其管道工作流程并显着减少停机时间和调试工作。

常见问题解答:云构建替换变量和验证

  • 问:Cloud Build 中的替代变量是什么?
    替换变量是 cloudbuild.yaml 文件中的占位符,触发构建时将替换为实际值。这些变量用于为不同的环境或配置定制构建。
  • 问:为什么我会看到 SUBSTITUTION_VARIABLE_NOT_DEFINED 错误?
    当 YAML 文件中引用的变量未通过构建触发器或环境传递,导致其在运行时未定义时,通常会发生此错误。
  • 问:触发构建时如何提供替换变量?
    您可以在设置触发器时通过 Google Cloud Console 传递替换变量,或者使用--substitutions标志通过 gcloud CLI 传递替换变量。
  • 问:我可以为替换变量设置默认值吗?
    Cloud Build 不支持直接在 YAML 中使用默认值,但您可以编写逻辑脚本来处理未定义的变量,并在 bash 或 Python 脚本中以编程方式分配后备值。
  • 问:在多个项目中强制变量存在的最佳方法是什么?
    在所有 cloudbuild.yaml 模板的开头使用共享验证脚本来强制一致性并在继续构建作业之前验证输入。