403试图在没有json文件的情况下从Gitlab运行terrform



经过一堆故障排除后,我设法让我的gitlab CICD管道连接到GCP,而不需要我的服务帐户使用JSON密钥。但是,由于以下错误,我无法使用远程状态文件对管道中的Terraform做任何事情:

Error: Failed to get existing workspaces: querying Cloud Storage failed: googleapi: Error 403: Insufficient Permission, insufficientPermissions

我gitlab-ci。Yml文件定义如下:

stages:
- auth
- validate
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
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
- terraform init
script:
- terraform validate

我的gcp-auth作业从我所看到的运行成功:

Authenticated with external account credentials for: [[MASKED]].

我还在gcp-auth作业中添加了gsutil cp命令,以确保我可以按预期访问所需的桶,我可以。我可以成功地编辑存储我的地形状态文件的桶的内容。

我对gitlab CICD管道相当陌生。我需要做些什么才能将gcp-auth工作绑定到tf-stuff工作?这就像该作业不知道管道先前使用服务帐户进行了身份验证。

谢谢!

就像其他海报提到的那样,gitlab作业独立运行,不共享环境变量或文件系统。因此,为了在作业之间保持登录状态,您必须以某种方式保持状态。

我写了一篇博客,其中有一个工作示例:https://ael-computas.medium.com/gcp-workload-identity-federation-on-gitlab-passing-authentication-between-jobs-ffaa2d51be2c

我已经做到了,就像github的行动是这样做的,通过存储(tmp)凭证作为工件。通过设置正确的环境变量,您应该能够"保持"登录状态(gcp将隐式刷新您的令牌),而无需创建包含所有内容的基本映像。所有作业都必须运行gcp_auth_before方法,或者扩展验证作业以使其工作。并且在作业之间保留_auth/artifacts

在下面的示例中,您可以看到在两个作业中保留了登录状态,但只有在第一个作业中实际登录。我已经将它与地形图像一起使用了进一步的步骤,到目前为止,它的工作就像一个魅力。

这是非常早期的,因此可能需要在生产中进行硬化。

希望这个例子能给你一些如何解决这个问题的想法!

.gcp_auth_before: &gcp_auth_before
- export GOOGLE_APPLICATION_CREDENTIALS=$CI_PROJECT_DIR/_auth/.gcp_temp_cred.json
- export CLOUDSDK_AUTH_CREDENTIAL_FILE_OVERRIDE=$CI_PROJECT_DIR/_auth/.gcp_temp_cred.json
- export GOOGLE_GHA_CREDS_PATH=$CI_PROJECT_DIR/_auth/.gcp_temp_cred.json
- export GOOGLE_CLOUD_PROJECT=$(cat $CI_PROJECT_DIR/_auth/.GOOGLE_CLOUD_PROJECT)
- export CLOUDSDK_PROJECT=$(cat $CI_PROJECT_DIR/_auth/.GOOGLE_CLOUD_PROJECT)
- export CLOUDSDK_CORE_PROJECT=$(cat $CI_PROJECT_DIR/_auth/.GOOGLE_CLOUD_PROJECT)
- export GCP_PROJECT=$(cat $CI_PROJECT_DIR/_auth/.GOOGLE_CLOUD_PROJECT)
- export GCLOUD_PROJECT=$(cat $CI_PROJECT_DIR/_auth/.GOOGLE_CLOUD_PROJECT)
.gcp-auth:
artifacts:
paths:
- _auth/
before_script:
*gcp_auth_before
stages:
- auth
- debug
auth:
stage: auth
image: "google/cloud-sdk:slim"
variables:
SERVICE_ACCOUNT_EMAIL: "... service account email ..."
WORKLOAD_IDENTITY_PROVIDER: "projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL/providers/PROVIDER"
GOOGLE_CLOUD_PROJECT: "... project id ...."
artifacts:
paths:
- _auth/
script:
- |
mkdir -p _auth 
echo "$CI_JOB_JWT_V2" > $CI_PROJECT_DIR/_auth/.ci_job_jwt_file
echo "$GOOGLE_CLOUD_PROJECT" > $CI_PROJECT_DIR/_auth/.GOOGLE_CLOUD_PROJECT
gcloud iam workload-identity-pools create-cred-config 
$WORKLOAD_IDENTITY_PROVIDER 
--service-account=$SERVICE_ACCOUNT_EMAIL 
--service-account-token-lifetime-seconds=600 
--output-file=$CI_PROJECT_DIR/_auth/.gcp_temp_cred.json 
--credential-source-file=$CI_PROJECT_DIR/_auth/.ci_job_jwt_file
gcloud config set project $GOOGLE_CLOUD_PROJECT
- "export GOOGLE_APPLICATION_CREDENTIALS=$CI_PROJECT_DIR/_auth/.gcp_temp_cred.json"
- "gcloud auth login --cred-file=$GOOGLE_APPLICATION_CREDENTIALS"
- gcloud auth list # DEBUG!!
debug:
extends: .gcp-auth
stage: debug
image: "google/cloud-sdk:slim"
script:
- env
- gcloud auth list
- gcloud storage ls

您的两个Gitlab作业为Kubernetes运行器在单独的pod上运行。

tf-stuff作业没有看到在gcp-auth作业中完成的身份验证。

为了解决这个问题,您可以在单独的Shell脚本中添加认证代码逻辑,然后在两个Gitlab作业中重用该脚本,例如:

AuthenticationShellscriptgcp_authentication.sh:

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
# Check if you need to set GOOGLE_APPLICATION_CREDENTIALS env var on `pwd`/.gcp_temp_cred.json

对于tf-stuff,您可以创建包含gcloudTerraform的自定义Docker图像,因为图像hashicorp/terraform本地不包含gcloudcli

您的Docker图像可以添加到Gitlab注册表

您的Gitlabyml文件:

stages:
- auth
- validate
gcp-auth:
stage: auth
image: google/cloud-sdk:slim
script:
- . ./gcp_authentication.sh
tf-stuff:
stage: validate
image:
name: yourgitlabregistry/your-custom-image:1.0.0
entrypoint:
- '/usr/bin/env'
- 'PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'
before_script:
- . ./gcp_authentication.sh
- export TF_LOG=DEBUG
- cd terraform
- rm -rf .terraform
- terraform --version
- terraform init
script:
- terraform validate

说明:

  • 相同的Shell脚本已经在2个Gitlab作业中使用:gcp_authentication.sh
  • 在与Terraform部分相关的作业中创建了Terraformgcloudcli的自定义Docker映像。此图像可以添加到Gitlab注册表
  • 在认证Shell脚本中,检查是否需要在pwd/. gcp_temp_credit .json上设置GOOGLE_APPLICATION_CREDENTIALSenv var

你必须给你的服务帐户所需的权限使用Gitlab工作负载标识:

  • roles/iam.workloadIdentityUser

您可以查看这个示例项目和文档

相关内容

最新更新