如何在Route53托管区域增删记录集时触发Lambda函数并监控数量?
实现Route53记录集变更触发Lambda及数量监控方案
一、触发Lambda响应记录集变更
1. 用EventBridge捕获Route53变更事件
Route53的记录集增删操作会调用ChangeResourceRecordSets API,CloudTrail会自动记录该API的调用事件,我们可以通过EventBridge直接过滤并触发Lambda:
- 创建EventBridge规则,设置事件模式为:
{ "source": ["aws.route53"], "detail-type": ["AWS API Call via CloudTrail"], "detail": { "eventSource": ["route53.amazonaws.com"], "eventName": ["ChangeResourceRecordSets"] } } - 将规则的目标指定为你的Lambda函数,这样每次执行记录集增删时,Lambda都会被触发。
- Lambda可以从事件参数的
detail字段中提取关键信息:托管区域ID、变更动作(CREATE/DELETE)、涉及的记录集详情等。
2. 替代方案:S3+CloudTrail日志触发
如果需要更细粒度的日志解析,也可以让CloudTrail将日志存储到S3桶,再给S3桶配置事件通知,当新日志文件写入时触发Lambda。不过这种方式需要自行解析日志内容,效率不如EventBridge直接过滤高。
二、监控托管区域记录集数量
1. 定时扫描+CloudWatch指标
适合需要周期性统计全量数据的场景:
- 创建定时触发的Lambda(用EventBridge定时规则,比如每小时执行一次),逻辑如下:
- 调用
ListHostedZones获取所有托管区域。 - 对每个区域,用
ListResourceRecordSets分页遍历记录集,统计总数。 - 将统计结果作为自定义指标发送到CloudWatch,命名空间设为
Route53/RecordSetCount,指标名称TotalRecords,维度包含HostedZoneId和HostedZoneName。
- 调用
- 在CloudWatch中配置告警,当记录集数量出现异常波动(突增/突降)时,通过SNS发送邮件、Slack通知等。
2. 实时更新计数(结合变更事件)
如果需要更实时的监控,可以在响应变更的Lambda中同步更新计数:
- 解析变更事件中的动作(CREATE/DELETE)和涉及的记录集数量(一个变更请求可能包含多个操作)。
- 用DynamoDB存储每个托管区域的当前计数,更新时使用原子操作(比如
UpdateItem的ADD指令)避免并发问题。 - 定期将DynamoDB中的计数同步到CloudWatch,或者直接在更新时调用
PutMetricData更新指标。
三、Lambda关键代码示例
处理变更事件的Python代码
import boto3 import json route53 = boto3.client('route53') cloudwatch = boto3.client('cloudwatch') def lambda_handler(event, context): detail = event['detail'] hosted_zone_id = detail['requestParameters']['hostedZoneId'] change_batch = detail['requestParameters']['changeBatch']['changes'] # 计算本次变更带来的计数变化 count_delta = 0 for change in change_batch: if change['action'] == 'CREATE': count_delta += 1 elif change['action'] == 'DELETE': count_delta -= 1 # 更新CloudWatch指标(也可以同步更新DynamoDB) cloudwatch.put_metric_data( Namespace='Route53/RecordSetCount', MetricData=[ { 'MetricName': 'TotalRecords', 'Dimensions': [{'Name': 'HostedZoneId', 'Value': hosted_zone_id}], 'Value': count_delta, 'Unit': 'Count', 'StorageResolution': 60 } ] ) print(f"托管区域{hosted_zone_id}记录集数量变更:{count_delta}") return {'statusCode': 200, 'body': json.dumps('变更处理完成')}
定时扫描计数的Python代码
import boto3 route53 = boto3.client('route53') cloudwatch = boto3.client('cloudwatch') def lambda_handler(event, context): hosted_zones = route53.list_hosted_zones()['HostedZones'] for zone in hosted_zones: zone_id = zone['Id'].split('/')[-1] zone_name = zone['Name'] # 分页统计记录集总数 record_count = 0 paginator = route53.get_paginator('list_resource_record_sets') for page in paginator.paginate(HostedZoneId=zone_id): record_count += len(page['ResourceRecordSets']) # 推送指标到CloudWatch cloudwatch.put_metric_data( Namespace='Route53/RecordSetCount', MetricData=[ { 'MetricName': 'TotalRecords', 'Dimensions': [ {'Name': 'HostedZoneId', 'Value': zone_id}, {'Name': 'HostedZoneName', 'Value': zone_name} ], 'Value': record_count, 'Unit': 'Count', 'StorageResolution': 60 } ] ) print(f"更新托管区域{zone_name}计数:{record_count}") return {'statusCode': 200, 'body': '全量计数更新完成'}
四、注意事项
- 权限配置:Lambda需要具备
route53:ListHostedZones、route53:ListResourceRecordSets、cloudwatch:PutMetricData权限;如果用EventBridge触发,还需要给EventBridge配置InvokeLambda的权限。 - 分页处理:当托管区域记录集超过1000条时,
ListResourceRecordSets会返回分页结果,必须用分页器遍历,避免漏统计。 - 事件过滤:可以在EventBridge规则中添加
detail.requestParameters.hostedZoneId的过滤条件,只关注特定托管区域的变更。
内容的提问来源于stack exchange,提问作者Moses Liao GZ
相关产品推荐
相关产品推荐

