AWS Lambda导出RDS快照到S3遇KMSKeyNotAccessibleFault权限问题
RDS Aurora快照导出S3时触发KMSKeyNotAccessibleFault错误排查
背景
部署了两个AWS Lambda函数,实现Amazon RDS(Aurora)快照的自动化创建与S3冷存储导出流程:
- 第一个函数:创建RDS快照并向AWS EventBridge发送事件
- 第二个函数:快照创建完成后由EventBridge规则触发,将快照导出至S3,导出后的快照通过S3生命周期策略转存至S3 Glacier长期存储
但第二个Lambda函数执行导出操作时,持续触发KMSKeyNotAccessibleFault错误。
Lambda代码
第一个Lambda函数(创建快照,Python)
import boto3 import json from datetime import datetime, timedelta rds_client = boto3.client('rds') eventbridge_client = boto3.client('events') def lambda_handler(event, context): db_cluster_identifier = 'staging-aurora' # 将UTC时间转换为IST时间 utc_time = datetime.utcnow() ist_time = utc_time + timedelta(hours=5, minutes=30) snapshot_identifier = f"cold-storage-snapshot-{ist_time.strftime('%Y-%m-%d-%H-%M-%S')}" try: # 创建Aurora集群快照 create_snapshot_response = rds_client.create_db_cluster_snapshot( DBClusterSnapshotIdentifier=snapshot_identifier, DBClusterIdentifier=db_cluster_identifier ) # 向EventBridge发送快照标识符 eventbridge_response = eventbridge_client.put_events( Entries=[ { 'Source': 'my.rds.snapshot', 'DetailType': 'RDSSnapshotCreated', 'Detail': json.dumps({ 'snapshot_identifier': snapshot_identifier, 'db_cluster_identifier': db_cluster_identifier }), 'EventBusName': 'default' } ] ) return { 'statusCode': 200, 'body': json.dumps({ 'message': f"快照{snapshot_identifier}创建已启动,事件已发送至EventBridge。", 'createSnapshotResponse': create_snapshot_response, 'eventbridgeResponse': eventbridge_response }) } except Exception as e: return { 'statusCode': 500, 'body': json.dumps({'message': str(e)}) }
第二个Lambda函数(导出快照到S3,Python)
import boto3 import json rds_client = boto3.client('rds') def lambda_handler(event, context): snapshot_identifier = event['detail']['SourceIdentifier'] # 从EventBridge获取快照ID s3_bucket_name = 'cold-storage-sample' kms_key_id = 'arn:aws:kms:ap-southeast-1:<account-id>:key/<key-id>' # KMS密钥ARN占位符 iam_role_arn = 'arn:aws:iam::<account-id>:role/RDS-Snapshot-Export-Role' # IAM角色ARN占位符 try: # 将快照导出至S3 export_task_response = rds_client.start_export_task( ExportTaskIdentifier=f"export-task-{snapshot_identifier}", SourceArn=f"arn:aws:rds:ap-southeast-1:<account-id>:cluster-snapshot:{snapshot_identifier}", S3BucketName=s3_bucket_name, IamRoleArn=iam_role_arn, KmsKeyId=kms_key_id ) return { 'statusCode': 200, 'body': json.dumps({ 'message': f"快照{snapshot_identifier}的导出任务已启动。", 'exportTaskResponse': export_task_response }) } except Exception as e: return { 'statusCode': 500, 'body': json.dumps({ 'message': f"快照导出至S3时出错: {str(e)}" }) }
问题详情
触发第二个Lambda函数时,持续收到如下错误:
{ "statusCode": 500, "body": "{\"message\": \"快照导出至S3时出错: 调用StartExportTask操作时发生错误(KMSKeyNotAccessibleFault): 指定的KMS密钥[arn:aws:kms:ap-southeast-1:<account-id>:key/<key-id>]不存在、未启用或您无访问权限。\"}" }
已排查项
- KMS密钥状态:密钥处于启用状态,已验证Lambda中使用的ARN正确。
- Lambda的IAM角色策略(RDS-Snapshot-Export-Role):已附加包含rds、kms、s3相关权限的策略。
- KMS密钥策略:已配置允许该Lambda角色访问密钥的权限。
- 区域一致性:Lambda、KMS密钥、S3桶、RDS快照均位于
ap-southeast-1区域。
求助问题
尽管已按文档配置权限与参数,仍触发KMSKeyNotAccessibleFault错误,是否遗漏了特定权限或配置?如何进一步调试与解决?
解决方案建议
- 检查IAM角色的信任策略:
start_export_task实际由RDS服务执行导出操作,而非Lambda直接执行,需确保RDS服务被允许扮演该IAM角色。信任策略需包含:{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "rds.amazonaws.com" }, "Action": "sts:AssumeRole" } ] } - 补充KMS密钥权限:确保KMS密钥策略允许导出角色执行以下操作:
kms:Encryptkms:Decryptkms:GenerateDataKeykms:DescribeKey
示例策略语句:
{ "Sid": "AllowRDSExportAccess", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::<account-id>:role/RDS-Snapshot-Export-Role" }, "Action": [ "kms:Encrypt", "kms:Decrypt", "kms:GenerateDataKey", "kms:DescribeKey" ], "Resource": "*" } - 验证EventBridge事件字段正确性:在第二个Lambda中添加
print(event)日志,确认event['detail']['SourceIdentifier']是否为正确的快照标识符,避免因字段错误导致SourceArn无效,间接触发KMS错误。 - 检查S3桶加密配置:若S3桶默认使用其他KMS密钥,需确保导出角色对该密钥有访问权限,或导出时指定的KMS密钥与桶加密密钥一致。
- 用CloudTrail排查细节:查看CloudTrail中
StartExportTask的调用日志,确认是Lambda还是RDS服务实体无法访问KMS密钥,获取更精准的权限拒绝信息。
内容的提问来源于stack exchange,提问作者Suhail Shaik
相关产品推荐
相关产品推荐

