7.1 KiB
stage | group | info |
---|---|---|
Package | Package Registry | To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments |
Terraform module registry (FREE)
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:
- A personal access token with at least
read_api
rights. - A CI/CD job token.
Publish a Terraform Module
When you publish a Terraform Module, if it does not exist, it is created.
Prerequisites:
- 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
write_package_registry
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), digits (0-9), and hyphens (- ). |
module-system |
string | yes | The 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-version |
string | yes | The 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 \
"https://gitlab.example.com/api/v4/projects/<your_project_id>/packages/terraform/modules/my-module/my-system/0.0.1/file"
Example response:
{
"message":"201 Created"
}
Example request using a deploy token:
curl --header "DEPLOY-TOKEN: <deploy_token>" \
--upload-file path/to/file.tgz \
"https://gitlab.example.com/api/v4/projects/<your_project_id>/packages/terraform/modules/my-module/my-system/0.0.1/file"
Example response:
{
"message":"201 Created"
}
Reference a Terraform Module
Prerequisites:
- 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:
stages:
- upload
upload:
stage: upload
image: curlimages/curl:latest
variables:
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
script:
- TERRAFORM_MODULE_NAME=$(echo "${TERRAFORM_MODULE_NAME}" | tr " _" -) # module-name must not have spaces or underscores, so translate them to hyphens
- tar -vczf ${TERRAFORM_MODULE_NAME}-${TERRAFORM_MODULE_SYSTEM}-${TERRAFORM_MODULE_VERSION}.tgz -C ${TERRAFORM_MODULE_DIR} --exclude=./.git .
- 'curl --location --header "JOB-TOKEN: ${CI_JOB_TOKEN}"
--upload-file ${TERRAFORM_MODULE_NAME}-${TERRAFORM_MODULE_SYSTEM}-${TERRAFORM_MODULE_VERSION}.tgz
${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/terraform/modules/${TERRAFORM_MODULE_NAME}/${TERRAFORM_MODULE_SYSTEM}/${TERRAFORM_MODULE_VERSION}/file'
rules:
- 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:
- The GitLab local file project creates a minimal Terraform module and uploads it into the Terraform module registry using GitLab CI/CD.
- The Terraform module test project uses the module from the previous example.
Troubleshooting
- Publishing a module with a duplicate name results in a
{"message":"Access Denied"}
error. There's an ongoing discussion about allowing duplicate module names in this issue.