You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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
}

额外注意事项

  1. 若aws_iam_instance_profile.ec2_role_profile在其他文件定义,需确保该资源存在且depends_on引用正确。
  2. 确认AWS托管服务角色(如AWSServiceRoleForAutoScaling、AWSServiceRoleForRDS)已创建:可通过IAM控制台“服务角色”页面查看,若不存在,可通过对应服务控制台启用(比如创建第一个AutoScaling组时自动生成)。
  3. 修复EC2实例启动错误后,需确保EC2关联的IAM角色本身拥有kms:Encrypt、kms:Decrypt等权限,配合KMS策略实现完整访问授权。

内容的提问来源于stack exchange,提问作者fangle xi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 20:25:54