Help us learn about your current experience with the documentation. Take the survey.

GitLab 与 Terraform 集成的故障排除

当你使用 GitLab 与 Terraform 的集成时,可能会遇到需要排查的问题。

刷新子组状态时未检测到 gitlab_group_share_group 资源

由于 “User with permissions cannot retrieve share_with_groups from the API” 的问题,GitLab Terraform 提供程序可能无法检测到现有的 gitlab_group_share_group 资源。这会导致运行 terraform apply 时出错,因为 Terraform 尝试重新创建已存在的资源。

例如,考虑以下组/子组配置:

parent-group
├── subgroup-A
└── subgroup-B

其中:

  • 用户 user-1 创建了 parent-groupsubgroup-Asubgroup-B
  • subgroup-Asubgroup-B 共享。
  • 用户 terraform-userparent-group 的成员,对两个子组都继承拥有 owner 访问权限。

当 Terraform 状态刷新时,提供程序发出的 API 查询 GET /groups/:subgroup-A_id 不会在 shared_with_groups 数组中返回 subgroup-B 的详细信息。这会导致错误。

要解决此问题,请确保应用以下条件之一:

  1. terraform-user 创建所有子组资源。
  2. subgroup-B 上为 terraform-user 用户授予 Maintainer 或 Owner 角色。
  3. terraform-user 继承对 subgroup-B 的访问权限,且 subgroup-B 包含至少一个项目。

Terraform 状态故障排除

无法使用先前作业的计划在 CI 作业中锁定 Terraform 状态文件以进行 terraform apply

当将 -backend-config= 传递给 terraform init 时,Terraform 会将这些值持久化到计划缓存文件中。这包括 password 值。

因此,要创建计划并在另一个 CI 作业中使用相同的计划,在使用 -backend-config=password=$CI_JOB_TOKEN 时可能会收到 Error: Error acquiring the state lock 错误。这是因为 $CI_JOB_TOKEN 的值仅在当前作业期间有效。

作为替代方案,在 CI 作业中使用 http backend configuration variables,这是遵循 Get started using GitLab CI 说明时后台发生的情况。

错误:“address”:必需字段未设置

默认情况下,我们将 TF_ADDRESS 设置为 ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/terraform/state/${TF_STATE_NAME}。如果在作业中没有设置 TF_STATE_NAMETF_ADDRESS,作业会失败并显示错误消息 Error: "address": required field is not set

要解决此问题,确保在返回错误的作业中可以访问 TF_ADDRESSTF_STATE_NAME

  1. 为作业配置 CI/CD environment scope
  2. 设置作业的 environment,与上一步的环境范围相匹配。

错误:刷新状态时,HTTP 远程状态端点需要身份验证

要解决此问题,请确保:

  • 你使用的访问令牌具有 api 范围。
  • 如果设置了 TF_HTTP_PASSWORD CI/CD 变量,请确保你:
    • 设置与 TF_PASSWORD 相同的值
    • 如果你的 CI/CD 作业不明确使用 TF_HTTP_PASSWORD,请删除该变量

启用 Developer 角色对破坏性命令的访问权限

要允许具有 Developer 角色的用户运行破坏性命令,你需要一个替代方案:

  1. 创建具有 api 范围的项目访问令牌
  2. TF_USERNAMETF_PASSWORD 添加到你的 CI/CD 变量中:
    1. TF_USERNAME 的值设置为你项目访问令牌的用户名。
    2. TF_PASSWORD 的值设置为你项目访问令牌的密码。
    3. 可选。保护这些变量,使它们仅在受保护分支或受保护标签上运行的管道中可用。

如果状态名称包含句点,则找不到状态

GitLab 15.6 及更早版本,如果状态名称包含句点且 Terraform 尝试锁定状态,会返回 404 错误。

你可以通过在 Terraform 命令中添加 -lock=false 来解决此限制。GitLab 后端接受请求,但内部会从状态名称中删除句点及其后的任何字符。例如,名为 foo.bar 的状态会被存储为 foo。但是,不建议使用此替代方案,甚至可能导致状态名称冲突。

在 GitLab 15.7 及更高版本中,支持包含句点的状态名称。如果你使用 -lock=false 替代方案并升级到 GitLab 15.7 或更高版本,你的作业可能会失败。失败的原因是 GitLab 后端使用完整的状态名称存储新状态,这与现有状态名称不一致。

要修复失败的作业,请重命名你的状态名称,排除句点及其后的任何字符。

如果设置了你的 TF_HTTP_ADDRESSTF_HTTP_LOCK_ADDRESSTF_HTTP_UNLOCK_ADDRESS,请确保更新那里的状态名称。

或者,你可以 迁移你的 OpenTofu 状态

错误:保存状态时出现 HTTP 错误:404

如果状态名称包含正斜杠 (/) 字符,可能会发生此错误。要解决此问题,请确保状态名称不包含任何正斜杠 (/) 字符。