Terraform local-exec引用self.triggers报null值错误排查
Terraform null_resource 调用self.triggers报空值错误的解决方法
错误根因
self引用的作用域规则没搞对:
self代表当前正在操作的资源实例,只有当资源已经存在于Terraform状态文件中时,self的属性才会有值。首次执行terraform apply创建null_resource时,资源还未完成写入状态的流程,解析provisioner的命令模板阶段self.triggers就是null,自然无法读取下属属性。- 你之前了解的「destroy-time provisioner不能直接引用
var.xxx变量」是正确的,但create/update阶段的provisioner没有这个限制,直接引用变量完全合法,不需要绕路通过self.triggers取值。
修复方式
- 不带
when参数、默认在资源创建/更新阶段执行的provisioner,所有变量直接通过var.xxx引用,不要使用self.triggers - 仅配置了
when = destroy的销毁阶段provisioner,保留self.triggers的引用方式即可——销毁动作触发时资源早已存在于状态中,不会出现空值问题。
修正后的可正常运行的配置示例:
resource "null_resource" "upload-swagger" { triggers = { swagger_name = "juice-shop-swagger" xc_password = var.xc_password xc_p12_path = var.xc_p12_path xc_api_url = var.xc_api_url xc_namespace = var.xc_namespace swaggerfile_location = var.swaggerfile_location } provisioner "local-exec" { command = <<EOT curl -sk --cert-type P12 \ --cert ${var.xc_p12_path}:${var.xc_password} \ -X PUT "${var.xc_api_url}/object_store/namespaces/${var.xc_namespace}/stored_objects/swagger/${self.triggers.swagger_name}" \ -H "Content-Type: application/json" \ -d '{ "bytes_value": "$(base64 --wrap=0 ${var.swaggerfile_location})", "content_format": "yaml", "name": "${self.triggers.swagger_name}", "namespace": "${var.xc_namespace}", "object_type": "swagger" }' EOT } provisioner "local-exec" { when = destroy command = <<EOT curl -sk --cert-type P12 \ --cert ${self.triggers.xc_p12_path}:${self.triggers.xc_password} \ -X DELETE "${self.triggers.xc_api_url}/object_store/namespaces/${self.triggers.xc_namespace}/stored_objects/swagger/${self.triggers.swagger_name}" \ -H "Content-Type: application/json" \ -d '{ "name": "${self.triggers.swagger_name}", "namespace": "${self.triggers.xc_namespace}", "object_type": "swagger" }' EOT } }
补充说明:如果使用Terraform 0.12.20以前的老旧版本,销毁阶段provisioner读取
self.triggers也可能出现空值,升级到0.13及以上稳定版本即可解决。
内容的提问来源于stack exchange,提问作者m-bers
相关产品推荐
相关产品推荐

