Terraform创建KMS Key报错‘策略含无效主体’原因排查问询
KMS密钥创建报错排查:Policy contains a statement with one or more invalid principals
问题描述
我在使用两段不同的Terraform代码创建KMS密钥时,均触发相同错误:Policy contains a statement with one or more invalid principals。多次尝试仍未定位原因,想确认KMS策略是否禁止使用通配符?该报错发生在创建用于批量配置资源权限的权限栈过程中。
报错信息
│ Error: updating KMS Key (ssss-cdb7-xxx-a58c-ss): updating policy: MalformedPolicyDocumentException: Policy contains a statement with one or more invalid principals. │ │ with module.kms.aws_kms_key.sns-encryption-key, │ on kms/main.tf line 181, in resource "aws_kms_key" "sns-encryption-key": │ 181: resource "aws_kms_key" "sns-encryption-key" {
两段Terraform代码
第一段代码
resource "aws_kms_key" "sns-encryption-key" { description = "This key is used to encrypt sns queue" deletion_window_in_days = 7 enable_key_rotation = true policy = jsonencode({ Version = "2012-10-17" Statement = [ { Effect = "Allow" Principal = { Service = "s3.amazonaws.com" } Action = [ "kms:GenerateDataKey*", "kms:Decrypt" ] Resource = "*" }, { Effect = "Allow" Principal = { AWS = [ "arn:aws:iam::${var.account_id}:role/${var.env_name}*", "arn:aws:iam::${var.account_id}:root" ] } Action = [ "kms:*", ] Resource = "*" }, ] }) tags = { Environment = var.env_name EnvironmentType = var.env_type CreatedAt = timestamp() } lifecycle { prevent_destroy = true } }
第二段代码
resource "aws_kms_key" "sns-encryption-key" { description = "This key is used to encrypt sns queue" deletion_window_in_days = 7 enable_key_rotation = true # Version = "2012-10-17", # Id = "key-policy-1", policy = jsonencode({ Version = "2012-10-17" Statement = [ { Effect = "Allow" Resource = "*" Action = ["kms:GenerateDataKey*", "kms:Decrypt", "kms:Encrypt"] Principal = { Service = "s3.amazonaws.com" } }, { Effect = "Allow" Principal = { AWS = "arn:aws:iam::${var.account_id}:role/*" } Action = [ "kms:*" ] Resource = "*" }, { Effect = "Allow" Principal = { AWS = "arn:aws:iam::${var.account_id}:root" } Action = ["kms:*"] Resource = "*" } ] }) tags = { Environment = var.env_name EnvironmentType = var.env_type CreatedAt = timestamp() } lifecycle { prevent_destroy = true } }
问题原因与解决方法
KMS密钥策略允许使用通配符,报错并非通配符本身导致,而是违反了KMS策略的核心规则:策略中Resource字段不能用*指代当前密钥,必须明确指定密钥自身的ARN。当设置Resource = "*"时,KMS无法正确识别目标密钥,进而触发Principal验证失败。
修正步骤
- 在策略中替换所有
Resource = "*"为当前KMS密钥的ARN,可直接使用Terraform内置的aws_kms_key.sns-encryption-key.arn引用。 - 确保包含根用户的语句合法(你的代码中已正确配置根用户ARN,无需修改)。
修正后的示例代码
resource "aws_kms_key" "sns-encryption-key" { description = "This key is used to encrypt sns queue" deletion_window_in_days = 7 enable_key_rotation = true policy = jsonencode({ Version = "2012-10-17" Statement = [ { Effect = "Allow" Principal = { Service = "s3.amazonaws.com" } Action = [ "kms:GenerateDataKey*", "kms:Decrypt" ] Resource = aws_kms_key.sns-encryption-key.arn }, { Effect = "Allow" Principal = { AWS = [ "arn:aws:iam::${var.account_id}:role/${var.env_name}*", "arn:aws:iam::${var.account_id}:root" ] } Action = [ "kms:*", ] Resource = aws_kms_key.sns-encryption-key.arn }, ] }) tags = { Environment = var.env_name EnvironmentType = var.env_type CreatedAt = timestamp() } lifecycle { prevent_destroy = true } }
额外注意事项
- Terraform会自动处理当前资源ARN的内部引用,不会引发循环依赖;若出现异常,可改用
aws_caller_identity数据源结合密钥ID构造ARN。 - 你代码中使用的角色ARN前缀通配符(如
${var.env_name}*、role/*)是合法的,KMS支持此类IAM身份的前缀匹配。
内容的提问来源于stack exchange,提问作者win
相关产品推荐
相关产品推荐

