Google Cloud Build 不会替换 cloudbuild.yaml 的机密部分中的值

Posted

技术标签:

【中文标题】Google Cloud Build 不会替换 cloudbuild.yaml 的机密部分中的值【英文标题】:Google Cloud Build doesn't substitute values in secrets section of cloudbuild.yaml 【发布时间】:2019-11-18 01:31:00 【问题描述】:

我正在尝试创建一个 Cloud Build 触发器,其中秘密环境变量使用 Cloud KMS 加密并存储为 Cloud Build 中的替代变量。这样,我的云构建 yaml 相当通用,并且在我们部署到的所有环境中都是相同的。

此云构建 yaml 工作正常:

steps:
- name: 'ubuntu'
  entrypoint: 'bash'
  args: ['-c', 'echo "$$APP_NAME HAS A VALUE $$HELLO_WORLD"']
  env:
    - 'APP_NAME=$_APP_NAME'
  secretEnv:
    - 'HELLO_WORLD'
secrets:
- kmsKeyName: 'projects/my-first-cicd-project/locations/europe-west1/keyRings/keyring-dev/cryptoKeys/key-backend'
  secretEnv:
    HELLO_WORLD: xxxxxxxxxxx

构建步骤产生以下日志行:

My App Name HAS A VALUE Hello there world!

完全符合预期。

现在是那些不起作用的事情,或者至少我不能去工作。假设我想让密钥环名称动态化。然后,我将该 yaml 中的“keyring-dev”替换为$_KMS_KEYRING_NAME。这将产生如下错误:

invalid build: failed to check access to "projects/my-first-cicd-project/locations/europe-west1/keyRings/$_KMS_KEYRING_NAME/cryptoKeys/key-backend"

如果我将 YAML 中的 base64 字符串(以“CiQAH...”开头)更改为 $_KMS_VAR_HELLO_WORLD 之类的替换变量,我会收到以下错误:

failed unmarshalling build config cloudbuild.yaml: illegal base64 data at input byte 0

仅供参考:base64 字符串的值不超过变量值的最大字符数 255。

所以我的猜测是,Cloud Build 不会替代 cloudbuild.yaml 的机密部分中的任何内容。有谁知道这个问题的解决方案吗?

【问题讨论】:

您好。我能够重现这一点,所以我可以验证你并不孤单。我正在内部与团队核实这是文档中的错误还是疏忽。 【参考方案1】:

这是 API 的一个已知限制。

替换适用于“字符串”字段,尽管秘密值使用“字节”字段。因此,我们不能对它们应用替换值。 关于 Keyring 名称和项目,更改它们会更改加密内容,并且内容不可替代。

【讨论】:

【参考方案2】:

这是 cloudbuild secrets api 的一个限制,但我使用了一种解决方法,涉及在构建步骤中解密秘密,如下所示:

steps:
- name: 'gcr.io/cloud-builders/gcloud'
  entrypoint: 'bash'
  args:
    - -c
    - |
      export HELLO_WORLD=$(echo -n $_ENC_HELLO_WORLD | \
        base64 -d - | \
        gcloud kms decrypt \
          --ciphertext-file - \
          --plaintext-file - \
          --project $PROJECT_ID \
          --location global \
          --keyring $_KMS_KEYRING_NAME \
          --key key-backend \
      )

      echo "$_APP_NAME has a value $$HELLO_WORLD"

【讨论】:

【参考方案3】:

我发现自动解密的值似乎是作为 bash 变量隐式注入的。

例如,如果我有以下脚本:

entrypoint: 'bash'
args: ['bin/hello.sh']
secretEnv:
- foo

其中hello.sh定义为:

#!/usr/bin/env bash
echo $foo

假设解密后的值为"bar"——我发现通过不在args 中显式传递 CLI 参数,它实际上是有效的,哈哈。

【讨论】:

以上是关于Google Cloud Build 不会替换 cloudbuild.yaml 的机密部分中的值的主要内容,如果未能解决你的问题,请参考以下文章

“gcloud builds submit”不会因为缺少所需的替换而触发错误

Google Cloud Build Bitbucket 集成不支持 git 标签

Google Cloud Build 超时

Google Cloud Build 中的环境变量

Google Cloud Build 可以通过工件目录递归吗?

在 Google Cloud Build 上使用 Docker Buildkit