Terraform remote state data source unsupported attribute

I’ve setup a project with the following structure

├── gke
│   ├── main.tf
│   ├── outputs.tf
│   ├── provider.tf
│   └── terraform.tfstate
├── k8s
│   ├── main.tf
│   ├── provider.tf
│   ├── terraform.tfvars
│   └── variables.tf
└── modules
    └── kubernetes
        └── namespace
            └── namespace.tf

In gke dir I’m using only google provider to manage a gke cluster

Using console I can query the endpoint value of gke cluster

 $ terraform console
> google_container_cluster.primary.endpoint
"1.2.3.4"

I put this value into root module outputs

$ cat outputs.tf
output "endpoint" {
  value = google_container_cluster.primary.endpoint
}

In k8s dir I’m using only kubernetes provider but I want authenticate using informations available in gke tfstate (endpoint ip and ca certificate)

Below the configuration of provider.tf in k8s dir

data "google_client_config" "default" {}


data "terraform_remote_state" "gke" {
  backend = "local"
  config = {
    path = "../gke/terraform.tfstate"
  }
}

provider "kubernetes" {
  host                   = "https://${data.terraform_remote_state.gke.google_container_cluster.primary.endpoint}"
  token                  = data.google_client_config.default.access_token
  cluster_ca_certificate = base64decode(data.terraform_remote_state.gke.google_container_cluster.primary.master_auth.0.cluster_ca_certificate)
}

If I run terraform plan inside k8s dir I get the following errors:

Error: Unsupported attribute

  on provider.tf line 19, in provider "kubernetes":
  19:   host                   = "https://${data.terraform_remote_state.gke.google_container_cluster.primary.endpoint}"

This object has no argument, nested block, or exported attribute named
"google_container_cluster".


Error: Unsupported attribute

  on provider.tf line 21, in provider "kubernetes":
  21:   cluster_ca_certificate = base64decode(data.terraform_remote_state.gke.google_container_cluster.primary.master_auth.0.cluster_ca_certificate)

This object has no argument, nested block, or exported attribute named
"google_container_cluster".

What I’m doing wrong?
Thanks for your help

try replacing

data.terraform_remote_state.gke.google_container_cluster.primary.master_auth.0.cluster_ca_certificate

with

data.terraform_remote_state.gke.outputs.google_container_cluster.primary.master_auth.0.cluster_ca_certificate

Reference: https://registry.terraform.io/providers/hashicorp/terraform/latest/docs/data-sources/remote_state#attributes-reference

Yes, I’ve already tried adding outputs but the issue persist

provider "kubernetes" {
  host                   = "https://${data.terraform_remote_state.gke.outputs.google_container_cluster.primary.endpoint}"
  token                  = data.google_client_config.default.access_token
  cluster_ca_certificate = base64decode(data.terraform_remote_state.gke.outputs.google_container_cluster.primary.master_auth.0.cluster_ca_certificate)
}

$ terraform plan
Error: Unsupported attribute

  on provider.tf line 19, in provider "kubernetes":
  19:   host                   = "https://${data.terraform_remote_state.gke.outputs.google_container_cluster.primary.endpoint}"
    |----------------
    | data.terraform_remote_state.gke.outputs is object with 1 attribute "endpoint"

This object does not have an attribute named "google_container_cluster".


Error: Unsupported attribute

  on provider.tf line 21, in provider "kubernetes":
  21:   cluster_ca_certificate = base64decode(data.terraform_remote_state.gke.outputs.google_container_cluster.primary.master_auth.0.cluster_ca_certificate)
    |----------------
    | data.terraform_remote_state.gke.outputs is object with 1 attribute "endpoint"

This object does not have an attribute named "google_container_cluster".

I’m unsure, but is it correct that output below doesn’t show the value of the variable?
From inside gke dir:

$ terraform output
endpoint = "google_container_cluster.primary.endpoint"

I think you might have two separate problems here, because that output value you showed doesn’t look right (it seems to be a string literally containing a Terraform expression rather than the result of a Terraform expression), but focusing on the error message you shared it seems like the problem is that Terraform can only see one output value called endpoint, and there isn’t an output value declared called google_container_cluster.

If you want to export that entire object as an output then you’d need to declare an output value in the module like this:

output "google_container_cluster" {
  value = {
    primary = google_container_cluster.primary
  }
}

It’s more typical, though, to export only a particular subset of the data from resource objects, so that the module’s interface is smaller and focused only on the problem at hand. If you wanted to do that, you could declare an output value called cluster_ca_certificate like this:

output "cluster_ca_certificate" {
  value = google_container_cluster.primary.master_auth.0.cluster_ca_certificate
}

…and then access it from the remote state data resource as data.terraform_remote_state.gke.outputs.cluster_ca_certificate.

1 Like

Thanks all, I made it working.

In gke/outputs

output "endpoint" {
  value = google_container_cluster.primary.endpoint
}
output "ca" {
  value = google_container_cluster.primary.master_auth.0.cluster_ca_certificate
}

Then I access from within k8s dir with:

provider "kubernetes" {
  host                   = "https://${data.terraform_remote_state.gke.outputs.endpoint}"
  token                  = data.google_client_config.default.access_token
  cluster_ca_certificate = base64encode(data.terraform_remote_state.gke.outputs.ca)
}

What I’ve fixed also is the output section of terraform.tfstate file
Because actually I have imported the gke resource and never did “terraform apply”

  "outputs": {
    "endpoint": {
      "value": "google_container_cluster.primary.endpoint",
      "type": "string"
    },
    "ca": {
      "value": "google_container_cluster.primary.master_auth.0.cluster_ca_certificate",
      "type": "string"
     }
  },

Last thing to investigate is the access of output variables inside gke dir.
Why I can’t access the value ?

$ terraform output
ca = "google_container_cluster.primary.master_auth.0.cluster_ca_certificate"
endpoint = "google_container_cluster.primary.endpoint"

Ok I’ve figured out what’s the problem with the output.
Output section within terraform.tfstate file should contains the value of the parameter, non the string.

  "outputs": {
    "endpoint": {
      "value": "1.2.3.4",
      "type": "string"
    },
...

Is there a way to fill these value automatically using terraform import?

Thanks all for your contributes, I’ve solved all the issues.