Terraform-provider-kubernetes: Feature request/RFC: Flag for adopting kubernetes_namespace if already existing

Created on 9 Sep 2019  ·  10Comments  ·  Source: hashicorp/terraform-provider-kubernetes

For Terraform to create resources in a namespace, it naturally needs to exist, so you'll create it with a kubernetes_namespace resource. However, it is not uncommon for separate processes that also creates namespaces to kick off automatically with cluster creation. So there's a race condition where Terraform might either fail to create the namespace (because it already exists) or fail to create the resource (because it doesn't yet exist, and due to the first error you configure Terraform to not create the namespace).

It might make sense to have a flag on kubernetes_namespace to accept the existing namespace if it is there, or create it otherwise? I know some resources in other providers have had this functionality either implicitly (GCP project for example) or explicitly (via a flag).

acknowledged enhancement

Most helpful comment

I've created PR https://github.com/terraform-providers/terraform-provider-kubernetes/pull/701 to add a new datasource that can query namespaces.

You can use this datasource to determine whether the namespace is present and in case it's not, trigger it's creation (by passing the bool value to the count attribute on the namespace resource).

Here's an example of how to use the datasource:

data "kubernetes_namespace" "testns" {
  metadata {
    name = "kube-system"
  }
}

output "ns-present" {
  value = lookup(data.kubernetes_namespace.testns, "id") != null
}

The output will be a boolean value indicating the presence of the namespace.

All 10 comments

Somewhat, not completely, related to #238 IMO.

That would be nice. I add this to all my resources now:

    namespace = (var.namespace != "default" ? kubernetes_namespace.monitoring[0].metadata.0.name : "default")

But what you are suggesting "create or import" is a major change from TF "philosophy" and I can see a future where everybody would ask for the same for any given resource.

@JordanP On that point, would it be fair to request a way to edit the default resources that Kubernetes creates? Be it system_namespace or default_namespace flags.

The only alternative I have for this is to manually import the namespaces after creation and essentially breaks my deployment up into two plans adding a lot of toil.

Something like this where only native namespaces are supported _(those created by kubernetes itself)_

 resource "kubernetes_namespace" "default" {
  metadata {
    labels = {
      istio-injection = "enabled"
   }
   default_namespace = "default|kube-system"
   }
}

Hi, we have the same issue: We have a terraform module which deploy an EKS cluster + deploy base k8s resources (such as Traefik, Prometheus, Grafana, Dashboard, ...) and after that we have different API we deployed in different namespaces (one namespace per client per environment) in another terraform module.

We need to tests if the namespace already exist and create it if not with a terraform custom module:

common/check-namespace/main.tf

variable "name" {
  type        = string
  default     = "default"
}

resource "null_resource" "check-namespace" {

  triggers = {
    build_number = "${timestamp()}"
  }
  provisioner "local-exec" {
    command = <<SCRIPT
      var=$(kubectl get namespaces|grep ${var.name}| wc -l)
      if [ "$var" -eq "0" ]
      then kubectl create namespace ${var.name}
      else echo '${var.name} already exists' >&3
      fi
    SCRIPT
  }
}

output "namespace_name" {
  value = var.name
}

output "id" {
  value = null_resource.check-namespace.id
}

and we use it at the beginning of all our terraform module to create or not namespaces:

module "check_namespace" {
  source = "../../../../common/check-namespace"
  name   = "kubernetes-dashboard"
}

I think it can be improved using Terraform external Data Source & directly return the namespace name.

But finally, I think it could improve DX a lot if you have a flag to "use_existing" to be able to retrieve the namespace if exists and if not it creates it as usual.

I've created PR https://github.com/terraform-providers/terraform-provider-kubernetes/pull/701 to add a new datasource that can query namespaces.

You can use this datasource to determine whether the namespace is present and in case it's not, trigger it's creation (by passing the bool value to the count attribute on the namespace resource).

Here's an example of how to use the datasource:

data "kubernetes_namespace" "testns" {
  metadata {
    name = "kube-system"
  }
}

output "ns-present" {
  value = lookup(data.kubernetes_namespace.testns, "id") != null
}

The output will be a boolean value indicating the presence of the namespace.

Awesome! Seems a good solution to me. Thanks a lot for the PR, hope this will be merged soon.

FYI everyone, the preferred / recommended way to approach this problem is to actually import the existing resource into Terraform if in fact it will at any point be managed / created by Terraform.

The datasource approach should only be used for inspecting resources that will never be managed by TF.

Sure, because if we add a kubernetes_namespace resources & we run terraform destroy it will destroy the namespace with all resources in it...

Finally if we want to share namespaces between terraform module we should create it before (kubectl, other module...) and pass it as variables.

We've decided to close this issue due to the reasons stated above. The partial workaround (data source) will be merged instead: https://github.com/terraform-providers/terraform-provider-kubernetes/pull/701

I'm going to lock this issue because it has been closed for _30 days_ ⏳. This helps our maintainers find and focus on the active issues.

If you feel this issue should be reopened, we encourage creating a new issue linking back to this one for added context. If you feel I made an error 🤖 🙉 , please reach out to my human friends 👉 [email protected]. Thanks!

Was this page helpful?
0 / 5 - 0 ratings