One feature that’s been noticeably absent from the Cloud Functions runtime until very recently has been support for environment variables.
Google’s Cloud Functions have been around for a little while now. The product works well with other Google Cloud Platform offerings and provides a scalable, event-driven runtime for serverless applications or microservices. Developers can write functions using (a relatively old version of
¯\_(ツ)_/¯) Node.js (other language runtimes aren’t available at this point
¯\_(ツ)_/¯) and attach them to events. Supported event triggers include a HTTP request, a message being published to a pub/sub topic or changes to an object in a cloud storage bucket.
One feature that’s been noticeably absent from the Cloud Functions runtime until very recently has been support for environment variables. This omission has made it more difficult than necessary to provide values to functions at runtime without using a database or hard coding. These are not ideal approaches to managing values such as third party API keys. The lack of environment variables has also made it awkward to manage the normal progression of code through development, QA, staging and production environments for example if different keys to the same third party API are required in each.
Fortunately Google recently played catchup, adding support for environment variables as a beta feature. This helps to close the gap between Google’s Cloud Functions and Amazon’s AWS Lambda, which had this feature since forever. Let’s take a look at how it works in practice…
There’s nothing exciting here… we can get the value of an environment variable in the same way as we would do in any other Node.js runtime. Let’s use a function called
helloEnvVarsthat we’ll attach to a URL for a browser to read:
The code expects three environment variables:
If it can’t find a value for any of these, it will fallback to displaying “UNKNOWN” in the resulting HTML.
If we deploy the function as usual (substitute
<projectID> for your Google Cloud Platform project ID):
$ gcloud functions deploy helloEnvVars --trigger-http --project <projectID>
We can then point a browser at the URL that appears in the gcloud command’s output and see that none of these environment variables are currently set…
Environment variables are set when the function is deployed. This is currently a beta function, so we’ll need to ensure that the gcloud command has beta functionality installed:
$ gcloud components update
$ gcloud components install beta
There are two ways to set environment variables:
To set an environment variable from the command line:
$ gcloud beta functions deploy helloEnvVars --trigger-http --set-env-vars SUCH_SECRET=hello --project <projectID>
(Note: we are now using
gcloud beta functions deploy)
Multiple environment variables can be set with a single command by providing a comma separated list of
$ gcloud beta functions deploy helloEnvVars --trigger-http --set-env-vars SUCH_SECRET=Hello,MANY_ENCRYPTS=World --project <projectID>
Revisiting the function’s URL shows that the code is able to access the values:
For large numbers of values or as part of a continuous integration progress, it probably makes more sense to use a file to deploy environment variables. Google supports the use of a YAML file for this. Let’s create a file called
To deploy the function and set all of the environment variables in the file, use:
$ gcloud beta functions deploy helloEnvVars --trigger-http --env-vars-file env.yaml --project <projectID>
Note: This method will reset the environment so that only the environment variables declared in the file are set. Any that previously existed and which are not listed in the file will be unset.
It’s important to note that environment variables are only set for the function that they are deployed with. If you have multiple functions in your project’s
index.js file or similar, deploying one of them with environment variables configured does not cause those environment variables to be available to other functions.
Updating environment variables appears to work in the same way as setting them for the first time, but using
$ gcloud beta functions deploy helloEnvVars --trigger-http --update-env-vars SUCH_SECRET=Updated --project <projectID>
As with the other commands, you can supply a comma separated list or specify a YAML file together with
It seems that you can also use
--set-env-vars to overwrite the values of existing environment variables and
--update-env-vars to add values for new ones. The two seem pretty interchangeable
¯\_(ツ)_/¯.I think I’ll stick with just using
--set-env-vars for everything unless there’s a good reason not to.
Environment variables can be unset (removed) individually. Let’s remove two in one command:
$ gcloud beta functions deploy helloEnvVars --trigger-http --remove-env-vars SUCH_SECRET,MANY_ENCRYPTS --project <projectID>
We can also unset all environment variables at once:
$ gcloud beta functions deploy helloEnvVars --trigger-http --clear-env-vars --project <projectID>
Remember: Environment variables are scoped to the function that they are deployed with. Removing them for one function in your project won’t remove them for others even if the other functions are defined in the same
I tripped over a few things while researching this topic, so thought I’d add these here to help others.
.gitignorefile as you likely don't want these adding to source control!
gcloud beta functions deploy helloEnvVars --trigger-http --project <projectID>
gcloudafter each successful function deployment
Don’t forget to quote and escape values when using
$ gcloud beta functions deploy helloEnvVars --trigger-http --set-env-vars MANY_ENCRYPTS="it'srTgHi0444452\!" --project <projectID>
If you don’t do this, the shell will try and interpret the values.
When deploying environment variables in a YAML file, be careful of values that can be interpreted as
int types by the YAML parser, e.g.:
These cause deployment errors:
ERROR: gcloud crashed (ValidationError): Expected type <type 'unicode'> for field value, found True (type <type 'bool'>)
The answer is to explicitly make the value a string:
The same applies to numeric values, for example:
will error on deploy, but:
If you’d like to use or study the code from this article feel free: I’ve put it on GitHub for you.
I spent time researching this topic while helping to build features for Zesty.io, a SaaS Content Management System running on Google Cloud. Thanks for reading, please give me a follow if you’d like to see more in future! I write about a range of technologies including Node.js, Go, Python, Raspberry Pi and Amazon Alexa.
This article first appeared on ITNEXT.