-
Notifications
You must be signed in to change notification settings - Fork 9.7k
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
Resource Instance Random ID Generator #32593
Comments
Thanks for sharing this use-case, @tgoodsell-tempus! This reminds me of an idea I posted a long time ago (before I was a member of the Terraform team at HashiCorp), which I mention only because there's some discussion there which might be interesting background context as we think about different ways to solve this problem. In that other issue I proposed using the prefix I also like your idea of using function syntax for this, because it makes it a bit clearer how we'd specify different arguments to customize the ID if needed. However, I think we'd need to be careful about how flexible we make that because otherwise I think it would raise questions about how much you're allowed to change the settings without forcing Terraform to generate a new ID. I was imagining keeping the ID for each resource would be stored in the Terraform state and then Terraform would change it only when replacing an object, but that approach suggests that there would only be one possible ID for each object and all modified versions would need to be somehow derived from it. One way to achieve that would be for Terraform to generate some arbitrary random bytes as the main ID and then have all of the possible ID variations be deterministically derived from those random bytes, essentially using the random data as a seed for predictably generating data in other formats. If Terraform can also see the rules for the derived ID at planning time then it could verify that the new value is different than the old one (pseudo-random generation could collide when generating short strings) and preemptively generate a new set of random bytes to avoid the collision if so. |
@apparentlymart Thanks for the comments! Yes I think your more fleshed out idea is probably the best way to implement. For example here is a sample of the
If this added another field similar to Ideally this value would be "generated" when the plan detected a Create/Recreate so uses of it could be visible at plan time. Then the new functions may not even need to require the user to reference it directly, maybe a function such as: |
Thanks for confirming, @tgoodsell-tempus! One interesting thing for us to consider here is that we've not previously had any function whose behavior varies depending on which block it's being called from, and so we'd probably want to evaluate whether folks would find that intuitive or confusing before deciding on that particular syntax. If it does seem like it would be confusing then a possible variation would be to expose something like It's interesting to note that this "derive an ID from some random data" function (or functions) is already what some of the resource types in the I suppose that actually does make a bunch of sense, because the If we implement the ability for provider plugins to contribute new functions to Terraform (#2771) then the existing // INVALID: This is a hypothetical example of one way to address this feature request
resource "google_compute_disk" "example" {
name = "example-name-${provider::random::string(meta.self_unique_id, { length = 5 })}"
size = 100
} (The |
@apparentlymart Cheers! Yes reading your commentary I agree that is may be better to just say that said value will be exposed under a Additionally your idea to have these types of functions also be wrapped into the work of allow providers to provider terraform functions makes a lot of sense considering:
Certainly both of these features are something I would love to see integrated into the tool whenever feasible. The ID thing especially would help an org like mine with a large number of objects with a complex dependency set have a good tool to ensure our terraform config is clean/clear on its use as well as ensure we don't have to do any funny business with plans / applies where these unique name resources are used. |
I spent a few hours today reading through the old threads from @apparentlymart before finding this thread. I wanted to add some more examples where uniqueness needs to be generated before the DAG is complete. We currently work around these by using static uniqueness with
These are the ones that I have recently encountered. My end goal is improving usability for our Terraform users while abstracting away meaningless hoop jumping if possible.
I am super excited that it would be possible to access providers directly for helper functions. |
+1. We have run into this a lot, and implemented a sort of workaround/hack. Our setup uses 1000s of very tiny terraform states (it speeds things up and keeps things separate), but that also means that we have a LOT of dependencies between states and use mostly data blocks to refer to objects between states (the dependency chain this creates is not ideal, but it is what it is). Across multiple teams we have services that have similar or same names, as each team is implementing their part of a shared service, or simply they both refer to their workload with the same name. Since we want to keep terraform as self-service as possible and still allow the flexibility for devs to name things whatever they like within our naming conventions ("${local.team}-${local.name}-${local.env}"), we found a solution using a combination of Terraform functions to generate reproducible unique IDs that we can easily call in a data block elsewhere without having to know anything about the actual random characters. module "rds_aurora" {
cluster_identifier = "${local.team}-${local.name}-${local.env}-${substr(sha256("${local.team}-${local.name}-${local.env}"), 0. 8)}"
} The issue with the above is that our org kept having re-orgs, and systems would change ownership, and then the The solution was to drop the Having something that is truly random and yet still repeatable in some way and also built into the framework would make this considerably easier for us. |
Terraform Version
Use Cases
Main Use Case:
google_compute_disk
.create_before_destroy
is set, this value changes / is rotated. However on normal plan/apply operations (Read/Update), this value does not change. Should be disposed on a delete.Attempted Solutions
A module with one of the
random_xxx
resources, including adding akeepers
value on specific inputs variables we expect haveForceNewIf
set on them. This has the draw backs of:compute_disk
example: A disk can increase in size normally, decreasing in size requires a recreate. Therefore, a keepers on the "size" field would not work; as any change in the "name" field would trigger an undesired recreate.Using a
random_xxx
resource, with it having the resource we want this behavior for placed in thereplace_triggered_by
lifecycle argument:Resource specific support. Some resources, such as
aws_iam_policy
andgoogle_compute_instance_template
, provide schema specific solutions to this problem. By either allowing for full auto-generation of these fields, or offering a "prefix" name where it autogenerates a remainder of the "true" name/ID passed to the API. It's drawbacks are:Proposal
For controlling what the
self.rand_id
would emit, I'm thinking either:terraform
block), there is a new setting struct which lets you set the properties of this. Ideally based on one or more of therandom_xxx
resource configurations, such as:terraform-provider-sdk
/terraform-provider-framework
enforced mechanism that resource schema whereForceNew
is used, also requires that resources have or produce any accompanying "randomizer" for the main primary key fields. Either requiring that these key fields are tagged and tested as supporting this behavior, or instead of building this intoterraform
, the providers include an option to configure a "random" element similar to the above, which is available for reference on resources. For example:References
#31707
The text was updated successfully, but these errors were encountered: