280 lines
12 KiB
Markdown
280 lines
12 KiB
Markdown
![]() |
---
|
||
|
layout: "docs"
|
||
|
page_title: "Provider Network Mirror Protocol"
|
||
|
sidebar_current: "docs-internals-provider-network-mirror-protocol"
|
||
|
description: |-
|
||
|
The provider network mirror protocol is implemented by a server intending
|
||
|
to provide a mirror or read-through caching proxy for Terraform providers,
|
||
|
as an alternative distribution source from the provider's origin provider
|
||
|
registry.
|
||
|
---
|
||
|
|
||
|
# Provider Network Mirror Protocol
|
||
|
|
||
|
-> Provider network mirrors are supported only in Terraform CLI v0.13.2 and later. Prior versions do not support this protocol.
|
||
|
|
||
|
The provider network mirror protocol is an optional protocol which you can
|
||
|
implement to provide an alternative installation source for Terraform providers,
|
||
|
regardless of their origin registries.
|
||
|
|
||
|
Terraform uses network mirrors only if you activate them explicitly in
|
||
|
[the CLI configuration's `provider_installation` block](/docs/commands/cli-config.html#provider-installation).
|
||
|
When enabled, a network mirror can serve providers belonging to any registry
|
||
|
hostname, which can allow an organization to serve all of the Terraform
|
||
|
providers they intend to use from an internal server, rather than from each
|
||
|
provider's origin registry.
|
||
|
|
||
|
This is _not_ the protocol that should be implemented by a host intending to
|
||
|
serve as an origin registry for Terraform Providers. To provide an origin
|
||
|
registry (whose hostname would then be included in the source addresses of the
|
||
|
providers it hosts), implement
|
||
|
[the provider registry protocol](./provider-registry-protocol.html)
|
||
|
instead.
|
||
|
|
||
|
## Provider Addresses
|
||
|
|
||
|
Each Terraform provider has an associated address which uniquely identifies it
|
||
|
within Terraform. A provider address has the syntax `hostname/namespace/type`,
|
||
|
which is described in more detail in
|
||
|
[the Provider Requirements documentation](/docs/configuration/provider-requirements.html).
|
||
|
|
||
|
By default, the `hostname` portion of a provider address serves both as part
|
||
|
of its unique identifier _and_ as the location of the registry to retrieve it
|
||
|
from. However, when you configure Terraform to install providers from a network
|
||
|
mirror, the `hostname` serves _only_ as an identifier and no longer as
|
||
|
an installation source. A provider mirror can therefore serve providers
|
||
|
belonging to a variety of different provider registry hostnames, including
|
||
|
providers from the public Terraform Registry at `registry.terraform.io`, from a
|
||
|
single server.
|
||
|
|
||
|
In the relative URL patterns later in this document, the placeholder `:hostname`
|
||
|
refers to the hostname from the address of the provider being requested, not
|
||
|
the hostname where the provider network mirror is deployed.
|
||
|
|
||
|
## Protocol Base URL
|
||
|
|
||
|
Most Terraform-native services use
|
||
|
[the remote service discovery protocol](./remote-service-discovery.html) so
|
||
|
that the physical location of the endpoints can potentially be separated from
|
||
|
the hostname used in identifiers. The Provider Network Mirror protocol does
|
||
|
_not_ use the service discovery indirection, because a network mirror location
|
||
|
is only a physical location and is never used as part of the identifier of a
|
||
|
dependency in a Terraform configuration.
|
||
|
|
||
|
Instead, the provider installation section of the CLI configuration accepts
|
||
|
a base URL directly. The given URL must use the scheme `https:`, and should
|
||
|
end with a trailing slash so that the relative URLs of the individual operation
|
||
|
endpoints will be resolved beneath it.
|
||
|
|
||
|
```hcl
|
||
|
provider_installation {
|
||
|
network_mirror {
|
||
|
url = "https://terraform.example.com/providers/"
|
||
|
}
|
||
|
}
|
||
|
```
|
||
|
|
||
|
Terraform uses the base URL only as a stem to resolve the operation endpoint
|
||
|
URLs against, and so it will never access the base URL directly. You can
|
||
|
therefore, if desired, publish human-readable usage documentation for your
|
||
|
network mirror at that URL.
|
||
|
|
||
|
The following sections describe the various operations that a provider
|
||
|
network mirror server must implement to be compatible with Terraform CLI's
|
||
|
provider installer. The indicated URLs are all relative to the given base URL,
|
||
|
as described above.
|
||
|
|
||
|
The URLs are shown with the convention that a path portion with a colon `:`
|
||
|
prefix is a placeholder for a dynamically-selected value, while all other
|
||
|
path portions are literal. For example, in `:hostname/:namespace/:type/index.json`,
|
||
|
the first three path portions are placeholders while the third is literally
|
||
|
the string "index.json".
|
||
|
|
||
|
The example requests in the following sections will assume the example mirror
|
||
|
base URL from the above CLI configuration example.
|
||
|
|
||
|
### Authentication
|
||
|
|
||
|
If the CLI configuration includes
|
||
|
[credentials](/docs/commands/cli-config.html#credentials) for the hostname
|
||
|
given in the network mirror base URL, Terraform will include those credentials
|
||
|
in its requests for operations described below.
|
||
|
|
||
|
If the given URL uses a non-standard port number (other than 443) then the
|
||
|
credentials must be associated with a hostname that includes the port number,
|
||
|
such as `terraform.example.com:8443`.
|
||
|
|
||
|
Terraform does _not_ send credentials when retrieving the archives whose
|
||
|
URLs are given in the "List Available Installation Packages" response below.
|
||
|
If a particular mirror considers the distribution packages themselves to be
|
||
|
sensitive then it must use cryptographically-secure, user-specific, and
|
||
|
time-limited URLs in the metadata response. Strategies for doing so are out
|
||
|
of scope of this protocol documentation.
|
||
|
|
||
|
## List Available Versions
|
||
|
|
||
|
This operation determines which versions are currently available for a
|
||
|
particular provider.
|
||
|
|
||
|
| Method | Path | Produces |
|
||
|
|--------|-----------------------------------------|--------------------|
|
||
|
| `GET` | `:hostname/:namespace/:type/index.json` | `application/json` |
|
||
|
|
||
|
### Parameters
|
||
|
|
||
|
* `hostname` (required): the hostname portion of the address of the requested
|
||
|
provider.
|
||
|
* `namespace` (required): the namespace portion of the address of the requested
|
||
|
provider.
|
||
|
* `type` (required): the type portion of the address of the requested provider.
|
||
|
|
||
|
### Sample Request
|
||
|
|
||
|
```
|
||
|
curl 'https://terraform.example.com/providers/registry.terraform.io/hashicorp/random/index.json'
|
||
|
```
|
||
|
|
||
|
### Sample Response
|
||
|
|
||
|
```json
|
||
|
{
|
||
|
"versions": {
|
||
|
"2.0.0": {},
|
||
|
"2.0.1": {}
|
||
|
}
|
||
|
}
|
||
|
```
|
||
|
|
||
|
### Response Properties
|
||
|
|
||
|
A successful result is a JSON object containing a single property `versions`,
|
||
|
which must be a JSON object.
|
||
|
|
||
|
Each of the property names of the `versions` object represents an available
|
||
|
version number. The property values must be objects, but no properties are
|
||
|
currently defined for those objects. Future versions of this protocol may
|
||
|
define optional per-version properties for Terraform to use as installation
|
||
|
hints, so implementations of the current version should leave those objects
|
||
|
empty.
|
||
|
|
||
|
Return `404 Not Found` to signal that the mirror does not have a provider
|
||
|
with the given address.
|
||
|
|
||
|
## List Available Installation Packages
|
||
|
|
||
|
This operation returns download URLs and associated metadata for the
|
||
|
distribution packages for a particular version of a provider.
|
||
|
|
||
|
Each distribution package is associated with a particular operating system
|
||
|
and architecture. A network mirror may host only a subset of the available
|
||
|
packages for a provider version, if the users of the mirror are known to all
|
||
|
use only a subset of the target platforms that Terraform supports.
|
||
|
|
||
|
Terraform CLI uses this operation after it has selected the newest available
|
||
|
version matching the configured version constraints, in order to find a zip
|
||
|
archive containing the plugin itself.
|
||
|
|
||
|
| Method | Path | Produces |
|
||
|
|--------|--------------------------------------------|--------------------|
|
||
|
| `GET` | `:hostname/:namespace/:type/:version.json` | `application/json` |
|
||
|
|
||
|
### Parameters
|
||
|
|
||
|
* `hostname` (required): the hostname portion of the address of the requested
|
||
|
provider.
|
||
|
* `namespace` (required): the namespace portion of the address of the requested
|
||
|
provider.
|
||
|
* `type` (required): the type portion of the address of the requested provider.
|
||
|
* `version` (required): the version selected to download. This will exactly
|
||
|
match one of the version strings returned from a previous call to
|
||
|
[List Available Versions](#list-available-versions).
|
||
|
|
||
|
### Sample Request
|
||
|
|
||
|
```
|
||
|
curl 'https://terraform.example.com/providers/registry.terraform.io/hashicorp/random/2.0.0.json'
|
||
|
```
|
||
|
|
||
|
### Sample Response
|
||
|
|
||
|
```json
|
||
|
{
|
||
|
"archives": {
|
||
|
"darwin_amd64": {
|
||
|
"url": "terraform-provider-random_2.0.0_darwin_amd64.zip",
|
||
|
"hashes": [
|
||
|
"h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs="
|
||
|
]
|
||
|
},
|
||
|
"linux_amd64": {
|
||
|
"url": "terraform-provider-random_2.0.0_linux_amd64.zip",
|
||
|
"hashes": [
|
||
|
"h1:lCJCxf/LIowc2IGS9TPjWDyXY4nOmdGdfcwwDQCOURQ="
|
||
|
]
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
```
|
||
|
|
||
|
### Response Properties
|
||
|
|
||
|
A successful result is a JSON object with a property called `archives`, which
|
||
|
must be a JSON object.
|
||
|
|
||
|
Each of the property names of the `archives` object is a target platform
|
||
|
identifier, which consists of an operating system and architecture concatenated
|
||
|
with an underscore (`_`).
|
||
|
|
||
|
Each property value in the `archives` object is itself a nested object with
|
||
|
the following properties:
|
||
|
|
||
|
* `url` (required): a string specifying the URL from which Terraform should
|
||
|
download the `.zip` archive containing the requested provider plugin version.
|
||
|
|
||
|
Terraform resolves the URL relative to the URL from which the current
|
||
|
JSON document was returned, so the examples above containing only a
|
||
|
filename would cause Terraform to construct a URL like:
|
||
|
|
||
|
```
|
||
|
https://terraform.example.com/providers/registry.terraform.io/hashicorp/random/terraform-provider-random_2.0.0_darwin_amd64.zip
|
||
|
```
|
||
|
|
||
|
* `hashes` (optional): a JSON array of strings containing one or more hash
|
||
|
values for the indicated archive. These hashes use Terraform's provider
|
||
|
package hashing algorithm. At present, the easiest way to populate these
|
||
|
is to construct a mirror's JSON indices using the `terraform providers mirror`
|
||
|
command, as described in a later section, which will include the calculated
|
||
|
hashes of each provider.
|
||
|
|
||
|
If the response includes at least one hash, Terraform will select the hash
|
||
|
whose algorithm it considers to be strongest and verify that the downloaded
|
||
|
package matches that hash. If the response does not include a `hashes`
|
||
|
property then Terraform will install the indicated archive with no
|
||
|
verification.
|
||
|
|
||
|
Terraform CLI will only attempt to download versions that it has previously
|
||
|
seen in response to [List Available Versions](#list-available-versions).
|
||
|
|
||
|
## Provider Mirror as a Static Website
|
||
|
|
||
|
The provider mirror protocol is designed so that it can potentially implemented
|
||
|
by placing files on typical static website hosting services. When using this
|
||
|
strategy, implement the JSON index responses described above as `.json` files
|
||
|
in the appropriate nested subdirectories, and ensure that your system is
|
||
|
configured to serve `.json` files with the `application/json` media type.
|
||
|
|
||
|
As a convenience, Terraform CLI includes
|
||
|
[the `terraform providers mirror` subcommand](https://www.terraform.io/docs/commands/providers/mirror.html),
|
||
|
which will analyze the current configuration for the providers it requires,
|
||
|
download the packages for those providers from their origin registries, and
|
||
|
place them into a local directory suitable for use as a mirror.
|
||
|
|
||
|
The `terraform providers mirror` subcommand also generates `index.json` and
|
||
|
version-specific `.json` files that can, when placed in a static website hosting
|
||
|
system, produce responses compatible with the provider mirror protocol.
|
||
|
|
||
|
If you wish to create a mirror with providers for a number of different
|
||
|
Terraform configurations, run `terraform providers mirror` in each configuration
|
||
|
in turn while providing the same output directory each time. Terraform will
|
||
|
then merge together all of the requirements into a single set of JSON indices.
|