Search code examples
kubernetesterraformkubernetes-custom-resources

getting an error while trying deploy a crd using terrafom


I'm trying to deploy a crd using terraform with the code bellow

resource "kubectl_manifest" "crd-deploy" {
  for_each  = [ for crd in var.crdslist : crd ]
  yaml_body = (fileexists("${path.module}/crds/${crd}.yaml") ? file("${path.module}/crds/${crd}") : "")
}

but i still get an error

 Error: Invalid reference
 
   on ../../00-modules/00-global/25-crd/10-crd.tf line 3, in resource "kubectl_manifest" "crd-deploy":
    3:   yaml_body = (fileexists("${path.module}/crds/${crd}.yaml") ? file("${path.module}/crds/${crd}") : "")
 
 A reference to a resource type must be followed by at least one attribute access, specifying the resource name.

input.tf in module_level

variable "crdslist" {
  type        = list(string)
  default     = []
}

input.tf in execution_module_level

locals {
  crdslist            = ["crd-test"]
}

From where i run the terraform plan to deploy K8s CRDs

module "crds" {
  source   = "../../modules/global/25-crd"
  crdslist = local.crdslist
}

Solution

  • Since the variable that is used is of type list(string), that means it cannot be used with for_each in its original form. The for_each meta-argument requires a variable to be of type map or set [1]:

    If a resource or module block includes a for_each argument whose value is a map or a set of strings, Terraform will create one instance for each member of that map or set.

    In order for the current configuration to work as expected, it is enough to use a Terraform built-in function toset [2]. The only change that needs to be made is inside of the module:

    resource "kubectl_manifest" "crd-deploy" {
      for_each  = toset(var.crdslist)
      yaml_body = (fileexists("${path.module}/crds/${each.vlaue}.yaml") ? file("${path.module}/crds/${each.vlaue}") : "")
    }
    

    Note that when the list is converted to a set, the key and value are the same, i.e., each.key and each.value can be used interchangeably [3].


    [1] https://www.terraform.io/language/meta-arguments/for_each

    [2] https://www.terraform.io/language/functions/toset

    [3] https://www.terraform.io/language/meta-arguments/for_each#the-each-object