Terraform部署KMS关联EC2/S3/RDS时遇状态及策略配置错误求助
问题分析与修复方案
一、初始EC2实例启动错误:Client.InvalidKMSKey.InvalidState
该错误核心原因是EC2实例无法正常访问指定KMS密钥,可能是密钥未启用、实例关联IAM角色无密钥访问权限,或是KMS密钥策略未授权相关角色。
二、KMS策略更新错误的具体修复
1. InvalidArnException 错误修复
你确认ARN格式和资源存在但仍报错,大概率是以下两种情况:
- Terraform资源依赖顺序问题:若
ec2_role_profile实例配置文件在KMS密钥之后创建,KMS策略引用时该资源尚未存在,AWS会判定ARN无效。需添加显式依赖,确保实例配置文件先于KMS密钥创建。 - 服务角色未创建:AWS托管服务角色(如AutoScaling、RDS的服务角色)需先存在才能在KMS策略中引用。需通过AWS控制台或CLI确认这些角色是否已创建,若未创建,需先启用对应服务的关联角色(比如创建第一个AutoScaling组时会自动生成AWSServiceRoleForAutoScaling)。
2. MalformedPolicyDocumentException 错误修复
针对RDS KMS密钥的错误,原因是策略未保留根账户修改密钥策略的权限。AWS要求所有KMS密钥策略必须允许至少一个主体拥有kms:PutKeyPolicy权限,否则会导致密钥策略无法后续修改,触发该错误。
三、修正后的Terraform代码
以下是修复后的完整KMS配置,解决了依赖和权限问题:
# 确保调用者身份数据块存在 data "aws_caller_identity" "current" {} # Secrets Manager KMS密钥(保留根账户管理权限) resource "aws_kms_key" "secret_manager_key" { description = "KMS key for Secrets Manager" deletion_window_in_days = 10 enable_key_rotation = true rotation_period_in_days = 90 policy = jsonencode({ Version = "2012-10-17", Statement = [ { Sid = "Allow root account to manage key policy" Effect = "Allow" Principal = { AWS = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:root" }, Action = [ "kms:PutKeyPolicy", "kms:DescribeKey", "kms:EnableKey", "kms:DisableKey" ], Resource = "*" }, { Sid = "Allow related roles to use key" Effect = "Allow" Principal = { AWS = [ "arn:aws:iam::${data.aws_caller_identity.current.account_id}:instance-profile/ec2_role_profile", "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/aws-service-role/autoscaling.amazonaws.com/AWSServiceRoleForAutoScaling" ] } Action = [ "kms:Encrypt", "kms:Decrypt", "kms:CreateGrant", "kms:ListGrants", "kms:RevokeGrant" ] Resource = "*" Condition = { Bool = { "kms:GrantIsForAWSResource" = "true" } } } ] }) } # EC2 KMS密钥(添加根账户权限与依赖) resource "aws_kms_key" "ec2_kms_key" { description = "KMS key for EC2" deletion_window_in_days = 10 enable_key_rotation = true rotation_period_in_days = 90 # 依赖实例配置文件,确保先创建实例配置文件 depends_on = [aws_iam_instance_profile.ec2_role_profile] policy = jsonencode({ Version = "2012-10-17" Statement = [ { Sid = "Allow root account to manage key policy" Effect = "Allow" Principal = { AWS = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:root" }, Action = [ "kms:PutKeyPolicy", "kms:DescribeKey", "kms:EnableKey", "kms:DisableKey" ], Resource = "*" }, { Sid = "Allow EC2 and AutoScaling to use key" Effect = "Allow" Principal = { AWS = [ "arn:aws:iam::${data.aws_caller_identity.current.account_id}:instance-profile/ec2_role_profile", "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/aws-service-role/autoscaling.amazonaws.com/AWSServiceRoleForAutoScaling" ] } Action = [ "kms:Encrypt", "kms:Decrypt", "kms:CreateGrant", "kms:ListGrants", "kms:RevokeGrant" ] Resource = "*" Condition = { Bool = { "kms:GrantIsForAWSResource" = "true" } } } ] }) } # RDS KMS密钥(添加根账户权限,解决策略锁死问题) resource "aws_kms_key" "rds_kms_key" { description = "KMS key for RDS" deletion_window_in_days = 10 enable_key_rotation = true rotation_period_in_days = 90 policy = jsonencode({ Version = "2012-10-17" Statement = [ { Sid = "Allow root account to manage key policy" Effect = "Allow" Principal = { AWS = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:root" }, Action = [ "kms:PutKeyPolicy", "kms:DescribeKey", "kms:EnableKey", "kms:DisableKey" ], Resource = "*" }, { Sid = "Allow RDS service to use key" Effect = "Allow" Principal = { AWS = [ "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/aws-service-role/rds.amazonaws.com/AWSServiceRoleForRDS" ] } Action = [ "kms:Encrypt", "kms:Decrypt", "kms:CreateGrant", "kms:ListGrants", "kms:RevokeGrant" ] Resource = "*" Condition = { Bool = { "kms:GrantIsForAWSResource" = "true" } } } ] }) } # S3 KMS密钥(添加根账户权限与依赖) resource "aws_kms_key" "s3_kms_key" { description = "KMS key for S3" deletion_window_in_days = 10 enable_key_rotation = true rotation_period_in_days = 90 depends_on = [aws_iam_instance_profile.ec2_role_profile] policy = jsonencode({ Version = "2012-10-17" Statement = [ { Sid = "Allow root account to manage key policy" Effect = "Allow" Principal = { AWS = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:root" }, Action = [ "kms:PutKeyPolicy", "kms:DescribeKey", "kms:EnableKey", "kms:DisableKey" ], Resource = "*" }, { Sid = "Allow related roles to use key" Effect = "Allow" Principal = { AWS = [ "arn:aws:iam::${data.aws_caller_identity.current.account_id}:instance-profile/ec2_role_profile", "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/aws-service-role/autoscaling.amazonaws.com/AWSServiceRoleForAutoScaling" ] } Action = [ "kms:Encrypt", "kms:Decrypt", "kms:CreateGrant", "kms:ListGrants", "kms:RevokeGrant" ] Resource = "*" Condition = { Bool = { "kms:GrantIsForAWSResource" = "true" } } } ] }) } # KMS别名配置不变 resource "aws_kms_alias" "ec2_key_alias" { name = "alias/ec2-key" target_key_id = aws_kms_key.ec2_kms_key.id } resource "aws_kms_alias" "rds_key_alias" { name = "alias/rds-key" target_key_id = aws_kms_key.rds_kms_key.id } resource "aws_kms_alias" "s3_key_alias" { name = "alias/s3-key" target_key_id = aws_kms_key.s3_kms_key.id } resource "aws_kms_alias" "secrets_manager_key_alias" { name = "alias/secrets-manager-key" target_key_id = aws_kms_key.secret_manager_key.id }
额外注意事项
- 若
aws_iam_instance_profile.ec2_role_profile在其他文件定义,需确保该资源存在且depends_on引用正确。 - 确认AWS托管服务角色(如AWSServiceRoleForAutoScaling、AWSServiceRoleForRDS)已创建:可通过IAM控制台“服务角色”页面查看,若不存在,可通过对应服务控制台启用(比如创建第一个AutoScaling组时自动生成)。
- 修复EC2实例启动错误后,需确保EC2关联的IAM角色本身拥有
kms:Encrypt、kms:Decrypt等权限,配合KMS策略实现完整访问授权。
内容的提问来源于stack exchange,提问作者fangle xi
相关产品推荐
相关产品推荐

