You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
terraform/internal/rpcapi/terraform1/terraform1.proto

1214 lines
45 KiB

// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
syntax = "proto3";
package terraform1;
import "google/protobuf/any.proto";
service Setup {
// Clients must call Handshake before any other function of any other
// service, to complete the capability negotiation step that may
// then affect the behaviors of subsequent operations.
//
// This function can be called only once per RPC server.
rpc Handshake(Handshake.Request) returns (Handshake.Response);
}
message Handshake {
message Request {
ClientCapabilities capabilities = 1;
}
message Response {
ServerCapabilities capabilities = 2;
}
}
// The capabilities that the client wishes to advertise to the server during
// handshake.
message ClientCapabilities {
// There are not yet any negotiatable capabilities.
}
// The capabilities that the server wishes to advertise to the client during
// handshake. Fields in this message can also be used to acknowledge and
// confirm support for client capabilities advertised in ClientCapabilities,
// in situations where the client must vary its behavior based on the server's
// level of support.
message ServerCapabilities {
// There are not yet any negotiatable capabilities.
}
service Dependencies {
// Opens a source bundle that was already extracted into the filesystem
// somewhere, returning an opaque source bundle handle that can be used for
// subsequent operations.
rpc OpenSourceBundle(OpenSourceBundle.Request) returns (OpenSourceBundle.Response);
// Closes a previously-opened source bundle, invalidating the given handle
// and therefore making it safe to delete or modify the bundle directory
// on disk.
rpc CloseSourceBundle(CloseSourceBundle.Request) returns (CloseSourceBundle.Response);
// Reads and parses an existing dependency lock file from the filesystem,
// returning a dependency locks handle.
//
// This function parses a user-provided source file, and so invalid content
// in that file is treated as diagnostics in a successful response rather
// than as an RPC error. Callers must check whether the dependency locks
// handle in the response is set (non-zero) before using it, and treat
// an unset handle as indicating a user error which is described in the
// accompanying diagnostics. Diagnostics can also be returned along with
// a valid handle, e.g. if there are non-blocking warning diagnostics.
rpc OpenDependencyLockFile(OpenDependencyLockFile.Request) returns (OpenDependencyLockFile.Response);
// Creates an in-memory-only dependency locks handle with a fixed set of
// dependency selections provided as arguments.
rpc CreateDependencyLocks(CreateDependencyLocks.Request) returns (CreateDependencyLocks.Response);
rpc CloseDependencyLocks(CloseDependencyLocks.Request) returns (CloseDependencyLocks.Response);
// Returns information about the provider version selections in a
// dependency locks object.
rpc GetLockedProviderDependencies(GetLockedProviderDependencies.Request) returns (GetLockedProviderDependencies.Response);
// Populates a new provider plugin cache directory in the local filesystem
// based on the provider version selections in a given dependency locks
// object.
//
// This particular RPC can only install already-selected provider packages
// recorded in a dependency locks object; it does not support "upgrading"
// provider selections to newer versions as a CLI user would do with
// "terraform init -upgrade", because there would be no way to then
// commit the updated locks to disk as a lock file.
rpc BuildProviderPluginCache(BuildProviderPluginCache.Request) returns (stream BuildProviderPluginCache.Event);
// Opens an existing local filesystem directory as a provider plugin cache
// directory, returning a plugin cache handle that can be used with other
// RPC operations.
rpc OpenProviderPluginCache(OpenProviderPluginCache.Request) returns (OpenProviderPluginCache.Response);
rpc CloseProviderPluginCache(CloseProviderPluginCache.Request) returns (CloseProviderPluginCache.Response);
// Returns information about the specific provider packages that are
// available in the given provider plugin cache.
rpc GetCachedProviders(GetCachedProviders.Request) returns (GetCachedProviders.Response);
// Returns information about the built-in providers that are compiled in
// to this Terraform Core server.
rpc GetBuiltInProviders(GetBuiltInProviders.Request) returns (GetBuiltInProviders.Response);
// Returns a description of the schema for a particular provider in a
// given provider plugin cache, or of a particular built-in provider
// known to this version of Terraform Core.
//
// WARNING: This operation requires executing the selected provider plugin,
// which therefore allows it to run arbitrary code as a child process of
// this Terraform Core server, with access to all of the same resources.
// This should typically be used only with providers explicitly selected
// in a dependency lock file, so users can control what external code
// has the potential to run in a context that probably has access to
// private source code and other sensitive information.
rpc GetProviderSchema(GetProviderSchema.Request) returns (GetProviderSchema.Response);
}
message OpenSourceBundle {
message Request {
string local_path = 1;
}
message Response {
int64 source_bundle_handle = 1;
}
}
message CloseSourceBundle {
message Request {
int64 source_bundle_handle = 1;
}
message Response {
}
}
message OpenDependencyLockFile {
message Request {
int64 source_bundle_handle = 1;
SourceAddress source_address = 2;
}
message Response {
int64 dependency_locks_handle = 1;
repeated Diagnostic diagnostics = 2;
}
}
message CreateDependencyLocks {
message Request {
// The provider selections to include in the locks object.
//
// A typical value would be the result of an earlier call to
// GetLockedProviderDependencies on some other locks object,
// e.g. if a caller needs to propagate a set of locks from one
// Terraform Core RPC server to another.
repeated ProviderPackage provider_selections = 1;
}
message Response {
int64 dependency_locks_handle = 1;
}
}
message CloseDependencyLocks {
message Request {
int64 dependency_locks_handle = 1;
}
message Response {
}
}
message GetLockedProviderDependencies {
message Request {
int64 dependency_locks_handle = 1;
}
message Response {
repeated ProviderPackage selected_providers = 1;
}
}
message BuildProviderPluginCache {
message Request {
string cache_dir = 1;
int64 dependency_locks_handle = 2;
repeated InstallMethod installation_methods = 3;
// If set, this populates the cache with plugins for a different
// platform than the one the Terraform Core RPC server is running on.
// If unset (empty) then the cache will be populated with packages
// for the same platform as Terraform Core was built for, if available.
//
// If this is set to a different platform than the Terraform Core RPC
// server's then the generated cache directory will appear empty to
// other operations on this server.
string override_platform = 4;
message InstallMethod {
oneof source {
bool direct = 1;
string local_mirror_dir = 2;
string network_mirror_url = 3;
}
repeated string include = 4;
repeated string exclude = 5;
}
}
message Event {
oneof event {
Pending pending = 1;
ProviderVersion already_installed = 2;
ProviderVersion built_in = 3;
ProviderConstraints query_begin = 4;
ProviderVersion query_success = 5;
ProviderWarnings query_warnings = 6;
FetchBegin fetch_begin = 7;
FetchComplete fetch_complete = 8;
Diagnostic diagnostic = 9;
}
message Pending {
repeated ProviderConstraints expected = 1;
}
message ProviderConstraints {
string source_addr = 1;
string versions = 2;
}
message ProviderVersion {
string source_addr = 1;
string version = 2;
}
message ProviderWarnings {
string source_addr = 1;
repeated string warnings = 2;
}
message FetchBegin {
ProviderVersion provider_version = 1;
string location = 2;
}
message FetchComplete {
ProviderVersion provider_version = 1;
AuthResult auth_result = 2;
// If auth_result is one of the "_SIGNED" variants then this
// might contain a UI-oriented identifier for the key that
// signed the package. The exact format of this string is not
// guaranteed; do not attempt to parse it or make automated
// decisions based on it.
string key_id_for_display = 3;
enum AuthResult {
UNKNOWN = 0;
VERIFIED_CHECKSUM = 1;
OFFICIAL_SIGNED = 2;
PARTNER_SIGNED = 3;
SELF_SIGNED = 4;
}
}
}
}
message OpenProviderPluginCache {
message Request {
string cache_dir = 1;
// As with the field of the same name in BuildProviderPluginCache.Request.
//
// If this is set to anything other than this RPC server's native
// platform then any operations that require executing the provider
// plugin are likely to fail due to executable format errors or
// similar. However, it's valid to use the returned handle with
// GetCachedProviders, since it only analyzes the cache metadata
// and doesn't actually run the plugins inside.
string override_platform = 2;
}
message Response {
int64 provider_cache_handle = 1;
}
}
message CloseProviderPluginCache {
message Request {
int64 provider_cache_handle = 1;
}
message Response {
}
}
message GetCachedProviders {
message Request {
int64 provider_cache_handle = 1;
}
message Response {
repeated ProviderPackage available_providers = 1;
}
}
message GetBuiltInProviders {
message Request {
}
message Response {
// The built-in providers that are compiled in to this Terraform Core
// server.
//
// This uses ProviderPackage messages for consistency with the other
// operations which list providers, but built-in providers do not
// have version numbers nor hashes so those fields will always be
// unset in the result.
repeated ProviderPackage available_providers = 1;
}
}
message GetProviderSchema {
message Request {
// The address of the provider to retrieve schema for, using the
// typical provider source address syntax.
//
// When requesting schema based on a ProviderPackage message, populate
// this with its "source_addr" field.
string provider_addr = 1;
// The version number of the given provider to retrieve the schema
// of, which must have already been populated into the cache directory.
//
// Not supported for built-in providers because we can only access the
// single "version" of the provider that's compiled into this Terraform
// Core server, and so must be left unset or empty for those.
//
// When requesting schema based on a ProviderPackage message, populate
// this with its "version" field.
string provider_version = 2;
// The handle for the previously-opened provider plugin cache to
// load the provider plugin from.
//
// Optional for built-in providers, but can still be specified in that
// case if desired so that callers can safely just send the handle they
// have in all cases and be naive about which providers are and are
// not built in.
int64 provider_cache_handle = 3;
}
message Response {
ProviderSchema schema = 1;
}
}
// Represents a selected or available version of a provider, from either a
// dependency lock object (selected) or a provider cache object (available).
//
// This message type corresponds in meaning with a single "provider" block in a
// dependency lock file, but not all messages of this type directly represent
// such a physical block.
message ProviderPackage {
// The address of the provider using the canonical form of the provider
// source address syntax.
string source_addr = 1;
// The version number of this provider package. Unset for (and only for)
// built-in providers; callers may use the set-ness of this field to
// distinguish installable vs. built-in providers without having to
// parse the source address syntax.
string version = 2;
// The hash strings that Terraform knows about for this provider package,
// using the same "scheme:hash" syntax used in Terraform's dependency
// lock file format.
//
// For a message representing a "selected" provider package this enumerates
// all of the checksums that were previously loaded from a dependency
// lock file or otherwise inserted into a dependency locks object, which
// are usually (but not necessarily) originally obtained from the
// provider's origin registry and then cached in the lock file.
//
// For a message representing an "available" provider package this
// describes only the actual package on disk, and so will typically
// include only the subset of the checksums from the corresponding
// "selected" package that are relevant to the current platform where
// Terraform Core is running.
repeated string hashes = 3;
}
// ProviderSchema describes the full schema for a particular provider.
message ProviderSchema {
Schema provider_config = 1;
map<string, Schema> managed_resource_types = 2;
map<string, Schema> data_resource_types = 3;
}
service Stacks {
// Load and perform initial static validation of a stack configuration
// in a previously-opened source bundle. If successful, returns a
// stack configuration handle that can be used with other operations.
rpc OpenStackConfiguration(OpenStackConfiguration.Request)
returns (OpenStackConfiguration.Response);
// Close a previously-opened stack configuration using its handle.
rpc CloseStackConfiguration(CloseStackConfiguration.Request)
returns (CloseStackConfiguration.Response);
// Validate an open stack configuration.
rpc ValidateStackConfiguration(ValidateStackConfiguration.Request)
returns (ValidateStackConfiguration.Response);
// Analyze a stack configuration to find all of the components it declares.
// This is static analysis only, so it cannot produce dynamic information
// such as the number of instances of each component.
rpc FindStackConfigurationComponents(FindStackConfigurationComponents.Request)
returns (FindStackConfigurationComponents.Response);
// Calculate a desired state from the given configuration and compare it
// with the current state to propose a set of changes to converge the
// current state with the desired state, at least in part.
rpc PlanStackChanges(PlanStackChanges.Request)
returns (stream PlanStackChanges.Event);
// Execute the changes proposed by an earlier call to PlanStackChanges.
rpc ApplyStackChanges(ApplyStackChanges.Request)
returns (stream ApplyStackChanges.Event);
// OpenStackInspector creates a stack inspector handle that can be used
// with subsequent calls to the "Inspect"-prefixed functions.
rpc OpenStackInspector(OpenStackInspector.Request)
returns (OpenStackInspector.Response);
// InspectExpressionResult evaluates an arbitrary expression in the context
// of a stack inspector handle.
rpc InspectExpressionResult(InspectExpressionResult.Request)
returns (InspectExpressionResult.Response);
}
message OpenStackConfiguration {
message Request {
int64 source_bundle_handle = 1;
SourceAddress source_address = 2;
}
message Response {
int64 stack_config_handle = 1;
repeated Diagnostic diagnostics = 2;
}
}
message CloseStackConfiguration {
message Request {
int64 stack_config_handle = 1;
}
message Response {
}
}
message ValidateStackConfiguration {
message Request {
int64 stack_config_handle = 1;
}
message Response {
repeated Diagnostic diagnostics = 1;
}
}
message FindStackConfigurationComponents {
message Request {
int64 stack_config_handle = 1;
}
message Response {
StackConfig config = 1;
}
enum Instances {
SINGLE = 0;
COUNT = 1;
FOR_EACH = 2;
}
message StackConfig {
map<string, Component> components = 1;
map<string, EmbeddedStack> embedded_stacks = 2;
}
message EmbeddedStack {
string source_addr = 1;
Instances instances = 2;
StackConfig config = 3;
}
message Component {
string source_addr = 1;
Instances instances = 2;
}
}
message PlanStackChanges {
message Request {
PlanMode plan_mode = 1;
int64 stack_config_handle = 2;
map<string, google.protobuf.Any> previous_state = 3;
int64 dependency_locks_handle = 4;
int64 provider_cache_handle = 5;
map<string, DynamicValueWithSource> input_values = 6;
// TODO: Various other planning options
}
message Event {
oneof event {
PlannedChange planned_change = 1;
Diagnostic diagnostic = 2;
StackChangeProgress progress = 10;
}
reserved 3 to 9; // formerly used for individual progress events
}
}
message ApplyStackChanges {
message Request {
// This must refer to exactly the same configuration that was
// passed to PlanStackChanges when creating this plan, or the
// results will be unpredictable.
int64 stack_config_handle = 1;
// The caller should send all of the keys present in the previous
// apply's description map. Terraform Core will use this for
// situations such as updating existing descriptions to newer
// formats even if no change is being made to the corresponding
// real objects.
repeated string known_description_keys = 3;
// This must include all of the "raw" values emitted through
// PlannedChange events during the PlanStackChanges operation
// that created this plan, concatenated together in the same
// order they were written to the PlanStackChanges event stream.
repeated google.protobuf.Any planned_changes = 4;
// This must be equivalent to the argument of the same name
// passed to PlanStackChanges when creating this plan.
int64 dependency_locks_handle = 5;
// This must be equivalent to the argument of the same name
// passed to PlanStackChanges when creating this plan.
int64 provider_cache_handle = 6;
reserved 2; // (formerly the previous state, but we now propagate that as part of planned_changes as an implementation detail)
}
message Event {
oneof event {
AppliedChange applied_change = 1;
Diagnostic diagnostic = 2;
StackChangeProgress progress = 3;
}
}
}
message OpenStackInspector {
message Request {
int64 stack_config_handle = 1;
map<string, google.protobuf.Any> state = 2;
int64 dependency_locks_handle = 3;
int64 provider_cache_handle = 4;
map<string, DynamicValueWithSource> input_values = 5;
}
message Response {
int64 stack_inspector_handle = 1;
repeated Diagnostic diagnostics = 2;
}
}
message InspectExpressionResult {
message Request {
int64 stack_inspector_handle = 1;
bytes expression_src = 2;
string stack_addr = 3;
}
message Response {
// The result of evaluating the expression, if successful enough to
// produce a result. Unpopulated if the expression was too invalid
// to produce a result, with the problem then described in the
// associated diagnostics.
//
// Uses a MessagePack encoding with in-band type information.
DynamicValue result = 1;
repeated Diagnostic diagnostics = 2;
}
}
// Represents dynamically-typed data from within the Terraform language.
// Typically only one of the available serialization formats will be populated,
// depending on what serializations are appropriate for a particular context
// and what capabilities the client and the server negotiated during Handshake.
message DynamicValue {
bytes msgpack = 1; // The default serialization format
repeated AttributePath sensitive = 2; // Paths to any sensitive-marked values.
}
// Represents a change of some object from one dynamic value to another.
message DynamicValueChange {
DynamicValue old = 1;
DynamicValue new = 2;
}
// Represents a DynamicValue accompanied by a source location where it was
// presumably defined, for values that originated in configuration files for
// situations such as returning error messages.
message DynamicValueWithSource {
DynamicValue value = 1;
SourceRange source_range = 2;
}
message AttributePath {
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.
string element_key_string = 2;
int64 element_key_int = 3;
}
}
repeated Step steps = 1;
}
// Represents the address of a specific component instance within a stack.
message ComponentInstanceInStackAddr {
// The address of the static component that this is an instance of.
string component_addr = 1;
// The address of the instance that's being announced. For
// multi-instance components this could have any combination of
// instance keys on the component itself or instance keys on any
// of the containing embedded stacks.
string component_instance_addr = 2;
}
// Represents the address of a specific resource instance inside a specific
// component instance within the containing stack.
message ResourceInstanceInStackAddr {
// Unique address of the component instance that this resource instance
// belongs to. This is comparable with
string component_instance_addr = 1;
// Unique address of the resource instance within the given component
// instance. Each component instance has a separate namespace of
// resource instance addresses, so callers must take both fields together
// to produce a key that's unique throughout the entire plan.
string resource_instance_addr = 2;
}
// Represents the address of a specific resource instance object inside a
// specific component instance within the containing stack.
message ResourceInstanceObjectInStackAddr {
// Unique address of the component instance that this resource instance
// belongs to. This is comparable with
string component_instance_addr = 1;
// Unique address of the resource instance within the given component
// instance. Each component instance has a separate namespace of
// resource instance addresses, so callers must take both fields together
// to produce a key that's unique throughout the entire plan.
string resource_instance_addr = 2;
// Optional "deposed key" populated only for non-current (deposed) objects,
// which can appear for "create before destroy" replacements where the
// create succeeds but then the destroy fails, leaving us with two different
// objects to track for the same resource instance.
string deposed_key = 3;
}
enum ResourceMode {
UNKNOWN = 0;
MANAGED = 1;
DATA = 2;
}
// A source address in the same form as it would appear in a Terraform
// configuration: a source string combined with an optional version constraint
// string, where the latter is valid only for registry module addresses.
//
// This is not used for "final" source addresses that have already been reduced
// to an exact version selection. For those we just directly encode the string
// representation of the final address, including a version number if necessary.
message SourceAddress {
string source = 1;
string versions = 2;
}
enum PlanMode {
NORMAL = 0;
REFRESH_ONLY = 1;
DESTROY = 2;
}
enum ChangeType {
NOOP = 0;
READ = 1;
CREATE = 2;
UPDATE = 3;
DELETE = 4;
}
// Describes one item in a stack plan. The overall plan is the concatentation
// of all messages of this type emitted as events during the plan; splitting
// this information over multiple messages just allows the individual events
// to double as progress notifications for an interactive UI.
message PlannedChange {
// Terraform Core's internal representation(s) of this change. Callers
// must provide the messages in this field, if any, verbatim to the
// ApplyStackChanges RPC in order to apply this change, and must not
// attempt to decode or analyze the contents because they are subject
// to change in future versions of Terraform Core.
//
// This might be unpopulated if this message represents only information
// for the caller and Terraform Core doesn't actually need to recall this
// information during the apply step. Callers must append each raw item
// to the raw plan in the order specified, and provide them all together
// in the same order to ApplyStackChanges.
repeated google.protobuf.Any raw = 1;
// Caller-facing descriptions of this change, to use for presenting
// information to end-users in the UI and for other subsystems such as
// imposing policy rules on the resulting plan.
//
// There can be zero or more description objects associated with each
// change. More than one is not common, but should be supported by clients
// by treating them the same way as if each description had arrived in
// a separate PlannedChange message. Clients should not treat the grouping
// or not-grouping of change description objects as meaningful information,
// since it's subject to change in future Terraform Core versions.
//
// DO NOT attempt to use this to surgically filter particular changes
// from a larger plan. Although external descriptions often match with
// the raw representations in field "raw", that is not guaranteed and
// Terraform Core assumes that it will always be provided with the full
// set of raw messages -- in the same order they were emitted -- during
// the apply step. For example, some raw messages might omit information
// that is implied by earlier raw messages and would therefore be
// incomplete if isolated.
repeated ChangeDescription descriptions = 2;
reserved 3 to 6; // formerly used for an inline "oneof description", now factored out into a separate message type
// Represents a single caller-facing description of a change, to use for
// presenting information to end users in the UI and for other subsystems
// such as imposing policy rules on the resulting plan.
//
// New description types might be added in future versions of Terraform
// Core, and so clients should tolerate description messages that appear
// to have none of the oneof fields set, and should just ignore those
// messages entirely.
message ChangeDescription {
oneof description {
ComponentInstance component_instance_planned = 1;
ResourceInstance resource_instance_planned = 2;
OutputValue output_value_planned = 3;
bool plan_applyable = 4;
}
}
// Reports the existence of a particular instance of a component,
// once Terraform has resolved arguments such as "for_each" that
// might make the set of instances dynamic.
message ComponentInstance {
ComponentInstanceInStackAddr addr = 1;
// The changes to the existence of this instance relative to the
// prior state. This only considers the component instance directly,
// and doesn't take into account what actions are planned for any
// resource instances inside.
repeated ChangeType actions = 2;
}
message ResourceInstance {
ResourceInstanceObjectInStackAddr addr = 1;
repeated ChangeType actions = 2;
DynamicValueChange values = 3;
Moved moved = 4;
Imported imported = 5;
ResourceMode resource_mode = 6;
string resource_type = 7;
string provider_addr = 8;
// previous_run_value is included only if it would be
// different from values.old, which typically means that
// Terraform detected some changes made outside of Terraform
// since the previous run. In that case, this field is
// the un-refreshed (but still upgraded) value from
// the previous run and values.old is the refreshed version.
//
// If this isn't set then values.old should be used as the
// previous run value, if needed.
DynamicValue previous_run_value = 9;
// This flag is set if Terraform Core considers the difference
// between previous_run_value and values.old to be "notable",
// which is a heuristic subject to change over time but is
// broadly intended to mean that it would be worth mentioning
// the difference between the two in the UI as a
// "change outside of Terraform". If this isn't set then the
// difference is probably not worth mentioning to the user
// by default, although it could still be shown behind an
// optional disclosure in UI contexts where such things are possible.
bool notable_change_outside = 10;
// TODO: Everything else we need for feature-parity with the
// existing JSON plan export format.
message Moved {
ResourceInstanceInStackAddr prev_addr = 1;
}
message Imported {
string import_id = 1;
}
}
// Note: this is only for output values from the topmost
// stack configuration, because all other output values are
// internal to the configuration and not part of its public API.
message OutputValue {
string name = 1;
repeated ChangeType actions = 2;
DynamicValueChange values = 3;
}
}
// Describes a change made during a Stacks.ApplyStackChanges call.
//
// All of the events of this type taken together represent a sort of "patch"
// modifying the two data structures that the caller must maintain: the
// raw state map, and the description map. Callers must apply these changes
// in the order of the emission of the messages and then retain the entirety
// of both data structures to populate fields in the next PlanStackChanges call.
message AppliedChange {
// Terraform Core's internal representation of the change, presented as
// a sequence of modifications to the raw state data structure.
//
// For each element, in order:
// - If both key and value are set and the key matches an element
// already in the raw state map, the new value replaces the existing one.
// - If both key and value are set but the key does not match an
// element in the raw state map, this represents inserting a new element
// into the map.
// - If key is set and value is not, this represents removing any existing
// element from the raw state map which has the given key, or a no-op
// if no such element exists.
// - No other situation is legal.
//
// This sequence can potentially be zero-length if a particular event only
// has a external-facing "description" component and no raw equivalent. In
// that case the raw state map is unmodified.
repeated RawChange raw = 1;
// Caller-facing description of this change, to use for presenting
// information to end-users in the UI and for other subsystems such as
// billing.
//
// Callers are expected to maintain a map of description objects that
// gets updated piecemeal by messages in this field. Callers must treat
// the keys as entirely opaque and thus treat the resulting data structure
// as if it were an unsorted set of ChangeDescription objects; the keys
// exist only to allow patching the data structure over time.
//
// For each element, in order:
// - If both key and description are set and the key matches an element
// from the previous apply's description map, the new value replaces
// the existing one.
// - If both key and value are set but the key does not match an
// element in the previous apply's description map, this represents
// inserting a new element into the map.
// - If key is set and description is "deleted", this represents removing
// any existing element from the previous apply's description map which
// has the given key, or a no-op if no such element exists.
// - If a description field is set that the caller doesn't understand,
// the caller should still write it to the updated description map
// but ignore it in further processing.
// - No other situation is legal.
//
// Callers MUST preserve the verbatim description message in the
// description map, even if it contains fields that are not present in
// the caller's current protobuf stubs. In other words, callers must use
// a protocol buffers implementation that is able to preserve unknown
// fields and store them so that future versions of the caller might
// use an updated set of stubs to interact with the previously-stored
// description.
//
// DO NOT attempt to use this to surgically filter particular raw state
// updates from a larger plan. Although external descriptions often match
// with the raw representations in field "raw", that is not guaranteed and
// Terraform Core assumes that it will always be provided with the full
// raw state map during the next plan step.
repeated ChangeDescription descriptions = 2;
message RawChange {
string key = 1;
google.protobuf.Any value = 2;
}
message ChangeDescription {
string key = 1;
oneof description {
Nothing deleted = 4; // explicitly represents the absense of a description
ResourceInstance resource_instance = 2;
OutputValue output_value = 3;
ComponentInstance component_instance = 5;
}
// Field number 20000 is reserved as a field number that will
// always be unknown to any client, to allow clients to test
// whether they correctly preserve unexpected fields.
reserved 20000;
}
message ResourceInstance {
ResourceInstanceObjectInStackAddr addr = 1;
DynamicValue new_value = 2;
ResourceMode resource_mode = 4;
string resource_type = 5;
string provider_addr = 6;
// Sometimes Terraform needs to make changes to a resource in
// multiple steps during the apply phase, with each step
// changing something about the state. This flag will be set
// for such interim updates, and left unset for whatever
// description Terraform Core considers to be "final", at
// which point the new value should be converged with the
// desired state.
//
// The intended use for this is when presenting updated values
// to users in the UI, where it might be best to ignore or
// present differently interim updates to avoid creating
// confusion by showing the not-yet-converged intermediate
// states.
//
// If Terraform encounters a problem during the apply phase
// and needs to stop partway through then a "final" change
// description might never arrive. In that case, callers
// should save the most recent interim object as the final
// description, since it would represent the most accurate
// description of the state the remote system has been left
// in.
bool interim = 3;
}
message ComponentInstance {
string component_addr = 3;
string component_instance_addr = 1;
map<string,DynamicValue> output_values = 2;
}
message OutputValue {
string name = 1;
DynamicValue new_value = 2;
}
message Nothing {}
}
// A container for "progress report" events in both Stacks.PlanStackChanges
// and Stacks.ApplyStackChanges, which share this message type to allow
// clients to share event-handling code between the two phases.
message StackChangeProgress {
// Some event types are relevant only to one of the two operations, while
// others are common across both but will include different status codes,
// etc in different phases.
oneof event {
ComponentInstanceStatus component_instance_status = 1;
ResourceInstanceStatus resource_instance_status = 2;
ResourceInstancePlannedChange resource_instance_planned_change = 3;
ProvisionerStatus provisioner_status = 4;
ProvisionerOutput provisioner_output = 5;
ComponentInstanceChanges component_instance_changes = 6;
ComponentInstances component_instances = 7;
}
// ComponentInstanceStatus describes the current status of a component instance
// undergoing a plan or apply operation.
message ComponentInstanceStatus {
ComponentInstanceInStackAddr addr = 1;
Status status = 2;
enum Status {
INVALID = 0;
PENDING = 1;
PLANNING = 2;
PLANNED = 3;
APPLYING = 4;
APPLIED = 5;
ERRORED = 6;
}
}
// ComponentInstanceStatus describes the current status of a resource instance
// undergoing a plan or apply operation.
message ResourceInstanceStatus {
ResourceInstanceObjectInStackAddr addr = 1;
Status status = 2;
enum Status {
INVALID = 0;
PENDING = 1;
REFRESHING = 2;
REFRESHED = 3;
PLANNING = 4;
PLANNED = 5;
APPLYING = 6;
APPLIED = 7;
ERRORED = 8;
}
}
// ResourceInstancePlannedChange describes summary information about a planned
// change for a resource instance. This does not include the full object change,
// which is described in PlannedChange.ResourceChange. The information in this
// message is intended for the event stream and need not include the instance's
// full object values.
message ResourceInstancePlannedChange {
ResourceInstanceObjectInStackAddr addr = 1;
repeated ChangeType actions = 2;
Moved moved = 3;
Imported imported = 4;
message Moved {
ResourceInstanceInStackAddr prev_addr = 1;
}
message Imported {
string import_id = 1;
}
}
// ProvisionerStatus represents the progress of a given provisioner during its
// resource instance's apply operation.
message ProvisionerStatus {
ResourceInstanceObjectInStackAddr addr = 1;
string name = 2;
ProvisionerStatus status = 3;
enum Status {
INVALID = 0;
PROVISIONING = 1;
PROVISIONED = 2;
ERRORED = 3;
}
}
// ProvisionerOutput represents recorded output data emitted by a provisioner
// during a resource instance's apply operation.
message ProvisionerOutput {
ResourceInstanceObjectInStackAddr addr = 1;
string name = 2;
string output = 3;
}
// ComponentInstanceChanges represents a roll-up of change counts for a
// component instance plan or apply operation.
message ComponentInstanceChanges {
ComponentInstanceInStackAddr addr = 1;
// total is the sum of all of the other count fields.
//
// Clients should sum all of the other count fields they know about
// and compare to total. If the sum is less than total then the
// difference should be treated as an "other change types" category,
// for forward-compatibility when the Terraform Core RPC server is
// using a newer version of this protocol than the client.
int32 total = 2;
int32 add = 3;
int32 change = 4;
int32 import = 5;
int32 remove = 6;
}
// ComponentInstances represents the result of expanding a component into zero
// or more instances.
message ComponentInstances {
string component_addr = 1;
repeated string instance_addrs = 2;
}
}
message Diagnostic {
enum Severity {
INVALID = 0;
ERROR = 1;
WARNING = 2;
}
Severity severity = 1;
string summary = 2;
string detail = 3;
SourceRange subject = 4;
SourceRange context = 5;
}
message SourceRange {
string source_addr = 1;
SourcePos start = 2;
SourcePos end = 3;
}
message SourcePos {
int64 byte = 1;
int64 line = 2;
int64 column = 3;
}
// Schema describes a schema for an instance of a particular object, such as
// a resource type or a provider's overall configuration.
message Schema {
// Block is the top level configuration block for this schema.
Block block = 1;
message Block {
repeated Attribute attributes = 1;
repeated NestedBlock block_types = 2;
DocString description = 3;
bool deprecated = 4;
}
message Attribute {
string name = 1;
bytes type = 2;
Object nested_type = 10;
DocString description = 3;
bool required = 4;
bool optional = 5;
bool computed = 6;
bool sensitive = 7;
bool deprecated = 8;
}
message NestedBlock {
enum NestingMode {
INVALID = 0;
SINGLE = 1;
LIST = 2;
SET = 3;
MAP = 4;
GROUP = 5;
}
string type_name = 1;
Block block = 2;
NestingMode nesting = 3;
}
message Object {
enum NestingMode {
INVALID = 0;
SINGLE = 1;
LIST = 2;
SET = 3;
MAP = 4;
}
repeated Attribute attributes = 1;
NestingMode nesting = 3;
}
message DocString {
string description = 1;
Format format = 2;
enum Format {
PLAIN = 0;
MARKDOWN = 1;
}
}
}
// The Packages service provides helper functions for retrieving Terraform
// modules and providers.
//
// Unlike the Dependencies service, the Packages service does not require any
// existing configuration or sourcebundle to function.
//
// This service is designed for use with a specific command-line tool, and is
// currently experimental. It can be changed and removed without warning, even
// in patch releases.
service Packages {
rpc ProviderPackageVersions(ProviderPackageVersions.Request) returns (ProviderPackageVersions.Response);
rpc FetchProviderPackage(FetchProviderPackage.Request) returns (FetchProviderPackage.Response);
rpc ModulePackageVersions(ModulePackageVersions.Request) returns (ModulePackageVersions.Response);
rpc ModulePackageSourceAddr(ModulePackageSourceAddr.Request) returns (ModulePackageSourceAddr.Response);
rpc FetchModulePackage(FetchModulePackage.Request) returns (FetchModulePackage.Response);
}
message ProviderPackageVersions {
message Request {
string source_addr = 1;
}
message Response {
repeated string versions = 1;
repeated Diagnostic diagnostics = 2;
}
}
message FetchProviderPackage {
message Request {
string cache_dir = 1;
string source_addr = 2;
string version = 3;
repeated string platforms = 4;
repeated string hashes = 5;
}
message Response {
// Each requested platform will return a result in this list. The order
// of the returned results will match the order of the requested
// platforms. If the binary for a given platform could not be downloaded
// there will still be an entry in the results with diagnostics
// explaining why.
repeated FetchProviderPackage.PlatformResult results = 1;
repeated Diagnostic diagnostics = 2;
}
message PlatformResult {
ProviderPackage provider = 1;
repeated Diagnostic diagnostics = 2;
}
}
message ModulePackageVersions {
message Request {
string source_addr = 2;
}
message Response {
repeated string versions = 1;
repeated Diagnostic diagnostics = 2;
}
}
message ModulePackageSourceAddr {
message Request {
string source_addr = 1;
string version = 2;
}
message Response {
string url = 1;
repeated Diagnostic diagnostics = 2;
}
}
message FetchModulePackage {
message Request {
string cache_dir = 1;
string url = 2;
}
message Response {
repeated Diagnostic diagnostics = 1;
}
}