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
}
CodePudding user response:
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