github.com/rstandt/terraform@v0.12.32-0.20230710220336-b1063613405c/docs/plugin-protocol/README.md (about)

     1  # Terraform Plugin Protocol
     2  
     3  This directory contains documentation about the physical wire protocol that
     4  Terraform Core uses to communicate with provider plugins.
     5  
     6  Most providers are not written directly against this protocol. Instead, prefer
     7  to use an SDK that implements this protocol and write the provider against
     8  the SDK's API.
     9  
    10  ----
    11  
    12  **If you want to write a plugin for Terraform, please refer to
    13  [Extending Terraform](https://www.terraform.io/docs/extend/index.html) instead.**
    14  
    15  This documentation is for those who are developing _Terraform SDKs_, rather
    16  than those implementing plugins.
    17  
    18  ----
    19  
    20  From Terraform v0.12.0 onwards, Terraform's plugin protocol is built on
    21  [gRPC](https://grpc.io/). This directory contains `.proto` definitions of
    22  different versions of Terraform's protocol.
    23  
    24  Only `.proto` files published as part of Terraform release tags are actually
    25  official protocol versions. If you are reading this directory on the `master`
    26  branch or any other development branch then it may contain protocol definitions
    27  that are not yet finalized and that may change before final release.
    28  
    29  ## RPC Plugin Model
    30  
    31  Terraform plugins are normal executable programs that, when launched, expose
    32  gRPC services on a server accessed via the loopback interface. Terraform Core
    33  discovers and launches plugins, waits for a handshake to be printed on the
    34  plugin's `stdout`, and then connects to the indicated port number as a
    35  gRPC client.
    36  
    37  For this reason, we commonly refer to Terraform Core itself as the plugin
    38  "client" and the plugin program itself as the plugin "server". Both of these
    39  processes run locally, with the server process appearing as a child process
    40  of the client. Terraform Core controls the lifecycle of these server processes
    41  and will terminate them when they are no longer required.
    42  
    43  The startup and handshake protocol is not currently documented. We hope to
    44  document it here or to link to external documentation on it in future.
    45  
    46  ## Versioning Strategy
    47  
    48  The Plugin Protocol uses a versioning strategy that aims to allow gradual
    49  enhancements to the protocol while retaining compatibility, but also to allow
    50  more significant breaking changes from time to time while allowing old and
    51  new plugins to be used together for some period.
    52  
    53  The versioning strategy described below was introduced with protocol version
    54  5.0 in Terraform v0.12. Prior versions of Terraform and prior protocol versions
    55  do not follow this strategy.
    56  
    57  The authoritative definition for each protocol version is in this directory
    58  as a Protocol Buffers (protobuf) service definition. The files follow the
    59  naming pattern `tfpluginX.Y.proto`, where X is the major version and Y
    60  is the minor version.
    61  
    62  ### Major and minor versioning
    63  
    64  The minor version increases for each change introducing optional new
    65  functionality that can be ignored by implementations of prior versions. For
    66  example, if a new field were added to an response message, it could be a minor
    67  release as long as Terraform Core can provide some default behavior when that
    68  field is not populated.
    69  
    70  The major version increases for any significant change to the protocol where
    71  compatibility is broken. However, Terraform Core and an SDK may both choose
    72  to support multiple major versions at once: the plugin handshake includes a
    73  negotiation step where client and server can work together to select a
    74  mutually-supported major version.
    75  
    76  The major version number is encoded into the protobuf package name: major
    77  version 5 uses the package name `tfplugin5`, and one day major version 6
    78  will switch to `tfplugin6`. This change of name allows a plugin server to
    79  implement multiple major versions at once, by exporting multiple gRPC services.
    80  Minor version differences rely instead on feature-detection mechanisms, so they
    81  are not represented directly on the wire and exist primarily as a human
    82  communication tool to help us easily talk about which software supports which
    83  features.
    84  
    85  ## Version compatibility for Core, SDK, and Providers
    86  
    87  A particular version of Terraform Core has both a minimum minor version it
    88  requires and a maximum major version that it supports. A particular version of
    89  Terraform Core may also be able to optionally use a newer minor version when
    90  available, but fall back on older behavior when that functionality is not
    91  available.
    92  
    93  Likewise, each provider plugin release is compatible with a set of versions.
    94  The compatible versions for a provider are a list of major and minor version
    95  pairs, such as "4.0", "5.2", which indicates that the provider supports the
    96  baseline features of major version 4 and supports major version 5 including
    97  the enhancements from both minor versions 1 and 2. This provider would
    98  therefore be compatible with a Terraform Core release that supports only
    99  protocol version 5.0, since major version 5 is supported and the optional
   100  5.1 and 5.2 enhancements will be ignored.
   101  
   102  If Terraform Core and the plugin do not have at least one mutually-supported
   103  major version, Terraform Core will return an error from `terraform init`
   104  during plugin installation:
   105  
   106  ```
   107  Provider "aws" v1.0.0 is not compatible with Terraform v0.12.0.
   108  
   109  Provider version v2.0.0 is the earliest compatible version.
   110  Select it with the following version constraint:
   111  
   112      version = "~> 2.0.0"
   113  ```
   114  
   115  ```
   116  Provider "aws" v3.0.0 is not compatible with Terraform v0.12.0.
   117  Provider version v2.34.0 is the latest compatible version. Select 
   118  it with the following constraint:
   119  
   120      version = "~> 2.34.0"
   121  
   122  Alternatively, upgrade to the latest version of Terraform for compatibility with newer provider releases.
   123  ```
   124  
   125  The above messages are for plugins installed via `terraform init` from a
   126  Terraform registry, where the registry API allows Terraform Core to recognize
   127  the protocol compatibility for each provider release. For plugins that are
   128  installed manually to a local plugin directory, Terraform Core has no way to
   129  suggest specific versions to upgrade or downgrade to, and so the error message
   130  is more generic:
   131  
   132  ```
   133  The installed version of provider "example" is not compatible with Terraform v0.12.0.
   134  
   135  This provider was loaded from:
   136       /usr/local/bin/terraform-provider-example_v0.1.0
   137  ```
   138  
   139  ## Adding/removing major version support in SDK and Providers
   140  
   141  The set of supported major versions is decided by the SDK used by the plugin.
   142  Over time, SDKs will add support for new major versions and phase out support
   143  for older major versions.
   144  
   145  In doing so, the SDK developer passes those capabilities and constraints on to
   146  any provider using their SDK, and that will in turn affect the compatibility
   147  of the plugin in ways that affect its semver-based version numbering:
   148  
   149  - If an SDK upgrade adds support for a new provider protocol, that will usually
   150    be considered a new feature and thus warrant a new minor version.
   151  - If an SDK upgrade removes support for an old provider protocol, that is
   152    always a breaking change and thus requires a major release of the provider.
   153  
   154  For this reason, SDK developers must be clear in their release notes about
   155  the addition and removal of support for major versions.
   156  
   157  Terraform Core also makes an assumption about major version support when
   158  it produces actionable error messages for users about incompatibilities:
   159  a particular protocol major version is supported for a single consecutive
   160  range of provider releases, with no "gaps".
   161  
   162  ## Using the protobuf specifications in an SDK
   163  
   164  If you wish to build an SDK for Terraform plugins, an early step will be to
   165  copy one or more `.proto` files from this directory into your own repository
   166  (depending on which protocol versions you intend to support) and use the
   167  `protoc` protocol buffers compiler (with gRPC extensions) to generate suitable
   168  RPC stubs and types for your target language.
   169  
   170  For example, if you happen to be targeting Python, you might generate the
   171  stubs using a command like this:
   172  
   173  ```
   174  protoc --python_out=. --grpc_python_out=. tfplugin5.1.proto
   175  ```
   176  
   177  You can find out more about the tool usage for each target language in
   178  [the gRPC Quick Start guides](https://grpc.io/docs/quickstart/).
   179  
   180  The protobuf specification for a version is immutable after it has been
   181  included in at least one Terraform release. Any changes will be documented in
   182  a new `.proto` file establishing a new protocol version.
   183  
   184  The protocol buffer compiler will produce some sort of library object appropriate
   185  for the target language, which depending on the language might be called a
   186  module, or a package, or something else. We recommend to include the protocol
   187  major version in your module or package name so that you can potentially
   188  support multiple versions concurrently in future. For example, if you are
   189  targeting major version 5 you might call your package or module `tfplugin5`.
   190  
   191  To upgrade to a newer minor protocol version, copy the new `.proto` file
   192  from this directory into the same location as your previous version, delete
   193  the previous version, and then run the protocol buffers compiler again
   194  against the new `.proto` file. Because minor releases are backward-compatible,
   195  you can simply update your previous stubs in-place rather than creating a
   196  new set alongside.
   197  
   198  To support a new _major_ protocol version, create a new package or module
   199  and copy the relevant `.proto` file into it, creating a separate set of stubs
   200  that can in principle allow your SDK to support both major versions at the
   201  same time. We recommend supporting both the previous and current major versions
   202  together for a while across a major version upgrade so that users can avoid
   203  having to upgrade both Terraform Core and all of their providers at the same
   204  time, but you can delete the previous major version stubs once you remove
   205  support for that version.
   206  
   207  **Note:** Some of the `.proto` files contain statements about being updated
   208  in-place for minor versions. This reflects an earlier version management
   209  strategy which is no longer followed. The current process is to create a
   210  new file in this directory for each new minor version and consider all
   211  previously-tagged definitions as immutable. The outdated comments in those
   212  files are retained in order to keep the promise of immutability, even though
   213  it is now incorrect.