如何在Terraform plan/apply时解决ClusterIssuer依赖cert-manager CRD的未找到报错
问题根因
你遇到的报错是因为Terraform Kubernetes Provider在terraform plan阶段就会预校验kubernetes_manifest对应的Kubernetes API资源类型是否存在,此时cert-manager还没有实际部署到集群,它提供的ClusterIssuer CRD自然不存在,所以校验直接失败。depends_on和time_sleep都是控制apply阶段的资源执行顺序,对plan阶段的校验逻辑完全无效。
解决方案
给kubernetes_manifest资源添加skip_plan_validation = true参数即可,这个参数会关闭plan阶段的API资源类型校验,等到apply阶段再执行资源创建逻辑,此时cert-manager已经部署完成,CRD已正常注册,就可以顺利创建ClusterIssuer,单次terraform apply即可完成所有资源部署。
修改后的配置代码
仅需要调整kubernetes_manifest.cluster_issuer部分,新增参数即可,原有time_sleep资源可以删除:
resource "helm_release" "cert_manager" { chart = "cert-manager" repository = "https://charts.jetstack.io" name = "cert-manager" create_namespace = var.cert_manager_create_namespace namespace = var.cert_manager_namespace # 新增wait参数,确保helm安装完成、CRD注册后再执行后续资源 wait = true set { name = "installCRDs" value = "true" } } resource "helm_release" "ingress_nginx" { name = "ingress-nginx" repository = "https://kubernetes.github.io/ingress-nginx" chart = "ingress-nginx" create_namespace = var.ingress_nginx_create_namespace namespace = var.ingress_nginx_namespace wait = true depends_on = [ helm_release.cert_manager ] } resource "kubernetes_manifest" "cluster_issuer" { # 新增该行,跳过plan阶段的资源类型校验 skip_plan_validation = true manifest = { "apiVersion" = "cert-manager.io/v1" "kind" = "ClusterIssuer" "metadata" = { "name" = var.cluster_issuer_name } "spec" = { "acme" = { "email" = var.cluster_issuer_email "privateKeySecretRef" = { "name" = var.cluster_issuer_private_key_secret_name } "server" = var.cluster_issuer_server "solvers" = [ { "http01" = { "ingress" = { "class" = "nginx" } } } ] } } } depends_on = [helm_release.cert_manager, helm_release.ingress_nginx] }
可选替代方案
如果你不想跳过plan阶段校验,可以将ClusterIssuer的YAML封装为一个极简的Helm Chart,通过helm_release资源部署,Helm不会在plan阶段提前校验集群中是否存在对应CRD,也可以达到单次apply完成所有部署的效果。
内容的提问来源于stack exchange,提问作者everspader
相关产品推荐
相关产品推荐

