能否用Python Lambda切换Route 53同名称CNAME记录集主备状态?
如何用Python Lambda切换Route 53同名CNAME记录的主备故障转移状态
当然可以用Python Lambda来实现这个需求!而且这是一个很常见的Route 53故障转移自动化方案,我来详细给你拆解怎么做,同时也分享几个其他的最优选项。
一、Python Lambda实现方案
1. 前提条件
- 确保你的两个CNAME记录已经配置了**故障转移(Failover)**类型,分别设置为
PRIMARY和SECONDARY,并且各自关联了健康检查。 - Lambda执行角色需要有Route 53的权限,至少要包含
route53:ChangeResourceRecordSets和route53:ListResourceRecordSets这两个权限(如果需要查询当前状态的话)。
2. 核心代码思路
Lambda的核心逻辑是调用Route 53的API,修改两个记录集的Failover属性,交换它们的主备状态——把原来的PRIMARY改成SECONDARY,原来的SECONDARY改成PRIMARY。下面是一个简化的示例代码:
import boto3 def lambda_handler(event, context): route53 = boto3.client('route53') hosted_zone_id = 'YOUR_HOSTED_ZONE_ID' record_name = 'your.example.com.' # 注意末尾必须带点号,符合DNS规范 ttl = 300 # 要匹配你现有记录的TTL值 # 先获取当前的目标记录集 response = route53.list_resource_record_sets( HostedZoneId=hosted_zone_id, StartRecordName=record_name, StartRecordType='CNAME' ) # 筛选出同名的CNAME记录 target_records = [rs for rs in response['ResourceRecordSets'] if rs['Name'] == record_name and rs['Type'] == 'CNAME'] if len(target_records) != 2: return {'statusCode': 400, 'body': 'Expected exactly 2 CNAME records for the target name'} # 准备变更请求:交换主备状态 change_batch = [] for record in target_records: current_failover = record['Failover'] new_failover = 'SECONDARY' if current_failover == 'PRIMARY' else 'PRIMARY' change_batch.append({ 'Action': 'UPSERT', 'ResourceRecordSet': { 'Name': record_name, 'Type': 'CNAME', 'TTL': ttl, 'ResourceRecords': record['ResourceRecords'], 'Failover': new_failover, 'HealthCheckId': record['HealthCheckId'] # 保留原健康检查配置 } }) # 提交变更到Route 53 change_response = route53.change_resource_record_sets( HostedZoneId=hosted_zone_id, ChangeBatch={ 'Comment': 'Swap primary/secondary failover status via Lambda', 'Changes': change_batch } ) return {'statusCode': 200, 'body': f"Change submitted successfully: {change_response['ChangeInfo']['Id']}"}
3. 触发方式
- 手动触发:直接通过Lambda控制台、AWS CLI或者SDK调用函数。
- 自动触发:可以结合CloudWatch告警,当主健康检查连续失败时自动触发Lambda切换;也可以用EventBridge定时任务做周期性测试切换。
二、其他最优方案
除了Lambda,还有几种更贴合Route 53原生能力的方案,可能更简单高效:
1. Route 53原生故障转移(首推)
如果你的需求是自动故障转移,其实Route 53本身就支持原生的故障转移机制:当PRIMARY记录关联的健康检查失败时,Route 53会自动切换到SECONDARY记录,完全不需要手动或Lambda干预。
注意:要确保两个记录都正确关联了健康检查,并且Route 53的健康检查状态正常(可以在控制台查看健康检查的监控数据)。
2. AWS CLI脚本
如果只是偶尔需要手动切换,用AWS CLI脚本会更直接,不需要部署Lambda:
# 替换成你自己的资源ID和域名信息 aws route53 change-resource-record-sets \ --hosted-zone-id YOUR_HOSTED_ZONE_ID \ --change-batch '{ "Comment": "Manual swap of primary/secondary CNAME records", "Changes": [ { "Action": "UPSERT", "ResourceRecordSet": { "Name": "your.example.com.", "Type": "CNAME", "TTL": 300, "ResourceRecords": [{"Value": "primary-dns.example.com."}], "Failover": "SECONDARY", "HealthCheckId": "YOUR_PRIMARY_HEALTH_CHECK_ID" } }, { "Action": "UPSERT", "ResourceRecordSet": { "Name": "your.example.com.", "Type": "CNAME", "TTL": 300, "ResourceRecords": [{"Value": "secondary-dns.example.com."}], "Failover": "PRIMARY", "HealthCheckId": "YOUR_SECONDARY_HEALTH_CHECK_ID" } } ] }'
3. AWS Systems Manager Automation
如果需要标准化、可审计的切换操作,可以创建一个自动化文档,封装切换逻辑,然后通过控制台、CLI或API执行,适合企业级的合规需求。
总结
- 若需要自动故障转移:优先用Route 53原生故障转移,无需额外代码;如果需要自定义逻辑(比如切换前发送通知、多步骤验证),再用Lambda+CloudWatch/EventBridge组合。
- 若只是手动临时切换:AWS CLI脚本是最快捷的选择。
- 若需要标准化、可审计的操作:AWS Systems Manager Automation是更合适的方案。
内容的提问来源于stack exchange,提问作者Tanuj Chinnu
相关产品推荐
相关产品推荐

