Update "Terraform Core Architecture Summary" doc (#27897)
* Update Godoc links from godoc.org to pkg.go.dev * Update reference to renamed GraphNodeResource interface Ref hashicorp/terraform#24389 * Update dead links; minor formatting adjustments * Add FIXME item following deprecation of EvalNode
This commit is contained in:
parent
7a03c3153e
commit
21d881d4d1
|
@ -23,7 +23,7 @@ in more detail in a corresponding section below.
|
||||||
Each time a user runs the `terraform` program, aside from some initial
|
Each time a user runs the `terraform` program, aside from some initial
|
||||||
bootstrapping in the root package (not shown in the diagram) execution
|
bootstrapping in the root package (not shown in the diagram) execution
|
||||||
transfers immediately into one of the "command" implementations in
|
transfers immediately into one of the "command" implementations in
|
||||||
[the `command` package](https://godoc.org/github.com/hashicorp/terraform/command).
|
[the `command` package](https://pkg.go.dev/github.com/hashicorp/terraform/command).
|
||||||
The mapping between the user-facing command names and
|
The mapping between the user-facing command names and
|
||||||
their corresponding `command` package types can be found in the `commands.go`
|
their corresponding `command` package types can be found in the `commands.go`
|
||||||
file in the root of the repository.
|
file in the root of the repository.
|
||||||
|
@ -35,7 +35,7 @@ but it applies to the main Terraform workflow commands `terraform plan` and
|
||||||
For these commands, the role of the command implementation is to read and parse
|
For these commands, the role of the command implementation is to read and parse
|
||||||
any command line arguments, command line options, and environment variables
|
any command line arguments, command line options, and environment variables
|
||||||
that are needed for the given command and use them to produce a
|
that are needed for the given command and use them to produce a
|
||||||
[`backend.Operation`](https://godoc.org/github.com/hashicorp/terraform/backend#Operation)
|
[`backend.Operation`](https://pkg.go.dev/github.com/hashicorp/terraform/backend#Operation)
|
||||||
object that describes an action to be taken.
|
object that describes an action to be taken.
|
||||||
|
|
||||||
An _operation_ consists of:
|
An _operation_ consists of:
|
||||||
|
@ -52,18 +52,18 @@ An _operation_ consists of:
|
||||||
The operation is then passed to the currently-selected
|
The operation is then passed to the currently-selected
|
||||||
[backend](https://www.terraform.io/docs/backends/index.html). Each backend name
|
[backend](https://www.terraform.io/docs/backends/index.html). Each backend name
|
||||||
corresponds to an implementation of
|
corresponds to an implementation of
|
||||||
[`backend.Backend`](https://godoc.org/github.com/hashicorp/terraform/backend#Backend), using a
|
[`backend.Backend`](https://pkg.go.dev/github.com/hashicorp/terraform/backend#Backend), using a
|
||||||
mapping table in
|
mapping table in
|
||||||
[the `backend/init` package](https://godoc.org/github.com/hashicorp/terraform/backend/init).
|
[the `backend/init` package](https://pkg.go.dev/github.com/hashicorp/terraform/backend/init).
|
||||||
|
|
||||||
Backends that are able to execute operations additionally implement
|
Backends that are able to execute operations additionally implement
|
||||||
[`backend.Enhanced`](https://godoc.org/github.com/hashicorp/terraform/backend#Enhanced);
|
[`backend.Enhanced`](https://pkg.go.dev/github.com/hashicorp/terraform/backend#Enhanced);
|
||||||
the command-handling code calls `Operation` with the operation it has
|
the command-handling code calls `Operation` with the operation it has
|
||||||
constructed, and then the backend is responsible for executing that action.
|
constructed, and then the backend is responsible for executing that action.
|
||||||
|
|
||||||
Most backends do _not_ implement this interface, and so the `command` package
|
Most backends do _not_ implement this interface, and so the `command` package
|
||||||
wraps these backends in an instance of
|
wraps these backends in an instance of
|
||||||
[`local.Local`](https://godoc.org/github.com/hashicorp/terraform/backend/local#Local),
|
[`local.Local`](https://pkg.go.dev/github.com/hashicorp/terraform/backend/local#Local),
|
||||||
causing the operation to be executed locally within the `terraform` process
|
causing the operation to be executed locally within the `terraform` process
|
||||||
itself, which (at the time of writing) is currently the only way an operation
|
itself, which (at the time of writing) is currently the only way an operation
|
||||||
can be executed.
|
can be executed.
|
||||||
|
@ -85,19 +85,19 @@ elsewhere.
|
||||||
|
|
||||||
To execute an operation locally, the `local` backend uses a _state manager_
|
To execute an operation locally, the `local` backend uses a _state manager_
|
||||||
(either
|
(either
|
||||||
[`statemgr.Filesystem`](https://godoc.org/github.com/hashicorp/terraform/states/statemgr#Filesystem) if the
|
[`statemgr.Filesystem`](https://pkg.go.dev/github.com/hashicorp/terraform/states/statemgr#Filesystem) if the
|
||||||
local backend is being used directly, or an implementation provided by whatever
|
local backend is being used directly, or an implementation provided by whatever
|
||||||
backend is being wrapped) to retrieve the current state for the workspace
|
backend is being wrapped) to retrieve the current state for the workspace
|
||||||
specified in the operation, then uses the _config loader_ to load and do
|
specified in the operation, then uses the _config loader_ to load and do
|
||||||
initial processing/validation of the configuration specified in the
|
initial processing/validation of the configuration specified in the
|
||||||
operation. It then uses these, along with the other settings given in the
|
operation. It then uses these, along with the other settings given in the
|
||||||
operation, to construct a
|
operation, to construct a
|
||||||
[`terraform.Context`](https://godoc.org/github.com/hashicorp/terraform/terraform#Context),
|
[`terraform.Context`](https://pkg.go.dev/github.com/hashicorp/terraform/terraform#Context),
|
||||||
which is the main object that actually performs Terraform operations.
|
which is the main object that actually performs Terraform operations.
|
||||||
|
|
||||||
The `local` backend finally calls an appropriate method on that context to
|
The `local` backend finally calls an appropriate method on that context to
|
||||||
begin execution of the relevant command, such as
|
begin execution of the relevant command, such as
|
||||||
[`Plan`](https://godoc.org/github.com/hashicorp/terraform/terraform#Context.Plan)
|
[`Plan`](https://pkg.go.dev/github.com/hashicorp/terraform/terraform#Context.Plan)
|
||||||
or
|
or
|
||||||
[`Apply`](), which in turn constructs a graph using a _graph builder_,
|
[`Apply`](), which in turn constructs a graph using a _graph builder_,
|
||||||
described in a later section.
|
described in a later section.
|
||||||
|
@ -105,21 +105,21 @@ described in a later section.
|
||||||
## Configuration Loader
|
## Configuration Loader
|
||||||
|
|
||||||
The top-level configuration structure is represented by model types in
|
The top-level configuration structure is represented by model types in
|
||||||
[package `configs`](https://godoc.org/github.com/hashicorp/terraform/configs).
|
[package `configs`](https://pkg.go.dev/github.com/hashicorp/terraform/configs).
|
||||||
A whole configuration (the root module plus all of its descendent modules)
|
A whole configuration (the root module plus all of its descendent modules)
|
||||||
is represented by
|
is represented by
|
||||||
[`configs.Config`](https://godoc.org/github.com/hashicorp/terraform/configs#Config).
|
[`configs.Config`](https://pkg.go.dev/github.com/hashicorp/terraform/configs#Config).
|
||||||
|
|
||||||
The `configs` package contains some low-level functionality for constructing
|
The `configs` package contains some low-level functionality for constructing
|
||||||
configuration objects, but the main entry point is in the sub-package
|
configuration objects, but the main entry point is in the sub-package
|
||||||
[`configload`](https://godoc.org/github.com/hashicorp/terraform/configs/configload]),
|
[`configload`](https://pkg.go.dev/github.com/hashicorp/terraform/configs/configload]),
|
||||||
via
|
via
|
||||||
[`configload.Loader`](https://godoc.org/github.com/hashicorp/terraform/configs/configload#Loader).
|
[`configload.Loader`](https://pkg.go.dev/github.com/hashicorp/terraform/configs/configload#Loader).
|
||||||
A loader deals with all of the details of installing child modules
|
A loader deals with all of the details of installing child modules
|
||||||
(during `terraform init`) and then locating those modules again when a
|
(during `terraform init`) and then locating those modules again when a
|
||||||
configuration is loaded by a backend. It takes the path to a root module
|
configuration is loaded by a backend. It takes the path to a root module
|
||||||
and recursively loads all of the child modules to produce a single
|
and recursively loads all of the child modules to produce a single
|
||||||
[`configs.Config`](https://godoc.org/github.com/hashicorp/terraform/configs#Config)
|
[`configs.Config`](https://pkg.go.dev/github.com/hashicorp/terraform/configs#Config)
|
||||||
representing the entire configuration.
|
representing the entire configuration.
|
||||||
|
|
||||||
Terraform expects configuration files written in the Terraform language, which
|
Terraform expects configuration files written in the Terraform language, which
|
||||||
|
@ -128,37 +128,37 @@ is a DSL built on top of
|
||||||
cannot be interpreted until we build and walk the graph, since they depend
|
cannot be interpreted until we build and walk the graph, since they depend
|
||||||
on the outcome of other parts of the configuration, and so these parts of
|
on the outcome of other parts of the configuration, and so these parts of
|
||||||
the configuration remain represented as the low-level HCL types
|
the configuration remain represented as the low-level HCL types
|
||||||
[hcl.Body](https://godoc.org/github.com/hashicorp/hcl/v2/hcl#Body)
|
[`hcl.Body`](https://pkg.go.dev/github.com/hashicorp/hcl/v2/#Body)
|
||||||
and
|
and
|
||||||
[hcl.Expression](https://godoc.org/github.com/hashicorp/hcl/v2/hcl#Expression),
|
[`hcl.Expression`](https://pkg.go.dev/github.com/hashicorp/hcl/v2/#Expression),
|
||||||
allowing Terraform to interpret them at a more appropriate time.
|
allowing Terraform to interpret them at a more appropriate time.
|
||||||
|
|
||||||
## State Manager
|
## State Manager
|
||||||
|
|
||||||
A _state manager_ is responsible for storing and retrieving snapshots of the
|
A _state manager_ is responsible for storing and retrieving snapshots of the
|
||||||
[Terraform state](https://www.terraform.io/docs/state/index.html)
|
[Terraform state](https://www.terraform.io/docs/language/state/index.html)
|
||||||
for a particular workspace. Each manager is an implementation of
|
for a particular workspace. Each manager is an implementation of
|
||||||
some combination of interfaces in
|
some combination of interfaces in
|
||||||
[the `statemgr` package](https://godoc.org/github.com/hashicorp/terraform/states/statemgr),
|
[the `statemgr` package](https://pkg.go.dev/github.com/hashicorp/terraform/states/statemgr),
|
||||||
with most practical managers implementing the full set of operations
|
with most practical managers implementing the full set of operations
|
||||||
described by
|
described by
|
||||||
[`statemgr.Full`](https://godoc.org/github.com/hashicorp/terraform/states/statemgr#Full)
|
[`statemgr.Full`](https://pkg.go.dev/github.com/hashicorp/terraform/states/statemgr#Full)
|
||||||
provided by a _backend_. The smaller interfaces exist primarily for use in
|
provided by a _backend_. The smaller interfaces exist primarily for use in
|
||||||
other function signatures to be explicit about what actions the function might
|
other function signatures to be explicit about what actions the function might
|
||||||
take on the state manager; there is little reason to write a state manager
|
take on the state manager; there is little reason to write a state manager
|
||||||
that does not implement all of `statemgr.Full`.
|
that does not implement all of `statemgr.Full`.
|
||||||
|
|
||||||
The implementation
|
The implementation
|
||||||
[`statemgr.Filesystem`](https://godoc.org/github.com/hashicorp/terraform/states/statemgr#Filesystem) is used
|
[`statemgr.Filesystem`](https://pkg.go.dev/github.com/hashicorp/terraform/states/statemgr#Filesystem) is used
|
||||||
by default (by the `local` backend) and is responsible for the familiar
|
by default (by the `local` backend) and is responsible for the familiar
|
||||||
`terraform.tfstate` local file that most Terraform users start with, before
|
`terraform.tfstate` local file that most Terraform users start with, before
|
||||||
they switch to [remote state](https://www.terraform.io/docs/state/remote.html).
|
they switch to [remote state](https://www.terraform.io/docs/language/state/remote.html).
|
||||||
Other implementations of `statemgr.Full` are used to implement remote state.
|
Other implementations of `statemgr.Full` are used to implement remote state.
|
||||||
Each of these saves and retrieves state via a remote network service
|
Each of these saves and retrieves state via a remote network service
|
||||||
appropriate to the backend that creates it.
|
appropriate to the backend that creates it.
|
||||||
|
|
||||||
A state manager accepts and returns a state snapshot as a
|
A state manager accepts and returns a state snapshot as a
|
||||||
[`states.State`](https://godoc.org/github.com/hashicorp/terraform/states#State)
|
[`states.State`](https://pkg.go.dev/github.com/hashicorp/terraform/states#State)
|
||||||
object. The state manager is responsible for exactly how that object is
|
object. The state manager is responsible for exactly how that object is
|
||||||
serialized and stored, but all state managers at the time of writing use
|
serialized and stored, but all state managers at the time of writing use
|
||||||
the same JSON serialization format, storing the resulting JSON bytes in some
|
the same JSON serialization format, storing the resulting JSON bytes in some
|
||||||
|
@ -167,7 +167,7 @@ kind of arbitrary blob store.
|
||||||
## Graph Builder
|
## Graph Builder
|
||||||
|
|
||||||
A _graph builder_ is called by a
|
A _graph builder_ is called by a
|
||||||
[`terraform.Context`](https://godoc.org/github.com/hashicorp/terraform/terraform#Context)
|
[`terraform.Context`](https://pkg.go.dev/github.com/hashicorp/terraform/terraform#Context)
|
||||||
method (e.g. `Plan` or `Apply`) to produce the graph that will be used
|
method (e.g. `Plan` or `Apply`) to produce the graph that will be used
|
||||||
to represent the necessary steps for that operation and the dependency
|
to represent the necessary steps for that operation and the dependency
|
||||||
relationships between them.
|
relationships between them.
|
||||||
|
@ -177,9 +177,9 @@ In most cases, the
|
||||||
graphs each represent a specific object in the configuration, or something
|
graphs each represent a specific object in the configuration, or something
|
||||||
derived from those configuration objects. For example, each `resource` block
|
derived from those configuration objects. For example, each `resource` block
|
||||||
in the configuration has one corresponding
|
in the configuration has one corresponding
|
||||||
[`GraphNodeResource`](https://godoc.org/github.com/hashicorp/terraform/terraform#GraphNodeResource)
|
[`GraphNodeConfigResource`](https://pkg.go.dev/github.com/hashicorp/terraform/terraform#GraphNodeConfigResource)
|
||||||
vertex representing it in the "plan" graph. (Terraform Core uses terminology
|
vertex representing it in the "plan" graph. (Terraform Core uses terminology
|
||||||
inconsistently, describing graph vertices also as graph nodes in various
|
inconsistently, describing graph _vertices_ also as graph _nodes_ in various
|
||||||
places. These both describe the same concept.)
|
places. These both describe the same concept.)
|
||||||
|
|
||||||
The [edges](https://en.wikipedia.org/wiki/Glossary_of_graph_theory_terms#edge)
|
The [edges](https://en.wikipedia.org/wiki/Glossary_of_graph_theory_terms#edge)
|
||||||
|
@ -194,26 +194,26 @@ graph from the set of changes described in the plan that is being applied.
|
||||||
|
|
||||||
The graph builders all work in terms of a sequence of _transforms_, which
|
The graph builders all work in terms of a sequence of _transforms_, which
|
||||||
are implementations of
|
are implementations of
|
||||||
[`terraform.GraphTransformer`](https://godoc.org/github.com/hashicorp/terraform/terraform#GraphTransformer).
|
[`terraform.GraphTransformer`](https://pkg.go.dev/github.com/hashicorp/terraform/terraform#GraphTransformer).
|
||||||
Implementations of this interface just take a graph and mutate it in any
|
Implementations of this interface just take a graph and mutate it in any
|
||||||
way needed, and so the set of available transforms is quite varied. Some
|
way needed, and so the set of available transforms is quite varied. Some
|
||||||
import examples include:
|
important examples include:
|
||||||
|
|
||||||
* [`ConfigTransformer`](https://godoc.org/github.com/hashicorp/terraform/terraform#ConfigTransformer),
|
* [`ConfigTransformer`](https://pkg.go.dev/github.com/hashicorp/terraform/terraform#ConfigTransformer),
|
||||||
which creates a graph vertex for each `resource` block in the configuration.
|
which creates a graph vertex for each `resource` block in the configuration.
|
||||||
|
|
||||||
* [`StateTransformer`](https://godoc.org/github.com/hashicorp/terraform/terraform#StateTransformer),
|
* [`StateTransformer`](https://pkg.go.dev/github.com/hashicorp/terraform/terraform#StateTransformer),
|
||||||
which creates a graph vertex for each resource instance currently tracked
|
which creates a graph vertex for each resource instance currently tracked
|
||||||
in the state.
|
in the state.
|
||||||
|
|
||||||
* [`ReferenceTransformer`](https://godoc.org/github.com/hashicorp/terraform/terraform#ReferenceTransformer),
|
* [`ReferenceTransformer`](https://pkg.go.dev/github.com/hashicorp/terraform/terraform#ReferenceTransformer),
|
||||||
which analyses the configuration to find dependencies between resources and
|
which analyses the configuration to find dependencies between resources and
|
||||||
other objects and creates any necessary "happens after" edges for these.
|
other objects and creates any necessary "happens after" edges for these.
|
||||||
|
|
||||||
* [`ProviderTransformer`](https://godoc.org/github.com/hashicorp/terraform/terraform#ProviderTransformer),
|
* [`ProviderTransformer`](https://pkg.go.dev/github.com/hashicorp/terraform/terraform#ProviderTransformer),
|
||||||
which associates each resource or resource instance with exactly one
|
which associates each resource or resource instance with exactly one
|
||||||
provider configuration (implementing
|
provider configuration (implementing
|
||||||
[the inheritance rules](https://www.terraform.io/docs/modules/usage.html#providers-within-modules))
|
[the inheritance rules](https://www.terraform.io/docs/language/modules/develop/providers.html))
|
||||||
and then creates "happens after" edges to ensure that the providers are
|
and then creates "happens after" edges to ensure that the providers are
|
||||||
initialized before taking any actions with the resources that belong to
|
initialized before taking any actions with the resources that belong to
|
||||||
them.
|
them.
|
||||||
|
@ -224,7 +224,7 @@ builder uses a different subset of these depending on the needs of the
|
||||||
operation that is being performed.
|
operation that is being performed.
|
||||||
|
|
||||||
The result of graph building is a
|
The result of graph building is a
|
||||||
[`terraform.Graph`](https://godoc.org/github.com/hashicorp/terraform/terraform#Graph), which
|
[`terraform.Graph`](https://pkg.go.dev/github.com/hashicorp/terraform/terraform#Graph), which
|
||||||
can then be processed using a _graph walker_.
|
can then be processed using a _graph walker_.
|
||||||
|
|
||||||
## Graph Walk
|
## Graph Walk
|
||||||
|
@ -232,17 +232,17 @@ can then be processed using a _graph walker_.
|
||||||
The process of walking the graph visits each vertex of that graph in a way
|
The process of walking the graph visits each vertex of that graph in a way
|
||||||
which respects the "happens after" edges in the graph. The walk algorithm
|
which respects the "happens after" edges in the graph. The walk algorithm
|
||||||
itself is implemented in
|
itself is implemented in
|
||||||
[the low-level `dag` package](https://godoc.org/github.com/hashicorp/terraform/dag#AcyclicGraph.Walk)
|
[the low-level `dag` package](https://pkg.go.dev/github.com/hashicorp/terraform/dag#AcyclicGraph.Walk)
|
||||||
(where "DAG" is short for [_Directed Acyclic Graph_](https://en.wikipedia.org/wiki/Directed_acyclic_graph)), in
|
(where "DAG" is short for [_Directed Acyclic Graph_](https://en.wikipedia.org/wiki/Directed_acyclic_graph)), in
|
||||||
[`AcyclicGraph.Walk`](https://godoc.org/github.com/hashicorp/terraform/dag#AcyclicGraph.Walk).
|
[`AcyclicGraph.Walk`](https://pkg.go.dev/github.com/hashicorp/terraform/dag#AcyclicGraph.Walk).
|
||||||
However, the "interesting" Terraform walk functionality is implemented in
|
However, the "interesting" Terraform walk functionality is implemented in
|
||||||
[`terraform.ContextGraphWalker`](https://godoc.org/github.com/hashicorp/terraform/terraform#ContextGraphWalker),
|
[`terraform.ContextGraphWalker`](https://pkg.go.dev/github.com/hashicorp/terraform/terraform#ContextGraphWalker),
|
||||||
which implements a small set of higher-level operations that are performed
|
which implements a small set of higher-level operations that are performed
|
||||||
during the graph walk:
|
during the graph walk:
|
||||||
|
|
||||||
* `EnterPath` is called once for each module in the configuration, taking a
|
* `EnterPath` is called once for each module in the configuration, taking a
|
||||||
module address and returning a
|
module address and returning a
|
||||||
[`terraform.EvalContext`](https://godoc.org/github.com/hashicorp/terraform/terraform#EvalContext)
|
[`terraform.EvalContext`](https://pkg.go.dev/github.com/hashicorp/terraform/terraform#EvalContext)
|
||||||
that tracks objects within that module. `terraform.Context` is the _global_
|
that tracks objects within that module. `terraform.Context` is the _global_
|
||||||
context for the entire operation, while `terraform.EvalContext` is a
|
context for the entire operation, while `terraform.EvalContext` is a
|
||||||
context for processing within a single module, and is the primary means
|
context for processing within a single module, and is the primary means
|
||||||
|
@ -258,7 +258,7 @@ will evaluate multiple vertices concurrently. Vertex evaluation code must
|
||||||
therefore make careful use of concurrency primitives such as mutexes in order
|
therefore make careful use of concurrency primitives such as mutexes in order
|
||||||
to coordinate access to shared objects such as the `states.State` object.
|
to coordinate access to shared objects such as the `states.State` object.
|
||||||
In most cases, we use the helper wrapper
|
In most cases, we use the helper wrapper
|
||||||
[`states.SyncState`](https://godoc.org/github.com/hashicorp/terraform/states#SyncState)
|
[`states.SyncState`](https://pkg.go.dev/github.com/hashicorp/terraform/states#SyncState)
|
||||||
to safely implement concurrent reads and writes from the shared state.
|
to safely implement concurrent reads and writes from the shared state.
|
||||||
|
|
||||||
## Vertex Evaluation
|
## Vertex Evaluation
|
||||||
|
@ -290,50 +290,53 @@ a plan operation would include the following high-level steps:
|
||||||
* Save the instance diff as part of the plan that is being constructed by
|
* Save the instance diff as part of the plan that is being constructed by
|
||||||
this operation.
|
this operation.
|
||||||
|
|
||||||
|
<!-- FIXME: EvalNode was removed in hashicorp/terraform#26413
|
||||||
|
The paragraphs below needs to be updated to reflect the current evaluation logic.
|
||||||
|
-->
|
||||||
Each evaluation step for a vertex is an implementation of
|
Each evaluation step for a vertex is an implementation of
|
||||||
[`terraform.EvalNode`](https://godoc.org/github.com/hashicorp/terraform/terraform#EvalNode).
|
[`terraform.EvalNode`](https://pkg.go.dev/github.com/hashicorp/terraform/terraform#EvalNode).
|
||||||
As with graph transforms, the behavior of these implementations varies widely:
|
As with graph transforms, the behavior of these implementations varies widely:
|
||||||
whereas graph transforms can take any action against the graph, an `EvalNode`
|
whereas graph transforms can take any action against the graph, an `EvalNode`
|
||||||
implementation can take any action against the `EvalContext`.
|
implementation can take any action against the `EvalContext`.
|
||||||
|
|
||||||
The implementation of `terraform.EvalContext` used in real processing
|
The implementation of `terraform.EvalContext` used in real processing
|
||||||
(as opposed to testing) is
|
(as opposed to testing) is
|
||||||
[`terraform.BuiltinEvalContext`](https://godoc.org/github.com/hashicorp/terraform/terraform#BuiltinEvalContext).
|
[`terraform.BuiltinEvalContext`](https://pkg.go.dev/github.com/hashicorp/terraform/terraform#BuiltinEvalContext).
|
||||||
It provides coordinated access to plugins, the current state, and the current
|
It provides coordinated access to plugins, the current state, and the current
|
||||||
plan via the `EvalContext` interface methods.
|
plan via the `EvalContext` interface methods.
|
||||||
|
|
||||||
In order to be evaluated, a vertex must implement
|
In order to be evaluated, a vertex must implement
|
||||||
[`terraform.GraphNodeEvalable`](https://godoc.org/github.com/hashicorp/terraform/terraform#GraphNodeEvalable),
|
[`terraform.GraphNodeEvalable`](https://pkg.go.dev/github.com/hashicorp/terraform/terraform#GraphNodeEvalable),
|
||||||
which has a single method that returns an `EvalNode`. In practice, most
|
which has a single method that returns an `EvalNode`. In practice, most
|
||||||
implementations return an instance of
|
implementations return an instance of
|
||||||
[`terraform.EvalSequence`](https://godoc.org/github.com/hashicorp/terraform/terraform#EvalSequence),
|
[`terraform.EvalSequence`](https://pkg.go.dev/github.com/hashicorp/terraform/terraform#EvalSequence),
|
||||||
which wraps a number of other `EvalNode` objects to be executed in sequence.
|
which wraps a number of other `EvalNode` objects to be executed in sequence.
|
||||||
|
|
||||||
There are numerous `EvalNode` implementations with different behaviors, but
|
There are numerous `EvalNode` implementations with different behaviors, but
|
||||||
some prominent examples are:
|
some prominent examples are:
|
||||||
|
|
||||||
* [`EvalReadState`](https://godoc.org/github.com/hashicorp/terraform/terraform#EvalReadState),
|
* [`EvalReadState`](https://pkg.go.dev/github.com/hashicorp/terraform/terraform#EvalReadState),
|
||||||
which extracts the data for a particular resource instance from the state.
|
which extracts the data for a particular resource instance from the state.
|
||||||
|
|
||||||
* [`EvalWriteState`](https://godoc.org/github.com/hashicorp/terraform/terraform#EvalWriteState),
|
* [`EvalWriteState`](https://pkg.go.dev/github.com/hashicorp/terraform/terraform#EvalWriteState),
|
||||||
which conversely replaces the data for a particular resource instance in
|
which conversely replaces the data for a particular resource instance in
|
||||||
the state with some updated data resulting from changes made by the
|
the state with some updated data resulting from changes made by the
|
||||||
provider.
|
provider.
|
||||||
|
|
||||||
* [`EvalInitProvider`](https://godoc.org/github.com/hashicorp/terraform/terraform#EvalInitProvider),
|
* [`EvalInitProvider`](https://pkg.go.dev/github.com/hashicorp/terraform/terraform#EvalInitProvider),
|
||||||
which starts up a provider plugin and passes the user-provided configuration
|
which starts up a provider plugin and passes the user-provided configuration
|
||||||
to it, caching the provider inside the `EvalContext`.
|
to it, caching the provider inside the `EvalContext`.
|
||||||
|
|
||||||
* [`EvalGetProvider`](https://godoc.org/github.com/hashicorp/terraform/terraform#EvalGetProvider),
|
* [`EvalGetProvider`](https://pkg.go.dev/github.com/hashicorp/terraform/terraform#EvalGetProvider),
|
||||||
which retrieves an already-initialized provider that is cached in the
|
which retrieves an already-initialized provider that is cached in the
|
||||||
`EvalContext`.
|
`EvalContext`.
|
||||||
|
|
||||||
* [`EvalValidateResource`](https://godoc.org/github.com/hashicorp/terraform/terraform#EvalValidateResource),
|
* [`EvalValidateResource`](https://pkg.go.dev/github.com/hashicorp/terraform/terraform#EvalValidateResource),
|
||||||
which checks to make sure that resource configuration conforms to the
|
which checks to make sure that resource configuration conforms to the
|
||||||
expected schema and gives a provider plugin the opportunity to check that
|
expected schema and gives a provider plugin the opportunity to check that
|
||||||
given values are within the expected range, etc.
|
given values are within the expected range, etc.
|
||||||
|
|
||||||
* [`EvalApply`](https://godoc.org/github.com/hashicorp/terraform/terraform#EvalApply),
|
* [`EvalApply`](https://pkg.go.dev/github.com/hashicorp/terraform/terraform#EvalApply),
|
||||||
which calls into a provider plugin to make apply some planned changes
|
which calls into a provider plugin to make apply some planned changes
|
||||||
to a given resource instance.
|
to a given resource instance.
|
||||||
|
|
||||||
|
@ -355,31 +358,32 @@ The high-level process for expression evaluation is:
|
||||||
to. For example, the expression `aws_instance.example[1]` refers to one of
|
to. For example, the expression `aws_instance.example[1]` refers to one of
|
||||||
the instances created by a `resource "aws_instance" "example"` block in
|
the instances created by a `resource "aws_instance" "example"` block in
|
||||||
configuration. This analysis is performed by
|
configuration. This analysis is performed by
|
||||||
[`lang.References`](https://godoc.org/github.com/hashicorp/terraform/lang#References),
|
[`lang.References`](https://pkg.go.dev/github.com/hashicorp/terraform/lang#References),
|
||||||
or more often one of the helper wrappers around it:
|
or more often one of the helper wrappers around it:
|
||||||
[`lang.ReferencesInBlock`](https://godoc.org/github.com/hashicorp/terraform/lang#ReferencesInBlock)
|
[`lang.ReferencesInBlock`](https://pkg.go.dev/github.com/hashicorp/terraform/lang#ReferencesInBlock)
|
||||||
or
|
or
|
||||||
[`lang.ReferencesInExpr`](https://godoc.org/github.com/hashicorp/terraform/lang#ReferencesInExpr)
|
[`lang.ReferencesInExpr`](https://pkg.go.dev/github.com/hashicorp/terraform/lang#ReferencesInExpr)
|
||||||
|
|
||||||
2. Retrieve from the state the data for the objects that are referred to and
|
1. Retrieve from the state the data for the objects that are referred to and
|
||||||
create a lookup table of the values from these objects that the
|
create a lookup table of the values from these objects that the
|
||||||
HCL evaluation code can refer to.
|
HCL evaluation code can refer to.
|
||||||
|
|
||||||
3. Prepare the table of built-in functions so that HCL evaluation can refer to
|
1. Prepare the table of built-in functions so that HCL evaluation can refer to
|
||||||
them.
|
them.
|
||||||
|
|
||||||
4. Ask HCL to evaluate each attribute's expression (a `hcl.Expression` object)
|
1. Ask HCL to evaluate each attribute's expression (a
|
||||||
against the data and function lookup tables.
|
[`hcl.Expression`](https://pkg.go.dev/github.com/hashicorp/hcl/v2/#Expression)
|
||||||
|
object) against the data and function lookup tables.
|
||||||
|
|
||||||
In practice, steps 2 through 4 are usually run all together using one
|
In practice, steps 2 through 4 are usually run all together using one
|
||||||
of the methods on [`lang.Scope`](https://godoc.org/github.com/hashicorp/terraform/lang#Scope);
|
of the methods on [`lang.Scope`](https://pkg.go.dev/github.com/hashicorp/terraform/lang#Scope);
|
||||||
most commonly,
|
most commonly,
|
||||||
[`lang.EvalBlock`](https://godoc.org/github.com/hashicorp/terraform/lang#Scope.EvalBlock)
|
[`lang.EvalBlock`](https://pkg.go.dev/github.com/hashicorp/terraform/lang#Scope.EvalBlock)
|
||||||
or
|
or
|
||||||
[`lang.EvalExpr`](https://godoc.org/github.com/hashicorp/terraform/lang#Scope.EvalExpr).
|
[`lang.EvalExpr`](https://pkg.go.dev/github.com/hashicorp/terraform/lang#Scope.EvalExpr).
|
||||||
|
|
||||||
Expression evaluation produces a dynamic value represented as a
|
Expression evaluation produces a dynamic value represented as a
|
||||||
[`cty.Value`](https://godoc.org/github.com/zclconf/go-cty/cty#Value).
|
[`cty.Value`](https://pkg.go.dev/github.com/zclconf/go-cty/cty#Value).
|
||||||
This Go type represents values from the Terraform language and such values
|
This Go type represents values from the Terraform language and such values
|
||||||
are eventually passed to provider plugins.
|
are eventually passed to provider plugins.
|
||||||
|
|
||||||
|
@ -401,9 +405,9 @@ known when the main graph is constructed, but become known while evaluating
|
||||||
other vertices in the main graph.
|
other vertices in the main graph.
|
||||||
|
|
||||||
This special behavior applies to vertex objects that implement
|
This special behavior applies to vertex objects that implement
|
||||||
[`terraform.GraphNodeDynamicExpandable`](https://godoc.org/github.com/hashicorp/terraform/terraform#GraphNodeDynamicExpandable). Such vertexes have their own nested _graph builder_, _graph walk_,
|
[`terraform.GraphNodeDynamicExpandable`](https://pkg.go.dev/github.com/hashicorp/terraform/terraform#GraphNodeDynamicExpandable).
|
||||||
|
Such vertices have their own nested _graph builder_, _graph walk_,
|
||||||
and _vertex evaluation_ steps, with the same behaviors as described in these
|
and _vertex evaluation_ steps, with the same behaviors as described in these
|
||||||
sections for the main graph. The difference is in which graph transforms
|
sections for the main graph. The difference is in which graph transforms
|
||||||
are used to construct the graph and in which evaluation steps apply to the
|
are used to construct the graph and in which evaluation steps apply to the
|
||||||
nodes in that sub-graph.
|
nodes in that sub-graph.
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue