-
Notifications
You must be signed in to change notification settings - Fork 9.6k
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
Update/replace resource when a dependency is changed #8099
Comments
Hi @OJFord Thanks. |
@radeksimko please check issue referenced #6613. This is pretty important and can be hit in other places as well. From my experiments, I observed that "depends on" is only related to order. It does not trigger a change. |
In Terraform's design, a dependency edge (which is what I think you are expecting an additional behavior: if there is an update to So in practice this means that the In practice this behavior does cause some trouble on edge cases, and those edge cases are what #4846 and #8769 are about: allowing Terraform to detect the side effects of a given update, such as the Regarding your connection to that other issue @cemo, you are right that the given issue is another one of these edge cases, though a slightly different one: taking an action (deploying) directly in response to another action (updating some other resource), rather than using attribute-based diffing... though for this API gateway case in particular, since API gateway encourages you to create a lot of resources, the specific syntax proposed there would likely be inconvenient/noisy. Again as @radeksimko said a specific example from @OJFord might allow us to suggest a workaround for a specific case today, in spite of the core mechanisms I've described above. In several cases we have made special allowances in the design of a resource such that a use-case can be met, and we may be able to either suggest an already-existing one of these to use or design a new "allowance" if we have a specific example to work with. (@cemo's API gateway example is already noted, and there were already discussions about that which I will describe in more detail over there.) |
I'm sorry that I never came back with an example; I'm afraid I can't remember exactly what I was doing - but:
is exactly right, that was what I misunderstood. Perhaps something like |
@OJFord the issue you don't remember might be #6613. I second @OJFord's proposition and expect something like a simpler thing as |
This I think this sort of thing would likely require some of the machinery from #6810 around detecting the presence of whole-resource diffs and correctly handling errors with them. There are some edge cases round what happens if B depends on A and A is changed but B encounters an error while replacing... since the intended change is not explicitly visible in the attributes, Terraform needs to make sure to do enough book-keeping that it knows it has more work to do when run again after the error is resolved. It might work out conceptually simpler to generalize the
In the above example, the This effectively gives you an extra place to represent explicit value dependencies that don't have an obvious home in the resource's own attributes. This is conceptually simpler because it can build on existing mechanisms and UX to some extent. For example, it might look like this in a diff:
In the short term we're likely to continue addressing this by adding special extra For the moment I'm going to re-tag this one as "thinking" to indicate that it's an interesting idea but we need to gather more data (real use-cases) in order to design it well. I'd encourage other folks to share concrete use-cases they have in this area as separate issues, similar to what's seen in #6613, and mention this issue by number so that it can become a collection of links to relevant use-cases that can inform further design. |
@mitchellh This issue might be considered for 0.8 release as you improved "depends_on" and this might be a quick win. |
Hi @apparentlymart, Here is another real user-case of my own. resource When I change the value of Why is it supposed to? Because in my practice, after (BTW. the both resources are actually defined in a module. maybe it matters, or not, I'm not sure). |
Hi @ckyoog! Thanks for sharing that. What you described there sounds like what's captured in hashicorp/terraform-provider-aws#240. If you think it's the same thing, it would be cool if you could post the same details in that issue since having a full reproduction case is very useful. I think in your particular case this is a bug that we ought to fix in the AWS provider, though you're right that if the feature I described in my earlier comment were implemented it could in principle be used as a workaround. In the mean time, you might be able to already workaround this by including an additional interpolation in your policy name to force it to get recreated when the target is recreated: name = "${var.global_vars["ecs_cluster_name"]}-${var.ecs_service_name}-cpu-scale-in-${aws_appautoscaling_target.ecs_target.id}" Since the name attribute forces new resource, this should cause the policy to get recreated each time the target is recreated. |
Thank you @apparentlymart for the workaround. Sure, I will post my case to issue terraform-provider/terraform-provider-aws#240. |
Hey, just got an idea of how this might be solutionned, now the approach is inspired fron Google Cloud and I don't know if it will apply to all use cases. Example:
The It would work like the implicit and explicit Now I understand that there are some subtle differences in the problems that have been mentioned like, I don't want to destroy, I want to update a resource for example. I don't know how my case would fit into this. Also, I think it would be best to stick with the cloud provider's semantics, and, in my case, it really reflects what I'm doing and how everything works. This system would be a reverse |
I have run into the need for this issue myself. The use case is the following: I have a resource for a database instance (In this case an AWS RDS instance) which performs a snapshot of its disk upon destruction. If I destroy this resource and recreate it and destroy it again, AWS returns an error because it will attempt to create a snapshot with the same identifier as before. This can be mitigated by using something like the "random_id" resource as a suffix/prefix to that identifier. The issue is that if I taint the database resource, I need to manually remember to taint the "random_id" resource as well otherwise the new instance will have the same "random_id" as before. Attempting to use a "keepers" pointing to the database resource id does not work because it causes a cyclic dependency. Any ideas on how one handles that? |
That's similar to what I'm bumping into and trying to work around right now ... trying to evaluate a solution and a "force_recreate/taint" in lifecycle, or similar, would be incredibly useful right now ... In my case I have a target group that needs to be recreated, but the listener (no rule involved here) is only getting a "update in place" change ... but then the target group cannot be destroyed because the listener isn't being destroyed ... For reference for others searching the issue for this in the AWS provider is being tracked in hashicorp/terraform-provider-aws#10233 |
I was running into the same issue with the Google Provider and the resource google_compute_resource_policy & google_compute_disk_resource_policy_attachment. When you create a policy for scheduling the snapshots of a GCE Disk you must attach the policy to the disk. That policy isn't editable so if you perform any changes Terraform has to recreate the resource but doesn't recreate the attachment resource, even if it's "linked" with the depends_on directive of Terraform. Example of the resources:
Terraform version
Any solution for this use case? |
@psanzm in this very specific use case, using the
Note: it works because the actual values of |
To add another example use case I recently ran into with Azure PostgreSQL. I wanted to upgrade the version of the PostgreSQL engine on the server, which requires replacement. The dependent resources such as firewall rules and Postgres configurations were not re-created. I had to run through two applies. This is a common occurrence in Azure where most IDs are based on the name of the resource, so if it is re-created the ID stays the same and dependent resources don't register the change. resource "azurerm_postgresql_server" "pgsql_server" {
name = "examplepgsql"
resource_group_name = "my-rg"
location = "eastus"
sku {
name = "GP_Gen5_2"
capacity = "2"
tier = "GeneralPurpose"
family = "Gen5"
}
storage_profile {
storage_mb = "51200"
backup_retention_days = 35
geo_redundant_backup = "Enabled"
}
administrator_login = var.admin_username
administrator_login_password = var.admin_password
version = "11"
ssl_enforcement = "Enabled"
}
resource "azurerm_postgresql_firewall_rule" "azure_services_firewall_rule" {
name = "AzureServices"
resource_group_name = azurerm_postgresql_server.pgsql_server.resource_group_name
server_name = azurerm_postgresql_server.pgsql_server.name
start_ip_address = "0.0.0.0"
end_ip_address = "0.0.0.0"
}
resource "azurerm_postgresql_configuration" "log_checkpoints_pgsql_config" {
name = "log_checkpoints"
resource_group_name = azurerm_postgresql_server.pgsql_server.resource_group_name
server_name = azurerm_postgresql_server.pgsql_server.name
value = "on"
} |
Another use case : I wanted to update an SSM parameter with the value of a AMI data block, but only when it changes. This is for use with an Automation workflow like the example posted in the AWS docs. My thought was : put in a Aha, I thought, I'll do this :
... sadly This seems a shame because otherwise you could implement quite sophisticated lifecycle management with the null resource, concocting triggers with interpolations and such and only triggering an update to a dependent resource when the ID changed as a result. |
I came to this thread from hashicorp/terraform-provider-azurerm#763. I do not know how this is connected, but that issue was closed for the sake of hashicorp/terraform-provider-azurerm#326, which in turn was closed for the sake of this one. So, if you guys understand how the connection was made, then here is another scenario and very real. We modify probing path on an azure traffic manager and boom - its endpoints are gone. This is very frustrating. Is there an ETA on the fix for this issue? |
@MarkKharitonov This issue is essentially a feature request, what you're describing with Azure sounds like a bug though (but I haven't used Azure or read through those issues) - so perhaps the link is 'sorry, nothing we can do without [this issue resolved], closing'. I phrased it as a bug in the OP (and I should perhaps edit that) out of misunderstanding, but it's really a request for a form of dependency control that isn't possible (solely) with terraform today. |
I do not understand. I have a traffic manager resource. The change does not recreate the resource - it is reported as an in-place replacement. Yet it blows away the endpoints. How come it is a feature request? |
@MarkKharitonov As I said, "what you're describing with Azure sounds like a bug", but this issue is a feature request, for something that does not exist in terraform core today. Possibly the Azure resolution was 'nothing we can do without a way of doing [what is described here]' - I have no idea - but this issue itself isn't a bug, and is labelled 'thinking'. There's no guarantee there'll ever be a way of doing this, nevermind an ETA. (I don't work for Hashicorp, I just opened this issue, there could be firmer internal plans for all I know, just trying to help.) |
I do not know what to do. There are real issues in the provider that are being closed claiming the issues is because of this one. But this one is something apparently huge in scope. So, I do not understand what am I supposed to do. Should I open yet another issue in terraform providers making reference to the already closed ones and to this one? How do we attract attention to the real bug without it being closed for nothing, which has already happened twice? |
@MarkKharitonov I'm not expert on Terraform or Terraform provider development so someone else please correct me if I'm wrong but I don't think there's anything that can be done in the provider. The issues in the Azure provider are caused by a limitation of Terraform, not a bug in the AzureRM provider that can be fixed. Based on the comments in this issue, there is a fundamental challenge with how the Azure API works and how Terraform handles dependencies. Azure's API does not have unique IDs for resources. So if you have a child resource that references a parent resource by ID, even if that parent resource is re-created the ID doesn't change. From Terraform's perspective, that means that no attribute was changed on the child-resource since the ID it's referencing is the same, even though in actuality the child resource was also destroyed together with the parent resource. The feature request here, as I understand it, is to add additional intelligence to Terraform dependencies to use them not just for ordering resource creation, but also to detect that a dependency (e.g. parent resource) was destroyed/re-created and trigger a destroy/re-create on the dependent resource (e.g. child resource), irrespective of if any attributes on the child resource have changed. |
This issue appears really critical and not a feature request at all. The fundamental core of terraform is to make sure to apply any missing changes if required. In this case not having terraform create dependency on a parent resource recreation is fundamentally an issue. Could someone clarify if the authorization rules not being created when the event hub associated with is re-created has been present a long time ago. Is there any previous version of azureRM or Terraform that would mitigate the issue until this gets resolved? Because the only approach that I can see to work around this issue is to invoke twice terraform deployment which to me is a non sense. |
Hey !
I tried using depends_on - maybe the ordering would help with it - but it didn't help I end up using timestamp to force recreation. |
We have the exact same problem on GCP which is described in details in this issue hashicorp/terraform-provider-google#6376. Here is part of the relevant config: resource "google_compute_region_backend_service" "s1" {
name = "s1"
dynamic "backend" {
for_each = google_compute_instance_group.s1
content {
group = backend.value.self_link
}
}
health_checks = [
google_compute_health_check.default.self_link,
]
}
resource "google_compute_health_check" "default" {
name = "s1"
tcp_health_check {
port = "80"
}
}
resource "google_compute_instance_group" "s1" {
count = local.s1_count
name = format("s1-%02d", count.index + 1)
zone = element(local.zones, count.index)
network = data.google_compute_network.network.self_link
} I'm not sure is this a general TF problem or a Google provider problem, but here it goes. So to sum it up, when I lower the number of the instance group resources TF does this:
It should do this the other way around:
What I don't understand is why doesn't TF know that it should do the update first, then remove instance groups? When I run destroy, TF does it correctly: first destroys the backend service, then instance groups. Also this is very hard to fix, because you need to make a temp config change, apply, then set the final config you want and again apply. |
@kustodian Can you use
|
@lorengordon I can, but it doesn't help. TF works exactly the same im my example with or without To be honest I'm not entirely sure that my issue is the same thing as what the issue reporter is describing. |
@apparentlymart May I suggest locking this issue? I suspect you and the team probably have enough examples and use cases to consider this feature now? I could 'unsubscribe' of course, it's just that I would like to be notified if/when there's a decision, some progress, or something to help test. Cheers. 🙂 |
Edit: It turns out this is really a function of kubernetes, and not really a terraform concern. Just adding my 0.02. This is also an issue with the kubernetes provider and secrets/config maps. A service using an updated config map or secret doesn't detect the change because the underlying pods of the service need to be restarted or recreated to detect the changes.
If the value for the |
I'm going to lock this issue for the time being, because the remaining discussion seems largely to be people supporting each other in workarounds. I’m happy to see people are helping each other work around this, and I've created a thread for this on the community forum so that people can continue these discussions without creating excess noise for people who just want succinct updates in GitHub. |
bar.foo
is not modified if the file 'foobar' changed without otherwise changing the resource that includes it.The text was updated successfully, but these errors were encountered: