Gitlab 作为 Terraform 状态管理,其 HTTP 后端不使用项目凭据?

Gitlab 作为 Terraform 状态管理,其 HTTP 后端不使用项目凭据?

我一直在努力让 Terraform 的 monorepo 启动并运行。Terraform 在容器内执行。但是,当我尝试init指向我自己托管的 Gitlab 的 http 后端时,它显示需要身份验证:

Successfully configured the backend "http"! Terraform will automatically
use this backend unless the backend configuration changes.
2021-04-15T13:02:00.815Z [TRACE] Meta.Backend: instantiated backend of type *http.Backend
2021-04-15T13:02:00.815Z [DEBUG] checking for provisioner in "."
2021-04-15T13:02:00.815Z [DEBUG] checking for provisioner in "/bin"
2021-04-15T13:02:00.815Z [INFO]  Failed to read plugin lock file .terraform/plugins/linux_amd64/lock.json: open .terraform/plugins/linux_amd64/lock.json: no such file or directory
2021-04-15T13:02:00.815Z [TRACE] Meta.Backend: backend *http.Backend does not support operations, so wrapping it in a local backend
2021/04/15 13:02:00 [DEBUG] GET https://gitlab.my_domain.tld/api/v4/projects/2/terraform/state/infrastructure
Error refreshing state: HTTP remote state endpoint requires auth

我已经确认我的项目令牌确实有效,方法是使用具有 API 访问权限的令牌对项目进行 curl:

bash-5.1# curl -k -I "https://gitlab.my_domain.tld/api/v4/projects?<my_token_id>"
HTTP/2 200 
server: nginx
date: Wed, 14 Apr 2021 23:59:43 GMT
content-type: application/json
vary: Accept-Encoding
cache-control: no-cache
link: <https://gitlab.my_domain.tld/api/v4/projects?<my_token_id>=&membership=false&order_by=created_at&owned=false&page=1&per_page=20&repository_checksum_failed=false&simple=false&sort=desc&starred=false&statistics=false&wiki_checksum_failed=false&with_custom_attributes=false&with_issues_enabled=false&with_merge_requests_enabled=false>; rel="first", <https://gitlab.my_domain.tld/api/v4/projects?<my_project_token>=&membership=false&order_by=created_at&owned=false&page=1&per_page=20&repository_checksum_failed=false&simple=false&sort=desc&starred=false&statistics=false&wiki_checksum_failed=false&with_custom_attributes=false&with_issues_enabled=false&with_merge_requests_enabled=false>; rel="last"
vary: Origin
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
x-gitlab-feature-category: projects
x-next-page:
x-page: 1
x-per-page: 20
x-prev-page:
x-request-id: 01F39D73G8ZXPJ1E1ZAK0ZS860
x-runtime: 0.184197
x-total: 1
x-total-pages: 1
strict-transport-security: max-age=31536000
referrer-policy: strict-origin-when-cross-origin

bash-5.1# 

凭证不会通过后端传递-backend-config,也不会直接放入backend.tfvars我拥有的文件中:

后端.tf:

terraform {
    backend "http" { }
}

后端.tfvars:

lock_method = "POST" 
unlock_method = "DELETE" 
retry_max = "3" 
skip_cert_verification = true

我已经通过导出确认了 和 的值TF_HTTP_USERNAMETF_HTTP_PASSWORD在环境变量中设置。天哪,我甚至将它们设置为全局变量:

declare -x TERRAFORM_VERSION="0.15.0"
declare -x TF_HTTP_PASSWORD="[MASKED]"
declare -x TF_HTTP_USERNAME="project_2_bot"
declare -x TF_LOG="trace"
declare -x TF_PASSWORD="[MASKED]"
declare -x TF_USERNAME="project_2_bot"
declare -x bot_2_token="[MASKED]"

我检查了 Gitlab 日志中的 api_json.json,看到有请求进来,但是 INFO 没有告诉我太多信息,只是有一次尝试进来:

{
  "time": "2021-04-15T13:02:00.924Z",
  "severity": "INFO",
  "duration_s": 0.00915,
  "db_duration_s": 0.00207,
  "view_duration_s": 0.00708,
  "status": 401,
  "method": "GET",
  "path": "/api/v4/projects/2/terraform/state/infrastructure",
  "params": [],
  "host": "gitlab.my_domain.tld",
  "remote_ip": "10.4.6.95, 127.0.0.1",
  "ua": "Go-http-client/1.1",
  "route": "/api/:version/projects/:id/terraform/state/:name",
  "queue_duration_s": 0.011228,
  "db_count": 2,
  "db_write_count": 0,
  "db_cached_count": 1,
  "cpu_s": 0.017418,
  "mem_objects": 10346,
  "mem_bytes": 423664,
  "mem_mallocs": 1771,
  "correlation_id": "01F3ASZH67FMVS0449NC289C47",
  "meta.caller_id": "/api/:version/projects/:id/terraform/state/:name",
  "meta.remote_ip": "10.4.6.95",
  "meta.feature_category": "infrastructure_as_code",
  "meta.client_id": "ip/10.4.6.95"
}

我正在尝试找出如何增加日志级别来捕获 API 传入的所有事件,但到目前为止还没有任何进展。

每次我尝试对后端运行命令时,它都会返回以下内容:

Error refreshing state: HTTP remote state endpoint requires auth

我尝试过 Terraform 版本 0.14.x(不记得最新版本是什么)和 0.15

我已经没有其他办法了。有人遇到过这种情况吗?或者能提供一些进一步排除故障的方法吗?

答案1

好的,我认为这对于任何关注或在后续搜索中找到此内容的观众来说都很重要。

因此,存在两个问题:

我认为 Terraform 和自签名证书行为存在问题(这甚至可能是下面的 go 代码)。因为即使我告诉它不检查证书,它仍然会报告一个非常奇怪的错误,即证书使用的是通用名称,而不是 SAN 值。但这是另一个问题的征兆。

我的实际问题是,我认为 Gitlab 文档是错误的。

因此根据 gitlab 文档这里在步骤 4 中说:

4. Create a Personal Access Token with the api scope.

其中,我没有使用需要许可证席位数量的个人访问令牌,而是创建了一个项目代币

此令牌是项目本地的,用户名是

project_$(project_id)_bot#

在我的例子中,它是 project_2_bot(因为是第一个,所以没有数字,真笨)

根据文档,它说令牌需要 API 访问权限才能命中 API。

我认为文档是错误的。我创建的令牌只有 API 访问权限,但一直失败。一旦我赋予它更多访问权限(API、对容器、注册表、存储库的读/写),它实际上就通过了。

相关内容