Cloudbuild 中的秘密环境变量(没有文件),如何?

Posted

技术标签:

【中文标题】Cloudbuild 中的秘密环境变量(没有文件),如何?【英文标题】:Secret environment variables in Cloudbuild (with out files), how? 【发布时间】:2019-10-27 01:04:13 【问题描述】:

我正在 Cloud Build 中创建一个非常基本的 Node.js 应用程序的 CI/CD 管道,并部署到 GCP appengine 标准。

非机密环境变量存储在app.yaml 文件中。但我当然不想把我的秘密放在那里。事实上,我不想将它们放在任何文件中(无论是否加密),因为该文件最终会出现在 AppEngine 实例上,并且可以被“坏管理员”“查看”。有许多示例建议加密/解密完整文件(有时甚至是代码),但我不想走这条路。

我正在寻找一种将秘密环境变量设置为“内存中”的方法,作为 CI/CD 管道的一部分。有人吗?

我在 app.yaml 文件 (env_variables) 中没有添加任何秘密 - 工作正常 在我的cloudbuild.yaml 文件(秘密)中添加了加密的秘密 - 没有错误 将 secretEnv: 添加到构建步骤中,但值不会在应用引擎中以 process.env.[KEY] 结尾

cloudbuild.yaml

steps:
- name: 'gcr.io/cloud-builders/npm'
  args: ['install']
  dir: "appengine/hello-world/standard"
 - name: "gcr.io/cloud-builders/gcloud"
  args: ["app", "deploy", "test-app.yaml"]
  dir: "appengine/hello-world/standard"
  secretEnv: ['API_KEY', 'API_URL']

secrets:
- kmsKeyName: projects/XXXXXXXX/locations/global/keyRings/customintegrations-secrets/cryptoKeys/integration-secrets
  secretEnv:
    API_KEY: XXQAoHgKKoHBKOURrUU2RqU+ki8XyqmTjz+ns+MEWp5Kx3hQBpgSQgATFQ5yRdW4m1TLNqNRIdHIqVJi8tn8jFrtlHIEouOzNDe/ASlOT0ZQBfl9Rf7xlvOHAa667poBq2hEoMNvOclxUQ==
    API_URL: YYQAoHgKKklo08ZsQF+/8M2bmi9nhWEtb6klyY4rNthUhSIhQ8oSQQATFQ5ywKOxaM/TLwGDmvMtCpl/1stXOOK0kgy42yipYbw/J/QZL68bMat1u4H3Hvp/GMbUVIKEb9jwUtN2xvbL

我希望secretEnv: ['API_KEY', 'API_URL'] 可以使解密后的值可以在应用引擎的代码 (process.env.API_KEY) 中访问。

【问题讨论】:

我一直想做同样的事情,但我发现的唯一方法是使用 Cloud Build 服务帐户有权访问和下载+解密的 KMS 加密 Cloud Storage 中的文件。这是为了集中(在某种程度上)秘密。 谢谢。您如何将文件中的值放入 env 变量中,以便您可以在 process.env.API_KEY 之类的代码中访问它们? 这个tutorial 解释了这个过程,所以一旦在构建步骤中解密了文件,您应该能够正常引用它。 @CorinneWhite 您引用的文档没有将 secretEnv: ['API_KEY', 'API_URL'] 解密值作为 ENV 变量。我已经尝试过了。你是在告诉我,我绝对没有办法达到我所需要的。 IE。 ENV 变量中的秘密,没有包含部署到 GAE 的明文秘密的文件。(详细信息请阅读上文) 使用“gcloud builds submit”命令,您可以替换构建规范中的参数:cloud.google.com/sdk/gcloud/reference/builds/…。查看文档,让我知道它是否适合您。 【参考方案1】:

这里有一个full tutorial,介绍如何在您的云构建(触发器)设置中安全地存储环境变量并将它们导入到您的应用中。

基本上分为三个步骤:

    将您的环境变量添加到您的构建触发器设置之一中的“变量”部分

    Screenshot of where to add variables in build triggers

    按照惯例,在构建触发器中设置的变量必须以下划线 (_) 开头

    配置cloudbuild.yaml(在代码示例的第二步中)从构建触发器中读取变量,将它们设置为环境变量,并将所有环境变量写入本地 .env 文件中

    couldbuild.yaml(下)添加到您的项目根目录

steps:
- name: node:10.15.1
  entrypoint: npm
  args: ["install"]
- name: node:10.15.1
  entrypoint: npm
  args: ["run", "create-env"]
  env:
    - 'MY_SECRET_KEY=$_MY_SECRET_KEY'
- name: "gcr.io/cloud-builders/gcloud"
  args: ["app", "deploy"]
timeout: "1600s"

create-env 脚本添加到package.json

"scripts": 
  "create-env": "printenv > .env"
,

    将环境变量从 .env 读取到您的应用 (config.js)

    安装 dotenv 包

    npm i dotenv -S

    在您的应用中添加config.js

// Import all env vars from .env file
require('dotenv').config()

export const MY_SECRET_KEY = process.env.MY_SECRET_KEY

console.log(MY_SECRET_KEY) // => Hello

完成!现在您可以通过触发云构建来部署您的应用,您的应用将可以访问环境变量。

【讨论】:

虽然你将变量放入 process.env 如果我没记错的话,这个解决方案仍然会创建一个新的 .env 文件,“坏管理员”仍然能够掌握并使用谷歌存储选项获取初始帖子中引用的秘密。 @TommyBs 我想这里的目标是将秘密存储在 GCP 帐户的某个位置,而不是本地代码中。因此,这些秘密只会与您的 GCP 登录一样安全。但是,我个人觉得设置谷歌存储来存储秘密并且必须在您的应用中获取它们是很多工作。 @highfivebrian 这仍然有效吗?我无法从 cloudbuild.yaml 创建 .env 文件。它肯定在几个月前工作。我正在尝试部署相同的代码,它没有在应用引擎中创建 .env 文件。有什么想法吗?【参考方案2】:

在您的 cloudbuild.yaml 中添加云触发步骤以在您的 app.yaml 文件中添加占位符

    steps:
    - name: "gcr.io/cloud-builders/gcloud"
      secretEnv: ['API_KEY','API_URL']
      entrypoint: 'bash'   args: 
      - -c
      - |
        echo $'\n  API_KEY: '$$API_KEY >> app.yaml
        echo $'\n  API_URL: '$$API_URL >> app.yaml
        gcloud app deploy
    availableSecrets:   secretManager:
      - versionName: projects/012345678901/secrets/API_KEY
        env: 'API_KEY'
      - versionName: projects/012345678901/secrets/API_URL
        env: 'API_URL'

看看下面的参考 app.yaml

runtime: nodejs
service: serviceone
env_variables:
  PROJECT_ID: demo
  PORT: 8080

参考:https://***.com/users/13763858/cadet

【讨论】:

看下面的参考 app.yaml runtime: nodejs main: cmd service: serviceone env_variables: PROJECT_ID: demo PORT: 8080

以上是关于Cloudbuild 中的秘密环境变量(没有文件),如何?的主要内容,如果未能解决你的问题,请参考以下文章

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

如何通过 gcloud cli args 或环境变量将 secretEnv 指定给 cloudbuild.yaml

有没有办法让 cloudbuild 步骤访问 GCP 中的 Cloud SQL

Angular 6,我应该将秘密环境变量放在 environment.ts 文件中吗?

使用 tox 和 Github Action 访问环境变量

Cloudbuild - 使用来自不同步骤的自定义变量构建 docker 映像