Skip to content

invalid new value for .triggers: was cty.StringVal(...), but now cty.StringVal(...) #280

Open
@sean-

Description

@sean-

Terraform CLI and Provider Versions

Terraform v1.6.3
on darwin_arm64
+ provider registry.terraform.io/cloudflare/cloudflare v4.17.0
+ provider registry.terraform.io/hashicorp/aws v5.23.1
+ provider registry.terraform.io/hashicorp/cloudinit v2.3.2
+ provider registry.terraform.io/hashicorp/external v2.3.1
+ provider registry.terraform.io/hashicorp/null v3.2.1
+ provider registry.terraform.io/hashicorp/random v3.5.1
+ provider registry.terraform.io/hashicorp/tls v4.0.4
+ provider registry.terraform.io/integrations/github v5.41.0

Your version of Terraform is out of date! The latest version
is 1.6.4. You can update by downloading from https://www.terraform.io/downloads.html```

### Terraform Configuration

```terraform
resource "null_resource" "ssh_authorized_keys" {
  count = length(local.ssh_authorized_keys_path) > 0 && fileexists(local.ssh_authorized_keys_path) ? 1 : 0

  triggers = {
    ssh_keys_content = filemd5(local.ssh_authorized_keys_path)
  }

  provisioner "file" {
    destination = ".ssh/authorized_keys"
    source      = local.ssh_authorized_keys_path

    connection {
      type = "ssh"
      host = aws_instance.node.public_ip
      user = local.user_unix
    }
  }

  depends_on = [aws_instance.node]
}

# In the caller:
resource "null_resource" "fetch_ssh_keys" {
  triggers = {
    team_members = jsonencode({ for member in sort(data.github_team.members.members) : member => format("'%s'", replace(member, "'", "'\\''")) })
  }

  provisioner "local-exec" {
    environment = {
      GITHUB_TOKEN = local.github_token
    }

    command = <<-EOT
      echo "# DO NOT EDIT: managed by automation" > ${local.ssh_authorized_keys_path};
      for user in ${join(" ", values(jsondecode(self.triggers.team_members)))}; do
        curl -s -H "Authorization: token $GITHUB_TOKEN" "https://api.github.com/users/$user/keys" | jq -r ".[] | .key + \" $user\"" >> ${local.ssh_authorized_keys_path};
      done
    EOT
  }
}

Expected Behavior

The null_resource provider to not crash.

Actual Behavior

│
│ When expanding the plan for null_resource.ssh_authorized_keys to include new values learned so far during apply, provider "registry.terraform.io/hashicorp/null" produced an
│ invalid new value for .triggers["ssh_keys_content"]: was cty.StringVal("5585de0b93009f6152e35b3dda22764d"), but now cty.StringVal("8600ffbbd655ccbfd64eaa65debb962d").
│
│ This is a bug in the provider, which should be reported in the provider's own issue tracker.```

### Steps to Reproduce

1. `terraform plan -out .tfplan`
2. `terraform apply .tfplan`

It doesn't happen every time.  Re-running the plan works.  If I had to guess, there's a race condition between the triggers and the other null resource that generates the authorized_keys file, but that seems unlikely.  This resource is embedded within a module that has a fan-out that creates between ~12-30 nodes in parallel and populates their authorized keys file.  The caller already has:

depends_on = [null_resource.fetch_ssh_keys]


But it looks like the evaluation of the triggers happens once and doesn't take into consideration that its value could change as a result of the evaluation of the execution of the plan.

### How much impact is this issue causing?

Medium

### Logs

_No response_

### Additional Information

_No response_

### Code of Conduct

- [X] I agree to follow this project's Code of Conduct

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions