Environment variables in Google Cloud Build

Nuruddin Iminokhunov picture Nuruddin Iminokhunov · Jul 29, 2018 · Viewed 9k times · Source

We want to migrate from Bitbucket Pipelines to Google Cloud Build to test, build and push Docker images.

How can we use environment variables without a CryptoKey? For example:

- printf "https://registry.npmjs.org/:_authToken=${NPM_TOKEN}\nregistry=https://registry.npmjs.org" > ~/.npmrc

Answer

bszom picture bszom · Jun 13, 2019

To use environment variables in the args portion of your build steps you need:

  • "a shell to resolve environment variables with $$" (as mentioned in the example code here)
  • and you also need to be careful with your usage of quotes (use single quotes)

See below the break for a more detailed explanation of these two points.

While the Using encrypted resources docs that David Bendory also linked to (and which you probably based your assumption on) show how to do this using an encrypted environment variable specified via secretEnv, this is not a requirement and it works with normal environment variables too.

In your specific case you'll need to modify your build step to look something like this:

# you didn't show us which builder you're using - this is just one example of
# how you can get a shell using one of the supported builder images

- name: 'gcr.io/cloud-builders/docker'
  entrypoint: 'bash'
  args: ['-c', 'printf "https://registry.npmjs.org/:_authToken=%s\nregistry=https://registry.npmjs.org" $$NPM_TOKEN > ~/.npmrc']

Note the usage of %s in the string to be formatted and how the environment variable is passed as an argument to printf. I'm not aware of a way that you can include an environment variable value directly in the format string.

Alternatively you could use echo as follows:

args: ['-c', 'echo "https://registry.npmjs.org/:_authToken=$${NPM_TOKEN}\nregistry=https://registry.npmjs.org" > ~/.npmrc']


Detailed explanation:

My first point at the top can actually be split in two:

  1. you need a shell to resolve environment variables, and
  2. you need to escape the $ character so that Cloud Build doesn't try to perform a substitution here

If you don't do 2. your build will fail with an error like: Error merging substitutions and validating build: Error validating build: key in the template "NPM_TOKEN" is not a valid built-in substitution

You should read through the Substituting variable values docs and make sure that you understand how that works. Then you need to realise that you are not performing a substitution here, at least not a Cloud Build substitution. You're asking the shell to perform a substitution.

In that context, 2. is actually the only useful piece of information that you'll get from the Substituting variable values docs (that $$ evaluates to the literal character $).

My second point at the top may be obvious if you're used to working with the shell a lot. The reason for needing to use single quotes is well explained by these two questions. Basically: "You need to use single quotes to prevent interpolation happening in your calling shell."