github.com/hugorut/terraform@v1.1.3/website/docs/internals/module-registry-protocol.mdx (about) 1 --- 2 page_title: Module Registry Protocol 3 description: |- 4 The module registry protocol is implemented by a host intending to be the 5 host of one or more Terraform modules, specifying which modules are available 6 and where to find their distribution packages. 7 --- 8 9 # Module Registry Protocol 10 11 -> Third-party module registries are supported only in Terraform CLI 0.11 and later. Prior versions do not support this protocol. 12 13 The module registry protocol is what Terraform CLI uses to discover metadata 14 about modules available for installation and to locate the distribution 15 package for a selected module. 16 17 The primary implementation of this protocol is the public 18 [Terraform Registry](https://registry.terraform.io/) at `registry.terraform.io`. 19 By writing and deploying your own implementation of this protocol, you can 20 create a separate registry to distribute your own modules, as an alternative to 21 publishing them on the public Terraform Registry. 22 23 The public Terraform Registry implements a superset of the API described on 24 this page, in order to capture additional information used in the registry UI. 25 For information on those extensions, see 26 [Terraform Registry HTTP API](/registry/api-docs). Third-party registry 27 implementations may choose to implement those extensions if desired, but 28 Terraform CLI itself does not use them. 29 30 ## Module Addresses 31 32 Each Terraform module has an associated address. A module address has the 33 syntax `hostname/namespace/name/system`, where: 34 35 - `hostname` is the hostname of the module registry that serves this module. 36 - `namespace` is the name of a namespace, unique on a particular hostname, that 37 can contain one or more modules that are somehow related. On the public 38 Terraform Registry the "namespace" represents the organization that is 39 packaging and distributing the module. 40 - `name` is the module name, which generally names the abstraction that the 41 module is intending to create. 42 - `system` is the name of a remote system that the module is primarily written 43 to target. For multi-cloud abstractions, there can be multiple modules with 44 addresses that differ only in "system" to reflect provider-specific 45 implementations of the abstraction, like 46 `registry.terraform.io/hashicorp/consul/aws` vs. 47 `registry.terraform.io/hashicorp/consul/azurerm`. The system name commonly 48 matches the type portion of the address of an official provider, like `aws` 49 or `azurerm` in the above examples, but that is not required and so you can 50 use whichever system keywords make sense for the organization of your 51 particular registry. 52 53 The `hostname/` portion of a module address (including its slash delimiter) 54 is optional, and if omitted defaults to `registry.terraform.io/`. 55 56 For example: 57 58 - `hashicorp/consul/aws` is a shorthand for 59 `registry.terraform.io/hashicorp/consul/aws`, which is a module on the 60 public registry for deploying Consul clusters in Amazon Web Services. 61 - `example.com/awesomecorp/consul/happycloud` is a hypothetical module published 62 on a third-party registry. 63 64 If you intend to share a module you've developed for use by all Terraform 65 users, please consider publishing it into the public 66 [Terraform Registry](https://registry.terraform.io/) to make your module more 67 discoverable. You only need to implement this module registry protocol if you 68 wish to publish modules whose addresses include a different hostname that is 69 under your control. 70 71 ## Module Versions 72 73 Each distinct module address has associated with it a set of versions, each 74 of which has an associated version number. Terraform assumes version numbers 75 follow the [Semantic Versioning 2.0](https://semver.org/) conventions, with 76 the user-facing behavior of the module serving as the "public API". 77 78 Each `module` block may select a distinct version of a module, even if multiple 79 blocks have the same source address. 80 81 ## Service Discovery 82 83 The module registry protocol begins with Terraform CLI using 84 [Terraform's remote service discovery protocol](/internals/remote-service-discovery), 85 with the hostname in the module address acting as the "User-facing Hostname". 86 87 The service identifier for the module registry protocol is `modules.v1`. 88 Its associated string value is the base URL for the relative URLs defined in 89 the sections that follow. 90 91 For example, the service discovery document for a host that _only_ implements 92 the module registry protocol might contain the following: 93 94 ```json 95 { 96 "modules.v1": "/terraform/modules/v1/" 97 } 98 ``` 99 100 If the given URL is a relative URL then Terraform will interpret it as relative 101 to the discovery document itself. The specific module registry protocol 102 endpoints are defined as URLs relative to the given base URL, and so the 103 specified base URL should generally end with a slash to ensure that those 104 relative paths will be resolved as expected. 105 106 The following sections describe the various operations that a module 107 registry must implement to be compatible with Terraform CLI's module 108 installer. The indicated URLs are all relative to the URL resulting from 109 service discovery, as described above. We use the current URLs on 110 Terraform Registry as working examples, assuming that the caller already 111 performed service discovery on `registry.terraform.io` to learn the base URL. 112 113 The URLs are shown with the convention that a path portion with a colon `:` 114 prefix is a placeholder for a dynamically-selected value, while all other 115 path portions are literal. For example, in `:namespace/:type/versions`, 116 the first two path portions are placeholders while the third is literally 117 the string "versions". 118 119 ## List Available Versions for a Specific Module 120 121 This is the primary endpoint for resolving module sources, returning the 122 available versions for a given fully-qualified module. 123 124 | Method | Path | Produces | 125 | ------ | ------------------------------------- | ------------------ | 126 | `GET` | `:namespace/:name/:provider/versions` | `application/json` | 127 128 ### Parameters 129 130 - `namespace` `(string: <required>)` - The user or organization the module is 131 owned by. This is required and is specified as part of the URL path. 132 133 - `name` `(string: <required>)` - The name of the module. 134 This is required and is specified as part of the URL path. 135 136 - `system` `(string: <required>)` - The name of the target system. 137 This is required and is specified as part of the URL path. 138 139 ### Sample Request 140 141 ```text 142 $ curl 'https://registry.terraform.io/v1/modules/hashicorp/consul/aws/versions' 143 ``` 144 145 ### Sample Response 146 147 The `modules` array in the response always includes the requested module as the 148 first element. 149 150 Other elements of this list are not currently used. Third-party implementations 151 should always use a single-element list for forward compatiblity with possible 152 future extensions to the protocol. 153 154 Each returned module has an array of available versions, which Terraform 155 matches against any version constraints given in configuration. 156 157 ```json 158 { 159 "modules": [ 160 { 161 "versions": [ 162 {"version": "1.0.0"}, 163 {"version": "1.1.0"}, 164 {"version": "2.0.0"} 165 ] 166 } 167 ] 168 } 169 ``` 170 171 Return `404 Not Found` to indicate that no module is available with the 172 requested namespace, name, and provider 173 174 ## Download Source Code for a Specific Module Version 175 176 This endpoint downloads the specified version of a module for a single provider. 177 178 | Method | Path | Produces | 179 | ------ | -------------------------------------------- | ------------------ | 180 | `GET` | `:namespace/:name/:system/:version/download` | `application/json` | 181 182 ### Parameters 183 184 - `namespace` `(string: <required>)` - The user the module is owned by. 185 This is required and is specified as part of the URL path. 186 187 - `name` `(string: <required>)` - The name of the module. 188 This is required and is specified as part of the URL path. 189 190 - `provider` `(string: <required>)` - The name of the target system. 191 This is required and is specified as part of the URL path. 192 193 - `version` `(string: <required>)` - The version of the module. 194 This is required and is specified as part of the URL path. 195 196 ### Sample Request 197 198 ```text 199 $ curl -i 'https://registry.terraform.io/v1/modules/hashicorp/consul/aws/0.0.1/download' 200 ``` 201 202 ### Sample Response 203 204 ```text 205 HTTP/1.1 204 No Content 206 Content-Length: 0 207 X-Terraform-Get: https://api.github.com/repos/hashicorp/terraform-aws-consul/tarball/v0.0.1//*?archive=tar.gz 208 ``` 209 210 A successful response has no body, and includes the location from which the 211 module version's source can be downloaded in the `X-Terraform-Get` header. 212 The value of this header accepts the same values as the `source` argument 213 in a `module` block in Terraform configuration, as described in 214 [Module Sources](/language/modules/sources), 215 except that it may not recursively refer to another module registry address. 216 217 The value of `X-Terraform-Get` may instead be a relative URL, indicated by 218 beginning with `/`, `./` or `../`, in which case it is resolved relative to 219 the full URL of the download endpoint to produce 220 [an HTTP URL module source](/language/modules/sources#http-urls).