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

时间:2019-07-08 13:55:55

标签: google-cloud-platform google-cloud-build google-cloud-kms

我正在尝试创建一个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(以“ CiQAH ...”开头)中的base64字符串更改为诸如$ {__ KMS_VAR_HELLO_WORLD}之类的替代变量,则会收到以下错误消息:

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

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

所以我的猜测是,Cloud Build不会替代cloudbuild.yaml的secret部分中的任何内容。有人知道解决方案吗?

3 个答案:

答案 0 :(得分:1)

这是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"

答案 1 :(得分:0)

这是API的已知限制。

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

答案 2 :(得分:0)

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

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

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

其中 hello.sh 定义为:

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

假设解密后的值是 "bar" — 我发现通过没有在 args 中明确传入 CLI 参数,它实际上是有效的,哈哈。