How to authenticate to gcp when using terraform cloud

Hi,

sorry for the noob question. I have a main.tf like so:

provider "google" {
  project = "terrademo"
  region  = "europe-west3"
  zone    = "europe-west3-a"
}

resource "google_compute_instance" "vm_instance" {
  name         = "terraform-instance"
  machine_type = "f1-micro"

  boot_disk {
    initialize_params {
      image = "debian-cloud/debian-9"
    }
  }

  network_interface {
    # A default network is created for all GCP projects
    network = "default"
    access_config {
    }
  }
}

resource "google_compute_network" "vpc_network" {
  name                    = "terraform-network"
  auto_create_subnetworks = "true"
}

terraform {
  backend "remote" {
    hostname      = "app.terraform.io"
    organization  = "my-org"

    workspaces {
      name = "my-repo"
    }
  }
}

I have a google service account and I can access gcp locally, but now when using the vcs workflow in terraform cloud, it obviously does not work, because I need to setup variables in terraform cloud … I just don’t know what pieces of the google service account json, which I received for the local setup I need to extract

I tried creating the environment variable: GOOGLE_APPLICATION_CREDENTIALS

1 Like

Hi,

Please see https://www.terraform.io/docs/backends/types/gcs.html

  • credentials / GOOGLE_BACKEND_CREDENTIALS / GOOGLE_CREDENTIALS - (Optional) Local path to Google Cloud Platform account credentials in JSON format. If unset, Google Application Default Credentials are used. The provided credentials need to have the devstorage.read_write scope and WRITER permissions on the bucket. Warning : if using the Google Cloud Platform provider as well, it will also pick up the GOOGLE_CREDENTIALS environment variable.
  • access_token - (Optional) A temporary [OAuth 2.0 access token] obtained from the Google Authorization server, i.e. the Authorization: Bearer token used to authenticate HTTP requests to GCP APIs. This is an alternative to credentials . If both are specified, access_token will be used over the credentials field.

thank you for your answer. unfortunately I do not understand what you said. you are linking me to the docs of terraform cli, but I am not using terraform cli, I am using terraform cloud and I am triggering changes in infrastructure through vcs… sooo what good is the gcp backend if I want to manage state via terraform cloud … sorry if I misunderstand something … also here is the nudge I get from the run in terraform cloud:

Terraform v0.13.5
Configuring remote state backend...
Initializing Terraform configuration...
e[0me[1mRefreshing Terraform state in-memory prior to plan...e[0m
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.
e[0m

------------------------------------------------------------------------
e[33m
e[1me[33mWarning: e[0me[0me[1mValue for undeclared variablee[0m

e[0mThe root module does not declare a variable named
"GOOGLE_APPLICATION_CREDENTIALS" but a value was found in file
"/terraform/infrastructure/terraform/terraform.tfvars". To use this value, add
a "variable" block to the configuration.

Using a variables file to set an undeclared variable is deprecated and will
become an error in a future release. If you wish to provide certain "global"
settings to all configurations in your organization, use TF_VAR_...
environment variables to set these instead.
e[0me[0m
e[31m
e[1me[31mError: e[0me[0me[1mAttempted to load application default credentials since neither `credentials` nor `access_token` was set in the provider block.  No credentials loaded. To use your gcloud credentials, run 'gcloud auth application-default login'.  Original error: google: error getting credentials using GOOGLE_APPLICATION_CREDENTIALS environment variable: open {: no such file or directorye[0m

e[0me[0me[0m

I guess all I have to do is to provide an environment variable right, but I can’t just paste in the json contents itself

I am not using Terraform Cloud, but looking at your error

e[0mThe root module does not declare a variable named
“GOOGLE_APPLICATION_CREDENTIALS” but a value was found in file
“/terraform/infrastructure/terraform/terraform.tfvars”. To use this value, add
a “variable” block to the configuration.

It tells you to add a variable block to your configuration/variables.tf named GOOGLE_APPLICATION_CREDENTIALS

That’s just because I tried providing the credentials for gcp through a terraform variable instead of an environment variable, if I add the variable in the configuration I get the same error that I get without specifying any variables:

Error: Attempted to load application default credentials since neither `credentials` nor `access_token` was set in the provider block.  No credentials loaded. To use your gcloud credentials, run 'gcloud auth application-default login'.  Original error: google: error getting credentials using GOOGLE_APPLICATION_CREDENTIALS environment variable: open {: no such file or directory

in a nutshell I am trying to do the exact same thing in terrafrom cloud as exporting the json locally

Found an answer here:

2 Likes

Create an environment variable: GOOGLE_CREDENTIALS
Copy/paste the json with the credentials into the value field.
(don’t create a variable in your .tf file)

If you get a validation error because of line breaks, remove the line breaks.
An easy way to do that is to just create a terraform variable in the cloud gui exactly as above. After hitting save, just click edit again and the json will not contain line breaks anymore (why doesn’t the other section have this feature ???, idk)…
Now create the env variable in the gui, copy the json from above, save, delete the terraform variable and manually queue a run … hope that helps!

Should look like this then:

4 Likes

Hi there,
Amazing solution you’ve found there, worked for me too, thanks for that!

In additional, in order to extend the test I created a terraform variable instead of environment variables, with the same value (the json file content), it worked too, however I had to got through a few more steps:

  1. Added the terraform variable, using a random key (I created something like “google_creds”)

  2. In the main.tf file, in the provider block I added the credentials field with its value being var.google_creds (credentials = var.google_creds)

  3. I created a variables.tf file (but you can also declare variables in the main.tf file if you want) with the variable name and type only (variables “google_creds” { type = string })

And in my case, my code is in a github repo and terraform cloud workspace configured to receive its webhook, after performing a push, the terraform plan worked successfully!!