sl1pm4t/terraform-provider-kubernetes

kubernetes_role/kubernetes_role_binding/etc. not auto ordering with kubernetes_namespace

jhoblitt opened this issue · 1 comments

Terraform Version

$ terraform version
Terraform v0.11.11

Affected Resource(s)

Please list the resources as a list, for example:

  • kubernetes_role
  • kubernetes_role_binding
  • kubernetes_cluster_role_binding
  • kubernetes_service_account

Terraform Configuration Files

provider "kubernetes" {
  version = "1.3.0-custom"
}

resource "kubernetes_namespace" "ingress_nginx" {
  metadata {
    name = "ingress-nginx"

    labels {
      name = "ingress-nginx"
    }
  }
}

resource "kubernetes_service_account" "nginx_ingress" {
  metadata {
    name      = "nginx-ingress-serviceaccount"
    namespace = "ingress-nginx"
  }

  #depends_on = ["kubernetes_namespace.ingress_nginx"]
}

resource "kubernetes_role" "nginx_ingress" {
  metadata {
    name      = "nginx-ingress-role"
    namespace = "ingress-nginx"
  }

  rule {
    api_groups = [""]
    resources  = ["configmaps", "pods", "secrets", "namespaces"]
    verbs      = ["get"]
  }

  rule {
    api_groups     = [""]
    resources      = ["configmaps"]
    resource_names = ["ingress-controller-leader-nginx"]
    verbs          = ["get", "update"]
  }

  rule {
    api_groups = [""]
    resources  = ["configmaps"]
    verbs      = ["create"]
  }

  rule {
    api_groups = [""]
    resources  = ["endpoints"]
    verbs      = ["get"]
  }

  #depends_on = ["kubernetes_namespace.ingress_nginx"]
}

resource "kubernetes_role_binding" "nginx_ingress" {
  metadata {
    name      = "nginx-ingress-role"
    namespace = "ingress-nginx"
  }

  role_ref {
    api_group = "rbac.authorization.k8s.io"
    kind      = "Role"
    name      = "nginx-ingress-role"
  }

  subject = {
    kind      = "ServiceAccount"
    name      = "nginx-ingress-serviceaccount"
    namespace = "ingress-nginx"
  }

  #depends_on = [
  #  "kubernetes_namespace.ingress_nginx",
  #  "kubernetes_service_account.nginx_ingress",
  #]
}

Steps to Reproduce

Without manual depends_on:

 $ terraform graph | grep "\->"
		"[root] kubernetes_namespace.ingress_nginx" -> "[root] provider.kubernetes"
		"[root] kubernetes_role.nginx_ingress" -> "[root] provider.kubernetes"
		"[root] kubernetes_role_binding.nginx_ingress" -> "[root] provider.kubernetes"
		"[root] kubernetes_service_account.nginx_ingress" -> "[root] provider.kubernetes"
		"[root] meta.count-boundary (count boundary fixup)" -> "[root] kubernetes_namespace.ingress_nginx"
		"[root] meta.count-boundary (count boundary fixup)" -> "[root] kubernetes_role.nginx_ingress"
		"[root] meta.count-boundary (count boundary fixup)" -> "[root] kubernetes_role_binding.nginx_ingress"
		"[root] meta.count-boundary (count boundary fixup)" -> "[root] kubernetes_service_account.nginx_ingress"
		"[root] provider.kubernetes (close)" -> "[root] kubernetes_namespace.ingress_nginx"
		"[root] provider.kubernetes (close)" -> "[root] kubernetes_role.nginx_ingress"
		"[root] provider.kubernetes (close)" -> "[root] kubernetes_role_binding.nginx_ingress"
		"[root] provider.kubernetes (close)" -> "[root] kubernetes_service_account.nginx_ingress"
		"[root] root" -> "[root] meta.count-boundary (count boundary fixup)"
		"[root] root" -> "[root] provider.kubernetes (close)"

with depends_on:

$ terraform graph | grep "\->"
		"[root] kubernetes_namespace.ingress_nginx" -> "[root] provider.kubernetes"
		"[root] kubernetes_role.nginx_ingress" -> "[root] kubernetes_namespace.ingress_nginx"
		"[root] kubernetes_role_binding.nginx_ingress" -> "[root] kubernetes_service_account.nginx_ingress"
		"[root] kubernetes_service_account.nginx_ingress" -> "[root] kubernetes_namespace.ingress_nginx"
		"[root] meta.count-boundary (count boundary fixup)" -> "[root] kubernetes_role.nginx_ingress"
		"[root] meta.count-boundary (count boundary fixup)" -> "[root] kubernetes_role_binding.nginx_ingress"
		"[root] provider.kubernetes (close)" -> "[root] kubernetes_role.nginx_ingress"
		"[root] provider.kubernetes (close)" -> "[root] kubernetes_role_binding.nginx_ingress"
		"[root] root" -> "[root] meta.count-boundary (count boundary fixup)"
		"[root] root" -> "[root] provider.kubernetes (close)"

Hi @jhoblitt - I don't see this as an issue with the Kubernetes provider, but just the expected Terraform behaviour.
None of the Terraform resources, in any of the providers (that I'm aware of) automatically setup resource type dependencies. They instead rely on the implicit + explicit dependency mechanisms of Terraform core.

e.g. the namespace dependency could be implicitly established with the following:

resource "kubernetes_namespace" "ingress_nginx" {
  metadata {
    name = "ingress-nginx"

    labels {
      name = "ingress-nginx"
    }
  }
}

resource "kubernetes_service_account" "nginx_ingress" {
  metadata {
    name      = "nginx-ingress-serviceaccount"
    namespace = "${kubernetes_namespace.ingress_nginx.metadata.0.name}" 
    #               ^^^^^^^ implicit dependency ^^^^^^^
  }
}