10

I've noticed that the developer console doesn't seem to expose anywhere where I can configure static environment variables.

Is the expectation on GAE that I will bundle those variables as part of the deployment from my build server? If so, is there any documentation on GAE/Google Cloud that covers why or details the philosophy?

Alexander Trauzzi
  • 7,277
  • 13
  • 68
  • 112

3 Answers3

12

Years have passed, and still it doesn't.

My workaround is to compile app.yaml during deployment process (locally or with CI). For example, I have a template file app.tml.yaml file

runtime: python37
handlers:
- url: /static
  static_dir: app/static/
- url: /.*
  script: auto
env_variables:
  DJANGO_GC_DATABASE_PASSWORD: ${DJANGO_GC_DATABASE_PASSWORD}

Then I call envsubst right before deployment envsubst < ./app.tml.yaml > app.yaml and after that gcloud app deploy as usual. After the deployment is done app.yaml with sensitive data is deleted. Variables are read from local .env file or are set in CI system.

There also other approaches I found listed in this post: https://dev.to/mungell/google-cloud-app-engine-environment-variables-5990 but for me they are not convienient or generic enough.

Daniel Titkov
  • 922
  • 1
  • 9
  • 14
  • Injecting secrets during the build phase is the "correct answer". GCP has Code Build that will allow you to keep secrets and encrypt entire files, and, as @daniel-titkov states, you can use just about any build tool out there to do the same. – Seth Jun 04 '20 at 12:43
  • after research of 3 hours, finally resolved. Thanks – Nalin Dobhal Aug 04 '21 at 13:41
7

Environment variables can be defined in your application's app.yaml

An example for a python/php/(maybe go?) app. Java uses a different format.

env_variables:
  MY_ENV_VAR: 'some value here'

https://cloud.google.com/appengine/docs/python/config/appconfig#Python_app_yaml_Defining_environment_variables

You can set these values during your CI process as well if you need to by programmatically appending them to your app.yaml before deploying.

Josh J
  • 6,813
  • 3
  • 25
  • 47
  • 3
    Just for the sake of completeness, is there anywhere they document the reasoning behind not offering environment variables? Or is there perhaps an opinion/theory piece? – Alexander Trauzzi Jun 30 '15 at 00:06
  • Well the basic concept around standard GAE instances are that they should be created/destroyed anywhere quick and often. You cant set environment variables directly because you have no access to the actual environment. This is only true in the standard instances, in Managed VMs you should be able to set variables like any regular server. – jirungaray Jun 30 '15 at 11:06
  • 3
    To address Omega's question, they DO offer environment variables. You have to define them at deploy time using your `app.yaml`. What they do not offer is an interface to set/unset these variables dynamically without pushing code. It is inconvenient sometimes but it also means you cannot accidentally change something from the web without explicitly pushing code. – Josh J Jun 30 '15 at 12:06
3

One solution is apparently https://cloud.google.com/secret-manager/docs, but I opted for the solution offered here:


Securely storing environment variables in GAE with app.yaml

First, put the environment variables in an env_variables.yaml, e.g.,

env_variables:
  SECRET: 'my_secret'

Then, include this env_variables.yaml in the app.yaml

includes:
  - env_variables.yaml

Finally, add the env_variables.yaml to .gitignore, so that the secret variables won't exist in the repository.


Further,

  • I commit env_variables.sample.yaml, with instructions and placeholder values which the next dev can fill in
  • in dev, I parse env_variables.yaml and add the vars to process.env so I have a single source of truth for those vars…
if (process.env.NODE_ENV === "development") {
  try {
    const fs = require("fs");
    const yaml = require("js-yaml");

    let fileContents = fs.readFileSync("./env_variables.yaml", "utf8");
    let {env_variables} = yaml.load(fileContents);
    console.log({ env_variables });
    Object.keys(env_variables).forEach((v) => {
      process.env[v] = env_variables[v];
    });
  } catch (error) {
    res.status(500).end("500: Problem getting env vars");
    return;
  }
}

I'm adding my solution here as the quoted question specifies python, and this question is generic.

As with other PAAS solutions (eg Heroku, Netlify), if a user has access to the App Engine console, they can see the secrets (in this case by browsing the source files in the console).

ptim
  • 14,902
  • 10
  • 83
  • 103