Terraform 模块仓库

  • Tier: 基础版, 专业版, 旗舰版
  • Offering: JihuLab.com, 私有化部署
History
    • 在极狐GitLab 15.11 中,基础设施仓库和 Terraform 模块仓库合并为一个 Terraform 模块仓库功能。
    • 对于群组的支持引入于极狐GitLab 16.9。

使用 Terraform 模块仓库时,您可以将极狐GitLab 项目作为私有仓库,用于 terraform 模块。您可以使用极狐GitLab CI/CD 创建和发布模块,然后可以从其他私有项目中使用这些模块。

查看 Terraform 模块#

History
    • 对于 README 文件的支持引入于极狐GitLab 17.2。

要查看项目或群组中的 Terraform 模块:

  1. 在左侧边栏,选择 搜索或转到 并找到您的项目或群组。
  2. 选择 运维 > Terraform 模块

您可以在此页面上搜索、排序和过滤模块。

您还可以通过选择一个模块,然后选择 Readme 来查看模块的 Readme 文件。

认证到 Terraform 模块仓库#

要认证到 Terraform 模块仓库,您需要以下之一:

不要使用此处未记录的方法进行认证。未记录的认证方法可能会在未来被移除。

发布 Terraform 模块#

当您发布 Terraform 模块时,如果模块不存在,则会创建它。

使用 API#

您可以使用 Terraform 模块仓库 API 发布 Terraform 模块。

前提条件:

  • 除非允许重复,否则模块名称必须在顶级命名空间中是唯一的。否则,会发生错误
  • 模块名称和版本在项目中必须是唯一的。
  • 项目和群组名称中不能包含点 (.)。例如,source = "gitlab.example.com/my.group/project.name"
  • 您必须使用 API 认证。如果使用部署密钥进行认证,必须配置 write_package_registry 范围。
plaintext
PUT /projects/:id/packages/terraform/modules/:module-name/:module-system/:module-version/file
属性类型必需描述
idinteger/string项目的 ID 或 URL 编码的项目路径
module-namestring模块名称。支持的语法:1 到 64 个 ASCII 字符,包括小写字母 (a-z) 和数字 (0-9)。模块名称不能超过 64 个字符。
module-systemstring模块系统。支持的语法:1 到 64 个 ASCII 字符,包括小写字母 (a-z) 和数字 (0-9)。模块系统不能超过 64 个字符。
module-versionstring模块版本。必须符合语义版本规范。

在请求体中提供文件内容。

如下示例所示,请求必须以 /file 结尾。如果您发送的请求以其他内容结尾,将导致 404 错误 {"error":"404 Not Found"}

使用个人访问密钥的示例请求:

shell
curl --fail-with-body --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"

使用部署密钥的示例请求:

shell
curl --fail-with-body --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"

示例响应:

json
{ "message":"201 Created" }

使用 CI/CD 模板(推荐)#

History
    • 引入于极狐GitLab 15.9。

您可以使用 Terraform-Module.gitlab-ci.yml 或高级 Terraform/Module-Base.gitlab-ci.yml CI/CD 模板将 Terraform 模块发布到极狐GitLab terraform 仓库:

yaml
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 模块的名称。不得包含空格或下划线。
TERRAFORM_MODULE_SYSTEMlocal您的 Terraform 模块目标的系统或提供者。例如,localawsgoogle
TERRAFORM_MODULE_VERSION${CI_COMMIT_TAG}Terraform 模块版本。您应该遵循语义版本规范。

手动使用 CI/CD#

要在极狐GitLab CI/CD中使用 Terraform 模块,您可以在命令中使用 CI_JOB_TOKEN 代替个人访问密钥。

例如,这个作业为 local 系统提供者上传了一个新模块,并使用 Git 提交标签中的模块版本:

yaml
1stages: 2 - deploy 3 4upload: 5 stage: deploy 6 image: curlimages/curl:latest 7 variables: 8 TERRAFORM_MODULE_DIR: ${CI_PROJECT_DIR} # Terraform 项目根目录的相对路径。 9 TERRAFORM_MODULE_NAME: ${CI_PROJECT_NAME} # Terraform 模块的名称,不得有任何空格或下划线(将被转换为连字符)。 10 TERRAFORM_MODULE_SYSTEM: local # 您的 Terraform 模块目标的系统或提供者(例如 local, aws, google)。 11 TERRAFORM_MODULE_VERSION: ${CI_COMMIT_TAG} # 版本 - 推荐遵循 SemVer 进行 Terraform 模块版本管理。 12 script: 13 - TERRAFORM_MODULE_NAME=$(echo "${TERRAFORM_MODULE_NAME}" | tr " _" -) # 模块名称不得有空格或下划线,因此将它们转换为连字符 14 - tar -vczf /tmp/${TERRAFORM_MODULE_NAME}-${TERRAFORM_MODULE_SYSTEM}-${TERRAFORM_MODULE_VERSION}.tgz -C ${TERRAFORM_MODULE_DIR} --exclude=./.git . 15 - 'curl --fail-with-body --location --header "JOB-TOKEN: ${CI_JOB_TOKEN}" 16 --upload-file /tmp/${TERRAFORM_MODULE_NAME}-${TERRAFORM_MODULE_SYSTEM}-${TERRAFORM_MODULE_VERSION}.tgz 17 ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/terraform/modules/${TERRAFORM_MODULE_NAME}/${TERRAFORM_MODULE_SYSTEM}/${TERRAFORM_MODULE_VERSION}/file' 18 rules: 19 - if: $CI_COMMIT_TAG

要触发此上传作业,请为您的提交添加一个 Git 标签。确保标签符合 Terraform 所需的语义版本规范rules:if: $CI_COMMIT_TAG 确保只有标记的提交会触发模块上传作业。 有关其他控制 CI/CD 流水线中的作业的方法,请参阅 CI/CD YAML 语法参考

允许重复的 Terraform 模块#

History
    • 引入于极狐GitLab 16.8。
    • 在极狐GitLab 17.0 中,所需的最小角色从维护者更改为所有者。

默认情况下,Terraform 模块仓库在同一命名空间中强制模块名称唯一。

要允许发布重复的模块名称:

  1. 在左侧边栏,选择 搜索或转到 并找到您的群组。
  2. 选择 设置 > 软件包和仓库
  3. 复制软件包 表中的 Terraform 模块 行中,关闭 允许复制 切换。
  4. 可选。在 例外 文本框中输入匹配允许的模块名称的正则表达式。

您的更改会自动保存。

如果启用了 允许复制,您可以在 例外 文本框中指定不应有重复的模块名称。

您还可以通过在 GraphQL API 中启用 terraform_module_duplicates_allowed 来允许发布重复名称。

要允许具有特定名称的重复:

  1. 确保禁用 terraform_module_duplicates_allowed
  2. 使用 terraform_module_duplicate_exception_regex 定义您想要允许重复的模块名称的正则表达式模式。

顶级命名空间设置优先于子命名空间设置。 例如,如果您为群组启用 terraform_module_duplicates_allowed,并为子群组禁用它,则允许群组及其子群组中的所有项目重复。

引用 Terraform 模块#

前提条件:

  • 您需要使用 API 认证。如果使用个人访问密钥进行认证,必须配置 read_api 范围。

从命名空间#

您可以为 terraform 在环境变量中提供认证密钥(作业密钥、个人访问密钥或部署密钥)。

您应该在环境变量的域名之前添加前缀 TF_TOKEN_,将点编码为下划线。

例如,一个名为 TF_TOKEN_gitlab_com 的变量的值在 CLI 向主机名 gitlab.com 发出服务请求时用作部署密钥:

shell
export TF_TOKEN_gitlab_com='glpat-<deploy_token>'

这种方法是企业实施的首选。对于本地或临时环境,您可能希望创建 ~/.terraformrc%APPDATA%/terraform.rc 文件:

terraform
credentials "gitlab.com" { token = "<TOKEN>" }

其中 gitlab.com 可以替换为极狐GitLab 私有化部署的主机名。

然后,您可以从下游 Terraform 项目中引用您的 Terraform 模块:

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

其中 <namespace> 是 Terraform 模块仓库的命名空间

从项目#

您可以在 ~/.netrc 文件中为 terraform 提供认证密钥(作业密钥、个人访问密钥或部署密钥):

plaintext
machine gitlab.com login <USERNAME> password <TOKEN>

其中 gitlab.com 可以替换为极狐GitLab 私有化部署的主机名,<USERNAME> 是您的密钥用户名。

您可以从下游 Terraform 项目中引用您的 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 模块:

  1. 在左侧边栏,选择 运维 > Terraform 模块
  2. 选择您要下载的模块名称。
  3. 活动 部分,选择您要下载的模块名称。

模块解析如何工作#

当您上传新模块时,极狐GitLab 会为模块生成一个路径,例如 https://gitlab.example.com/parent-group/my-infra-package

  • 此路径符合 Terraform 规范。
  • 路径名称在命名空间中必须是唯一的。

对于子群组中的项目,如果不允许重复,极狐GitLab 会检查模块名称是否已存在于命名空间中的任何位置,包括所有子群组和父群组。

例如,如果:

  • 项目是 gitlab.example.com/parent-group/subgroup/my-project
  • Terraform 模块是 my-infra-package

模块名称在 parent-group 下的所有群组中的所有项目中必须是唯一的。如果允许重复,模块解析基于最近发布的模块。

删除 Terraform 模块#

您无法在 Terraform 模块仓库中发布后编辑 Terraform 模块。相反,您必须删除并重新创建它。

要删除模块,您必须拥有适当的权限

您可以使用软件包 API或 UI 删除模块。

要在 UI 中删除模块,请从您的项目中:

  1. 在左侧边栏,选择 Operate > Terraform modules
  2. 找到您要删除的软件包名称。
  3. 选择 Delete

软件包被永久删除。

禁用 Terraform 模块仓库#

Terraform 模块仓库是自动启用的。

对于极狐GitLab 私有化部署实例,极狐GitLab 管理员可以禁用 软件包和仓库,这会从侧边栏中移除此菜单项。

您还可以为特定项目移除 Terraform 模块仓库:

  1. 在您的项目中,转到 设置 > 通用
  2. 展开 可见性、项目功能、权限 部分并关闭 软件包(灰色)。
  3. 选择 保存变更

要重新启用它,请按照上述步骤操作并将其打开(蓝色)。

故障排除#

  • 使用重复名称发布模块会导致 {"message":"A module with the same name already exists in the namespace."} 错误。