개요
현재 근무하고 있는 회사에서 모바일 앱을 위한 간단한 API 서버가 필요했습니다. (통칭 “앱 서버”)
PoC로 진행하던 프로젝트가 예상보다 빠르게 완성되었고, 비즈니스 요구사항을 충족한다고 판단되어 프로덕션 환경에 반영되었습니다.
최근 회사에서 새벽에 서비스 점검을 진행하게 되었고, 이 참에 개발계에 존재하던 앱 서버도 운영계로 옮기면 좋겠다고 생각이 들어 진행하게 되었습니다.
운영계로 옮기는 계획을 짰고, 간단하게 진행될 것으로 예상했습니다.
하지만, 역시나 그렇지 않았고 쉽지 않은 과정에 대한 회고를 남기면 좋을 것 같아 이 글을 작성하게 되었습니다.
구조
앱 서버의 구조는 다음과 같습니다.
사용자 요청
저희 개발계서는 운영 도메인의 dev라는 키워드를 추가한 서브 도메인을 사용합니다.
(이번 글에서는
xxx.dev.domain.com
이라는 주소로 가정하겠습니다.)사실 모바일 앱에서는 리버스 엔지니어링을 하지 않는 한 요청 주소가 노출되지 않기 때문에 개발계 서브도메인을 사용하는 것에 대한 부담은 없었습니다.
Route 53
Route 53에서 앱 서버의 주소를 API Gateway로 맵핑해 두었습니다.
API Gateway
API Gateway는 AWS Lambda를 호출하는 트리거가 됩니다.
API Gateway도 자체적으로 엔드포인트를 가지고 있습니다.
AWS Lambda
(앱 서버라고 칭했지만 서버리스입니다😅)
한동안 회사에서 Lambda 열풍이 불었습니다.
간단하고, 가용성에 대한 고려를 덜어줍니다.
저희는 serverless라는 프레임워크를 활용해서 AWS Lambda 프로젝트를 관리 및 배포하고 있습니다.
기회가 된다면 다른 글에서 serverless에 대해 다뤄보도록 하겠습니다.
개발 당시, AWS Lambda를 private subnet에 둘 생각을 하지 못했습니다.
누구나 접근 가능해야 하는 리소스이다 보니, 당연하게 public subnet에 두어야 한다고 생각했는데, 이러한 생각은 앱 서버를 운영계로 옮기는 작업을 진행하며 바뀌게 됩니다.
RDS
AWS Lamdba는 public subnet에 배치했지만, RDS는 아닙니다. (절대 지켜)
계획
계획은 정말 간단했습니다.
계발계에 존재하는 모든 리소스를 운영계에 동일하게 세팅해 두고,
xxx.dev.domain.com
으로 오는 요청을 다시 xxx.domain.com
도메인으로 리다이렉트 시키는 것이었습니다.
이것이 기술적으로 가능한지 테스트한 후 실제 철야작업에 들어갔습니다.

문제 1) 인증서 이슈
철야작업 이전에 운영계에 AWS 리소스 세팅을 해두었기 때문에, RDS만 동기화를 시키고 바로 도메인 리다이렉트를 적용했습니다.
예상과는 다르게 https 인증이 되지 않는 문제가 발생했고, 이를 해결하기 위해 다음 일들을 추가로 시도했습니다.
- xxx.dev.domain.com를 운영계 API Gateway의 엔드포인트로 리다이렉트
- *.dev.domain.com 서브도메인을 운영계 계정의 Route 53에 등록
모든 시도가 실패로 돌아갔고, 다음 원인들이 있었습니다.
작업 이전에 수행한 테스트는 Postman으로 진행했는데, 당시 HTTPS 인증 실패에 관한 내용을 확인하지 못했습니다. 단순히 응답만 오는 것을 보고 기술적 구현이 가능하다고 오판했습니다.
Postman은 기본적으로 HTTPS 인증 오류를 무시하거나, 신뢰하지 않는 인증서를 신뢰하도록 설정할 수 있는 것으로 인해 인해 HTTPS 인증 문제를 간과했습니다.
운영계와 개발계의 aws 계정 분리로 인해 인증서가 공유되지 않았습니다.
(인증서는 AWS Certificate Manager(ACM)으로 생성했습니다.)
*.domain.com
인증서가 서브도메인(*.dev.domain.com
) 인증까지 제공할 것이라 생각했지만, 그렇지 않았습니다.
Plan B
기존 계획을 기술적으로 해결하기 어렵다 판단하고 플랜 B를 세워야 했습니다.
함께 철야 작업을 수행하던 동료분께서 개발계에 위치한 앱 서버를 운영계의 에코서버로 만드는 아이디어를 주셨습니다.
모바일 앱에서 이후 필수 업데이트를 요구할 때까지 운영계와 개발계의 AWS Lambda를 유지하되, RDS는 운영계의 것만 사용하는 전략입니다.
문제 2) 요청이 외부로 나가지 않는 이슈
개발계 AWS Lambda에서 운영계 앱 서버로 요청을 보내는 코드를 추가하고 배포를 진행했습니다.
개발계에서 어떠한 요청을 보내도, 운영계 앱 서버에서는 아무런 로그도 기록되지 않았습니다.
원인은 개발계 Lambda가 public subnet에 위치해도 public IP가 할당되지 않아서 Internet Gateway로 외부 요청이 불가한 것이었습니다.
이를 해결하기 위해서 개발계 Lambda가 NAT Gateway를 통해 요청을 보내어 public ip를 할당받을 수 있도록 해야 했습니다.
기존에 private subnet에서 NAT Gateway로 통신할 수 있도록 Routing Table에 맵핑한 후, 개발계 Lambda를 private subnet으로 옮겨서 배포한 후에 문제를 해결할 수 있었습니다.
배운 점
기술적으로 배운 점은 다음이 있습니다.
Postman로 테스트할 때 유의점:
Postman은 HTTPS 인증을 무시할 수 있는 기능을 제공하기 때문에 Postman 환경이 개발 및 운영 환경과 유사한 지 검토할 것
SSL 인증서와 리다이렉트의 위험성:
SSL 인증서를 숨기기 위해 이리저리 리다이렉트 하는 방법은 시스템을 공격하는 행위와 다를 바 없다는 것
NAT Gateway의 역할:
NAT가 분리된 사설 네트워크에서도 외부와 통신할 수 있도록 도울 수 있는 이유는 public IP로 변환하기 때문이라는 것
'회고' 카테고리의 다른 글
TDD, 클린 코드 with Kotlin 회고 (0) | 2023.12.10 |
---|