Terraform部署AWS KMS密钥政策遇异常:初始成功后重部署超时
Terraform配置AWS KMS密钥策略的超时问题排查
问题背景
配置aws_kms_key_policy时,最初因未保留根账户权限触发MalformedPolicyDocumentException(提示无法在未来更新密钥策略);添加根账户权限后首次部署成功,但无任何修改重新部署时出现超时错误:
Error: attaching KMS Key policy...timeout while waiting for state to become 'TRUE'
初始错误代码
resource "aws_kms_key_policy" "kms_key" { key_id = aws_kms_key.kms_key.key_id policy = jsonencode({ Id = "kms-key-policy", Statement = [ { Effect = "Allow", Principal = { Service = "states.amazonaws.com" }, Action = [ "kms:Encrypt", "kms:Decrypt", "kms:ReEncrypt", "kms:GenerateDataKey", "kms:DescribeKey", "kms:PutKeyPolicy", "kms:CreateGrant" ], Resource = aws_kms_key.kms_key.arn } ] }) }
更新后代码
resource "aws_kms_key_policy" "kms_key" { key_id = aws_kms_key.kms_key.key_id policy = jsonencode({ Id = "kms-key-policy", Statement = [ { Sid = "Allow administration of the key", Effect = "Allow", Principal = { "AWS" = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:root" }, Action = [ "kms:Create*", "kms:Describe*", "kms:Enable*", "kms:List*", "kms:Put*", "kms:Update*", "kms:Revoke*", "kms:Disable*", "kms:Get*", "kms:Delete*", "kms:ScheduleKeyDeletion", "kms:CancelKeyDeletion", ], Resource = "*" }, { Effect = "Allow", Principal = { Service = "states.amazonaws.com" }, Action = [ "kms:Encrypt", "kms:Decrypt", "kms:ReEncrypt", "kms:GenerateDataKey", "kms:DescribeKey", "kms:CreateGrant" ], Resource = aws_kms_key.kms_key.arn, } ] }) }
可能的原因及解决方案
1. Terraform执行身份缺少必要权限
虽然密钥策略中给了根账户全管理权限,但如果Terraform通过IAM子角色/用户执行,该身份不会自动继承根账户权限,需要明确授权kms:GetKeyPolicy和kms:PutKeyPolicy操作,否则Terraform无法验证策略状态,最终超时。
解决方式:给执行Terraform的IAM身份添加如下权限策略:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "kms:GetKeyPolicy", "kms:PutKeyPolicy" ], "Resource": "arn:aws:kms:<区域>:<账户ID>:key/<密钥ID>" } ] }
2. KMS策略更新的延迟问题
AWS KMS密钥策略更新后,部分区域可能存在状态同步延迟,超过Terraform默认超时阈值导致报错。
解决方式:在aws_kms_key_policy资源中增加timeouts配置,延长等待时间:
resource "aws_kms_key_policy" "kms_key" { key_id = aws_kms_key.kms_key.key_id # 原有policy配置... timeouts { create = "10m" update = "10m" } }
3. JSON策略的编码差异
jsonencode生成的JSON格式可能与AWS存储的策略存在细微差异(比如空格、语句顺序),导致Terraform误判需要重新更新策略,反复执行操作最终超时。
解决方式:
- 改用
aws_kms_key资源内置的policy参数管理策略,避免独立资源的重复校验问题; - 或者将策略内容保存为外部JSON文件,使用
file()函数读取,减少动态编码差异:
resource "aws_kms_key_policy" "kms_key" { key_id = aws_kms_key.kms_key.key_id policy = file("kms-key-policy.json") }
4. 根账户权限的Resource范围问题
虽然Resource = "*"在KMS策略中合法,但部分场景下可能导致权限生效异常。可以尝试将根账户的Resource改为具体的密钥ARN:
Principal = { "AWS" = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:root" }, Action = [ # 原有动作列表... ], Resource = aws_kms_key.kms_key.arn
内容的提问来源于stack exchange,提问作者thom4s94
相关产品推荐
相关产品推荐

