September 19, 2017·6 min read·engineeringterraformmodulesregistry

Terraform Module Registry standardizes discovery and module releases

The new registry connects reusable modules to searchable documentation and tagged releases. Its launch also exposes an important gap between versioned publication and version-constrained consumption.

A reusable infrastructure module needs more than a repository URL. A prospective user has to find it, understand its inputs and decide whether its maintenance and release practices fit the intended deployment. Terraform already supports remote module sources, but distributing code does not automatically make that code easy to evaluate. The Module Registry adds a shared discovery and publication workflow around those existing module boundaries.

HashiCorp's September 19 announcement introduces a public registry of verified and community modules. The service connects publishers with consumers and displays information about a module's inputs, outputs and resources. Its launch makes reuse easier to start, while leaving the underlying infrastructure decisions inside the module.

I value Terraform's ability to make API abstractions reusable. A registry helps when it exposes enough of a module's contract to judge whether that abstraction fits. Reuse becomes less useful when a short source declaration hides assumptions that the caller cannot discover.

A module already has an interface

The module usage documentation in Terraform 0.10.5 explains that arguments on a module block correspond to variables declared by the module. A caller supplies those inputs while the module contains resource declarations. Outputs provide the supported way to refer to values produced inside the module.

This interface is a useful basis for generated documentation. A registry can describe the variables callers must provide and the outputs they can reference without asking a publisher to maintain a second independent description of those names. The source remains available for understanding the implementation behind the interface.

Encapsulation also affects dependency relationships. The usage documentation says resources in one module cannot directly depend on another module's internal attributes unless those values are exported through outputs. A reference to an exported output creates a dependency relationship. Module design therefore determines which implementation details callers can depend on.

This matters for evaluating a registry result. Two modules that create similar resources can expose very different contracts. One may require callers to provide existing networking, while another may create networking internally. The useful comparison is the responsibility expressed by the inputs and outputs, not merely the module's name.

Discovery uses information from the repository

The registry publishing instructions available at launch explain that the service extracts documentation and input/output information from module source. The repository description supplies the short description. A standard module structure lets the registry inspect the code and track resource use.

Public registry modules must reside in public GitHub repositories. Their repository names follow terraform-PROVIDER-NAME, with the primary provider in the middle. Examples in the instructions include terraform-aws-consul and terraform-google-vault. This convention gives the publication service predictable information about what a repository contains.

The publishing flow requests GitHub hook access so the registry can observe releases. A repository's tags are therefore the input to an ongoing synchronization process, as well as evidence that an initial release exists. Publishers retain their Git workflow while the service builds the catalog around it.

The naming requirement is consequently part of the service's indexing contract. An arbitrary collection of Terraform files does not become a publishable module merely because it is public. The repository must also have the expected structure and an initial release tag.

The launch-day usage documentation says search matches module names, providers and descriptions. Filters refine the results. A specific description helps a consumer distinguish related modules before reading their full source.

That makes documentation quality an operational part of distribution. A description that names the infrastructure responsibility is more useful than one that promises general simplicity. The same applies to inputs whose names and descriptions explain whether callers supply an existing object or ask the module to create one.

Registry addresses shorten the dependency declaration

A registry module uses a namespace/name/provider source address. The launch documentation gives hashicorp/consul/aws as its example. A module block can therefore identify the package without embedding a repository transport URL.

module "consul" {
  source = "hashicorp/consul/aws"
}

This is the source declaration shown in the documentation, not a complete deployment configuration for every use of that module. Required inputs still have to be supplied. The registry's usage instructions help a caller find those requirements, and initialization retrieves the module.

The shorter source does not replace the module interface. Variables remain the inputs, outputs remain the references available to other configuration, and the module's resources remain part of the resulting infrastructure plan. Discovering a module through a service changes how it is located, not what its resource declarations mean.

Existing module sources also remain relevant. The 0.10.5 source reference documents local paths and Git repositories, among other locations. Git sources can select a branch, tag or commit with ref. The registry adds a common publication convention to an ecosystem that already has several ways to retrieve configuration.

For an organization with its own repository arrangements, that distinction is useful. The public registry does not make existing source forms invalid. It supplies a shared catalog and address convention for modules published through its workflow.

Publication is versioned before consumption gains constraints

The publishing instructions require release tags that follow semantic version syntax, optionally prefixed with v. An initial publication needs at least one such tag. Subsequent tags notify the registry through a webhook, so the repository's release practice drives the versions visible in the catalog.

The service can therefore show a version history at launch. However, the usage documentation says Terraform currently downloads only the latest version of each registry module. Full constraints on registry module versions are described as a coming capability.

Those are separate facts about the system. A publisher can produce versioned releases, and the service can track them, before the client can express an acceptable version range in a module block. Adding a constraint example to a launch-day explanation would claim client behavior that the documentation does not yet provide.

This limit changes how the source declaration should be read. It identifies the registry module, but it does not by itself state which historical release a fresh initialization must use. The registry's release history is useful information for evaluating changes, while the current client behavior determines what gets downloaded.

I prefer to make this gap explicit because the word versioned can otherwise imply more control than the client supplies. Publication metadata and dependency-selection policy need to agree before a caller can rely on a constraint being enforced.

Verification describes a review relationship

The verified-module documentation at launch says verified modules receive HashiCorp review and active maintenance by contributors. Verification is initially a manual process limited to trusted partners. A blue badge identifies that status.

The same documentation is careful about what the badge does not describe. Verification does not indicate broad flexibility or extensive feature support. A simple example can qualify. An unverified module can also be well maintained and high quality.

This makes verification evidence about a particular review and maintenance arrangement. It is not a substitute for determining whether the module's inputs and resource choices fit a deployment. Verified and unverified modules use the same configuration mechanism.

Search initially displays verified results by default, with filters exposing unverified modules. That influences discovery without changing the Terraform behavior of the selected package. A consumer needs to distinguish a catalog's presentation choices from the semantics of the module that ultimately enters configuration.

Reuse still affects resource identity

The existing usage documentation shows instantiating the same module twice with different names and inputs. Each instance receives its own module prefix in resource addresses. A reusable package can therefore produce multiple sets of managed objects without copying its implementation.

Those addresses also explain why reorganizing an existing configuration into a module is not simply a documentation edit. Moving resource declarations changes their Terraform addresses. The usage reference warns that extraction can lead to proposed destruction and recreation if ownership is not accounted for.

A registry makes it easier to obtain a module, but adopting it still means choosing a concrete interface and resource organization. The catalog can expose the information needed for that choice. The resulting configuration determines which objects the module manages and which values callers depend on through its outputs.