16

无论如何将环境变量从 Cloud Build 注入 App Engine 标准环境?

我不想将我的环境变量推送到 GitHubapp.yaml.env. 因此,当 Cloud Build 拉取和部署时,它会丢失.env文件并且服务器无法完成某些请求。

我试图避免使用 Datastore,因为 Datastore 的异步特性会使代码更加混乱。我尝试使用此处找到的加密机密,但这似乎不起作用,因为我将机密添加到应用程序部署并且它们没有进入部署,所以我认为这不是 Cloud Build 的用例。

我还尝试了这里的教程,将.env文件从存储导入 App Engine 标准,但由于标准没有本地存储,我认为它进入了空白。

那么有没有办法在.env不使用数据存储、提交app.yaml.env更改控制的情况下将其注入 App Engine 标准环境?可能使用 Cloud Build、KMS 或某种类型的存储?

这是我尝试过的cloudbuild.yaml

steps:
- name: "gcr.io/cloud-builders/gcloud"
  args: ["app", "deploy"]
  secretEnv: ['SECRET1', 'SECRET2', 'SECRET3', 'SECRET4', 'SECRET5']
timeout: "1600s"

secrets:
- kmsKeyName: projects/<Project-Name>/locations/global/keyRings/<Key-Ring-Name>/cryptoKeys/<Key-Name>
  secretEnv:
    SECRET1: <encrypted-key-base64 here>
    SECRET2: <encrypted-key-base64 here>
    SECRET3: <encrypted-key-base64 here> 
    SECRET4: <encrypted-key-base64 here> 
    SECRET5: <encrypted-key-base64 here>
4

4 回答 4

19

这是一个关于如何在您的云构建(触发器)设置中安全地存储环境变量并将它们导入您的应用程序的教程。

基本上分为三个步骤:

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

    在构建触发器中添加变量的位置的屏幕截图

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

  2. 配置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"
},

  1. 将环境变量从 .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

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

于 2019-06-29T06:10:27.017 回答
3

如果有人仍然对此感兴趣,我还有另一个解决方案。这应该适用于所有语言,因为环境变量直接添加到app.yaml文件中

  1. 在构建触发器中添加替换变量(如本答案中所述)。

  2. 将环境变量添加到app.yaml可以轻松替换为构建触发器变量的方式。像这样:

    env_variables:
     SECRET_KEY: %SECRET_KEY%
  1. 添加一个步骤,用构建触发器中的值cloudbuild.yaml替换里面的所有%XXX%变量。app.yaml
    - name: 'gcr.io/cloud-builders/gcloud'
      entrypoint: bash
      args:
      - '-c'
      - |
      sed -i 's/%SECRET_KEY%/'${_SECRET_KEY}'/g' app.yaml
      gcloud app deploy  app.yaml

于 2020-02-06T09:15:35.103 回答
0

highfivebrian 的答案很棒,但我添加了稍微不同的解决方案。

1)。在根项目文件夹中,我们需要 cloudbuild.yaml 文件,但我会调用它buildsetttings.yaml,因为第一个名称有问题

在 buildsetttings.yaml 我添加了这段代码:

    steps:
  - name: node
    entrypoint: npm
    args: ['install']
  - name: node
    entrypoint: npm
    env:
      - 'DB_URL=${_DB_URL}'
      - 'SENDGRID_API_KEY=${_SENDGRID_API_KEY}'
      - 'CLIENT_ID=${_CLIENT_ID}'
    args: ['run', 'create-app-yaml']
  - name: 'gcr.io/cloud-builders/gcloud'
    args: ['app', 'deploy']

buildsetttings.yaml 将使用 npmcreate-app-yaml命令在 Cloud Build 中创建 app.yaml 文件。 提示:我们将使用 app.yaml 文件将我们的应用部署到 GCP App Engine。

2)。在根文件夹(靠近 buildsetttings.yaml)中,我们需要创建create-app-yaml.js从 buildsetttings.yaml 调用后将在 Cloud Build 中运行的文件夹。

在 buildsetttings.yaml 我添加了这段代码:

require('dotenv').config();

const fs = require('fs');

const appYamlContent = `runtime: nodejs14
env_variables:
  DB_URL: ${process.env.DB_URL}
  SENDGRID_API_KEY: ${process.env.SENDGRID_API_KEY}
  CLIENT_ID: ${process.env.CLIENT_ID}`;

fs.writeFileSync('./app.yaml', appYamlContent);

此代码使用 npm 包dotenv(将其添加到 package.json)并从 Cloud Build 触发器变量中获取变量并使用它们创建 app.yaml 文件。

3)。app.yaml 文件是在 Cloud 构建中创建的,我们在 buildsetttings.yaml 中的最后一步(名称:'gcr.io/cloud-builders/gcloud'),使用 app.yaml 文件,将项目部署到 Google Cloud App Engine .

成功!

简而言之,它的工作原理如下: buildsetttings.yaml 在 Cloud Build 中运行“create-app-yaml.js”,然后通过添加来自 Cloud Build 触发变量的变量来动态创建 app.yaml 文件,然后在应用引擎。

笔记:

  • 从您的项目中删除文件 app.yamlin,因为它将在 Cloud Build 中动态创建。同时删除 cloudbuild.yaml 文件,因为我们使用的是 buildsetttings.yaml。

  • 包.json:

代码

  • Cloud Build 触发变量:

GCP 构建云 nodejs

于 2021-10-02T23:06:53.437 回答
-1

根据您突出显示的偏好(Cloud Build、KMS)。您提到的 Google Secrets 链接涉及使用Cloud KMS在构建或运行时存储敏感数据:KeyRing 和 CryptoKey。但是,谷歌也提供了其他使用 Cloud KMS 的秘密管理解决方案。

以下是您在存储 Secrets时可以使用的其他几个选项:

选项 1:您可以将机密存储在使用 Cloud KMS 中的密钥加密的代码中。 (这通常用于在应用层加密您的秘密。)

好处:提供了一层安全层来抵御内部威胁,因为它使用相应的密钥限制对代码的访问。

[您可以在此处的 Google 文档中找到有关这些选项的一些附加信息。]

选项 2:您可以将机密存储在您的数据处于静态加密的 Google 存储桶中。(与选项 1 类似,它能够将秘密访问权限限制为一小部分开发人员。)

好处:将您的秘密存储在单独的位置可确保如果您的代码存储库发生泄露,您的秘密可能仍然受到保护。)

[注意:Google 建议您使用两个项目来进行适当的职责分离。一个项目将使用 Cloud KMS 管理密钥,另一个项目将使用 Cloud Storage 存储机密。]

如果上面列出的选项仍然不能满足您的需求,我发现了一个StackOverflow 问题,该问题与您的项目具有相似的目标。(即:在没有Datastore 的情况下在 GAE 中存储环境变量)

链接上提供的解决方案说明了将密钥存储在 client_secrets.json 文件中的使用,该文件在上传到 git 时被排除在 .gitignore 中。您可以在此处找到一些使用的Google 示例(Python) 。

于 2018-10-17T19:03:37.747 回答