opentofu/plans/internal/planproto/planfile.proto
Martin Atkins a43b7df282 core: Handle forced-create_before_destroy during the plan walk
Previously we used a single plan action "Replace" to represent both the
destroy-before-create and the create-before-destroy variants of replacing.
However, this forces the apply graph builder to jump through a lot of
hoops to figure out which nodes need it forced on and rebuild parts of
the graph to represent that.

If we instead decide between these two cases at plan time, the actual
determination of it is more straightforward because each resource is
represented by only one node in the plan graph, and then we can ensure
we put the right nodes in the graph during DiffTransformer and thus avoid
the logic for dealing with deposed instances being spread across various
different transformers and node types.

As a nice side-effect, this also allows us to show the difference between
destroy-then-create and create-then-destroy in the rendered diff in the
CLI, although this change doesn't fully implement that yet.
2018-10-16 19:14:11 -07:00

206 lines
8.2 KiB
Protocol Buffer

syntax = "proto3";
package tfplan;
// For Terraform's own parsing, the proto stub types go into an internal Go
// package. The public API is in github.com/hashicorp/terraform/plans/planfile .
option go_package = "github.com/hashicorp/terraform/plans/internal/planproto";
// Plan is the root message type for the tfplan file
message Plan {
// Version is incremented whenever there is a breaking change to
// the serialization format. Programs reading serialized plans should
// verify that version is set to the expected value and abort processing
// if not. A breaking change is any change that may cause an older
// consumer to interpret the structure incorrectly. This number will
// not be incremented if an existing consumer can either safely ignore
// changes to the format or if an existing consumer would fail to process
// the file for another message- or field-specific reason.
uint64 version = 1;
// The variables that were set when creating the plan. Each value is
// a msgpack serialization of an HCL value.
map<string, DynamicValue> variables = 2;
// An unordered set of proposed changes to resources throughout the
// configuration, including any nested modules. Use the address of
// each resource to determine which module it belongs to.
repeated ResourceInstanceChange resource_changes = 3;
// An unordered set of proposed changes to outputs in the root module
// of the configuration. This set also includes "no action" changes for
// outputs that are not changing, as context for detecting inconsistencies
// at apply time.
repeated OutputChange output_changes = 4;
// An unordered set of target addresses to include when applying. If no
// target addresses are present, the plan applies to the whole
// configuration.
repeated string target_addrs = 5;
// The version string for the Terraform binary that created this plan.
string terraform_version = 14;
// SHA256 digests of all of the provider plugin binaries that were used
// in the creation of this plan.
map<string, Hash> provider_hashes = 15;
// Backend is a description of the backend configuration and other related
// settings at the time the plan was created.
Backend backend = 13;
}
// Backend is a description of backend configuration and other related settings.
message Backend {
string type = 1;
DynamicValue config = 2;
string workspace = 3;
}
// Action describes the type of action planned for an object.
// Not all action values are valid for all object types.
enum Action {
NOOP = 0;
CREATE = 1;
READ = 2;
UPDATE = 3;
DELETE = 5;
DELETE_THEN_CREATE = 6;
CREATE_THEN_DELETE = 7;
}
// Change represents a change made to some object, transforming it from an old
// state to a new state.
message Change {
// Not all action values are valid for all object types. Consult
// the documentation for any message that embeds Change.
Action action = 1;
// msgpack-encoded HCL values involved in the change.
// - For update and replace, two values are provided that give the old and new values,
// respectively.
// - For create, one value is provided that gives the new value to be created
// - For delete, one value is provided that describes the value being deleted
// - For read, two values are provided that give the prior value for this object
// (or null, if no prior value exists) and the value that was or will be read,
// respectively.
// - For no-op, one value is provided that is left unmodified by this non-change.
repeated DynamicValue values = 2;
}
message ResourceInstanceChange {
// module_path is an address to the module that defined this resource.
// module_path is omitted for resources in the root module. For descendent modules
// it is a string like module.foo.module.bar as would be seen at the beginning of a
// resource address. The format of this string is not yet frozen and so external
// callers should treat it as an opaque key for filtering purposes.
string module_path = 1;
// mode is the resource mode.
ResourceMode mode = 2;
enum ResourceMode {
managed = 0; // for "resource" blocks in configuration
data = 1; // for "data" blocks in configuration
}
// type is the resource type name, like "aws_instance".
string type = 3;
// name is the logical name of the resource as defined in configuration.
// For example, in aws_instance.foo this would be "foo".
string name = 4;
// instance_key is either an integer index or a string key, depending on which iteration
// attributes ("count" or "for_each") are being used for this resource. If none
// are in use, this field is omitted.
oneof instance_key {
string str = 5;
int64 int = 6;
};
// deposed_key, if set, indicates that this change applies to a deposed
// object for the indicated instance with the given deposed key. If not
// set, the change applies to the instance's current object.
string deposed_key = 7;
// provider is the address of the provider configuration that this change
// was planned with, and thus the configuration that must be used to
// apply it.
string provider = 8;
// Description of the proposed change. May use "create", "read", "update",
// "replace" and "delete" actions. "no-op" changes are not currently used here
// but consumers must accept and discard them to allow for future expansion.
Change change = 9;
// raw blob value provided by the provider as additional context for the
// change. Must be considered an opaque value for any consumer other than
// the provider that generated it, and will be returned verbatim to the
// provider during the subsequent apply operation.
bytes private = 10;
// An unordered set of paths that prompted the change action to be
// "replace" rather than "update". Empty for any action other than
// "replace".
repeated Path required_replace = 11;
}
message OutputChange {
// Name of the output as defined in the root module.
string name = 1;
// Description of the proposed change. May use "no-op", "create",
// "update" and "delete" actions.
Change change = 2;
// Sensitive, if true, indicates that one or more of the values given
// in "change" is sensitive and should not be shown directly in any
// rendered plan.
bool sensitive = 3;
}
// DynamicValue represents a value whose type is not decided until runtime,
// often based on schema information obtained from a plugin.
//
// At present dynamic values are always encoded as msgpack, with extension
// id 0 used to represent the special "unknown" value indicating results
// that won't be known until after apply.
//
// In future other serialization formats may be used, possibly with a
// transitional period of including both as separate attributes of this type.
// Consumers must ignore attributes they don't support and fail if no supported
// attribute is present. The top-level format version will not be incremented
// for changes to the set of dynamic serialization formats.
message DynamicValue {
bytes msgpack = 1;
}
// Hash represents a hash value.
//
// At present hashes always use the SHA256 algorithm. In future other hash
// algorithms may be used, possibly with a transitional period of including
// both as separate attributes of this type. Consumers must ignore attributes
// they don't support and fail if no supported attribute is present. The
// top-level format version will not be incremented for changes to the set of
// hash algorithms.
message Hash {
bytes sha256 = 1;
}
// Path represents a set of steps to traverse into a data structure. It is
// used to refer to a sub-structure within a dynamic data structure presented
// separately.
message Path {
message Step {
oneof selector {
// Set "attribute_name" to represent looking up an attribute
// in the current object value.
string attribute_name = 1;
// Set "element_key" to represent looking up an element in
// an indexable collection type.
DynamicValue element_key = 2;
}
}
repeated Step steps = 1;
}