Terraform module registry

Introduced in GitLab 14.0.

Publish Terraform modules in your project’s Infrastructure Registry, then reference them using GitLab as a Terraform module registry.

Authenticate to the Terraform module registry

To authenticate to the Terraform module registry, you need either:

Publish a Terraform Module

When you publish a Terraform Module, if it does not exist, it is created.


  • A package with the same name and version must not already exist 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 write_package_registry scope.
PUT /projects/:id/packages/terraform/modules/:module-name/:module-system/:module-version/file
idinteger/stringyesThe ID or URL-encoded path of the project.
module-namestringyesThe package name. Supported syntax: One to 64 ASCII characters, including lowercase letters (a-z), digits (0-9), and hyphens (-).
module-systemstringyesThe package system. Supported syntax: One to 64 ASCII characters, including lowercase letters (a-z), digits (0-9), and hyphens (-). More information can be found in the Terraform Module Registry Protocol documentation.
module-versionstringyesThe package version. It must be valid according to the Semantic Versioning Specification.

Provide the file content in the request body.

As the following example shows, requests must end with /file. If you send a request ending with something else, it results in a 404 error {"error":"404 Not Found"}.

Example request using a personal access token:

curl --header "PRIVATE-TOKEN: <your_access_token>" \
     --upload-file path/to/file.tgz \

Example response:

  "message":"201 Created"

Example request using a deploy token:

curl --header "DEPLOY-TOKEN: <deploy_token>" \
     --upload-file path/to/file.tgz \

Example response:

  "message":"201 Created"

Reference a Terraform Module


  • You need to authenticate with the API. If authenticating with a personal access token, it must be configured with the read_api scope.

Authentication tokens (Job Token or Personal Access Token) 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.

You can then refer to your Terraform Module from a downstream Terraform project:

module "<module>" {
  source = "gitlab.com/<namespace>/<module-name>/<module-system>"

Where <namespace> is the namespace of the Terraform module registry.

Publish a Terraform module by using CI/CD

To work with Terraform modules in GitLab CI/CD, you can use CI_JOB_TOKEN in place of the personal access token in your commands.

For example, this job uploads a new module for the local system provider and uses the module version from the Git commit tag:

  - upload

  stage: upload
  image: curlimages/curl:latest
    TERRAFORM_MODULE_DIR: ${CI_PROJECT_DIR} # The path to your Terraform module
    TERRAFORM_MODULE_NAME: ${CI_PROJECT_NAME} # The name of your Terraform module
    TERRAFORM_MODULE_SYSTEM: local # The system or provider your Terraform module targets (ex. local, aws, google)
    TERRAFORM_MODULE_VERSION: ${CI_COMMIT_TAG} # Tag commits with SemVer for the version of your Terraform module to be published
    - TERRAFORM_MODULE_NAME=$(echo "${TERRAFORM_MODULE_NAME}" | tr " _" -) # module-name must not have spaces or underscores, so translate them to hyphens
    - 'curl --location --header "JOB-TOKEN: ${CI_JOB_TOKEN}"
    - if: $CI_COMMIT_TAG

To trigger this upload job, add a Git tag to your commit. Ensure the tag follows the Semantic Versioning Specification that Terraform requires. The rules:if: $CI_COMMIT_TAG ensures that only tagged commits to your repo trigger the module upload job. For other ways to control jobs in your CI/CD pipeline, refer to the .gitlab-ci.yml keyword reference.

Example projects

For examples of the Terraform module registry, check the projects below: