AWS 방화벽 요청 자동화 설계 및 구현
방화벽 요청이 이미 열려 있는지 먼저 확인하고, 막힌 것만 미리보기 뒤 적용하며, 실제 트래픽으로 검증하는 CLI입니다.
규칙과 라우트로 판정
이 코드가 하는 일: 앞에서 평가한 보안그룹 규칙 중 하나라도 통과하지 못하면 판정을 실패로 바꾸고 “Security group rule needed”를 이유로 남깁니다. 출발지는 AWS 리소스인데 목적지가 AWS 밖이면, 출발지 서브넷의 라우트 테이블을 찾아 목적지로 가는 경로가 있는지 확인하고, 있으면 다음 홉을, 없으면 어느 테이블에 경로가 없는지를 기록합니다. 경로가 없을 때는 “Route needed”를 따로 남겨, 보안그룹을 열어도 해결되지 않는 경우를 구분합니다.
if any(not c.ok for c in verdict.checks):
verdict.ok = False
verdict.issues.append("Security group rule needed")
if source.resources and not target.resources:
for resource in source.resources:
ec2 = self.sessions.client("ec2", resource.account)
result = route_analysis.evaluate(
route_analysis.find_table(ec2, resource.subnet_id, resource.vpc_id), dst
)
detail = (
f"via {route_analysis.next_hop(result.routes[0])}"
if result.ok
else f"no route in {result.table_id or 'any table'}"
)
verdict.checks.append(Check("route", resource.label, result.ok, detail))
if not result.ok:
verdict.ok = False
verdict.issues.append("Route needed")
return verdict
규칙 추가만 하는 적용
이 코드가 하는 일: 계획된 변경의 방향에 따라 인바운드 또는 아웃바운드 규칙 추가 API만 호출합니다. 규칙을 삭제하거나 고치는 호출은 없어서 이 도구가 기존 통신을 끊을 수 없습니다. 같은 규칙이 이미 있어 AWS가 InvalidPermission.Duplicate 오류를 돌려주면 “already present”로 처리하고 넘어가며, 그 밖의 오류는 숨기지 않고 그대로 올립니다.
def apply(self, change: Change) -> str:
ec2 = self.sessions.client("ec2", change.account)
call = (
ec2.authorize_security_group_ingress
if change.direction == "ingress"
else ec2.authorize_security_group_egress
)
try:
call(GroupId=change.sg_id, IpPermissions=change.permissions)
except ClientError as error:
if error.response["Error"]["Code"] == "InvalidPermission.Duplicate":
return "already present"
raise
return "applied"