-
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
Pre-refreshed resources #2976
Comments
Great write up, @apparentlymart! This is a concept I've been kicking around the back of my head in various forms, and I think your model may just be the way to go. I'm going to let this percolate a bit and I'll follow up. |
Seems there's another detail necessary for this to work: having a provider configuration depend on a
It would seem the condition for this is that not only a provider depends on the remote state, but also some other resource that was created. But that's a pretty common scenario. But since pre-refreshed resources shouldn't need to participate in the create process, they shouldn't need to participate in destroy, either. Thus breaking the cycle. |
Having played with my prototype in #3060 some more, my conception of this issue has changed slightly. The concept of loading data to be used in the configuration seems distinct from the concept of creating something where another thing of the same name may already exist. Therefore I think there are two separate ideas here:
The first of these issues is a more pertinent concern to me right now, since my Terraform configs are getting a lot of these "data sources" as we use both When I have more time to focus on this I intended to break this issue into two separate issues and then prototype the |
I would point out that we already have a mechanism for "loading data to be used in the configuration": This is basically how I've had to work around this issue anyway: I have a bunch of hairy scripts and rules in make which pull the outputs from one configuration and stuff them into the |
This functionality would be extremely useful for us for the scenario I described in #3657 (closed). |
+1 |
As I previously mentioned, I'm splitting this into two separate proposals that each aim to solve half of the problem space presented in this ticket:
|
I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues. If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further. |
There are several resource types that don't actually create something but rather either just record some local state inside Terraform (logical providers) or retrieve data about a pre-existing object. The implementations of these usually simply do nothing except populating the id inside the
Create
function, and then do all of their interesting work insideRead
, and possiblyUpdate
.Some resources of this type include:
terraform_remote_state
consul_keys
(though this one is weird because it can also write, depending on the config)template_file
atlas_artifact
Meanwhile, Terraform allows resource attributes to be interpolated into provider configurations, which is very handy when parts of the config are set dynamically from outside the configuration. For example:
This capability doesn't work quite right because provider configurations need to be processed in order to run
terraform plan
, but on the first run theconsul_keys
resource hasn't been created yet and so its state is empty. This works (after a fashion) if one adds theconsul_keys
resource first, runsterraform apply
, and then adds the provider configuration using the result. But this sort of two-step configuration dance is troublesome when using deployment orchestration tooling.This limitation could be addressed by allowing particular resources to opt-in to being pre-refreshed, which means that
terraform refresh
(and all of the implicit paths into the same functionality) treats them as immediately existing.In other words,
terraform refresh
will call theRead
implementation on such a resource even if there's no record of it in the state already. TheRead
implementation can then use the resource parameters from the configuration to populate any computed attributes just like it would for a pre-existing resource, making sure that the state is updated before we runterraform plan
, and thus that the providers will get the values they are expecting.Of course, the providers are needed for
terraform refresh
too, so Terraform still needs to take care to order the individual resource refresh operations so that e.g. in my above example the AWS provider is not instantiated until theconsul_keys
resource has been refreshed.With this concept in place, I think it would then be reasonable to make it a fatal error for a provider to depend on a non-pre-refreshed resource, giving the user better feedback about why this is not a sensible configuration.
Although my primary motivation is addressing the "interpolated provider config" use-case, this new concept has some other benefits:
aws_s3_bucket_object
, these resources could be set as "pre-refreshed" and then theRead
implementation could check if a same-named object already exists and record it into the state, thus causing it to show up as an update rather than a create in the diff. Again, this provides a more accurate diff to the user, and allows the user to make a better decision about whether to apply the plan.Overall I think this concept better models a class of resources and helps Terraform to "do the right thing" in more cases, by allowing the provider to give it more information.
The text was updated successfully, but these errors were encountered: