plans

package
v1.17.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 27, 2021 License: MPL-2.0 Imports: 9 Imported by: 0

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

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Action

type Action rune
const (
	NoOp             Action = 0
	Create           Action = '+'
	Read             Action = '←'
	Update           Action = '~'
	DeleteThenCreate Action = '∓'
	CreateThenDelete Action = '±'
	Delete           Action = '-'
)

func (Action) IsReplace

func (a Action) IsReplace() bool

IsReplace returns true if the action is one of the two actions that represents replacing an existing object with a new object: DeleteThenCreate or CreateThenDelete.

func (Action) String

func (i Action) String() string

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

func NewBackend(typeName string, config cty.Value, configSchema *configschema.Block, workspaceName string) (*Backend, error)

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

func (c *Change) Encode(ty cty.Type) (*ChangeSrc, 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 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
}

ChangeSrc is a not-yet-decoded Change.

func (*ChangeSrc) Decode

func (cs *ChangeSrc) Decode(ty cty.Type) (*Change, error)

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) Empty

func (c *Changes) Empty() bool

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) 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) 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) 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) 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

func NewDynamicValue(val cty.Value, ty cty.Type) (DynamicValue, error)

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

func (v DynamicValue) Decode(ty cty.Type) (cty.Value, error)

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 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 {
	VariableValues  map[string]DynamicValue
	Changes         *Changes
	TargetAddrs     []addrs.Targetable
	ProviderSHA256s map[string][]byte
	Backend         Backend
}

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 state and 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

	// 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

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 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

	// 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
}

ResourceInstanceChangeSrc is a not-yet-decoded ResourceInstanceChange. Pass the associated resource type's schema type to method Decode to obtain a ResourceInstancChange.

func (*ResourceInstanceChangeSrc) Decode

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

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.

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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL