AWS 보안 그룹(Security Group)에 설정된 기존 IP 범위(OLD_PREFIX)를 기반으로 새로운 IP 범위(NEW_PREFIX)를 자동으로 추가하는 스크립트입니다.
핵심 목적
기존 IP가 111.222.333.N/32이면, 자동으로 110.220.330.N/32를 같은 규칙에 추가합니다.
단, 동일한 IP가 이미 등록되어 있으면 생략합니다.
#!/usr/bin/env python3
import argparse
import sys
import boto3
from botocore.exceptions import ClientError
def normalize(cidr):
return cidr.split('/')[0]
def replicate_permission(sg_id, perm, old_prefix, new_prefix, ec2):
proto = perm['IpProtocol']
from_port = perm.get('FromPort')
to_port = perm.get('ToPort')
existing = [normalize(r.get('CidrIp','')) for r in perm.get('IpRanges', [])]
if any(ip.startswith(new_prefix + '.') for ip in existing):
print(f" [SKIP] SG {sg_id} {proto} {from_port}-{to_port}, new-prefix already present")
return
old_ips = [ip for ip in existing if ip.startswith(old_prefix + '.')]
if not old_ips:
return
print(f" [INFO] SG {sg_id} {proto} {from_port}-{to_port}: found old-prefix entries {old_ips}")
for old_ip in old_ips:
last = old_ip.split('.')[-1]
new_ip = f"{new_prefix}.{last}"
if new_ip in existing:
print(f" - skip {new_ip}/32, already exists")
continue
ip_perm = {
'IpProtocol': proto,
**({'FromPort': from_port, 'ToPort': to_port} if from_port is not None else {}),
'IpRanges': [{'CidrIp': f"{new_ip}/32"}]
}
print(f" + adding {new_ip}/32 ... ", end='')
try:
ec2.authorize_security_group_ingress(
GroupId=sg_id,
IpPermissions=[ip_perm]
)
print("OK")
except ClientError as e:
code = e.response['Error']['Code']
if code == 'InvalidPermission.Duplicate':
print("AlreadyExists")
else:
print(f"ERROR ({code})")
def main():
parser = argparse.ArgumentParser(
description="Replicate OLD_PREFIX→NEW_PREFIX CIDRs for all SGs in a region"
)
parser.add_argument('--old-prefix', required=True,
help="Old prefix, e.g. 111.222.333")
parser.add_argument('--new-prefix', required=True,
help="New prefix, e.g. 110.220.330")
parser.add_argument('--region', required=True,
help="AWS region, e.g. ap-northeast-2")
parser.add_argument('--profile',
help="AWS CLI profile name")
args = parser.parse_args()
sess_kwargs = {'region_name': args.region}
if args.profile:
sess_kwargs['profile_name'] = args.profile
session = boto3.Session(**sess_kwargs)
ec2 = session.client('ec2')
paginator = ec2.get_paginator('describe_security_groups')
sg_ids = []
for page in paginator.paginate():
sg_ids += [sg['GroupId'] for sg in page['SecurityGroups']]
print(f"[INFO] Found {len(sg_ids)} SGs in {args.region}")
for sg_id in sg_ids:
try:
sg = ec2.describe_security_groups(GroupIds=[sg_id])['SecurityGroups'][0]
except ClientError as e:
print(f"[ERROR] describe SG {sg_id}: {e}", file=sys.stderr)
continue
perms = sg.get('IpPermissions', [])
print(f"\n[PROCESS] SG {sg_id} ({len(perms)} permissions)")
for perm in perms:
replicate_permission(sg_id, perm, args.old_prefix, args.new_prefix, ec2)
if __name__ == '__main__':
main()
사용 예시
python sg_replicate_by_prefix.py \
--old-prefix 111.222.333 \
--new-prefix 110.220.330 \
--region ap-northeast-2 \
--profile my-aws-profile
특정 리전에 존재하는 모든 보안 그룹에 IP를 자동으로 등록함으로써, 매번 수동으로 IP를 추가해야 하는 번거로움을 효과적으로 해소했습니다.