5

My terraform gcp provider config looks like

provider "google" {
  project     = var.project
  region      = var.region
  credentials = file("account.json")
}

I want to run my terraform file on terraform cloud and I don't want want to put the account.json file in source control. How can I store the json GCP service account file in terraform cloud and then access it from the terraform script?

ams
  • 60,316
  • 68
  • 200
  • 288
  • 1
    Are you set on using a file for that? you can alternatively use a string variable and pass the content of that file, then just use the Terraform Variables or Environment Variables similar to the tutorial for AWS: https://learn.hashicorp.com/terraform/cloud-getting-started/setup-workspace#configure-workspace-variables – Helder Sepulveda Jun 20 '20 at 23:37

3 Answers3

6

You can supply the credentials as an Multi-Line value called google_credentials in the Terraform Cloud UI and mark it as a Sensitive Value and enter something like this with the correct values for your account (likely just a copy paste of your account.json file you have already):

{
  "type": "service_account",
  "project_id": "project-id",
  "private_key_id": "key-id",
  "private_key": "-----BEGIN PRIVATE KEY-----\nprivate-key\n-----END PRIVATE KEY-----\n",
  "client_email": "service-account-email",
  "client_id": "client-id",
  "auth_uri": "https://accounts.google.com/o/oauth2/auth",
  "token_uri": "https://accounts.google.com/o/oauth2/token",
  "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
  "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/service-account-email"
}

You can then provide the credentials from the workspace variable to your google provider in your Terraform module as follows as a single variable which will be interpreted as JSON:

provider "google" {
  project     = var.project
  region      = var.region
  credentials = var.google_credentials
}

variable "google_credentials" {
  description = "the contents of a service account key file in JSON format."
  type = string
}

credentials - (Optional) Either the path to or the contents of a service account key file in JSON format. You can manage key files using the Cloud Console.

From Google Provider Configuration Reference.

Alain O'Dea
  • 21,033
  • 1
  • 58
  • 84
  • If you run it outside of terraform cloud is there a special syntax to set the multiline variable in .tfvars how do you make the .tf work on local machine and terraform cloud – ams Jun 21 '20 at 12:40
  • 1
    You are better off supplying the path to account.json when running it locally. Multiline tfvars values are awkward. That will work too.`terraform apply -var='google_credentials="/absolute/path/to/account.json"` – Alain O'Dea Jun 21 '20 at 12:47
  • @ams please accept my answer as it addresses your question as written. I'm happy to respond to additional questions if you post and link to them. – Alain O'Dea Jun 21 '20 at 14:59
  • @AlainO'Dea : I tried this and it looks like a direct copy paste of JSON doesn't work. Have you tested this ? – Prashant Dec 11 '20 at 04:25
  • @Prashant yes. I used this code unmodified in production. I addressed the perils of using a multiline variable locally in my July 21 comment. It's particularly awkward supplying the JSON like that and I recommended supplying a file instead. Please try that. – Alain O'Dea Dec 11 '20 at 11:03
  • Thanks for confirmation. I pasted the whole json as a variable. It did not work. I have tried this in normal cli way, but How would you supply the file in Terraform cloud instance.. – Prashant Dec 11 '20 at 11:11
  • @Prashant I'd contact Terraform Cloud support, because raw multiline text in variables are supposed to work. Make sure that you have not marked the variable as HCL. It's not and setting that will break things. A really straight forward test is to create a module with nothing but an outputof a single variable and then put the JSON with credentials redacted into Terraform Cloud and run it. "It doesn't work" is not a useful statement. You need to share the specific errors you are getting. I suggest opening a new question that links to this with full details (excluding your credentials of course) – Alain O'Dea Dec 11 '20 at 11:24
1

A better answer would be to remove the newline in the service account key file by running

tr -d '\n' < current_service_key.json > no_new_line_key.json

Paste the content of "no_new_line_key.json" to the variable section of Terraform Cloud and use any of the variable names such as GOOGLE_CREDENTIALS or GOOGLE_CLOUD_KEYFILE_JSON documented here:(https://registry.terraform.io/providers/hashicorp/google/latest/docs/guides/provider_reference). I used GOOGLE_CREDENTIALS

Screenshot of the configuration

Thien Phan
  • 358
  • 4
  • 8
1

You can always export below variable in your shell environment and omit passing on credentials through provider entry

export GOOGLE_APPLICATION_CREDENTIALS="/~/path/to/gcp-sa.json"

mati kepa
  • 2,543
  • 19
  • 24