Cannot move null_resource to terraform_data: This value is null, so it does not have any attributes

Hello!

I’m trying to migrate a null_resource to terraform_data for debt housekeeping.

I had this kind of resource (with 3 input variables, not mentioned here):

resource "null_resource" "folder_destroy" {
  triggers = {
    storage_account_name = var.storage_account_name
    filesystem           = var.filesystem_name
    folder_path          = var.folder_path
  }
  provisioner "local-exec" {
    when        = destroy
    command     = "./delete_adl2_folder_content.sh ${self.triggers .storage_account_name} ${self.triggers .filesystem} ${self.triggers .folder_path}"
    working_dir = "${path.module}/assets"
    interpreter = ["bash", "-c"]
  }
}

I tried to moved this resource this way:

resource "terraform_data" "folder_destroy" {
  input = {
    storage_account_name = var.storage_account_name
    filesystem           = var.filesystem_name
    folder_path          = var.folder_path
  }

  provisioner "local-exec" {
    when        = destroy
    command     = "./delete_adl2_folder_content.sh ${self.input.storage_account_name} ${self.input.filesystem} ${self.input.folder_path}"
    working_dir = "${path.module}/assets"
    interpreter = ["bash", "-c"]
  }
}

But when running the apply, it failed as follow. What is wrong in my code?

  # .terraform_data.folder_destroy must be replaced
  # (moved from null_resource.folder_destroy)
-/+ resource "terraform_data" "folder_destroy" {
      ~ id               = "4504610820338043230" -> (known after apply)
      + input            = {
          + filesystem           = "private-data"
          + folder_path          = "40_project/A43"
          + storage_account_name = "xxx"
        }
      + output           = (known after apply)
      - triggers_replace = {
          - filesystem           = "private-data"
          - folder_path          = "40_project/A43"
          - storage_account_name = "xxx"
        } -> null
    }

Plan: 1 to add, 0 to change, 1 to destroy.

Do you want to perform these actions in workspace "tests_A43"?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

terraform_data.folder_destroy: Destroying... [id=7413024805265850289]
╷
│ Error: Attempt to get attribute from null value
│
│   on main.tf line 59, in resource "terraform_data" "folder_destroy":
│   59:     command     = "./delete_adl2_folder_content.sh ${self.input.storage_account_name} ${self.input.filesystem} ${self.input.folder_path}"
│     ├────────────────
│     │ self.input is null
│
│ This value is null, so it does not have any attributes.
╵
╷
│ Error: Attempt to get attribute from null value
│
│   on main.tf line 59, in resource "terraform_data" "folder_destroy":
│   59:     command     = "./delete_adl2_folder_content.sh ${self.input.storage_account_name} ${self.input.filesystem} ${self.input.folder_path}"
│     ├────────────────
│     │ self.input is null
│
│ This value is null, so it does not have any attributes.
╵
╷
│ Error: Attempt to get attribute from null value
│
│   on main.tf line 59, in resource "terraform_data" "folder_destroy":
│   59:     command     = "./delete_adl2_folder_content.sh ${self.input.storage_account_name} ${self.input.filesystem} ${self.input.folder_path}"
│     ├────────────────
│     │ self.input is null
│
│ This value is null, so it does not have any attributes.
╵

Hi @sebastien.latre

The migration from null_resource to terraform_data is going to move the value from triggers to triggers_replace. You can see this in the plan output as triggers_replace has the original value and is being updated to null, which is why the plan indicates the resource needs to be replaced.

The apply fails because your provisioner references input, but the data was not stored there, it was stored in triggers_replace.

Thanks a lot for your reply!
It’s unfortunate. I was hoping I could do it in one go (migrating from null_resource.triggers to terraform_data.input).
Triggers was the only way to pass in some data to null_resource but in fact I don’t want to replace the resource in case some of this data is changed so would prefer input over triggers_replace.

I will change my mind and use instead a removed block to perform the same “migration” operation.