Documentation ¶
Overview ¶
Package plans contains the types that are used to represent Terraform plans.
A plan describes a set of changes that Terraform will make to update remote objects to match with changes to the configuration.
Index ¶
- type Action
- type Backend
- type Change
- type ChangeSrc
- type Changes
- func (c *Changes) Empty() bool
- func (c *Changes) InstancesForConfigResource(addr addrs.ConfigResource) []*ResourceInstanceChangeSrc
- func (c *Changes) OutputValue(addr addrs.AbsOutputValue) *OutputChangeSrc
- func (c *Changes) OutputValues(parent addrs.ModuleInstance, module addrs.ModuleCall) []*OutputChangeSrc
- func (c *Changes) PlannedState(prior *states.State) (*states.State, error)
- func (c *Changes) ResourceInstance(addr addrs.AbsResourceInstance) *ResourceInstanceChangeSrc
- func (c *Changes) ResourceInstanceDeposed(addr addrs.AbsResourceInstance, key states.DeposedKey) *ResourceInstanceChangeSrc
- func (c *Changes) SyncWrapper() *ChangesSync
- type ChangesSync
- func (cs *ChangesSync) AppendOutputChange(changeSrc *OutputChangeSrc)
- func (cs *ChangesSync) AppendResourceInstanceChange(changeSrc *ResourceInstanceChangeSrc)
- func (cs *ChangesSync) GetChangesForConfigResource(addr addrs.ConfigResource) []*ResourceInstanceChangeSrc
- func (cs *ChangesSync) GetOutputChange(addr addrs.AbsOutputValue) *OutputChangeSrc
- func (cs *ChangesSync) GetOutputChanges(parent addrs.ModuleInstance, module addrs.ModuleCall) []*OutputChangeSrc
- func (cs *ChangesSync) GetResourceInstanceChange(addr addrs.AbsResourceInstance, gen states.Generation) *ResourceInstanceChangeSrc
- func (cs *ChangesSync) IsFullDestroy() bool
- func (cs *ChangesSync) RemoveOutputChange(addr addrs.AbsOutputValue)
- func (cs *ChangesSync) RemoveResourceInstanceChange(addr addrs.AbsResourceInstance, gen states.Generation)
- type DynamicValue
- type Mode
- type OutputChange
- type OutputChangeSrc
- type Plan
- type ResourceInstanceChange
- type ResourceInstanceChangeActionReason
- type ResourceInstanceChangeSrc
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Action ¶
type Action rune
type Backend ¶
type Backend struct { // Type is the type of backend that the plan will apply against. Type string // Config is the configuration of the backend, whose schema is decided by // the backend Type. Config DynamicValue // Workspace is the name of the workspace that was active when the plan // was created. It is illegal to apply a plan created for one workspace // to the state of another workspace. // (This constraint is already enforced by the statefile lineage mechanism, // but storing this explicitly allows us to return a better error message // in the situation where the user has the wrong workspace selected.) Workspace string }
Backend represents the backend-related configuration and other data as it existed when a plan was created.
func NewBackend ¶
type Change ¶
type Change struct { // Action defines what kind of change is being made. Action Action // Interpretation of Before and After depend on Action: // // NoOp Before and After are the same, unchanged value // Create Before is nil, and After is the expected value after create. // Read Before is any prior value (nil if no prior), and After is the // value that was or will be read. // Update Before is the value prior to update, and After is the expected // value after update. // Replace As with Update. // Delete Before is the value prior to delete, and After is always nil. // // Unknown values may appear anywhere within the Before and After values, // either as the values themselves or as nested elements within known // collections/structures. Before, After cty.Value }
Change describes a single change with a given action.
func (*Change) Encode ¶
Encode produces a variant of the reciever that has its change values serialized so it can be written to a plan file. Pass the type constraint that the values are expected to conform to; to properly decode the values later an identical type constraint must be provided at that time.
Where a Change is embedded in some other struct, it's generally better to call the corresponding Encode method of that struct rather than working directly with its embedded Change.
type ChangeSrc ¶
type ChangeSrc struct { // Action defines what kind of change is being made. Action Action // Before and After correspond to the fields of the same name in Change, // but have not yet been decoded from the serialized value used for // storage. Before, After DynamicValue // BeforeValMarks and AfterValMarks are stored path+mark combinations // that might be discovered when encoding a change. Marks are removed // to enable encoding (marked values cannot be marshalled), and so storing // the path+mark combinations allow us to re-mark the value later // when, for example, displaying the diff to the UI. BeforeValMarks, AfterValMarks []cty.PathValueMarks }
ChangeSrc is a not-yet-decoded Change.
func (*ChangeSrc) Decode ¶
Decode unmarshals the raw representations of the before and after values to produce a Change object. Pass the type constraint that the result must conform to.
Where a ChangeSrc is embedded in some other struct, it's generally better to call the corresponding Decode method of that struct rather than working directly with its embedded Change.
type Changes ¶
type Changes struct { // Resources tracks planned changes to resource instance objects. Resources []*ResourceInstanceChangeSrc // Outputs tracks planned changes output values. // // Note that although an in-memory plan contains planned changes for // outputs throughout the configuration, a plan serialized // to disk retains only the root outputs because they are // externally-visible, while other outputs are implementation details and // can be easily re-calculated during the apply phase. Therefore only root // module outputs will survive a round-trip through a plan file. Outputs []*OutputChangeSrc }
Changes describes various actions that Terraform will attempt to take if the corresponding plan is applied.
A Changes object can be rendered into a visual diff (by the caller, using code in another package) for display to the user.
func NewChanges ¶
func NewChanges() *Changes
NewChanges returns a valid Changes object that describes no changes.
func (*Changes) InstancesForConfigResource ¶ added in v0.13.0
func (c *Changes) InstancesForConfigResource(addr addrs.ConfigResource) []*ResourceInstanceChangeSrc
InstancesForConfigResource returns the planned change for the current objects of the resource instances of the given address, if any. Returns nil if no changes are planned.
func (*Changes) OutputValue ¶
func (c *Changes) OutputValue(addr addrs.AbsOutputValue) *OutputChangeSrc
OutputValue returns the planned change for the output value with the
given address, if any. Returns nil if no change is planned.
func (*Changes) OutputValues ¶ added in v0.13.0
func (c *Changes) OutputValues(parent addrs.ModuleInstance, module addrs.ModuleCall) []*OutputChangeSrc
OutputValues returns planned changes for all outputs for all module instances that reside in the parent path. Returns nil if no changes are planned.
func (*Changes) PlannedState ¶
PlannedState merges the set of changes described by the receiver into the given prior state to produce the planned result state.
The result is an approximation of the state as it would exist after applying these changes, omitting any values that cannot be determined until the changes are actually applied.
func (*Changes) ResourceInstance ¶
func (c *Changes) ResourceInstance(addr addrs.AbsResourceInstance) *ResourceInstanceChangeSrc
ResourceInstance returns the planned change for the current object of the resource instance of the given address, if any. Returns nil if no change is planned.
func (*Changes) ResourceInstanceDeposed ¶
func (c *Changes) ResourceInstanceDeposed(addr addrs.AbsResourceInstance, key states.DeposedKey) *ResourceInstanceChangeSrc
ResourceInstanceDeposed returns the plan change of a deposed object of the resource instance of the given address, if any. Returns nil if no change is planned.
func (*Changes) SyncWrapper ¶
func (c *Changes) SyncWrapper() *ChangesSync
SyncWrapper returns a wrapper object around the receiver that can be used to make certain changes to the receiver in a concurrency-safe way, as long as all callers share the same wrapper object.
type ChangesSync ¶
type ChangesSync struct {
// contains filtered or unexported fields
}
ChangesSync is a wrapper around a Changes that provides a concurrency-safe interface to insert new changes and retrieve copies of existing changes.
Each ChangesSync is independent of all others, so all concurrent writers to a particular Changes must share a single ChangesSync. Behavior is undefined if any other caller makes changes to the underlying Changes object or its nested objects concurrently with any of the methods of a particular ChangesSync.
func (*ChangesSync) AppendOutputChange ¶
func (cs *ChangesSync) AppendOutputChange(changeSrc *OutputChangeSrc)
AppendOutputChange records the given output value change in the set of planned value changes.
The caller must ensure that there are no concurrent writes to the given change while this method is running, but it is safe to resume mutating it after this method returns without affecting the saved change.
func (*ChangesSync) AppendResourceInstanceChange ¶
func (cs *ChangesSync) AppendResourceInstanceChange(changeSrc *ResourceInstanceChangeSrc)
AppendResourceInstanceChange records the given resource instance change in the set of planned resource changes.
The caller must ensure that there are no concurrent writes to the given change while this method is running, but it is safe to resume mutating it after this method returns without affecting the saved change.
func (*ChangesSync) GetChangesForConfigResource ¶ added in v0.13.0
func (cs *ChangesSync) GetChangesForConfigResource(addr addrs.ConfigResource) []*ResourceInstanceChangeSrc
GetChangesForConfigResource searched the set of resource instance changes and returns all changes related to a given configuration address. This is be used to find possible changes related to a configuration reference.
If no such changes exist, nil is returned.
The returned objects are a deep copy of the change recorded in the plan, so callers may mutate them although it's generally better (less confusing) to treat planned changes as immutable after they've been initially constructed.
func (*ChangesSync) GetOutputChange ¶
func (cs *ChangesSync) GetOutputChange(addr addrs.AbsOutputValue) *OutputChangeSrc
GetOutputChange searches the set of output value changes for one matching the given address, returning it if it exists.
If no such change exists, nil is returned.
The returned object is a deep copy of the change recorded in the plan, so callers may mutate it although it's generally better (less confusing) to treat planned changes as immutable after they've been initially constructed.
func (*ChangesSync) GetOutputChanges ¶ added in v0.13.0
func (cs *ChangesSync) GetOutputChanges(parent addrs.ModuleInstance, module addrs.ModuleCall) []*OutputChangeSrc
GetOutputChanges searches the set of output changes for any that reside in module instances beneath the given module. If no changes exist, nil is returned.
The returned objects are a deep copy of the change recorded in the plan, so callers may mutate them although it's generally better (less confusing) to treat planned changes as immutable after they've been initially constructed.
func (*ChangesSync) GetResourceInstanceChange ¶
func (cs *ChangesSync) GetResourceInstanceChange(addr addrs.AbsResourceInstance, gen states.Generation) *ResourceInstanceChangeSrc
GetResourceInstanceChange searches the set of resource instance changes for one matching the given address and generation, returning it if it exists.
If no such change exists, nil is returned.
The returned object is a deep copy of the change recorded in the plan, so callers may mutate it although it's generally better (less confusing) to treat planned changes as immutable after they've been initially constructed.
func (*ChangesSync) IsFullDestroy ¶ added in v0.14.0
func (cs *ChangesSync) IsFullDestroy() bool
IsFullDestroy returns true if the set of changes indicates we are doing a destroy of all resources.
func (*ChangesSync) RemoveOutputChange ¶
func (cs *ChangesSync) RemoveOutputChange(addr addrs.AbsOutputValue)
RemoveOutputChange searches the set of output value changes for one matching the given address, and removes it from the set if it exists.
func (*ChangesSync) RemoveResourceInstanceChange ¶
func (cs *ChangesSync) RemoveResourceInstanceChange(addr addrs.AbsResourceInstance, gen states.Generation)
RemoveResourceInstanceChange searches the set of resource instance changes for one matching the given address and generation, and removes it from the set if it exists.
type DynamicValue ¶
type DynamicValue []byte
DynamicValue is the representation in the plan of a value whose type cannot be determined at compile time, such as because it comes from a schema defined in a plugin.
This type is used as an indirection so that the overall plan structure can be decoded without schema available, and then the dynamic values accessed at a later time once the appropriate schema has been determined.
Internally, DynamicValue is a serialized version of a cty.Value created against a particular type constraint. Callers should not access directly the serialized form, whose format may change in future. Values of this type must always be created by calling NewDynamicValue.
The zero value of DynamicValue is nil, and represents the absense of a value within the Go type system. This is distinct from a cty.NullVal result, which represents the absense of a value within the cty type system.
func NewDynamicValue ¶
NewDynamicValue creates a DynamicValue by serializing the given value against the given type constraint. The value must conform to the type constraint, or the result is undefined.
If the value to be encoded has no predefined schema (for example, for module output values and input variables), set the type constraint to cty.DynamicPseudoType in order to save type information as part of the value, and then also pass cty.DynamicPseudoType to method Decode to recover the original value.
cty.NilVal can be used to represent the absense of a value, but callers must be careful to distinguish values that are absent at the Go layer (cty.NilVal) vs. values that are absent at the cty layer (cty.NullVal results).
func (DynamicValue) Copy ¶
func (v DynamicValue) Copy() DynamicValue
Copy produces a copy of the receiver with a distinct backing array.
func (DynamicValue) Decode ¶
Decode retrieves the effective value from the receiever by interpreting the serialized form against the given type constraint. For correct results, the type constraint must match (or be consistent with) the one that was used to create the receiver.
A nil DynamicValue decodes to cty.NilVal, which is not a valid value and instead represents the absense of a value.
func (DynamicValue) ImpliedType ¶
func (v DynamicValue) ImpliedType() (cty.Type, error)
ImpliedType returns the type implied by the serialized structure of the receiving value.
This will not necessarily be exactly the type that was given when the value was encoded, and in particular must not be used for values that were encoded with their static type given as cty.DynamicPseudoType. It is however safe to use this method for values that were encoded using their runtime type as the conforming type, with the result being semantically equivalent but with all lists and sets represented as tuples, and maps as objects, due to ambiguities of the serialization.
type Mode ¶ added in v0.15.2
type Mode rune
Mode represents the various mutually-exclusive modes for creating a plan.
const ( // NormalMode is the default planning mode, which aims to synchronize the // prior state with remote objects and plan a set of actions intended to // make those remote objects better match the current configuration. NormalMode Mode = 0 // DestroyMode is a special planning mode for situations where the goal // is to destroy all remote objects that are bound to instances in the // prior state, even if the configuration for those instances is still // present. // // This mode corresponds with the "-destroy" option to "terraform plan", // and with the plan created by the "terraform destroy" command. DestroyMode Mode = 'D' // RefreshOnlyMode is a special planning mode which only performs the // synchronization of prior state with remote objects, and skips any // effort to generate any change actions for resource instances even if // the configuration has changed relative to the state. // // This mode corresponds with the "-refresh-only" option to // "terraform plan". RefreshOnlyMode Mode = 'R' )
type OutputChange ¶
type OutputChange struct { // Addr is the absolute address of the output value that the change // will apply to. Addr addrs.AbsOutputValue // Change is an embedded description of the change. // // For output value changes, the type constraint for the DynamicValue // instances is always cty.DynamicPseudoType. Change // Sensitive, if true, indicates that either the old or new value in the // change is sensitive and so a rendered version of the plan in the UI // should elide the actual values while still indicating the action of the // change. Sensitive bool }
OutputChange describes a change to an output value.
func (*OutputChange) Encode ¶
func (oc *OutputChange) Encode() (*OutputChangeSrc, error)
Encode produces a variant of the reciever that has its change values serialized so it can be written to a plan file.
type OutputChangeSrc ¶
type OutputChangeSrc struct { // Addr is the absolute address of the output value that the change // will apply to. Addr addrs.AbsOutputValue // ChangeSrc is an embedded description of the not-yet-decoded change. // // For output value changes, the type constraint for the DynamicValue // instances is always cty.DynamicPseudoType. ChangeSrc // Sensitive, if true, indicates that either the old or new value in the // change is sensitive and so a rendered version of the plan in the UI // should elide the actual values while still indicating the action of the // change. Sensitive bool }
OutputChangeSrc describes a change to an output value.
func (*OutputChangeSrc) Decode ¶
func (ocs *OutputChangeSrc) Decode() (*OutputChange, error)
Decode unmarshals the raw representation of the output value being changed.
func (*OutputChangeSrc) DeepCopy ¶
func (ocs *OutputChangeSrc) DeepCopy() *OutputChangeSrc
DeepCopy creates a copy of the receiver where any pointers to nested mutable values are also copied, thus ensuring that future mutations of the receiver will not affect the copy.
Some types used within a resource change are immutable by convention even though the Go language allows them to be mutated, such as the types from the addrs package. These are _not_ copied by this method, under the assumption that callers will behave themselves.
type Plan ¶
type Plan struct { // Mode is the mode under which this plan was created. // // This is only recorded to allow for UI differences when presenting plans // to the end-user, and so it must not be used to influence apply-time // behavior. The actions during apply must be described entirely by // the Changes field, regardless of how the plan was created. UIMode Mode VariableValues map[string]DynamicValue Changes *Changes TargetAddrs []addrs.Targetable ForceReplaceAddrs []addrs.AbsResourceInstance ProviderSHA256s map[string][]byte Backend Backend State *states.State }
Plan is the top-level type representing a planned set of changes.
A plan is a summary of the set of changes required to move from a current state to a goal state derived from configuration. The described changes are not applied directly, but contain an approximation of the final result that will be completed during apply by resolving any values that cannot be predicted.
A plan must always be accompanied by the configuration it was built from, since the plan does not itself include all of the information required to make the changes indicated.
func (*Plan) ProviderAddrs ¶
func (p *Plan) ProviderAddrs() []addrs.AbsProviderConfig
ProviderAddrs returns a list of all of the provider configuration addresses referenced throughout the receiving plan.
The result is de-duplicated so that each distinct address appears only once.
type ResourceInstanceChange ¶
type ResourceInstanceChange struct { // Addr is the absolute address of the resource instance that the change // will apply to. Addr addrs.AbsResourceInstance // DeposedKey is the identifier for a deposed object associated with the // given instance, or states.NotDeposed if this change applies to the // current object. // // A Replace change for a resource with create_before_destroy set will // create a new DeposedKey temporarily during replacement. In that case, // DeposedKey in the plan is always states.NotDeposed, representing that // the current object is being replaced with the deposed. DeposedKey states.DeposedKey // Provider is the address of the provider configuration that was used // to plan this change, and thus the configuration that must also be // used to apply it. ProviderAddr addrs.AbsProviderConfig // Change is an embedded description of the change. Change // ActionReason is an optional extra indication of why we chose the // action recorded in Change.Action for this particular resource instance. // // This is an approximate mechanism only for the purpose of explaining the // plan to end-users in the UI and is not to be used for any // decision-making during the apply step; if apply behavior needs to vary // depending on the "action reason" then the information for that decision // must be recorded more precisely elsewhere for that purpose. // // Sometimes there might be more than one reason for choosing a particular // action. In that case, it's up to the codepath making that decision to // decide which value would provide the most relevant explanation to the // end-user and return that. It's not a goal of this field to represent // fine details about the planning process. ActionReason ResourceInstanceChangeActionReason // RequiredReplace is a set of paths that caused the change action to be // Replace rather than Update. Always nil if the change action is not // Replace. // // This is retained only for UI-plan-rendering purposes and so it does not // currently survive a round-trip through a saved plan file. RequiredReplace cty.PathSet // Private allows a provider to stash any extra data that is opaque to // Terraform that relates to this change. Terraform will save this // byte-for-byte and return it to the provider in the apply call. Private []byte }
ResourceInstanceChange describes a change to a particular resource instance object.
func (*ResourceInstanceChange) Encode ¶
func (rc *ResourceInstanceChange) Encode(ty cty.Type) (*ResourceInstanceChangeSrc, error)
Encode produces a variant of the reciever that has its change values serialized so it can be written to a plan file. Pass the implied type of the corresponding resource type schema for correct operation.
func (*ResourceInstanceChange) Simplify ¶
func (rc *ResourceInstanceChange) Simplify(destroying bool) *ResourceInstanceChange
Simplify will, where possible, produce a change with a simpler action than the receiever given a flag indicating whether the caller is dealing with a normal apply or a destroy. This flag deals with the fact that Terraform Core uses a specialized graph node type for destroying; only that specialized node should set "destroying" to true.
The following table shows the simplification behavior:
Action Destroying? New Action --------+-------------+----------- Create true NoOp Delete false NoOp Replace true Delete Replace false Create
For any combination not in the above table, the Simplify just returns the receiver as-is.
type ResourceInstanceChangeActionReason ¶ added in v0.15.2
type ResourceInstanceChangeActionReason rune
ResourceInstanceChangeActionReason allows for some extra user-facing reasoning for why a particular change action was chosen for a particular resource instance.
This only represents sufficient detail to give a suitable explanation to an end-user, and mustn't be used for any real decision-making during the apply step.
const ( // In most cases there's no special reason for choosing a particular // action, which is represented by ResourceInstanceChangeNoReason. ResourceInstanceChangeNoReason ResourceInstanceChangeActionReason = 0 // ResourceInstanceReplaceBecauseTainted indicates that the resource // instance must be replaced because its existing current object is // marked as "tainted". ResourceInstanceReplaceBecauseTainted ResourceInstanceChangeActionReason = 'T' // ResourceInstanceReplaceByRequest indicates that the resource instance // is planned to be replaced because a caller specifically asked for it // to be using ReplaceAddrs. (On the command line, the -replace=... // planning option.) ResourceInstanceReplaceByRequest ResourceInstanceChangeActionReason = 'R' // ResourceInstanceReplaceBecauseCannotUpdate indicates that the resource // instance is planned to be replaced because the provider has indicated // that a requested change cannot be applied as an update. // // In this case, the RequiredReplace field will typically be populated on // the ResourceInstanceChange object to give information about specifically // which arguments changed in a non-updatable way. ResourceInstanceReplaceBecauseCannotUpdate ResourceInstanceChangeActionReason = 'F' )
func (ResourceInstanceChangeActionReason) String ¶ added in v0.15.2
func (i ResourceInstanceChangeActionReason) String() string
type ResourceInstanceChangeSrc ¶
type ResourceInstanceChangeSrc struct { // Addr is the absolute address of the resource instance that the change // will apply to. Addr addrs.AbsResourceInstance // DeposedKey is the identifier for a deposed object associated with the // given instance, or states.NotDeposed if this change applies to the // current object. // // A Replace change for a resource with create_before_destroy set will // create a new DeposedKey temporarily during replacement. In that case, // DeposedKey in the plan is always states.NotDeposed, representing that // the current object is being replaced with the deposed. DeposedKey states.DeposedKey // Provider is the address of the provider configuration that was used // to plan this change, and thus the configuration that must also be // used to apply it. ProviderAddr addrs.AbsProviderConfig // ChangeSrc is an embedded description of the not-yet-decoded change. ChangeSrc // ActionReason is an optional extra indication of why we chose the // action recorded in Change.Action for this particular resource instance. // // This is an approximate mechanism only for the purpose of explaining the // plan to end-users in the UI and is not to be used for any // decision-making during the apply step; if apply behavior needs to vary // depending on the "action reason" then the information for that decision // must be recorded more precisely elsewhere for that purpose. // // See the field of the same name in ResourceInstanceChange for more // details. ActionReason ResourceInstanceChangeActionReason // RequiredReplace is a set of paths that caused the change action to be // Replace rather than Update. Always nil if the change action is not // Replace. RequiredReplace cty.PathSet // Private allows a provider to stash any extra data that is opaque to // Terraform that relates to this change. Terraform will save this // byte-for-byte and return it to the provider in the apply call. Private []byte }
ResourceInstanceChangeSrc is a not-yet-decoded ResourceInstanceChange. Pass the associated resource type's schema type to method Decode to obtain a ResourceInstanceChange.
func (*ResourceInstanceChangeSrc) Decode ¶
func (rcs *ResourceInstanceChangeSrc) Decode(ty cty.Type) (*ResourceInstanceChange, error)
Decode unmarshals the raw representation of the instance object being changed. Pass the implied type of the corresponding resource type schema for correct operation.
func (*ResourceInstanceChangeSrc) DeepCopy ¶
func (rcs *ResourceInstanceChangeSrc) DeepCopy() *ResourceInstanceChangeSrc
DeepCopy creates a copy of the receiver where any pointers to nested mutable values are also copied, thus ensuring that future mutations of the receiver will not affect the copy.
Some types used within a resource change are immutable by convention even though the Go language allows them to be mutated, such as the types from the addrs package. These are _not_ copied by this method, under the assumption that callers will behave themselves.
Source Files ¶
Directories ¶
Path | Synopsis |
---|---|
internal
|
|
planproto
Package planproto is home to the Go stubs generated from the tfplan protobuf schema.
|
Package planproto is home to the Go stubs generated from the tfplan protobuf schema. |
Package objchange deals with the business logic of taking a prior state value and a config value and producing a proposed new merged value, along with other related rules in this domain.
|
Package objchange deals with the business logic of taking a prior state value and a config value and producing a proposed new merged value, along with other related rules in this domain. |
Package planfile deals with the file format used to serialize plans to disk and then deserialize them back into memory later.
|
Package planfile deals with the file format used to serialize plans to disk and then deserialize them back into memory later. |