Terraform创建KMS Key报MalformedPolicyDocumentException错误如何解决
问题根因
该报错的直接原因是KMS策略最终生成的内容里存在不合法的Principal ARN,结合你提供的策略代码,常见触发原因如下:
- 变量
var.account_id或var.organization_id传值异常:取值为空、格式不符合规范(AWS账户ID应为12位数字,组织ID应为o-开头的字符串),导致生成的Principal ARN或条件值非法。 - 策略插值未生效:直接将带变量占位符的JSON字符串传入KMS策略参数时,Terraform没有完成变量替换,最终部署的策略里仍然保留
${var.xxx}格式的占位符,导致Principal ARN不合法。 - 区域适配问题:如果你的资源部署在AWS中国区,使用全球区的服务主体(比如
cloudtrail.amazonaws.com)也会被判定为非法Principal。
修复方案
- 第一步验证变量取值:在Terraform代码中新增临时output打印变量值,确认两个变量的取值符合规范,无空值、拼写错误:
output "account_id" { value = var.account_id } output "organization_id" { value = var.organization_id }
执行terraform apply后查看输出,确认取值正确后可删除该output配置。
- 第二步替换策略生成方式:建议使用
aws_iam_policy_document数据源生成KMS策略,避免手动拼接JSON带来的插值错误,示例配置如下:
data "aws_iam_policy_document" "kms_key" { statement { sid = "Enable IAM User Permissions" effect = "Allow" principals { type = "AWS" identifiers = ["arn:aws:iam::${var.account_id}:root"] } actions = ["kms:*"] resources = ["*"] } statement { sid = "Allow CloudTrail access" effect = "Allow" principals { type = "Service" identifiers = ["cloudtrail.amazonaws.com"] # 中国区请替换为 ["cloudtrail.amazonaws.com.cn"] } actions = ["kms:DescribeKey"] resources = ["*"] } statement { sid = "Allow Cloudtrail to encrypt logs" effect = "Allow" principals { type = "Service" identifiers = ["cloudtrail.amazonaws.com"] # 中国区请替换为 ["cloudtrail.amazonaws.com.cn"] } actions = ["kms:GenerateDataKey*"] resources = ["*"] condition { test = "StringLike" variable = "kms:EncryptionContext:aws:cloudtrail:arn" values = ["arn:aws:cloudtrail:*:${var.organization_id}:trail/*"] # 中国区ARN前缀请替换为 "arn:aws-cn:cloudtrail:*:${var.organization_id}:trail/*" } } statement { sid = "Allow Cloudtrail to decrypt logs" effect = "Allow" principals { type = "AWS" identifiers = ["*"] } actions = ["kms:Decrypt"] resources = ["*"] condition { test = "StringEquals" variable = "aws:PrincipalOrgID" values = [var.organization_id] } } statement { sid = "Allow AWS Config to encrypt/decrypt logs" effect = "Allow" principals { type = "Service" identifiers = ["config.amazonaws.com"] # 中国区请替换为 ["config.amazonaws.com.cn"] } actions = ["kms:Decrypt", "kms:GenerateDataKey"] resources = ["*"] } } resource "aws_kms_key" "this" { description = "KMS key for CloudTrail and Config" policy = data.aws_iam_policy_document.kms_key.json }
- 第三步验证最终策略:执行
terraform plan,在输出的资源变更详情中查看KMS策略的实际生成内容,确认所有变量都已经替换为正确取值,无占位符残留后再执行terraform apply。
内容的提问来源于stack exchange,提问作者dcloud
相关产品推荐
相关产品推荐

