如何在Terraform模块中引用AWS Provider的Access/Secret Key
解决Terraform中CodeBuild引用AWS共享凭据的问题
核心限制
Terraform的AWS Provider不会将已加载的凭据暴露为可直接引用的变量,因此无法直接从provider块中提取AWS_ACCESS_KEY_ID和AWS_SECRET_ACCESS_KEY,需要通过以下方式实现需求:
方案1:通过外部命令读取共享凭据文件
利用external数据源调用AWS CLI读取指定profile的凭据,再传递给CodeBuild模块:
步骤1:在main.tf中添加外部数据源
# 读取dev-terraform profile的凭据 data "external" "dev_aws_credentials" { program = ["bash", "-c", "aws configure get aws_access_key_id --profile dev-terraform && aws configure get aws_secret_access_key --profile dev-terraform"] }
步骤2:将凭据作为变量传入CodeBuild模块
module "code_build" { source = "../../modules/code_build" # 传递凭据变量 aws_access_key_id = data.external.dev_aws_credentials.result["0"] aws_secret_access_key = data.external.dev_aws_credentials.result["1"] # 其他模块参数... }
步骤3:在code_build.tf中引用变量
# 先在模块中定义变量 variable "aws_access_key_id" { type = string description = "AWS Access Key ID from dev-terraform profile" } variable "aws_secret_access_key" { type = string description = "AWS Secret Access Key from dev-terraform profile" } resource "aws_codebuild_project" "sls_deploy" { ... environment { ... environment_variable { name = "AWS_ACCESS_KEY_ID" value = var.aws_access_key_id type = "PLAINTEXT" # 注意:明文存储风险高,仅适合测试环境 } environment_variable { name = "AWS_SECRET_ACCESS_KEY" value = var.aws_secret_access_key type = "PLAINTEXT" } } }
注意:此方案会将明文凭据写入Terraform状态文件,存在安全风险,不建议生产环境使用。
方案2:用Secrets Manager存储凭据(安全版本)
将凭据存入AWS Secrets Manager,让CodeBuild动态读取,避免明文暴露:
步骤1:创建Secrets Manager存储凭据
# 创建凭据存储 resource "aws_secretsmanager_secret" "codebuild_dev_creds" { name = "codebuild-dev-terraform-credentials" } # 写入凭据内容 resource "aws_secretsmanager_secret_version" "codebuild_dev_creds" { secret_id = aws_secretsmanager_secret.codebuild_dev_creds.id secret_string = jsonencode({ AWS_ACCESS_KEY_ID = data.external.dev_aws_credentials.result["0"] AWS_SECRET_ACCESS_KEY = data.external.dev_aws_credentials.result["1"] }) }
步骤2:CodeBuild引用Secrets Manager中的凭据
resource "aws_codebuild_project" "sls_deploy" { ... environment { ... environment_variable { name = "AWS_ACCESS_KEY_ID" value = "{{resolve:secretsmanager:${aws_secretsmanager_secret.codebuild_dev_creds.id}:SecretString:AWS_ACCESS_KEY_ID}}" type = "SECRETS_MANAGER" } environment_variable { name = "AWS_SECRET_ACCESS_KEY" value = "{{resolve:secretsmanager:${aws_secretsmanager_secret.codebuild_dev_creds.id}:SecretString:AWS_SECRET_ACCESS_KEY}}" type = "SECRETS_MANAGER" } } }
方案3:使用CodeBuild服务角色(最佳实践)
完全避免传递静态凭据,给CodeBuild分配IAM角色,让其运行时自动获取临时凭据:
步骤1:创建CodeBuild服务角色
resource "aws_iam_role" "code_build_role" { name = "codebuild-sls-deploy-role" assume_role_policy = jsonencode({ Version = "2012-10-17" Statement = [ { Action = "sts:AssumeRole" Effect = "Allow" Principal = { Service = "codebuild.amazonaws.com" } } ] }) } # 给角色添加所需权限(根据实际业务调整) resource "aws_iam_role_policy_attachment" "code_build_s3_access" { role = aws_iam_role.code_build_role.name policy_arn = "arn:aws:iam::aws:policy/AmazonS3FullAccess" }
步骤2:CodeBuild关联服务角色
resource "aws_codebuild_project" "sls_deploy" { ... service_role = aws_iam_role.code_build_role.arn # 无需再设置AWS_ACCESS_KEY_ID和AWS_SECRET_ACCESS_KEY环境变量 ... }
此方案符合AWS安全最佳实践,无需管理静态凭据,推荐生产环境使用。
内容的提问来源于stack exchange,提问作者Fostah
相关产品推荐
相关产品推荐

