-
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
Cannot use interpolations in lifecycle attributes #3116
Comments
Thanks for the report, @clstokes. The real issue here is that lifecycle blocks cannot contain interpolated values. This is because lifecycle modifications can change the shape of the graph, which makes handling computed values for them extra tricky. It's something we can theoretically do, but requires some thought and effort. Tagging as an enhancement. |
Just wanted to chime in and share my use case for this feature. I'm trying to set up a "staging" and "production" environments that share most of the infrastructure template via Terraform modules. Staging environment is unstable and I'd like to set I guess there's currently no way to express this idea in Terraform, which is unfortunate :( Still, thanks for your awesome work! |
Perhaps at the very least we could generalize the special-cased handling of variables within |
+1 |
Well, yup, this becomes quite painful when you try to utilize "prevent destroy" functionality in a shared module, that is just not supposed to be modified. I have a use-case similar to @laggyluke 's |
+1 |
Alternatively, supporting prevent_destroy at the module level would be useful and might be easier than supporting interpolation? |
+1 |
3 similar comments
+1 |
+1 |
+1 |
+1 Yet another terraform behavior that makes no sense in production. |
This is preventing me from implementing a pretty obvious deployment pattern: create new resources without destroying the previous ones (based on This is a feature which should ideally come ASAP. |
Are you familiar with create_before_destroy?
|
Hey @nathanielks! I am indeed aware of that flag, however that's not going to cut it for most environments and CI/CD implementations. The idea for me is being able to bring up new systems based on a new AMI (for example) being built, having the LB re-adjusted to use those new boxes, and then blowing away those older instances (using Terraform), isn't easily do-able whilst we can't control Doing it all manually isn't an issue of course, but that's not the CI/CD solution we're looking for :-) |
+1 |
+1 I like Terraform, but I feel like it fights me all the time and it makes me sad when things like this happen. |
I love Terraform, and use it for all infrastructure deployments in AWS. I understand, you want to keep Terraform "simple to use", but we need to create very complex scripts to be able to reuse modules and avoid duplication. This actually defeats the purpose, because the "simple language" causes more complexity in our code. I would rather work with a full blown language (like the full Ruby in Chef) and ignore the instructions I don't need. To do DevOps work I am coming from the software development side, so I miss the power of a real programming language. |
+1 |
I'm running into this as well. |
This is not an enhancement - it should be standard functionality and is a bug. We should be able to interpolate all variable types and over load them this is much more important than a graph feature which is a nice to have but probably much less used or needed. |
@pixie79 I'm not a Terraform developer, but to the best of my knowledge resource graphs are a core aspect of terraforms dependency modeling, and a key reason why terraform is declarative and parse order independent. @jonapich suggestion of supporting lifecycle attributes at the module level would satisfy my use cases as well. |
+1 |
3 similar comments
+1 |
+1 |
+1 |
Sure. In our case, we were using Terraform to create self-service AWS clusters for research computing projects. Our primary set of templates focused on Compute resources. The compute module included several different sets of templates allowing users to create a cluster containing a master node, hourly nodes, spot nodes, etc. Variables are used to pass instance counts, instance type, AMI etc. If a user didn't want spot instances, they could simply set the instance count to 0. Storage was separated into another module. We wrote a front end Python script for configuring a cluster. That script would write out a root module declaring instances of the compute and storage modules based on the user's input. This would be written out as a JSON template. Using modules allowed us to define a clean interface between Python and Terraform. Points of interface were all input variables and output data from terraform. This allowed us to develop our Python code independently from the Terraform templates; major changes could be made to either, with minimal changes to that interface. Separating storage into it's own module made it relatively safe to remove a compute cluster without deleting the data; simply remove the compute module declaration, but leave storage in place. That storage could later be attached to another compute module. Basically: Python > JSON Root Terraform Module > compute/storage implementation modules. |
Great stuff. Doing same-same with Azure/SharePoint. Similar approach with module separation - some for Azure bootstrapping, some for servers bootstrapping in different configs, some for domain controllers, some for SQL and SharePoint and so on. Exactly that's why we stumbled upon various limitations while combining modules together - lacking parameters and cleaner control over parametrization and module combinations. Heading same direction with PowerShell: PowerShell DSL > Terraform Module > bunch of the modules |
+1 |
@avishnyakov , @cbarbour don't we lose here the main idea of declarative infrastructure description? If we need to write scripts to generate terraform templates, why we need it at all? We can just create classes using cloud provider SDK and reuse them in scripts. Maybe we should take a look on Chef/Puppet approach: DSL + libraries for non-common logic? |
Any progress on the issue? |
+1 |
1 similar comment
+1 |
+1 |
1 similar comment
+1 |
Hi @mitchellh, can you say if this enhancement has some possibility to be added to a |
+1 I have an RDS module and I want the default marked as prevent_destroy so we don't lose data. Unfortunately this means that if I ever do want to destroy that DB I have to either modify that module (not ideal) or I need to go into the AWS console and do it. Please add this as a feature! |
+1 |
2 similar comments
+1 |
+1 |
As a dirty hack workaround for this, I've made this to make lifecycle work as a variable:
So, if I want to protect an ASG, then I would set that variable, and random would generate itself with the data from that ASG's ID. Random can not change itself without a delete/recreate, and would trigger the prevent_destroy. If I don't want to protect the resource, then the count = 0 for the random thing, and it doesn't get created. The downside to this method is that it's pretty tough to un-protect a resource :(. To provide a bit more granularity, the following might help: Inside the module:
And in the module caller:
This second way lets you turn off the prevent_destroy for the single resource that calls the module, rather than for all modules. To override and make a change, change the prevent_destroy to false first. |
2nd anniversary of that "enhancement" comes in ~4 months. Could maintainers please shed some light if this issue going to be fixed or not. It's hard to circumvent these limitations in module development thus decision should be made: should we do enormous code duplications going forward or not. Thank you! |
This is another issue that rolls up into the broader proposal #4149, which gives us a building-block we need to allow the use of possibly-dynamic data in attributes that influence graph construction. It is a goal to get that (or something like it) done eventually, but it's a pretty big change and so it's had trouble rising to the top of the list to work on. Some internal refactoring done in Terraform 0.8 and 0.9 has put us in a much better spot to get that done, but I'm afraid it's not a short-term goal since the whole team is allocated to other work at this time. I understand the frustration caused by this limitation, and I would very much like to address it eventually! |
Thanks for the update. Hope this issue can be fixed before release v1.0 |
+1 to this feature. Being able to create modules with with the flexibility of flags to conditionally control create_before_destroy or similar attributes would go a long way to keep modules as simple as possible. In my current use case, I'd love to pass a flag to this community module which would conditionally enable rolling releases. |
+1 |
Hi everyone! Thanks for the great discussion here. Since it seems to have now reached the point of just attracting "+1" comments I'm going to lock it to reduce the noise for the many people who are watching this issue. We'll come back and unlock it when we get the point of being ready to start work here (once the prerequisite work has been done.) |
Per #33031 (comment), this issue as written no longer describes a problem that is fully relevant in modern Terraform (circa 2023). I will quote the full comment here for posterity:
To follow up with the modern ancestors of this issue, please see the following: References
|
I was wanting to parameterize a boolean resource property with a variable, but it seems this isn't possible. I tried this with
enable_dns_hostnames
onaws_vpc
too, so it doesn't seem limited to theprevent_destroy
example below.The example below fails if the variable's default value is unquoted or quoted.
Tested with v0.6.0 and v0.6.3.
The text was updated successfully, but these errors were encountered: