Terraform部署AWS VPC遇KMS权限问题及三类技术疑问
问题场景
执行Terraform代码部署AWS VPC时,状态刷新日志如下:
module.vpc.aws_route.private_nat_gateway[0]: Refreshing state... [id=r-rtb-0757df1e6d39122912345678987]
module.vpc_endpoints.data.aws_vpc_endpoint_service.this["s3"]: Read complete after 0s [id=421234567]
module.vpc_endpoints.aws_vpc_endpoint.this["s3"]: Refreshing state... [id=vpce-0c225a51234567898]
随后触发KMS密钥访问错误:
Error: reading KMS Key (999999999-c13c-8888-a5cb-9876554321): reading KMS Key (999999999-c13c-8888-a5cb-9876554321): AccessDeniedException: User: arn:aws:iam::12345678998765:user/peter.user is not authorized to perform: kms:DescribeKey on resource: arn:aws:kms:us-east-2:12345678998765:key/999999999-c13c-8888-a5cb-9876554321 because no resource-based policy allows the kms:DescribeKey action
关联的Terraform代码:
module "vpc" { source = "terraform-aws-modules/vpc/aws" version = "5.0.0" azs = local.availability_zones cidr = local.vpc_cidr create_database_subnet_group = false create_flow_log_cloudwatch_iam_role = true create_flow_log_cloudwatch_log_group = true database_subnets = local.database_subnets enable_dhcp_options = true enable_dns_hostnames = true enable_dns_support = true enable_flow_log = true enable_nat_gateway = true flow_log_cloudwatch_log_group_retention_in_days = var.days flow_log_max_aggregation_interval = var.interval name = var.environment one_nat_gateway_per_az = false private_subnets = local.private_subnets public_subnets = local.public_subnets single_nat_gateway = true tags = var.tags } module "vpc_endpoints" { source = "terraform-aws-modules/vpc/aws//modules/vpc-endpoints" version = "5.0.0" vpc_id = module.vpc.vpc_id tags = var.tags endpoints = { s3 = { route_table_ids = flatten([module.vpc.private_route_table_ids, module.vpc.public_route_table_ids]) service = "s3" service_type = "Gateway" tags = { Name = "s3-vpc-endpoint" } } } }
技术问题解答
1. 为何当前Terraform代码会调用该KMS密钥?
因为你启用了VPC流日志并配置将日志存储到CloudWatch日志组(create_flow_log_cloudwatch_log_group = true),该日志组之前被配置为使用这个KMS密钥进行加密。Terraform在刷新状态时,需要读取日志组关联的KMS密钥信息来同步状态,因此会触发kms:DescribeKey操作,导致权限错误。
2. 如何配置代码以停止使用已离职人员创建的该KMS密钥?
有两种可行方式:
- 方式一:关闭CloudWatch日志组加密
在module "vpc"块中添加参数,禁用日志组加密:enable_flow_log_cloudwatch_log_group_encryption = false - 方式二:改用AWS管理密钥
在module "vpc"块中显式指定不使用自定义KMS密钥:
此时日志组会自动使用AWS管理的CloudWatch KMS密钥,无需依赖自定义密钥。flow_log_cloudwatch_log_group_kms_key_id = ""
3. 如何将代码配置为使用本人创建的KMS密钥?
在module "vpc"块中添加参数,指定你创建的KMS密钥ARN或ID:
flow_log_cloudwatch_log_group_kms_key_id = "arn:aws:kms:us-east-2:12345678998765:key/你的密钥ID"
同时确保你的IAM用户拥有该KMS密钥的kms:DescribeKey、kms:Encrypt、kms:Decrypt等必要权限(可通过KMS密钥的资源策略或IAM权限策略配置)。
内容的提问来源于stack exchange,提问作者user20208419

