如何隐藏Terraform计划中external数据源的AWS凭证?
解决Terraform Plan中暴露AWS访问密钥的问题
我明白你现在的困境:团队要求用现有方案,但data "external"的query参数把敏感的密钥明文直接暴露在了Terraform Plan里。问题的核心在于Terraform会默认记录数据源的输入参数(比如query),而你之前的写法把敏感值直接放到了query里,导致明文泄露。下面是基于你现有方案的改进思路和代码:
核心改进思路
把敏感值从query参数转移到环境变量中传递给Shell脚本——Terraform会自动将环境变量中的敏感值标记为<sensitive>,不会在Plan中显示明文。同时修正Shell脚本的输出格式,符合external数据源的要求(必须输出单一有效的JSON对象)。
修改后的Terraform代码
resource "aws_iam_access_key" "key" { user = aws_iam_user.user.name } resource "null_resource" "access_key_shell" { triggers = { aws_user = aws_iam_user.user.name } } data "external" "stdout" { depends_on = [null_resource.access_key_shell] program = ["sh", "${path.module}/read.sh"] # 用环境变量传递敏感值,Terraform会自动隐藏这些值 environment = { AWS_ACCESS_ID = aws_iam_access_key.key.id AWS_SECRET_ID = aws_iam_access_key.key.secret } } # 避免在triggers中引用敏感值,改用无敏感信息的用户ARN作为触发器 resource "null_resource" "contents_access" { triggers = { aws_user_arn = aws_iam_user.user.arn } } output "aws_iam_podcast_logstash_access_key" { value = chomp(data.external.stdout.result.access_key) }
修改后的read.sh脚本
#!/bin/bash set -euo pipefail # 从环境变量读取敏感值,而非query的JSON输入 ACCESS_ID="${AWS_ACCESS_ID}" SECRET_ID="${AWS_SECRET_ID}" # 执行KMS加密操作 ENCRYPTED_ACCESS=$(aws kms encrypt --key-id alias/amp_key --plaintext "${ACCESS_ID}" --output text --query CiphertextBlob) ENCRYPTED_SECRET=$(aws kms encrypt --key-id alias/amp_key --plaintext "${SECRET_ID}" --output text --query CiphertextBlob) # 输出符合external数据源要求的单一JSON对象 echo "{\"access_key\":\"${ENCRYPTED_ACCESS}\",\"secret_key\":\"${ENCRYPTED_SECRET}\"}"
为什么这样能解决问题?
- 环境变量的敏感值隐藏:Terraform会自动识别
environment参数中的敏感资源属性(比如aws_iam_access_key的id和secret),在Plan中显示为<sensitive>,不会泄露明文。 - 移除危险的
query参数:原来的query直接把敏感值暴露在Plan的输入记录里,现在完全移除了这部分,从根源上避免了泄露。 - 修正脚本输出格式:原来的脚本输出了两个独立的字符串,不符合
external数据源的要求(必须输出一个有效的JSON对象),修正后不会导致Terraform解析错误。
改进后的Plan输出示例
修改后,你的Terraform Plan中data.external.stdout部分会变成这样:
<= data.external.stdout id: <computed> program.#: "2" program.0: "sh" program.1: "/Users/xxxx/projects/tf_iam_stage/read.sh" environment.%: "2" environment.AWS_ACCESS_ID: <sensitive> environment.AWS_SECRET_ID: <sensitive> result.%: <computed>
敏感值已经被安全隐藏,不会再暴露到GitHub的Jenkins输出里。
内容的提问来源于stack exchange,提问作者user6826691
相关产品推荐
相关产品推荐

