Reputation: 316
Currently I am doing a small refactor in our infrastructure. My current version of my project is similar to the following: And I am trying to use for_each to reuse variables.
resource "google_cloud_scheduler_job" "job" {
name = "Create_All_Dossier_Summary"
description = "desc1"
schedule = "0 19 * * 1"
time_zone = "America/Sao_Paulo"
attempt_deadline = "320s"
retry_config {
retry_count = 1
}
http_target {
http_method = "POST"
uri = "<some-url>"
}
}
And I am trying to upgrade it to something like the following:
variable "description" {
default = ["desc1", "desc 2"]
}
resource "google_cloud_scheduler_job" "job" {
for_each = toset(var.description)
name = "Create_All_Dossier_Summary"
description = each.value
schedule = "0 19 * * 1"
time_zone = "America/Sao_Paulo"
attempt_deadline = "320s"
retry_config {
retry_count = 1
}
http_target {
http_method = "POST"
uri = "<some-url>"
}
}
So, the configuration is ok, but after running terraform plan
, terraform is destroying my old one, and that is not what I'd like terraform to do, I was aiming that it just created the second one since the first is already there and the configuration is the same.
Is there a way to tell terraform to not recreate that first resource after doing this refactor?
Plan: 2 to add, 0 to change, 1 to destroy.
# google_cloud_scheduler_job.job will be destroyed
# google_cloud_scheduler_job.job["desc 2"] will be created
# google_cloud_scheduler_job.job["desc1"] will be created
BTW: I am trying to use a list of objects, I have used a list of strings here because it's easier to demonstrate.
Upvotes: 6
Views: 2907
Reputation: 141
I think in terms of terraform code that exeecutes inside of CI it is better to use 'moved' block which is described here https://developer.hashicorp.com/terraform/language/modules/develop/refactoring this is the way not to do any manual terminal commands and have everything done by 'terraform apply' Your block should look something like this.
moved {
from = google_cloud_scheduler_job.job
to = google_cloud_scheduler_job.job["desc 2"]
}
I usually put it right after block with for_each, but not sure that this is the best place for it
Upvotes: 4
Reputation: 28739
When the namespace/address of the resource changes in the Terraform config, then you must rename its corresponding id in the state with the state mv
subcommand:
terraform state mv google_cloud_scheduler_job.job 'google_cloud_scheduler_job.job["desc 2"]'
Note that the second resource address must be entirely cast as a literal string for the shell to interpret it correctly as an argument due to the use of "
in the syntax.
Upvotes: 12