Terraform使用k8sraw provider部署时报was present but now absent错误如何解决?
问题根因分析
- 你遇到的报错是第三方k8sraw provider的已知兼容问题,该开源项目多年未维护,最后一次代码更新为2020年,未适配Terraform 0.12+版本后的provider协议变更,2021年10月报错出现的时间点正好对应Terraform官方收紧旧协议校验规则的时间窗口,因此此前正常运行的代码会突然触发报错。
- 此外你部署的WorkflowTemplate属于Argo的自定义资源(CRD),k8sraw provider对CRD的状态校验逻辑存在缺陷,apply后读取资源状态时无法正确识别CRD的返回字段,就会判定「之前存在的属性现在消失」,触发资源不一致性报错。
可行解决方案
方案1:替换为官方kubernetes_manifest资源(最推荐,长期兼容)
Terraform官方Kubernetes provider从1.10.0版本开始原生支持kubernetes_manifest资源,可以直接提交任意YAML格式的Kubernetes资源,包括CRD,完全可以替代已停止维护的k8sraw provider。
修改步骤:
- 移除k8sraw provider的声明,升级kubernetes provider到1.10.0以上版本
- 把原来的
k8sraw_yaml资源替换为kubernetes_manifest,示例代码:
resource "kubernetes_manifest" "test-template" { manifest = yamldecode(data.template_file.test-template.rendered) }
- 执行
terraform state rm k8sraw_yaml.test-template移除旧资源的状态记录,再执行导入命令把集群中已部署的WorkflowTemplate导入到新资源状态:
terraform import kubernetes_manifest.test-template "apiVersion=argoproj.io/v1alpha1,kind=WorkflowTemplate,namespace=test-account,name=test-test-deploy-try-template"
- 后续正常执行plan和apply即可,不会影响集群中已部署的工作流资源。
方案2:临时规避(适合短期不想调整代码的场景)
在执行apply命令时添加环境变量关闭Terraform的资源一致性校验即可绕过报错,注意该方案仅为临时处理方式,存在状态不一致的风险:
TF_PLUGIN_DEV_MODE=1 terraform apply -auto-approve -var-file="vars/test.tfvars"
方案3:自行修复k8sraw provider代码
如果必须保留该provider,可以拉取源码修改资源的Read方法,补全CRD的状态校验逻辑,重新编译后放到本地Terraform provider目录使用,核心改动点为在资源读取逻辑中跳过不存在的属性校验,兼容CRD的返回结构。
内容的提问来源于stack exchange,提问作者Sean Xia
相关产品推荐
相关产品推荐

