You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GitLab CI/CD无JSON密钥连GCP,Terraform远程状态报403权限错误

问题根源

GitLab CI的每个Job都是独立运行在各自的容器环境中,彼此之间不会共享文件系统或认证状态。你在gcp-auth任务里完成的GCP认证,只会在该任务的容器内生效,不会自动传递到tf-stuff任务中,这就是Terraform初始化时触发403权限错误的原因。

解决方案

下面提供几种可落地的解决方式:

方法1:传递认证凭证作为Artifact

修改gcp-auth任务,将生成的认证凭证文件标记为Artifact,让后续任务可以下载使用:

gcp-auth:
  stage: auth
  image: google/cloud-sdk:slim
  script:
    - echo ${CI_JOB_JWT_V2} > .ci_job_jwt_file
    - gcloud iam workload-identity-pools create-cred-config ${GCP_WORKLOAD_IDENTITY_PROVIDER}
      --service-account="${GCP_SERVICE_ACCOUNT}"
      --output-file=.gcp_temp_cred.json
      --credential-source-file=.ci_job_jwt_file
    - gcloud auth login --cred-file=`pwd`/.gcp_temp_cred.json
    - gcloud auth list
    - gsutil cp test-file gs://your-state-bucket/ # 验证权限
  artifacts:
    paths:
      - .gcp_temp_cred.json
    expire_in: 1h # 缩短凭证有效期,降低安全风险

接着修改tf-stuff任务,加载凭证文件并设置Terraform能识别的环境变量:

tf-stuff:
  stage: validate
  image:
    name: hashicorp/terraform:light
    entrypoint:
      - '/usr/bin/env'
      - 'PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'
  before_script:
    - export TF_LOG=DEBUG
    - cd terraform
    - rm -rf .terraform
    - terraform --version
    # 设置GCP认证环境变量,让Terraform使用该凭证
    - export GOOGLE_APPLICATION_CREDENTIALS="../.gcp_temp_cred.json"
    - terraform init
  script:
    - terraform validate

方法2:在tf-stuff任务内直接完成认证

既然每个Job独立,直接在tf-stuff里完成Workload Identity认证,省去文件传递步骤:

tf-stuff:
  stage: validate
  image:
    name: hashicorp/terraform:light
    entrypoint:
      - '/usr/bin/env'
      - 'PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'
  before_script:
    - export TF_LOG=DEBUG
    # 安装gcloud SDK(terraform镜像默认不带)
    - apt-get update && apt-get install -y curl gnupg
    - echo "deb [signed-by=/usr/share/keyrings/cloud.google.gpg] https://packages.cloud.google.com/apt cloud-sdk main" | tee -a /etc/apt/sources.list.d/google-cloud-sdk.list
    - curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key --keyring /usr/share/keyrings/cloud.google.gpg add -
    - apt-get update && apt-get install -y google-cloud-sdk
    # 执行Workload Identity认证流程
    - echo ${CI_JOB_JWT_V2} > .ci_job_jwt_file
    - gcloud iam workload-identity-pools create-cred-config ${GCP_WORKLOAD_IDENTITY_PROVIDER}
      --service-account="${GCP_SERVICE_ACCOUNT}"
      --output-file=.gcp_temp_cred.json
      --credential-source-file=.ci_job_jwt_file
    - export GOOGLE_APPLICATION_CREDENTIALS=".gcp_temp_cred.json"
    - cd terraform
    - rm -rf .terraform
    - terraform --version
    - terraform init
  script:
    - terraform validate

方法3:直接传递临时访问令牌(推荐)

不用生成凭证文件,直接获取临时访问令牌传递给Terraform:

tf-stuff:
  stage: validate
  image:
    name: hashicorp/terraform:light
    entrypoint:
      - '/usr/bin/env'
      - 'PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'
  before_script:
    - export TF_LOG=DEBUG
    # 安装gcloud SDK
    - apt-get update && apt-get install -y curl gnupg
    - echo "deb [signed-by=/usr/share/keyrings/cloud.google.gpg] https://packages.cloud.google.com/apt cloud-sdk main" | tee -a /etc/apt/sources.list.d/google-cloud-sdk.list
    - curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key --keyring /usr/share/keyrings/cloud.google.gpg add -
    - apt-get update && apt-get install -y google-cloud-sdk
    # 生成认证配置并获取临时访问令牌
    - echo ${CI_JOB_JWT_V2} > .ci_job_jwt_file
    - gcloud iam workload-identity-pools create-cred-config ${GCP_WORKLOAD_IDENTITY_PROVIDER}
      --service-account="${GCP_SERVICE_ACCOUNT}"
      --output-file=.gcp_temp_cred.json
      --credential-source-file=.ci_job_jwt_file
    - export GOOGLE_OAUTH_ACCESS_TOKEN=$(gcloud auth print-access-token --cred-file=.gcp_temp_cred.json)
    - cd terraform
    - rm -rf .terraform
    - terraform --version
    - terraform init
  script:
    - terraform validate
额外检查项
  • 确认GCP_SERVICE_ACCOUNT拥有目标GCS存储桶的roles/storage.objectAdmin或roles/storage.admin权限,确保能读写Terraform状态文件。
  • 检查Terraform的backend配置是否正确指向存储桶,示例配置:
terraform {
  backend "gcs" {
    bucket = "your-terraform-state-bucket"
    prefix = "terraform/state"
  }
}

内容的提问来源于stack exchange,提问作者Gary Turner

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 06:45:32