GitLab CI/CD通过OIDC使用Role ARN访问AWS的问题排查
GitLab CI/CD + Terraform + AWS OIDC 认证问题排查与解决
问题1:Terraform构建阶段报错 "No valid credential sources found"
核心原因
Terraform默认从环境变量、本地凭证文件等位置读取AWS凭证,但OIDC认证后的临时凭证未正确注入到Terraform可读取的上下文,或AWS Provider配置未适配无硬编码凭证的场景。
解决方案
确认AWS OIDC角色信任策略配置
确保角色信任策略包含GitLab OIDC的受众与项目身份校验,示例:{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Federated": "arn:aws:iam::你的AWS账号ID:oidc-provider/gitlab.example.com" }, "Action": "sts:AssumeRoleWithWebIdentity", "Condition": { "StringEquals": { "gitlab.example.com:aud": "https://gitlab.example.com", "gitlab.example.com:sub": "project_path:你的项目路径:ref_type:branch:ref:main" } } } ] }正确注入临时凭证到环境变量
在GitLab CI脚本中,通过aws sts assume-role-with-web-identity获取凭证后,必须导出三个核心环境变量,确保Terraform能读取:# 用GitLab提供的JWT令牌获取临时凭证 aws sts assume-role-with-web-identity \ --role-arn "arn:aws:iam::你的AWS账号ID:role/你的OIDC角色名" \ --role-session-name "gitlab-ci-session" \ --web-identity-token "$CI_JOB_JWT_V2" \ --duration-seconds 3600 > credentials.json # 导出凭证到环境变量 export AWS_ACCESS_KEY_ID=$(jq -r '.Credentials.AccessKeyId' credentials.json) export AWS_SECRET_ACCESS_KEY=$(jq -r '.Credentials.SecretAccessKey' credentials.json) export AWS_SESSION_TOKEN=$(jq -r '.Credentials.SessionToken' credentials.json)Terraform AWS Provider配置适配
确保Provider不硬编码凭证,完全依赖环境变量:provider "aws" { region = "你的AWS区域" # 不指定access_key/secret_key,自动读取环境变量中的临时凭证 }
问题2:合并脚本后 validate 阶段报错 "Terraform has no command named 'sh'"
核心原因
在GitLab CI配置中,错误地将sh命令作为Terraform的子命令执行,而非独立的脚本步骤(比如把shell脚本嵌套在terraform命令参数里)。
解决方案
修正CI配置的脚本执行逻辑
错误示例(触发报错的配置):validate: stage: validate image: hashicorp/terraform:latest script: - terraform sh ./assume-role.sh # 错误:把sh当作Terraform命令执行正确的CI配置示例
将认证脚本放在before_script或独立的script步骤中,先完成认证再执行Terraform命令:validate: stage: validate image: hashicorp/terraform:latest before_script: # 安装依赖工具(Terraform镜像默认无aws-cli和jq) - apk add --no-cache aws-cli jq # 执行OIDC认证并导出凭证 - | aws sts assume-role-with-web-identity \ --role-arn "arn:aws:iam::你的AWS账号ID:role/你的OIDC角色名" \ --role-session-name "gitlab-ci-session" \ --web-identity-token "$CI_JOB_JWT_V2" \ --duration-seconds 3600 > credentials.json export AWS_ACCESS_KEY_ID=$(jq -r '.Credentials.AccessKeyId' credentials.json) export AWS_SECRET_ACCESS_KEY=$(jq -r '.Credentials.SecretAccessKey' credentials.json) export AWS_SESSION_TOKEN=$(jq -r '.Credentials.SessionToken' credentials.json) script: - terraform init - terraform validateGitLab Terraform模板适配
如果使用GitLab官方的Terraform模板(如gitlab-terraform),需确保认证步骤在模板的Terraform命令执行前完成,可通过模板的before_script扩展点注入认证逻辑。
内容的提问来源于stack exchange,提问作者DevGuy
相关产品推荐
相关产品推荐

