* stacks: fix bug preventing cross-provider move refactorings
* also make provider functions work
* stacks: add support for provider functions in .tfstack.hcl files
When the topmost stack configuration declares an ephemeral input variable,
its values must be provided separately for each of the plan and apply
phases.
Therefore here we extend the API to allow specifying input variable values
during the apply phase, and add rules to check whether all of the
apply-time-required input variables have been specified and whether any
non-ephemeral variables are either unspecified or re-specified with equal
values during the apply phase.
This also extends the FindStackConfigurationComponents response to include
more metadata about the input variables and output values so that a caller
can know which ones are ephemeral. The name of that RPC function had
already become a little too specific with the inclusion of embedded stack
information and is even moreso now; we might choose to rename it to
something more generic like "AnalyzeStackConfiguration" in future, but
that'd be a breaking change and therefore requires more coordination.
We need to retain the prior state (in a form that Terraform Core's modules
runtime can accept) between the plan and apply phases because Terraform
uses it to verify that the provider's "final plan" is consistent with
the initial plan.
We previously tried to do this by reusing the "old" value from the planned
change, but that's not really possible in practice because of the
historical implementation detail that Terraform wants state information
in a JSON format and plan information in MessagePack.
This also contains the beginnings of handling the "discarding" of
unrecognized keys from the state data structures, although we'll probably
need to do more in that area later since this is just the bare minimum.
We need to preserve the input variable values provided during the plan
phase so we can reuse them during the apply phase to recalculate derived
results based on new information learned during the apply process.
We also need to recalculate the input values for individual components
during the apply phase, so we can react to previously-unknown values that
come from other upstream components.
This package includes both some model types to represent plans (and parts
thereof) in memory, and logic for translating between the in-memory
representation and our protocol-buffers-based storage serialization.
Unlike the traditional saved plan file format, the stacks model for
planning is slightly asymmetrical: while constructing the plan the system
will emit chunks of the overall plan piecemeal as PlannedChange values,
streamed to the rpcapi client. When reloading that plan to apply it,
the client must provide all of the raw plan blobs in sequence which we
can then decode one by one to construct a single Plan object covering the
entire effect of the plan.
Another intentional asymmetry is that PlannedChange includes enough
information to produce both the raw internal plan representation and the
public-facing plan description, whereas Plan only includes the subset of
information actually required for Terraform Core to apply the plan, from
the raw internal representation exclusively.