Search code examples
kubernetesterraformterraform-provider-kubernetes

Terraform Error: missing resource instance key


I'm unsure what I'm doing wrong. Trying to create role and role binding in terraform.

I have terraform as such:

resource "kubernetes_cluster_role" "allow_port_forward" {
  count = (
    (var.env != "prod")
    && (var.env != "infra")
  ) ? 1 : 0
  metadata {
    annotations = {
      "CCE.com/IAM" : "true"
    }
    name = "allow-port-forward"
  }

  rule {
    api_groups = ["rbac.authorization.k8s.io"]
    resources  = ["pods", "pods/portforward"]
    verbs      = ["get", "list", "create"]
  }
}

resource "kubernetes_cluster_role_binding" "allow_port_forward" {
  count = (
    (var.env != "prod")
    && (var.env != "infra")
  ) ? 1 : 0
  metadata {
    annotations = {
      "CCE.com/IAM" : "true"
    }
    name = "allow-port-forward"
  }

  role_ref {
    api_group = "rbac.authorization.k8s.io"
    kind      = "ClusterRole"
    name = kubernetes_cluster_role.allow_port_forward.metadata[0].name

  }
  subject {
    # developer group
    kind      = "Group"
    name      = "0f2762d3df0025dd3f71c00207c49c39"
    api_group = "rbac.authorization.k8s.io"
  }
}

Terraform plan returns this. it complains about count, but unsure what to do with it.

Error: Missing resource instance key
│ 
│   on modules/rbac/cluster_role_binding/main.tf line 98, in resource "kubernetes_cluster_role_binding" "allow_port_forward":
│   98:     name = kubernetes_cluster_role.allow_port_forward.metadata[0].name
│ 
│ Because kubernetes_cluster_role.allow_port_forward has "count" set, its attributes must be accessed on specific instances.
│ 
│ For example, to correlate with indices of a referring resource, use:
│     kubernetes_cluster_role.allow_port_forward[count.index]

Solution

  • Since you are creating the kubernetes_cluster_role resource with the count meta-argument:

      count = (
        (var.env != "prod")
        && (var.env != "infra")
      ) ? 1 : 0
    

    that means if the condition is true, there will be exactly one instance of the kubernetes_cluster_role. Now, the count meta-argument adds indexes, so in order to reference any of the resources created with count, you need either to know the exact index or to use count.index object. Since the second resource, i.e., kubernetes_cluster_role_binding, is using the same count meta-argument logic, you can fix this issue with:

    resource "kubernetes_cluster_role_binding" "allow_port_forward" {
      count = (
        (var.env != "prod")
        && (var.env != "infra")
      ) ? 1 : 0
    .
    .
    .
    
      role_ref {
        api_group = "rbac.authorization.k8s.io"
        kind      = "ClusterRole"
        name = kubernetes_cluster_role.allow_port_forward[count.index].metadata[0].name
      }
    .
    .
    .
    }
    

    The documentation has some pretty good examples.