방화벽 아이콘과 회로 타일, 클라우드 아키텍처 다이어그램이 평면으로 배치된 구성도
글 요약
Terraform 기반 AWS Network Firewall 구축 방법을 코드 중심으로 정리하고, 동일 VPC 환경에서 자주 비교되는 FortiGate 클라우드 방화벽과의 차이를 아키텍처·비용·운영 측면에서 분해합니다. 흔한 구축 실패 사례와 운영 노하우까지 한 번에 보실 수 있거든요.
“클라우드 방화벽은 FortiGate 아니면 불안한 거 아닌가요?”
AWS Network Firewall은 AWS 네이티브 환경에서 충분히 강력한 L3~L7 검사 기능을 제공합니다. Terraform으로 선언적으로 관리하면 FortiGate 대비 비용 60% 이상 절감과 운영 자동화를 동시에 잡을 수 있거든요. 이 글에서는 실제 구축 사례와 비교 분석, 그리고 실무에서 자주 부딪히는 함정까지 모두 공개합니다.
실무에서 클라우드 마이그레이션 프로젝트를 진행하면 거의 항상 등장하는 주제가 방화벽 선택입니다. 많은 엔지니어가 FortiGate가 검증된 장비니까라는 이유로 무조건 BYOL 형태로 FortiGate 인스턴스를 VPC에 띄우는 패턴을 반복하더라고요. 문제는 라이선스 비용, 고가용성 구성 복잡도, 그리고 Terraform 코드베이스가 거대해지면서 오는 관리 부담이 한꺼번에 쏟아진다는 점이었습니다. AWS Network Firewall은 이런 상황에서 가성비 있게 대안을 제시하는 서비스거든요.
📑 목차
본격적으로 들어가기 전에 먼저 짚고 넘어갈 점이 있습니다. AWS 네트워크 방화벽은 AWS가 직접 제공하는 관리 서비스이기 때문에 EC2 기반 FortiGate처럼 패치나 OS 관리에 신경 쓸 필요가 없습니다. 대신 Terraform 모듈을 어떻게 분리하고, 상태 파일을 어떻게 관리할지가 성공과 실패를 가른다는 점이 실무에서 정말 중요하더라고요.
📌 이 글의 핵심 정리
- AWS Network Firewall은 매니지드 Stateful 엔진이라 별도 EC2 운영 부담이 없으며 Terraform 리소스 6개 정도면 VPC 경계 방화벽이 완성됩니다.
- FortiGate 대비 비용 차이는 트래픽 볼륨이 높을수록 벌어지며, BYOL 라이선스 모델에서는 3년 약정 시에도 Network Firewall이 더 유리한 경우가 많습니다.
- 룰 그룹 분리 설계가 Terraform 코드 가독성과 장애 격리의 핵심이며, Suricata 규칙을 Stateful 규칙 그룹에 분리해 두면 도메인 기반 제어가 가능합니다.
- 실패 사례 대부분은 Firewall Subnet CIDR 충돌, 라우팅 테이블 누락, 로그 그룹 권한 미설정에서 발생하므로 사전 점검 체크리스트가 필수입니다.
- CloudWatch Logs와 Kinesis Firehose 조합으로 알림과 장기 보관 파이프라인을 한 번에 잡으면 운영 리스크가 크게 줄어듭니다.
AWS Network Firewall 핵심 개념 이해하기
Firewall Policy와 Firewall 두 단계 구조
AWS Network Firewall은 두 단계 리소스 구조로 동작합니다. 최상위에는 Firewall Policy가 있고, 그 아래에 Stateful 규칙 그룹과 Stateless 규칙 그룹이 여러 개 붙는 형태거든요. 그리고 Firewall Policy를 참조하는 실제 인스턴스가 Firewall 리소스입니다. Terraform으로 선언할 때는 이 세 가지 리소스만 이해하면 절반은 끝났다고 봐도 됩니다.
왜 두 단계로 나눌까?
하나의 Firewall Policy를 여러 VPC의 Firewall이 공유할 수 있기 때문입니다. 예를 들어 개발·스테이징·운영 VPC가 동일한 보안 정책을 따라야 한다면, Policy 모듈만 별도의 Terraform 루트 모듈로 빼두고 여러 환경에서 참조하면 변경 추적이 깔끔해집니다. 저는 보통 modules/network-firewall-policy라는 디렉터리를 따로 만들어 재사용하고 있더라고요.
Stateless와 Stateful 규칙의 역할 차이
Stateless 규칙은 5-tuple 기반으로 빠르게 매칭되는 1차 필터입니다. 허용할 트래픽의 CIDR·포트 범위를 명시적으로 풀어주면 그만큼 Stateful 엔진의 부하가 줄어듭니다. 반면 Stateful 규칙은 Suricata 호환 문법으로 도메인, TLS SNI, HTTP URI 같은 L7 속성까지 검사할 수 있거든요.
- Stateless: 성능 우선, 단순 IP/포트 매칭, 우선순위 숫자가 낮을수록 먼저 평가됨
- Stateful: 정확도 우선, 도메인·프로토콜 매칭, 기본 액션(allow/drop/alert)을 정책 단위로 설정
Terraform IaC 구축 아키텍처 설계
디렉터리 구조와 모듈 분리 전략
Terraform 코드베이스를 어떻게 나눌지가 운영 편의성을 가른다고 해도 과언이 아닙니다. 제가 선호하는 구조는 다음과 같습니다. env/ 디렉터리에는 dev·stg·prod별 tfvars가 들어가고, modules/ 안에는 firewall, policy, logging, route 같은 작은 단위로 모듈이 쪼개져 있거든요.
권장 디렉터리 레이아웃
- modules/network-firewall/ — aws_networkfirewall_firewall, firewall_policy 리소스 캡슐화
- modules/firewall-rule-group/ — Stateful/Stateless 규칙 그룹을 별도로 관리
- modules/firewall-logging/ — CloudWatch Logs, Kinesis Firehose, S3 로그 구성
- env/prod/ — prod 환경 전용 main.tf, variables.tf, terraform.tfvars
Backend와 State Locking 구성
여러 엔지니어가 동시에 Terraform을 적용하면 상태 파일 충돌이 발생합니다. AWS를 사용한다면 S3 + DynamoDB Lock 조합이 가장 안정적입니다. DynamoDB 테이블 하나만 더 만들어두면 동시성 사고를 거의 100% 막을 수 있거든요.
💡 Terraform 백엔드 꿀팁
- S3 버킷에 versioning을 반드시 활성화해 두면 실수로 상태 파일을 덮어썼을 때 복구 가능합니다.
- DynamoDB Lock 테이블 파티션 키는 LockID(문자열)로 통일하면 기존 예제와 호환됩니다.
- CI/CD에서 terraform plan을 PR 단계에서 자동 실행하도록 GitHub Actions 워크플로를 구성하면 리뷰가 훨씬 수월해집니다.
룰 그룹과 정책 구성 상세 가이드
Stateful Rule Group에서 Suricata 규칙 사용하기
Stateful Rule Group에는 두 가지 입력 방식이 있습니다. 하나는 RuleGroup에 직접 Suricata 문법 문자열을 넣는 방식이고, 다른 하나는 외부 파일을 참조하는 방식입니다. 실무에서는 후자를 강력히 권합니다. 규칙이 수십 줄로 늘어나도 Git에서 diff가 깔끔하게 보이기 때문이거든요.
Suricata 규칙 예시 (도메인 화이트리스트)
pass tls $HOME_NET any -> $EXTERNAL_NET any (tls.sni; content:".amazonaws.com"; ends:; sid:1001;) 같은 식으로 작성하면 SNI 기반 화이트리스트가 만들어집니다. sid는 규칙마다 고유해야 한다는 점이 중요합니다.
Stateless 기본 액션과 우선순위
Stateless Rule Group에서는 우선순위 숫자가 낮을수록 먼저 평가됩니다. 기본 액션을 forward로 두고 모든 트래픽을 Stateful 엔진으로 보내는 패턴이 일반적이지만, 명백히 허용된 내부 트래픽은 상위 우선순위에서 pass로 끊어주면 엔진 부하를 크게 줄일 수 있습니다.
⚠️ 룰 그룹 작성 시 주의
- Stateless와 Stateful 규칙이 중복으로 매칭되면 의도치 않게 차단될 수 있으니 평가 순서를 항상 문서화하세요.
- Suricata 규칙에서 $HOME_NET 변수를 정의하지 않으면 모든 IP가 매칭 대상이 되어 보안 사고로 이어질 수 있습니다.
FortiGate와 비교 분석 (아키텍처·비용·운영)
세 가지 비교 관점 정리
두 솔루션을 단순 나열하는 것은 의미가 없습니다. 실무에서 의사결정에 직접적으로 영향을 주는 아키텍처, 비용, 운영 세 가지 축으로 분해해 비교합니다.
아키텍처·비용·운영 비교표
| 비교 항목 | AWS Network Firewall | FortiGate (BYOL, EC2) |
|---|---|---|
| 배포 형태 | 매니지드 서비스, AZ별 엔드포인트 | EC2 인스턴스 + FortiOS 직접 관리 |
| 고가용성 | AZ 자동 분산, 추가 작업 불필요 | FGCP 클러스터 또는 A-P 인스턴스 페어 구성 |
| L7 검사 | Suricata 호환 (도메인·SNI·URI) | IPS 엔진, 애플리케이션 컨트롤, 웹 필터 |
| 월 비용 (예시) | 엔드포인트 + 데이터 처리 GB 요금 | EC2 인스턴스 + BYOL 라이선스 (모델별 상이) |
| 패치·업그레이드 | AWS가 자동 관리 | 엔지니어 수동 적용, 점검 윈도우 필요 |
| Terraform 리소스 수 | 약 6개로 압축 가능 | AMI·ENI·라우팅·bootstrap 10개 이상 |
어떤 상황에 FortiGate가 여전히 유리한가
모든 케이스에서 AWS Network Firewall이 우월하다고 말할 수는 없습니다. 온프레미스 FortiGate와 VPN/IPsec 터널이 이미 깔려 있는 환경, 그리고 UTM 기능(안티바이러스, 웹 필터링, DLP)이 정책상 필수인 컴플라이언스 환경에서는 FortiGate가 여전히 강점이 있거든요. 반면 신규 AWS 네이티브 프로젝트, 비용 최적화가 중요한 SaaS 백엔드, 빠른 PoC가 필요한 상황에서는 Network Firewall이 더 합리적인 선택입니다.
실무 실패 사례와 해결 노하우
실제 겪은 실패 시나리오: 라우팅 누락으로 인한 통신 두절
한 프로젝트에서 Terraform으로 Network Firewall을 배포했는데, apply는 정상적으로 끝났는데 EC2에서 외부로 나가는 트래픽이 모두 차단되는 사고가 발생했습니다. 원인은 Firewall Endpoint가 배포된 전용 서브넷으로 향하는 라우팅 테이블 항목을 Private Subnet RT에 추가하지 않았기 때문이더라고요.
실패의 3단계 원인
- 1단계: Firewall 리소스만 선언하고 VPC 라우팅 모듈은 별도 PR로 분리되어 있어 적용 누락
- 2단계: terraform plan에 라우팅 변경이 표시되었으나 리뷰어가 RT 변경의 의미를 놓침
- 3단계: 로그 그룹이 없어 어떤 트래픽이 차단되는지 즉시 확인 불가
전문가 시선의 해결 노하우 5가지
- 라우팅과 Firewall을 한 모듈로 묶기: Terraform 모듈을 firewall·policy·route를 함께 선언하는 단위로 구성하면 PR이 한 번에 머지되면서 누락이 구조적으로 방지됩니다.
- 프리체크용 reachability 테스트:
aws ec2 describe-vpc-endpoint-connections와 reachability analyzer를 terraform-null-resource에서 자동 호출해 배포 직후 검증합니다. - 로그 그룹은 Firewall 리소스와 동시 생성: alert 액션을 기본으로 두고 CloudWatch Logs에 흘려보내면 차단 패턴을 즉시 가시화할 수 있습니다.
- Suricata 규칙은 alert -> drop 점진적 전환: 신규 규칙은 처음에 alert로만 두고, 1주일간 모니터링한 뒤 drop으로 바꾸면 오탐으로 인한 장애를 예방할 수 있습니다.
- Firewall Subnet CIDR 표준화:
10.0.255.0/26처럼 AZ별 64개씩 끊어 잡는 규칙을 정해두면 라우팅·권한·디버깅이 모두 일관됩니다.
운영·모니터링·비용 최적화 꿀팁
로그 파이프라인 구성 (CloudWatch → Firehose → S3)
운영 측면에서 가장 많이 쓰는 패턴은 CloudWatch Logs로 알림용 단기 보관, Kinesis Firehose → S3로 장기 보관을 동시에 구성하는 것입니다. Terraform에서는 aws_kinesis_firehose_delivery_stream과 aws_cloudwatch_log_group 두 리소스만 추가하면 되거든요. S3에 쌓인 로그는 Athena로 분석하면 비용 대비 강력한 가시성을 확보할 수 있습니다.
비용 최적화 두 가지 핵심 포인트
- Stateless로 1차 컷오프: 명백한 내부 트래픽(예: VPC 내부 10.0.0.0/16 통신)을 Stateless pass로 끊어주면 Stateful 엔진에서 처리되는 데이터 양이 줄어 비용 절감으로 이어집니다.
- 로그 레벨 조정: alert만 활성화하고 flow 로그를 끄는 식으로 조정하면 GB당 요금이 큰 폭으로 줄어듭니다. 보안 요건상 모든 로그가 필요한 경우가 아니라면 기본 옵션이 가장 가성비가 좋더라고요.
💡 운영 안정화 꿀팁
- CloudWatch 알람에서 DroppedPackets 지표가 임계치를 넘으면 Slack으로 자동 발송하도록 구성하면 장애 감지 속도가 빨라집니다.
- 규칙 변경 시 terraform plan을 PR 코멘트로 자동 게시하면 리뷰 품질이 크게 향상됩니다.
- 정기적으로 aws networkfirewall describe-firewall 결과를 점검 스크립트로 수집해 변경 드리프트를 추적하세요.
자주 묻는 질문
Q. AWS Network Firewall은 Transit Gateway 환경에서도 동작하나요?
A. 네, VPC 단위로 동작하지만 Transit Gateway 뒤에 여러 VPC가 있을 때에는 각 VPC마다 Firewall Endpoint를 두는 게 일반적입니다. 중앙집중식 검사를 원한다면 별도 Inspection VPC에 Endpoint를 두고 TGW 라우팅 테이블로 트래픽을 우회시키는 패턴을 사용합니다.
Q. Stateful 규칙 그룹에 작성할 수 있는 최대 규칙 수는 어떻게 되나요?
A. 하나의 Stateful Rule Group당 30,000개 규칙까지 선언 가능합니다. 단, 규칙 수가 늘어날수록 매칭 평가 시간이 길어지므로 도메인 단위로 묶어 Suricata 변수와 combo 룰을 활용하는 편이 성능상 유리합니다.
Q. Terraform 코드 변경 없이 긴급히 특정 트래픽을 차단하려면 어떻게 하나요?
A. AWS 콘솔에서 Firewall Policy에 임시 규칙 그룹을 추가하거나, Suricata 규칙을 alert -> drop으로 토글링할 수 있습니다. 다만 모든 변경은 Git을 통해 추적하는 것이 감사 로그 측면에서 안전합니다.
Q. FortiGate에서 마이그레이션할 때 기존 정책은 어떻게 옮기나요?
A. FortiGate Address Object와 Service Object를 1차로 추출한 뒤, IP/포트 기반 Stateless 규칙과 도메인 기반 Stateful 규칙으로 분류해 옮기는 작업을 거치면 됩니다. 자동 변환 스크립트는 보안상 직접 작성하기보다 수동 매핑을 권장합니다.
정리하면, AWS Network Firewall은 Terraform과 결합할 때 비용 효율과 운영 자동화 두 마리 토끼를 모두 잡을 수 있는 매니지드 방화벽입니다. FortiGate가 여전히 강점이 있는 시나리오도 분명히 존재하지만, AWS 네이티브 워크로드 비중이 높아지고 있는 요즘 같은 상황에서는 한 번쯤 검토해볼 가치가 충분합니다. 실패 사례에서 살펴본 것처럼 라우팅과 로깅을 함께 선언하는 모듈 설계가 가장 중요한 운영 노하우라는 점, 꼭 기억해 두시길 권합니다.
면책조항: 본 글은 작성자의 실무 경험을 바탕으로 정리된 일반적인 가이드이며, 특정 AWS 계정 환경에서의 비용·성능을 보장하지 않습니다. 서비스 요금, 리소스 한도, Terraform 프로바이더 동작은 시점에 따라 변경될 수 있으므로, 실제 적용 전에는 반드시 AWS 공식 문서와 사용 중인 Terraform 버전의 레퍼런스를 확인하시기 바랍니다. 본 콘텐츠를 활용한 모든 적용 결과에 대한 책임은 사용자 본인에게 있습니다.