Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

I would like provisioner/s to support when=update #35825

Open
davidbuzz opened this issue Oct 8, 2024 · 2 comments
Open

I would like provisioner/s to support when=update #35825

davidbuzz opened this issue Oct 8, 2024 · 2 comments

Comments

@davidbuzz
Copy link

davidbuzz commented Oct 8, 2024

Terraform Version

Terraform v1.9.2
on linux_amd64

Use Cases

i have a :
resource "terraform_data" "ssh_target" { ... }

and I "push" a shell script to the remote server:

  provisioner "file" {
    source      = "./modules/install_dependencies/depsetup.sh"
    destination = "/tmp/depsetup.sh"
  }

and I currently run 2x provisioners :

provisioner "remote-exec" {

    when = create 

    inline = [
      "echo CREATE provisioner",
      "chmod +x /tmp/depsetup.sh",
      "/tmp/depsetup.sh '${var.dependencies}'",
    ]
  }

  provisioner "remote-exec" {

    when = destroy

    inline = [
      "echo DESTROY provisioner",
      "rm -f /tmp/depsetup.sh",
    ]
  }

and it would be really helpful to be able to run the same remote script, or a different one, when = update

My script is written to be safe to re-run under all circumstances, and doesn't actually need to be removed or cleaned up, it just needs to be reliably run every time there's any sort of local change.

Attempted Solutions

right now, what seems to happen is DESTROY is always run before CREATE, and I'd prefer if i could run an UPDATE instead.

Proposal

terraform_data supports a lifecycle element replace_triggered_by=[ stuff ]
it should also support a lifecycle element of update_triggered_by=[ stuff ]

eg:
this doesnt work but work be great:

in this hypothetical, "replace" would run destroy+create, but update doesn't run either of them

resource "terraform_data" "mycreater" {
  triggers_create =  timestamp()
}
resource "terraform_data" "myupdater" {
  triggers_update = timestamp()
}
resource "terraform_data" "mydestroyer" {
  triggers_destroy = timestamp()
}

lifecycle {
  replace_triggered_by = [ terraform_data.mycreater,terraform_data.mydestroyer]
  update_triggered_by = [ terraform_data.myupdater]
}

References

No response

@crw
Copy link
Collaborator

crw commented Oct 8, 2024

Thanks for this feature request! If you are viewing this issue and would like to indicate your interest, please use the 👍 reaction on the issue description to upvote this issue. We also welcome additional use case descriptions.

Just as an FYI, new development is not likely to happen on provisioners. Please see https://developer.hashicorp.com/terraform/language/resources/provisioners/syntax#provisioners-are-a-last-resort and https://github.com/hashicorp/terraform/blob/main/.github/CONTRIBUTING.md#provisioners. I am happy to leave this issue open in case we do decide to support provisioner-like functionality outside of providers at some point in the future.

Thanks again!

@davidbuzz
Copy link
Author

A well-written provisioner with current 'create' and 'destroy' capabilities is specifically hamstrung by not having "update" even made available in the ecosystem.

I have found that my current best-practive is to make my 'create' provisioner shell scripts arbitrarily re-runnable without concern [ ie enough basic if logic that they dont re-perform an action that's already been done to completion ] AND a 'destroy' provisioner that does almost nothing, but only because that's the only way to prevent execssive tear-downs and re-builds in the current no-update world.

Or to put it another way, real software engineers expect CRUD capabilities, ie Create,Read,Update,and Delete , which when mapped to TF terminology is "Create,Read,Destroy" ( whats missing )? -> Update! TF "fakes" a "update" by running "destroy+create" to mean the same thing , but in what world is that the same thing.? What that means is it artificially tears-down ( the destroy) a bunch of stuff we almost certainly didnt need to, to present a state that's more-likely to "create" friendly. but its really not a "create", its a update.

There are many reasons why supporting "when = update" on a provisioner can make more sense, and it could totally be done in a totally backward compatible way ... ie in the absence of a "when=update', it could just do the same behavior as it does now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants