Reference to undeclared resource works 0.11.x and doesn't work in 0.12

terraform version
Terraform v0.12.19
+ provider.google v3.4.0
+ provider.kubernetes v1.10.0

I am trying to use this example with the latest terraform version


and I am getting this

terraform validate

Error: Reference to undeclared resource

  on main.tf line 15, in resource "kubernetes_secret" "google-application-credentials":
  15:     credentials.json = base64decode(google_service_account_key.mykey.private_key)

A managed resource "credentials" "json" has not been declared in the root
module.

the same stuff I have that is compatible with 0.11.14 and validate doesn’t complain about anything

terraform version
Terraform v0.11.14
+ provider.google v2.12.0
+ provider.google-beta v2.20.1
+ provider.kubernetes v1.10.0

Your version of Terraform is out of date! The latest version
is 0.12.19. You can update by downloading from www.terraform.io/downloads.html

terraform validate -var="env=qa" -var="project_id=123id" -var="region=us-east4"

Here is the code that works with 0.11.14

resource "google_service_account" "this" {
  account_id   = "thisid-${var.env}"
  display_name = "${var.env} SA"
  project      = "${var.project_id}"
}

provider "kubernetes" {
  alias            = "${var.gke_cluster_name}"
  load_config_file = false
  host             = "https://${var.gke_cluster_endpoint}"
  token            = "${var.google_client_access_token}"
}

resource "google_service_account_key" "this" {
  service_account_id = "${google_service_account.this.email}"
}
resource "kubernetes_secret" "this" {
  provider = "kubernetes.${var.gke_cluster_name}"

  metadata = {
    name      = "this-instance-credentials"
    namespace = "this-system"
  }

  data = {
    credentials.json = "${base64decode(google_service_account_key.this.private_key)}"
  }
}

Do you have any idea what could be wrong?

Hi @konstantin-recurly,

Terraform 0.12 introduced support for map keys to be arbitrary expressions rather than always literal strings, and unfortunately this is a situation where adding a new feature required changing how Terraform interpreted map keys in prior versions.

Specifically, in Terraform 0.11 and earlier the text to the left of the = was always understood as a literal name, giving "credentials.json" as the key in your example. But in Terraform 0.12, that interpretation only applies to naked identifiers like name: Terraform is understanding credentials.json as a reference to a resource of type credentials named json, as if you had a block like this:

resource "credentials" "json" {
  # ...
}

Of course, that’s not the interpretation you intended here (and there’s not actually a provider called credentials for this to be referring to), but fortunately the remedy is relatively simple: if you add explicit quotes around the name then you can force Terraform to interpret it as a single string:

  data = {
    "credentials.json" = base64decode(google_service_account_key.this.private_key)
  }

Thank you very much!
It works as you suggested. Seems that the documentation needs to be updated.

Hi @konstantin-recurly,

That particular documentation belongs to the Google Cloud Platform provider, so if you raise an issue for that in the GCP Provider repository then someone there should be able to fix it up.

Fortunately the quotes will be accepted by Terraform 0.11 too, so showing it in quotes would make the example work in both Terraform 0.11 and 0.12.