Crashtest Security Blog

Resource does not have attribute

Nov 29, 2018 8:19:00 AM / by Janosch Maier

Resolve a Terraform data source issue

resource_does_not_have_attribute

 

At Crashtest Security we provision our infrastructure using Terraform. Therefore we are able to recreate whole Kubernetes clusters within minutes. We use our Terraform setup also to integrate some external tools such as Vault within our cluster.

Vault needs to the Kubernetes API to work properly. Therefore, we create a Kubernetes service account using Terraform and provision Vault with its JWT token.

When you implement this naively, you will end up creating a Kubernetes service account, getting its secret (using this provider data source) and then trying to use the secret's token as input for the Vault configuration.

However any access to data.kubernetes_secret.vault_tokenreviewer.data.token will fail, if the service account in Kubernetes is not existing yet. You will receive an error message like resource data.kubernetes_secret_vault_tokenreviewer does not have attribute data.token.

This appears, because the data attribute is a map, which does not contain any value until the service account is created.

This issue can be circumvented using the lookup function in Terraform. So instead of accessing data.kubernetes_secret.vault_tokenreviewer.data.token, you access lookup(data.kubernetes_secret.vault_tokenreviewer.data, "token", "").

So when the secret does not exist yet during the planning phase, it won't break the plan. During the apply phase the value is calculated correctly.

The following plan runs smoothly then:

resource “kubernetes_service_account” “vault_tokenreviewer” {
  metadata {
    name = “vault-tokenreviewer”
  }
}


data “kubernetes_secret” “vault_tokenreviewer” {
  metadata {
    name = “${kubernetes_service_account.vault_tokenreviewer.default_secret_name}”
  }
}


resource “vault_auth_backend” “kubernetes_backend” {
  type = “kubernetes”
}


resource “vault_kubernetes_auth_backend_config” “kubernetes_backend_config” {
  backend = “${vault_auth_backend.kubernetes_backend.path}”
  kubernetes_host = “https://${var.kubernetes_host}”
  kubernetes_ca_cert = “${var.kubernetes_cluster_ca_certificate}”
  token_reviewer_jwt = “${lookup(data.kubernetes_secret.vault_tokenreviewer.data, “token”, “”)}”
}

 

Sources:

Topics: VulnerabilityAssessment

Janosch Maier

Written by Janosch Maier

Co-Founder @ Crashtest Security. I write and give workshops regarding Web Security