如何在 Google App Engine 标准环境中使用 Google Cloud Build 或其他方法设置环境变量?

How to set environment variables using Google Cloud Build or other method in Google App Engine Standard Environment?

是否可以将 Cloud Build 中的环境变量注入 App Engine 标准环境?

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

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

我还尝试了教程 here,将 .env 文件从存储导入 App Engine 标准,但由于标准没有本地存储,我认为它无效。

那么,是否可以在不使用 Datastore 或提交 app.yaml.env 来更改控制的情况下将 .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>

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

以下是您可以在 storing Secrets:

时使用的其他几个选项

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

好处: 提供一层 安全性 来抵御内部威胁,因为它 限制访问 代码 和对应的密钥 .

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

选项 2:您可以在 Google 存储 Bucket where your data is at rest encryption.存储秘密 (与选项 1 类似,它能够将对秘密的访问限制为一小部分开发人员。)

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

[注:Google建议您使用两个项目来适当separation of duties。一个项目将使用 Cloud KMS 来管理密钥,另一个项目将使用 Cloud Storage 来存储机密。]

如果上面列出的选项仍然不能满足您的需求,我找到了一个 Whosebug question 与您的项目共享相似的 objective。 (即:在没有 数据存储的情况下在 GAE 中存储环境变量)

link illustrates the use of storing keys in a client_secrets.json file that gets excluded when uploading to git by listing it in .gitignore. You can find some Google examples (Python) of usage here上提供的解决方案。

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

基本上分为三个步骤:

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

    Screenshot of where to add variables in build triggers

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

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

    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

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

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

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

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

    env_variables:
     SECRET_KEY: %SECRET_KEY%
  1. cloudbuild.yaml 中添加一个步骤,用构建触发器中的值替换 app.yaml 中的所有 %XXX% 变量。
    - 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

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

1). 在根项目文件夹中,我们需要 cloudbuild.yaml 文件,但我将其命名为 buildsetttings.yaml,因为 第一个名字有 problem

在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 将使用 npm create-app-yaml 命令在 Cloud Build 中创建 app.yaml 文件。 提示: app.yaml 文件,然后我们将使用该文件将我们的应用程序部署到 GCP App Engine。

2). 在根文件夹中(buildsetttings.yaml 附近)我们需要创建 create-app-yaml.js 之后将在 Cloud Build 中 运行它是从 buildsetttings.yaml.

调用的

在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 Trigger Variables 获取变量并使用它们创建 app.yaml 文件。

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

成功!

简而言之,它是这样工作的: buildsetttings.yaml 运行 “create-app-yaml.js” 在 Cloud Build 中,之后它通过从 Cloud Build Trigger Variables 添加变量动态创建一个 app.yaml 文件,然后在 App Engine 中进行部署。

备注:

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

  • package.json:

  • Cloud Build 触发器变量: