The Terraform Module Registry in GitLab provides a private registry for Terraform modules hosted on GitLab projects and groups. With the Terraform Module Registry, you can use GitLab projects as a private registry for Terraform modules. You can create and publish modules with GitLab CI/CD, which can then be consumed from other private projects. The feature is available on Tier Free, Premium, Ultimate and Offering GitLab.com, GitLab Self-Managed, GitLab Dedicated.
The registry unifies infrastructure registry and Terraform Module Registry into a single Terraform Module Registry feature in GitLab 15.11. Support for groups was introduced in GitLab 16.9. Support for Readme files was introduced in GitLab 17.2. Publish Terraform modules in your project’s Infrastructure Registry, then reference them using GitLab as a Terraform module registry was introduced in GitLab 14.0. CI/CD template introduced in GitLab 15.9.
Core capabilities
The Terraform Module Registry allows viewing, authenticating, publishing, referencing, downloading, and deleting Terraform modules. Module resolution works through the Packages API endpoints used by the Terraform CLI.
To view Terraform modules in your project or group:
- On the left sidebar, select Search or go to and find your project or group.
- Select Operate > Terraform modules.
You can search, sort, and filter modules on this page. You can also view the module’s Readme file by selecting a module, and then selecting Readme.
Authentication model
To authenticate to the Terraform Module Registry, you need either:
- A personal access token with at least the read_api scope.
- A CI/CD job token.
- A deploy token with the readpackageregistry or writepackageregistry scope, or both.
When using the API:
- If you authenticate with a deploy token, you must apply the writepackageregistry scope to publish a module. To download a module, apply the readpackageregistry scope.
- If you authenticate with a personal access token, you must configure it with at least the read_api scope.
Do not use authentication methods other than the methods documented here.
Authentication tokens can be provided for terraform in your ~/.terraformrc file:
credentials "gitlab.com" {
token = "<TOKEN>"
}
Where gitlab.com can be replaced with the hostname of your self-managed GitLab instance.
For local or temporary environments, you might want to create a ~/.terraformrc or %APPDATA%/terraform.rc file:
credentials "gitlab.com" {
token = "<TOKEN>"
}
Where gitlab.com can be replaced with the hostname of GitLab Self-Managed.
You can also provide authentication tokens for terraform in your ~/.netrc file:
machine gitlab.com
login <USERNAME>
password <TOKEN>
Where gitlab.com can be replaced with the hostname of GitLab Self-Managed, and
When terraform init runs, it needs to authenticate to your GitLab instance to download private modules.
Environment Variables for CI/CD: Set TFTOKENgitlabcom with a suitable token, replacing gitlabcom with your instance, underscores for dots.
Publishing modules
Publishing Modules Via GitLab CI/CD is recommended.
Structure your module in a dedicated GitLab project. Use a .gitlab-ci.yml file that triggers on Git tags which should follow semantic versioning, e.g., v1.0.1. The CI job will package your module usually as a .tgz archive and use GitLab's API with CIJOBTOKEN to publish it to the registry.
GitLab provides CI/CD templates for this. With templates being deprecated, you might adapt this logic or use newer component-based approaches if available.
CI/CD template introduced in GitLab 15.9.
include:
template: Terraform-Module.gitlab-ci.yml
The pipeline contains the following jobs:
- fmt
- Validate the formatting of the Terraform module.
- kics-iac-sast
- Test the Terraform module for security issues.
- deploy
- For tag pipelines only. Deploy the Terraform module to the GitLab Terraform Registry.
You can configure the pipeline with the following variables:
| Variable | Default | Description |
|---|---|---|
| TERRAFORMMODULEDIR | ${CIPROJECTDIR} | The relative path to the root directory of the Terraform project. |
| TERRAFORMMODULENAME | ${CIPROJECTNAME} | The name of your Terraform module. Must not contain any spaces or underscores. |
| TERRAFORMMODULESYSTEM | local | The system or provider of your Terraform module targets. For example, local, aws, google. |
| TERRAFORMMODULEVERSION | ${CICOMMITTAG} | The Terraform module version |
Via API Manually:
You can also use curl and the Packages API with a GitLab Personal Access Token, Project Access Token, or Deploy Token with readpackageregistry and writepackageregistry scopes to upload your packaged module.
Prerequisites for publishing via API:
- The package name and version must be unique in the top-level namespace.
- Your project and group names must not include a dot (.). For example, source = "gitlab.example.com/my.group/project.name".
- You must authenticate with the API. If authenticating with a deploy token, it must be configured with the writepackageregistry scope.
- The name of a module must be unique within the scope of its group, otherwise an error occurs.
PUT /projects/:id/packages/terraform/modules/:module-name/:module-system/:module-version/file
| Attribute | Type | Required | Description |
|---|---|---|---|
| id | integer/string | yes | The ID or URL-encoded path of the project. |
| module-name | string | yes | The package name. Supported syntax: One to 64 ASCII characters, including lowercase letters (a-z) and digits (0-9). The package name can’t exceed 64 characters. |
| module-system | string | yes | The package system |
When you publish a Terraform Module, if it does not exist, it is created.
Referencing and consuming modules
You can then refer to your Terraform Module from a downstream Terraform project:
module "<module>" {
source = "gitlab.com/<namespace>/<module-name>/<module-system>"
}
Where
To reference a Terraform module using a project-level source, use the fetching archives over HTTP source type provided by Terraform.
You can refer to your Terraform module from a downstream Terraform project:
module "<module>" {
source = "https://gitlab.com/api/v4/projects/<project-id>/packages/terraform/modules/<module-name>/<module-system>/<module-version>"
}
If you need to reference the latest version of a module, you can omit the
If there are duplicate module names in the same namespace, referencing the module from the namespace level installs the recently published module.
Example: Referencing a Module from GitLab Registry in your Terraform code:
module "<module>" {
source = "gitlab.com/<namespace>/<module-name>/<module-system>"
}
Where
API interaction
Terraform Module Registry API
- Tier: Free, Premium, Ultimate
- Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated
Use this API to interact with the Terraform CLI. This API is used by the Terraform CLI and is generally not meant for manual consumption. Undocumented authentication methods might be removed in the future.
List available versions for a specific module
List all available versions for a specified module.
GET packages/terraform/modules/v1/:modulenamespace/:modulename/:module_system/versions
| Attribute | Type | Required | Description |
|---|---|---|---|
| module_namespace | string | yes | The top-level group (namespace) to which Terraform module’s project or subgroup belongs. |
| module_name | string | yes | The module name. |
| module_system | string | yes | The name of the module system or provider |
Module resolution and lifecycle
How module resolution works is documented in the registry.
Disable the Terraform Module Registry can be performed by administrators.
Delete a Terraform module removes a published version.
GitLab has its own private Terraform Registry to host and share your custom modules across your organization.
Conclusion
The GitLab Terraform Module Registry provides a fully integrated path from source to consumption for Terraform modules with authentication enforced through personal access tokens, CI/CD job tokens, and deploy tokens scoped to readpackageregistry and writepackageregistry. Publishing is streamlined through a CI/CD template introduced in GitLab 15.9 with fmt, kics-iac-sast, and deploy jobs, configurable via TERRAFORMMODULEDIR, TERRAFORMMODULENAME, TERRAFORMMODULESYSTEM, and TERRAFORMMODULEVERSION variables. API publishing requires unique package name and version within the top-level namespace, no dots in project and group names, and proper scopes.
Authentication for consumption is supported via ~/.terraformrc credentials blocks or ~/.netrc machine entries, with environment variable TFTOKENgitlab_com for CI/CD. Referencing uses source strings of the form gitlab.com/
Sources
- https://docs.gitlab.com/user/packages/terraformmoduleregistry/
- https://scalr.com/learning-center/using-terraform-with-gitlab
- https://docs.gitlab.co.jp/ee/user/packages/terraformmoduleregistry/
- https://gitlab-docs-d6a9bb.gitlab.io/ee/user/packages/terraformmoduleregistry/index.html
- https://docs.gitlab.com/api/packages/terraform-modules/