Terraform 模块注册表
- Tier: Free, Premium, Ultimate
- Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated
通过 Terraform 模块注册表,您可以:
- 使用 GitLab 项目作为 Terraform 模块的私有注册表。
- 使用 GitLab CI/CD 创建和发布模块,然后可以从其他私有项目中使用这些模块。
认证到 Terraform 模块注册表
要认证到 Terraform 模块注册表,您需要以下任一方式:
- 一个具有至少
read_api权限的个人访问令牌。 - 一个CI/CD 作业令牌。
- 一个具有
read_package_registry或write_package_registry权限,或两者都有的部署令牌。
使用 API 时:
- 如果使用部署令牌进行认证,必须应用
write_package_registry权限才能发布模块。要下载模块,请应用read_package_registry权限。 - 如果使用个人访问令牌进行认证,必须将其配置为至少具有
read_api权限。
不要使用此处文档之外的其他认证方法。未记录的认证方法将来可能会被移除。
前置条件
要发布 Terraform 模块:
- 您必须至少拥有 Developer 角色。
要删除模块:
- 您必须至少拥有 Maintainer 角色。
发布 Terraform 模块
发布 Terraform 模块会创建它(如果不存在)。
发布 Terraform 模块后,您可以在 Terraform 模块注册表 页面中查看它。
使用 API
使用 Terraform 模块注册表 API 发布 Terraform 模块。
PUT /projects/:id/packages/terraform/modules/:module-name/:module-system/:module-version/file| 属性 | 类型 | 必需 | 描述 |
|---|---|---|---|
id |
integer/string | 是 | 项目的 ID 或 URL 编码路径。 |
module-name |
string | 是 | 模块名称。支持的语法:1 到 64 个 ASCII 字符,包括小写字母 (a-z) 和数字 (0-9)。 |
module-system |
string | 是 | 模块系统。支持的语法:1 到 64 个 ASCII 字符,包括小写字母 (a-z) 和数字 (0-9)。更多信息请参见 Module Registry Protocol。 |
module-version |
string | 是 | 模块版本。应遵循 语义版本规范。 |
在请求正文中提供文件内容。
请求必须以 /file 结尾。
如果您发送以其他内容结尾的请求,会导致 404 Not Found 错误。
使用个人访问令牌的示例请求:
curl --fail-with-body --header "PRIVATE-TOKEN: <your_access_token>" \
--upload-file path/to/file.tgz \
--url "https://gitlab.example.com/api/v4/projects/<your_project_id>/packages/terraform/modules/<your_module>/<your_system>/0.0.1/file"使用部署令牌的示例请求:
curl --fail-with-body --header "DEPLOY-TOKEN: <deploy_token>" \
--upload-file path/to/file.tgz \
--url "https://gitlab.example.com/api/v4/projects/<your_project_id>/packages/terraform/modules/<your_module>/<your_system>/0.0.1/file"示例响应:
{
"message":"201 Created"
}使用 CI/CD 模板(推荐)
您可以使用 Terraform-Module.gitlab-ci.yml
或高级的 Terraform/Module-Base.gitlab-ci.yml
CI/CD 模板将 Terraform 模块发布到 GitLab Terraform 模块注册表:
include:
template: Terraform-Module.gitlab-ci.yml该管道包含以下作业:
fmt: 验证 Terraform 模块的格式kics-iac-sast: 测试 Terraform 模块的安全问题deploy: 将 Terraform 模块部署到 Terraform 模块注册表(仅限标签管道)
使用管道变量
使用以下变量配置管道:
| 变量 | 默认值 | 描述 |
|---|---|---|
TERRAFORM_MODULE_DIR |
${CI_PROJECT_DIR} |
Terraform 项目的根目录的相对路径。 |
TERRAFORM_MODULE_NAME |
${CI_PROJECT_NAME} |
模块名称。不能包含任何空格或下划线。 |
TERRAFORM_MODULE_SYSTEM |
local |
您模块的目标系统或提供者。例如 local、aws 或 google。 |
TERRAFORM_MODULE_VERSION |
${CI_COMMIT_TAG} |
模块版本。应遵循 语义版本规范。 |
手动配置 CI/CD
要在 GitLab CI/CD 中使用 Terraform 模块,请在命令中使用 CI_JOB_TOKEN 替代个人访问令牌。
例如,此作业为 local 系统提供者 上传新模块,并使用 Git 提交标签中的模块版本:
stages:
- deploy
upload:
stage: deploy
image: curlimages/curl:latest
variables:
TERRAFORM_MODULE_DIR: ${CI_PROJECT_DIR} # Terraform 项目的根目录的相对路径。
TERRAFORM_MODULE_NAME: ${CI_PROJECT_NAME} # 您的 Terraform 模块名称,不能有任何空格或下划线(将转换为连字符)。
TERRAFORM_MODULE_SYSTEM: local # 您的 Terraform 模块的目标系统或提供者(例如 local、aws、google)。
TERRAFORM_MODULE_VERSION: ${CI_COMMIT_TAG} # 版本 - 建议遵循 SemVer 进行 Terraform 模块版本控制。
script:
- TERRAFORM_MODULE_NAME=$(echo "${TERRAFORM_MODULE_NAME}" | tr " _" -) # 模块名称不能有空格或下划线,因此将它们转换为连字符
- tar -vczf /tmp/${TERRAFORM_MODULE_NAME}-${TERRAFORM_MODULE_SYSTEM}-${TERRAFORM_MODULE_VERSION}.tgz -C ${TERRAFORM_MODULE_DIR} --exclude=./.git .
- 'curl --fail-with-body --location --header "JOB-TOKEN: ${CI_JOB_TOKEN}"
--upload-file /tmp/${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要触发此上传作业,请向您的提交添加 Git 标签。
确保标签遵循 Terraform 所需的 语义版本规范。
rules:if: $CI_COMMIT_TAG 确保
只有标记到您仓库的提交才会触发模块上传作业。
有关控制 CI/CD 管道中作业的其他方法,请参见 CI/CD YAML 语法参考。
模块解析工作流
当您上传新模块时,GitLab 会为该模块生成一个路径。例如:
https://gitlab.example.com/parent-group/my-infra-package
此路径符合 Terraform 模块注册表协议,其中:
gitlab.example.com是主机名。parent-group是 Terraform 模块注册表的唯一顶级 命名空间。my-infra-package是模块的名称。
如果不允许重复,模块名称和版本在 parent-group 下的所有组、子组和项目中必须是唯一的。否则,您将收到以下错误:
{"message":"命名空间中已存在同名模块。"}
如果允许重复,模块解析基于最近发布的模块。
例如,如果:
- 项目是
gitlab.example.com/parent-group/subgroup/my-project。 - Terraform 模块是
my-infra-package。 如果允许重复,my-infra-package是有效的模块。 如果不允许重复,模块名称在parent-group下的所有组中的所有项目中必须是唯一的。
当您命名模块时,请记住这些命名约定:
- 您的项目和组名称不能包含点(
.)。 例如,source = "gitlab.example.com/my.group/project.name"是无效的。 - 模块版本应遵循 语义版本规范。
允许重复的 Terraform 模块
默认情况下,Terraform 模块注册表强制在同一命名空间中模块名称的唯一性。
要允许发布重复的模块名称:
- 在左侧边栏,选择 搜索或转到 并找到您的组。
- 选择 设置 > 包和注册表。
- 在 重复包 表的 Terraform 模块 行中,关闭 允许重复 开关。
- 可选。在 例外 文本框中,输入与要允许的模块名称匹配的正则表达式。
您的更改将自动保存。
如果 允许重复 已开启,您可以在 例外 文本框中指定不应有重复的模块名称。
您还可以通过在 GraphQL API 中启用 terraform_module_duplicates_allowed 来允许发布重复名称。
要允许特定名称的重复:
- 确保
terraform_module_duplicates_allowed已禁用。 - 使用
terraform_module_duplicate_exception_regex定义您要允许重复的模块名称的正则表达式模式。
顶级命名空间设置优先于子命名空间设置。
例如,如果您为组启用 terraform_module_duplicates_allowed,并为子组禁用它,
则允许组及其子组中所有项目的重复。
有关模块解析的更多信息,请参见 模块解析工作流
查看 Terraform 模块
要在您的项目或组中查看 Terraform 模块:
- 在左侧边栏,选择 搜索或转到 并找到您的项目或组。
- 选择 操作 > Terraform 模块。
您可以在此页面上搜索、排序和过滤模块。
要查看模块的 README 文件:
- 从 Terraform 模块注册表 页面,选择一个 Terraform 模块。
- 选择
README。
引用 Terraform 模块
从组或项目引用模块。
从命名空间
您可以为 terraform 在环境变量中提供认证令牌(作业令牌、个人访问令牌或部署令牌)。
您应该为环境变量名添加 TF_TOKEN_ 前缀,并将点编码为下划线。
更多信息,请参见 环境变量凭据。
例如,名为 TF_TOKEN_gitlab_com 的变量的值,当 CLI 向主机名 gitlab.com 发送服务请求时,将用作部署令牌:
export TF_TOKEN_gitlab_com='glpat-<deploy_token>'此方法适用于企业实现。对于本地或临时环境,
您可能需要创建一个 ~/.terraformrc 或 %APPDATA%/terraform.rc 文件:
credentials "<gitlab.com>" {
token = "<TOKEN>"
}其中 gitlab.com 可以替换为您 GitLab 自托管实例的主机名。
然后您可以从下游 Terraform 项目引用您的 Terraform 模块:
module "<module>" {
source = "gitlab.com/<namespace>/<module-name>/<module-system>"
}从项目
要使用项目源引用 Terraform 模块, 使用 Terraform 提供的 通过 HTTP 获取归档 源类型。
您可以在 ~/.netrc 文件中为 terraform 提供认证令牌(作业令牌、个人访问令牌或部署令牌):
machine <gitlab.com>
login <USERNAME>
password <TOKEN>其中 gitlab.com 可以替换为您 GitLab 自托管实例的主机名,
<USERNAME> 是您的令牌用户名。
您可以从下游 Terraform 项目引用您的 Terraform 模块:
module "<module>" {
source = "https://gitlab.com/api/v4/projects/<project-id>/packages/terraform/modules/<module-name>/<module-system>/<module-version>"
}如果需要引用模块的最新版本,可以从源 URL 中省略 <module-version>。为防止未来出现问题,如果可能,应引用特定版本。
如果同一命名空间中存在重复的模块名称,从命名空间级别引用模块将安装最近发布的模块。要引用重复模块的特定版本,请使用项目级源类型。
下载 Terraform 模块
要下载 Terraform 模块:
- 在左侧边栏,选择 操作 > Terraform 模块。
- 选择您要下载的模块的名称。
- 从 资源 表中,选择您要下载的模块。
删除 Terraform 模块
在 Terraform 模块注册表中发布 Terraform 模块后,您无法编辑它。相反, 您必须删除并重新创建它。
您可以使用 packages API 或 UI 删除模块。
要在 UI 中删除模块,从您的项目:
- 在左侧边栏,选择 操作 > Terraform 模块。
- 找到您要删除的包的名称。
- 选择 删除。
该包将被永久删除。
禁用 Terraform 模块注册表
Terraform 模块注册表默认启用。
对于 GitLab 自托管实例,GitLab 管理员可以 禁用 包和注册表, 这会从侧边栏中删除此菜单项。
您还可以为特定项目移除 Terraform 模块注册表:
- 在您的项目中,转到 设置 > 常规。
- 展开 可见性、项目功能、权限 部分,并关闭 包。
- 选择 保存更改。
示例项目
有关 Terraform 模块注册表的示例,请查看以下项目:
- _GitLab 本地文件_项目 创建了一个最小的 Terraform 模块,并使用 GitLab CI/CD 将其上传到 Terraform 模块注册表。
- _Terraform 模块测试_项目 使用了前一个示例中的模块。