如何使用Boto3更新AWS安全组规则并解决重复规则报错
Boto3更新AWS安全组规则重复报错解决方案
报错原因
你使用的authorize_security_group_ingress接口仅用于新增安全组入站规则,只要规则的协议、端口、源CIDR三个核心要素完全匹配的记录已存在,无论描述是否修改,都会触发InvalidPermission.Duplicate错误,该接口没有内置覆写参数。
另外你原脚本存在缩进错误:authorize_security_group_ingress的调用逻辑没有放在安全组遍历循环内,只会处理最后一个匹配到的office_sg,需要先调整缩进层级。
对应解决方案
场景1:仅需要修改已有规则的描述
直接调用官方提供的专门更新规则描述的接口即可,无需删改规则本身,不会触发重复报错:
# 对应安全组遍历内的逻辑 for sg_res in describe_sg['SecurityGroups']: gpname = sg_res.get('GroupName') gpid = sg_res.get('GroupId') print([aws_account[1], gpname]) # 遍历现有入站规则 for perm in sg_res['IpPermissions']: # 匹配你要修改的规则端口、协议条件 if perm['IpProtocol'] == '-1' and perm['FromPort'] == 0 and perm['ToPort'] == 0: # 匹配目标CIDR后更新描述 update_cidrs = [] for ip_range in perm['IpRanges']: if ip_range['CidrIp'] in ['10.2.3.4/32', '10.5.6.7/32']: update_cidrs.append({ 'CidrIp': ip_range['CidrIp'], 'Description': 'Sec' # 填写新的描述 }) if update_cidrs: resp = ec2_client.update_security_group_rule_descriptions_ingress( GroupId=gpid, IpPermissions=[{ 'FromPort': 0, 'ToPort': 0, 'IpProtocol': '-1', 'IpRanges': update_cidrs }] ) print(resp)
场景2:需要调整规则的端口、协议等核心配置,或确保规则和你定义的配置完全一致
先删除匹配的旧规则,再新增新规则,避免重复报错:
# 先定义你的目标规则配置 TARGET_PERM = { 'FromPort': 0, 'ToPort': 0, 'IpProtocol': '-1' } TARGET_CIDRS = [ {'CidrIp': '10.2.3.4/32', 'Description': 'Sec'}, {'CidrIp': '10.5.6.7/32', 'Description': 'Sec'} ] target_cidr_list = [item['CidrIp'] for item in TARGET_CIDRS] # 安全组遍历逻辑 for sg_res in describe_sg['SecurityGroups']: gpname = sg_res.get('GroupName') gpid = sg_res.get('GroupId') print([aws_account[1], gpname]) # 第一步:删除已存在的同条件旧规则 for perm in sg_res['IpPermissions']: if perm['IpProtocol'] == TARGET_PERM['IpProtocol'] \ and perm['FromPort'] == TARGET_PERM['FromPort'] \ and perm['ToPort'] == TARGET_PERM['ToPort']: # 筛选需要删除的CIDR del_cidrs = [r for r in perm['IpRanges'] if r['CidrIp'] in target_cidr_list] if del_cidrs: ec2_client.revoke_security_group_ingress( GroupId=gpid, IpPermissions=[{ **TARGET_PERM, 'IpRanges': del_cidrs }] ) # 第二步:新增目标规则 add_resp = ec2_client.authorize_security_group_ingress( GroupId=gpid, IpPermissions=[{ **TARGET_PERM, 'IpRanges': TARGET_CIDRS }] ) print(add_resp)
内容的提问来源于stack exchange,提问作者jawad846
相关产品推荐
相关产品推荐

