如何使用极狐GitLab 软件包仓库功能托管 terraform?

极狐GitLab 是 GitLab 在中国的发行版,关于中文参考文档和资料有:

Terraform 模块库 (BASIC ALL)


  • 基础设施仓库和 Terraform 模块仓库合并到单个 Terraform 模块仓库功能引入于极狐GitLab 15.11。
  • 对于群组的支持引入于极狐GitLab 16.9。

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

查看 Terraform 模块


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

查看项目中的 Terraform 模块:

1.进入项目。

2.在左侧边栏中,选择 软件包和镜像库 > Terraform 模块

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

有关如何创建和上传软件包的信息,请查看适用于您的软件包类型的极狐GitLab 文档:

Terraform 模块库身份验证


要对 Terraform 模块库进行身份验证,您需要:

  • 至少具有 read_api 权限的个人访问令牌。

  • CI/CD 作业令牌。

  • 一个具有 read_package_registry 或/和 write_package_registry 范围的部署令牌。

不要使用此处记录的方法以外的身份验证方法。将来可能会删除未记录的身份验证方法。

发布 Terraform 模块


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

先决条件:

  • 顶级命名空间中必须不存在具有相同名称和版本的包。
  • 您的项目和组名称不得包含点 (.)。例如,source = "gitlab.example.com/my.group/project.name"
  • 您必须使用 API 进行身份验证。如果使用部署令牌进行身份验证,则必须使用 write_package_registry 范围进行配置。
  • 除非允许重复的 Terraform 模块,否则模块名称必须在其群组的范围内是唯一的,否则会发生错误。
clike 复制代码
PUT /projects/:id/packages/terraform/modules/:module-name/:module-system/:module-version/file
属性 类型 是否必需 描述
id integer/string yes ID 或项目的 URL 编码路径。
module-name string yes 模块名称。支持的语法:1 到 64 个 ASCII 字符,包括小写字母 (a-z)、数字 (0-9) 和连字符 (-)。
module-system string yes 模块系统。支持的语法:1 到 64 个 ASCII 字符,包括小写字母 (a-z)、数字 (0-9) 和连字符 (-)。查看更多信息:Terraform Module Registry Protocol documentation。
module-version string yes 模块版本。根据语义版本规范,它必须是有效的。

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

请注意,在以下示例中,请求必须以 /file 结尾。

如果您发送以其他内容结尾的请求,则会导致 404 错误 {"error":"404 Not Found"}

使用个人访问令牌的示例请求:

clike 复制代码
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"

使用部署令牌的示例请求:

clike 复制代码
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"

示例响应:

clike 复制代码
{
  "message":"201 Created"
}

使用 CI/CD 模板(推荐)

  • 引入于 15.9 版本。

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

clike 复制代码
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_SYSTEM local Terraform 模块目标的系统或提供者。例如,localawsgoogle
TERRAFORM_MODULE_VERSION ${CI_COMMIT_TAG} Terraform 模块版本。您应该遵循语义版本控制规范。

手动使用 CI/CD


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

例如:

clike 复制代码
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

要触发此上传作业,请将 Git 标签添加到您的提交中。rules:if: $CI_COMMIT_TAG 定义这一点,因此不是每次提交到您的仓库都会触发上传。有关在 CI/CD 流水线中控制作业的其他方法,请参阅 .gitlab-ci.yml 关键字参考。

允许重复的 terraform 模块

  • 引入于极狐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 范围进行配置。

从命名空间中

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

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

比如,当 CLI 向 jihulab.com 发送服务请求时,使用名为 TF_TOKEN_jihulab_com 的变量的值作为部署令牌。

clike 复制代码
export TF_TOKEN_gitlab_com='glpat-<deploy_token>'

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

clike 复制代码
credentials "jihulab.com" {
  token = "<TOKEN>"
}

将其中的 jihulab.com 替换为您私有化部署实例的主机名。

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

clike 复制代码
module "<module>" {
  source = "jihulab.com/<namespace>/<module-name>/<module-system>"
}

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

从项目中

要引用一个使用项目级别资源的 Terraform 模块,您可以使用 Terraform 提供的 通过 HTTP 获取归档 源类型。

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

clike 复制代码
machine jihulab.com
login <USERNAME>
password <TOKEN>

其中,jihulab.com 可以替换为私有化部署实例的主机名,<USERNAME> 是您的令牌用户名。

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

clike 复制代码
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/sub-group/my-project
  • Terraform 模块为 my-infra-package

项目名称在 parent-group 下所有群组的所有项目中必须是唯一的。

删除 Terraform 模块


在 Terraform 模块库中发布 Terraform 模块后,您将无法对其进行编辑,您必须删除并重新创建它。

要删除模块,您必须具有合适的权限。

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

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

1.在左侧边栏中,选择 软件包与镜像库 > Terraform 模块。

2.找到要删除的软件包的名称。

3.选择 删除

软件包被永久删除。

禁用 Terraform 模块库


Terraform 模块库自动启用。

对于私有化部署实例,极狐GitLab 管理员可以禁用 软件包与镜像库,系统会从侧边栏中删除此菜单项。

您还可以删除特定项目的 Terraform 模块库:

1.在您的项目中,转到 设置 > 通用

2.展开 可视化、项目功能和权限 部分并关闭 软件包(灰色)

3.选择 保存更改

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

故障排查


  • 发布具有重复名称的模块时,您可能会遇到 {"message":"A module with the same name already exists in the namespace."} 错误。
相关推荐
色空大师11 分钟前
【网站搭建实操(一)环境部署】
java·linux·数据库·mysql·网站搭建
江南风月39 分钟前
日志审计系统WGLOG支持syslog吗
运维·网络·日志审计
A.A呐1 小时前
【Linux第十三章】缓冲区
linux·服务器
吴声子夜歌2 小时前
TypeScript——泛型
前端·git·typescript
想唱rap2 小时前
Linux线程
java·linux·运维·服务器·开发语言·mysql
JFSJFX2 小时前
手机短信误删怎么办?这4种恢复办法亲测有效,轻松找回短信
运维·服务器
春日见2 小时前
3三分彻底了解Git Graph极其应用
git
yuzhuanhei2 小时前
docker常用命令
运维·docker·容器
無名路人2 小时前
Zsh 脚本 + VS Code 任务:NestJS + Vue3 一键部署到 1Panel
运维·后端·自动化运维
anarckk2 小时前
docker volume 导入导出命令
运维·docker·容器