GAE:如何部署各种秘密环境?

max*_*ime 7 google-app-engine ansible

我在App Engine上有一个暂存和生产项目,每个项目有6个服务.

目前,我们使用开发人员计算机部署 gcloud app deploy app.staging.yaml --project staging-project

要么 gcloud app deploy app.production.yaml --project production-project

它可以工作,但它会导致环境变量问题,尤其是秘密问题.

我们的应用程序从环境变量获取其Api密钥,数据库凭据和其他内容 - 这使我们可以在本地,Docker容器或App Engine中运行完全相同的应用程序,而无需知道它的部署位置.

如果我按照文档方式进行部署,我们的app.yaml文件将如下所示:

app.production.yaml

runtime: nodejs
env: flex

manual_scaling:
  instances: 1
env_variables:
  DATABASE_PASSWORD: "topsecret"
  MY_API_KEY: "ultrasecret"
Run Code Online (Sandbox Code Playgroud)

我想每个人都很容易理解为什么将它存储在Git存储库中是一个坏主意.

目前,我们有一个每个开发人员在部署之前必须填充的影子文件

app.production.yaml.shadow

runtime: nodejs
env: flex

manual_scaling:
  instances: 1
env_variables:
  DATABASE_PASSWORD: "set me"
  MY_API_KEY: "set me"
Run Code Online (Sandbox Code Playgroud)

但随着团队的发展,我们希望每个人都能够在登台时进行部署,为每个开发人员和每项服务设置正确的设置变得越来越困难.

我找到了3个解决方法,以及他们不使用的原因:

  • 使用Google KMS - 允许我们将加密的秘密直接放入项目中,但它要求我们在我们的应用程序中放置自定义代码来解密它们.它在本地,登台和生产之间创建了不同的环境管理.由于复杂性,它增加了错误的风险.
  • 在Google Datastore中存储机密 - 我试过了,我创建了一个帮助程序,在proccess.ENV中搜索env变量,然后在缓存中搜索,最后在Datastore中搜索.但是像KMS一样,它会增加复杂性.
  • 将秘密存储在JSON文件中并放入Google云端存储:再次,它需要通过检查env变量的帮助程序加载env变量,然后加载文件等...

最终,我们正在探索使用可由开发人员或持续集成触发的部署服务器的可行性,并在部署到App Engine时处理所有秘密注入.但是像Ansible,Salt,Puppet,Chef 这样的工具只有Compute Engine的插件,不支持App Engine.

+-------------------------+    +-------------------+   +---------------------+
|                         |    |                   +--->                     |
| Developer workspace     |    |    Ansible        |   | App Engine STAGING  |
|                         +---->   (or other)      |   |                     |
+-------------------------+    |                   |   +---------------------+
                               |                   |
+-------------------------+    |                   |   +---------------------+
|                         +---->   Injects secrets |   |                     |
| Continous Integration        |                   |   | App Engine PROD.    |
|                         |    |                   +--->                     |
+-------------------------+    +-------------------+   +---------------------+
Run Code Online (Sandbox Code Playgroud)

这引出了3个问题:

  • 您认为使用App Engine部署服务器是个好主意吗?
  • 如何确保生产和暂存机密保持同步,以便开发人员的部署始终是正确的?
  • 有没有办法在App Engine上使用经典环境变量来保密?

Ven*_*ius 5

我强烈建议您考虑结合使用KMS和云存储,如Google 在此处概述。

没错,安装起来可能有点麻烦,但是一旦安装到位,就很容易使用。我们建立了独立的钥匙圈为每个环境(devteststagingprod),并为每个应用程序,然后单独的密钥,写一个命令行工具,它使平凡的我们的团队的任何开发人员编写秘密进入秘密存储(而在同一时间阻止他们从阅读生产秘密回来)。

最终,机密管理仍然是一个难题。随着团队的成长,管理多个应用程序/环境的秘密非常困难。但是,我真的鼓励您只付钱购买诸如KMS之类的东西,因为这将使您的生活从根本上更轻松,并真正减少了意外射中脚的风险。


Man*_*ngu 1

正如您所说,不可能将这些解决方案(Ansible、Salt 等)与 App Engine 一起使用。如果你要使用它们,你就必须转向 GCE。谷歌有一些关于如何开始使用这些技术的官方教程。

如果您继续使用 App Engine,则可以使用上述解决方案之一,KMS 更适合此目的。

另一种可能的解决方案是迁移到自定义运行时。根据您的应用程序,您可以使用以下命令生成 Dockerfile:

$ gcloud beta app gen-config --custom

您的 Dockerfile 将如下所示:

FROM gcr.io/google_appengine/nodejs
RUN /usr/local/bin/install_node '>=4.3.2'
COPY . /app/
RUN npm install --unsafe-perm || \
  ((if [ -f npm-debug.log ]; then \
      cat npm-debug.log; \
    fi) && false)
CMD npm start
Run Code Online (Sandbox Code Playgroud)

然后,您可以修改它以包含存储在环境变量中的密钥,例如如何在文件中输入密钥的示例:

sed 's/topsecret/'"$KEY_1"'/g;s/ultrasecret/'"$KEY_2"'/g' app.production.yaml.shadow > app.production.yaml

请注意在 KEY_1 和 KEY_2 前后使用单引号和双引号,因为您需要它们使用sed.