Hi @lijok,
A subtlety to know about if you are interpreting the graph output is that this only reflects the sequence of actions for a particular sub-operation (by default, as in this case, the creation of a plan). It doesn’t represent the full set of actions required to create a plan and apply it, because applying is an entirely separate sub-operation with its own graph.
The upshot of this for your example here is that Terraform will indeed plan the necessary actions for the aws_s3_bucket.this
resource before it configures provider.grafana
, but if the result of planning the bucket is to produce a create action (that is, if there is not yet a remote object associated with the resource), the valuation of that bucket might be something like this:
bucket = "my-test-bucket"
arn = (known after apply)
# (and all of the other arguments/attributes)
Terraform will then visit provider.grafana
and evaluate its configuration, producing an object like this:
url = "https://grafana.mydomain.com"
auth = (known after apply)
That value – including the “known after apply” placeholder (which is how I’m representing the idea of “unknown” for the sake of this explanation) – is what Terraform Core sends to the provider as its configuration. The provider ultimately decides how to react to that unknown value; the grafana
provider happens to accept it, as I described in my previous comment.
Terraform will then move on to grafana_folder.this
and ask the provider to produce a plan for that object. Again, it’s entirely up to the provider how to respond to that request, and in this case the provider seems to succeed.
There were two opportunities in this path where things could’ve failed, though:
- The call to configure the
grafana
provider in the provider.grafana
node might’ve rejected the unknown value outright.
- The call to plan
grafana_folder.this
in the grafana_folder.this
node might’ve failed if it were necessary to contact the Grafana server to produce an accurate plan for that object, because no auth
value is available.
For the sake of completeness, there is also one other possible path that can potentially allow things to succeed: the AWS provider could return a known value for arn
as part of creating a plan for aws_s3_bucket.this
. Exported attributes are typically values that are determined by the remote API rather than the provider itself, but in situations where a provider has enough information to predict a specific result it can include that known value as part of the plan. In this case, the AWS provider could potentially apply the rule that the bucket ARN is just a fixed prefix on the bucket name and return the ARN that would result from that during planning:
bucket = "my-test-bucket"
arn = "arn:aws:s3:::my-test-bucket"
# (and all of the other arguments/attributes)
As far as I know the AWS provider does not do this, but if it did then the arn
would be known during the plan phase and so the Grafana provider configuration would be entirely known:
url = "https://grafana.mydomain.com"
auth = "arn:aws:s3:::my-test-bucket"
Again, this is something that only works when intentionally supported by a provider, so it’s not something we can generally rely on and so the Terraform Language documentation doesn’t talk about it. If the AWS provider were providing a bucket ARN during planning then it would presumably mention that in the documentation for that attribute, thus giving you the license to ignore the general guidance in the Terraform Language documentation when working with that attribute in particular.
(In practice, this sort of pre-population of values during planning is not commonly implemented, because provider developers try to avoid re-implementing logic implemented by the remote APIs in the provider in case that logic changes later. However, it is a capability available to provider developers in situations where the benefit of doing so outweighs the potential risk of drift in the upstream API design.)