Azure AD SSO + 서버리스 배포
Flask Lambda · Next.js S3/CloudFront · DynamoDB · Azure AD
과정 개요
왜 이 스택인가, 무엇을 만드는가, 어떻게 배우는가.
이 교육이 필요한 이유
GS Retail AX Squad의 프로젝트들은 대부분 같은 스택을 씁니다. 사내 Azure AD 계정으로 로그인하고, Flask 백엔드를 Lambda에 올리고, Next.js 화면을 S3 + CloudFront로 서빙하는 구조입니다.
그런데 이 흐름을 처음부터 끝까지 "왜 이렇게 되는지" 설명할 수 있는 사람이 팀에 몇 명이나 있나요?
| 😰 지금 흔한 상황 | 결과 |
|---|---|
| CORS 오류가 나면 무작정 구글링 | 진짜 원인을 모른 채 일단 동작 |
| Lambda에 배포하면 왜 500이 나는지 모름 | API Gateway 타입 문제인지 IAM 문제인지 구분 불가 |
| 새 프로젝트에 SSO 붙이려면 이전 코드를 복붙 | 왜 그 코드가 필요한지 모름 — 버그 디버깅 불가 |
전체 아키텍처 한눈에
이 과정에서 다루는 시스템은 아래 세 계층으로 이루어져 있습니다. 각 계층이 어떤 역할을 하는지 먼저 큰 그림으로 이해하세요.
인증 흐름 단계별
output: 'export' 정적 빌드에서는 서버사이드 코드를 실행할 수 없습니다. 브라우저가 API Gateway를 직접 호출하는 구조입니다.왜 이 구성 요소인가
각 기술을 선택한 데는 이유가 있습니다. 그 이유를 이해해야 문제가 생겼을 때 올바른 방향으로 해결할 수 있습니다.
왜 서버(EC2) 대신 Lambda인가
음식 배달 앱을 생각해보세요. 점심·저녁에는 주문이 폭발적으로 늘어나고, 새벽에는 거의 없습니다. EC2 서버를 쓰면 새벽에도 서버 비용이 나갑니다. Lambda는 요청이 있을 때만 실행하고, 없으면 비용이 0입니다.
| 구분 | EC2 (항상 켜진 서버) | Lambda (서버리스) |
|---|---|---|
| 비용 | 24시간 과금 | 요청 건당 과금 (교육 데모는 거의 0원) |
| 운영 | OS 패치, 보안 업데이트 직접 관리 | AWS가 관리 |
| 스케일 | 수동 스케일업 또는 Auto Scaling 설정 | 자동 확장 |
| 단점 | 항상 비용 발생 | Cold start (첫 요청 지연 1~3초) |
왜 Next.js를 정적 빌드로 S3에 올리는가
식당으로 비유하면, 메뉴판(HTML/JS/CSS)은 미리 인쇄해서 탁자에 올려두는 것과 같습니다. 손님마다 새로 만들어줄 필요가 없습니다. 정적 빌드(output: 'export')는 미리 완성된 파일들을 S3에 저장하고 CloudFront가 전 세계에 빠르게 전달합니다.
| 방식 | 설명 | 이 프로젝트 |
|---|---|---|
| SSR (서버 렌더링) | 요청마다 서버가 HTML 생성 | ❌ Lambda에 Next.js 서버 없음 |
| 정적 빌드 | 빌드 시 HTML/JS/CSS 미리 생성 | ✅ output: 'export' 사용 |
왜 CloudFront에 OAC를 쓰는가
S3 버킷을 인터넷에 직접 공개하면 누구나 파일 URL로 접근할 수 있습니다. OAC(Origin Access Control)는 "CloudFront를 통해서만 S3에 접근 가능"하도록 잠그는 자물쇠입니다. 버킷은 완전히 비공개 상태를 유지합니다.
| 방식 | S3 공개 여부 | 보안 |
|---|---|---|
| S3 퍼블릭 공개 | 누구나 직접 접근 가능 | 😰 취약 |
| OAC + CloudFront | S3는 비공개, CloudFront만 허용 | ✅ 안전 |
왜 Azure AD SSO인가
GS Retail 임직원은 이미 사내 Microsoft 계정을 갖고 있습니다. Azure AD SSO를 사용하면 별도의 회원 DB, 비밀번호 관리, 세션 관리가 필요 없습니다. 사내 계정으로 로그인하면 Azure AD가 토큰을 발급하고, 우리 Flask 서버는 그 토큰을 검증하기만 하면 됩니다.
전체 모듈 로드맵
이 과정은 7개 모듈 + 1개 레퍼런스로 구성됩니다. 순서대로 읽어도 되고, 궁금한 모듈부터 봐도 됩니다.
| 순서 | 모듈 | 핵심 내용 | 난이도 |
|---|---|---|---|
| 00 | 과정 개요 (현재) | 전체 아키텍처, 각 기술 선택 이유 | ⭐ |
| 01 | Azure AD SSO 이해 | JWT 구조, RS256 검증, MSAL 흐름 | ⭐⭐ |
| 02 | Flask on Lambda | Zappa 해부, ephemeral storage, CORS 두 층 | ⭐⭐ |
| 03 | Next.js → CloudFront | SSR 격리 패턴, React 18 고정 이유, 캐시 전략 | ⭐⭐ |
| 04 | IAM 최소 권한 | Service Role vs Resource-based Policy, gsr-* 와일드카드 | ⭐⭐ |
| 05 | 원샷 부트스트랩 | Claude Code 프롬프트 템플릿, 11 STEP 흐름 | ⭐⭐ |
| 06 | 로컬 개발 환경 | Flask + Next.js 로컬 연동, 환경변수 관리 | ⭐ |
| R | 트러블슈팅 레퍼런스 | 실제 오류 15가지 + 해결책 | 레퍼런스 |
사전 준비 체크리스트
이 과정을 시작하기 전에 아래 항목을 확인하세요. Module 05 (원샷 부트스트랩)를 직접 실행하려면 모두 준비되어야 합니다. 개념 이해만 원한다면 AWS 계정 없이도 01~04 모듈을 읽을 수 있습니다.
| ☐ | 항목 | 확인 방법 | 필요 모듈 |
|---|---|---|---|
| ☐ | AWS CLI 설치 + 프로파일 설정 | aws sts get-caller-identity --profile <프로파일명> | 02, 03, 04, 05 |
| ☐ | Python 3.12 설치 | /opt/homebrew/opt/python@3.12/bin/python3.12 --version | 02, 05 |
| ☐ | Node.js v20+ 설치 | node --version | 03, 05 |
| ☐ | pnpm 설치 | pnpm --version | 03, 05, 06 |
| ☐ | Azure AD Tenant ID + Client ID 확보 | Azure Portal → 앱 등록 → 해당 앱 → 개요 | 01, 05 |
| ☐ | AWS IAM 서비스 역할 사전 생성 | IAM 콘솔 → 역할 → 이름 + ARN 확인 | 04, 05 |
python3.12 심볼릭 링크를 PATH에 추가하지 않습니다. /opt/homebrew/opt/python@3.12/bin/python3.12를 사용하거나, brew install python@3.12로 먼저 설치하세요.완성 데모 앱 — 이것을 만듭니다
이 과정을 마치면 아래 기능을 가진 앱이 AWS에 배포된 상태가 됩니다.
Microsoft 계정으로 로그인
사내 Azure AD 계정으로 로그인하면 Azure에서 토큰을 발급합니다. 별도 회원가입 불필요.
내 토큰 정보 확인
로그인 후 Azure AD가 발급한 JWT claims(이름, 이메일, 만료시각 등)를 화면에 표시합니다.
DynamoDB 기록 조회
로그인할 때마다 DynamoDB에 기록됩니다. 내가 언제, 어떤 IP에서 접속했는지 이력을 볼 수 있습니다.
CloudFront URL로 접근
https://xxxx.cloudfront.net 주소로 전 세계에서 접근 가능한 상태로 배포됩니다.