-
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
Prototype of Initial Resource State #3060
Conversation
@phinze here's a prototype solution for what we were discussing in #2976. This fixes the quirks I noted in that issue. However it also has some interesting implications that are worth noting:
Definitely think there's more iteration to do here but I just wanted to share what I have in case it helps develop a more complete solutoin. |
Some resources don't really have a true "create" step: either they are just reading a resource or they are executing an "upsert"-like operation on a particular unique name. This new mechanism allows such resources to participate in the "refresh" step without first going through an "apply", thus allowing them to see if a resource of the same name already exists and produce a diff in terms of that existing resource. This mechanism is only appropriate for situations where the Read function is able to completely update the state based on an existing resource. If a resource has write-only attributes that only get set during Create then this mechanism won't work well for them.
This resource exists only to read data, so there's no reason not to treat it as existing immediately, so that its data can be used in provider configurations.
S3 buckets have globally-unique names, so an existing bucket may already exist with the same name. If it's owned by the same account then we can treat it as an update of that existing resource in diffs, giving a more honest account of what we're going to do when we apply. If it's owned by a different account then we'll still fail, but it's still better because we'll fail during the planning stage rather than the apply stage, and thus we won't blow up leaving the state half-applied.
IAM objects must have unique names. Now if a user declares an object with a name that is already in use, Terraform will notice this and diff the configuration against the existing object.
#2976 is getting a lot of duplicating bug reports, so clearly this issue is providing trouble for lots of folks. I'm planning to take another attempt at this with the following modification: rather than having a new, separate As far as I can tell, the only downsides of this are some extra hoop-jumping during initial resource creation to execute a bunch of no-op refreshes (which I expect to cause only a marginal slowdown) and, slightly more annoyingly, the @phinze if you happen to see this and want to tell me it's the wrong approach before I start then that'd be great 😀 but otherwise I hope to spend some time on this in the near future, and will produce a revised prototype for us to pick apart. |
I had to do a little bit of manual work to resolve the conflicts, but otherwise I like it! 👍 I can confirm this fixes #2765 Would you mind rebasing this & resolving conflicts? |
@radeksimko My plan was to do one more prototyping iteration before trying to land this, since I think the current approach has some architectural issues that I'd like to do better. But I hope to get back to this in the near future. My comment above describes the tactical changes I'd like to make to support this particular approach, although over in #2976 I was also thinking about whether data sources and resources ought to be separate concepts, so it's clear to the user whether a particular resource block is going to create something or read something, and so that the dependency rules can be clearer: resources can depend on both resources and data sources, but data sources and providers can only depend on data sources and not resources. |
This prototyping exercise led me to a different approach proposed in #4169. I plan to do some more prototyping with that new idea as long as the proposal withstands initial scrutiny from others. |
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. |
This is a prototype of one possible solution to the issue discussed in #2976.
It adds a new mechanism to allow resource implementations to provide an "initial state", based entirely on what's in the configuration, that gets processed during
terraform refresh
when a new resource is encountered that doesn't yet exist in the state.If a resource provides an initial state for an instance then the
Refresh
step is executed for that resource just as would've happened for a resource that already existed in the state.This supports two different use-cases:
terraform_remote_state
, to be initialized immediately during an initial plan, so their data is available during the planning phase and can thus be used within provider configurations.aws_iam_user
, to recognize when a resource of the same name already exists and present an update diff rather than a create diff. This makes the diff more accurate and thus reduces surprises duringapply
.This is intended just as a prototype for discussion, not as a final solution. Consequently it doesn't yet have any tests.
I've included some subsequent commits that show how this new facility might be used in
terraform_remote_state
,aws_s3_bucket
and various IAM objects as examples.