로컬 개발 환경 — AWS 없이 개발하기
Flask 로컬 서버, .env 관리, pnpm 설정까지
로컬 개발 환경
Lambda에 배포하기 전에 로컬에서 Flask와 Next.js를 연동하는 방법
백엔드 로컬 실행 — Flask dev server
Zappa 없이 Flask를 로컬에서 바로 실행할 수 있습니다. python -m flask run으로 실행하면 http://localhost:5000에서 API가 동작합니다.
📋 Flask 로컬 실행
cd my-project/api
source venv/bin/activate
# Flask 앱 위치 지정 + 개발 모드 실행
FLASK_APP=samples.api.app:app \
FLASK_ENV=development \
python -m flask run --port 5000
# 또는 환경변수를 .env에서 불러오기 (python-dotenv 설치 시 자동 로드)
flask run --port 5000
FLASK_ENV=development). 빠른 반복 개발이 가능합니다..env 파일 구성 — 로컬용 환경변수
로컬 개발에는 .env 파일을 사용합니다. Lambda 배포 시에는 zappa_settings.json의 environment_variables 섹션에서 환경변수를 주입합니다.
# Azure AD
AZURE_TENANT_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
AZURE_CLIENT_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
# DynamoDB
DYNAMODB_TABLE_NAME=gsr-my-project-login-history
AWS_DEFAULT_REGION=ap-northeast-2
# AWS 프로파일 (로컬에서 boto3가 사용)
AWS_PROFILE=gsr-dev
# 로컬 개발 전용 — 프로덕션 Lambda에는 없음
FLASK_ENV=development
FLASK_DEBUG=1
.gitignore에 .env가 포함되어 있는지 반드시 확인하세요. Azure Tenant ID와 Client ID는 공개 정보처럼 보이지만, 실제 사내 Azure AD에 연결된 식별자입니다. 레포 공개 시 피싱 공격의 표적이 될 수 있습니다.Lambda 환경변수 주입 (zappa_settings.json)
📋 zappa_settings.json — environment_variables
{
"prod": {
...
"environment_variables": {
"AZURE_TENANT_ID": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"AZURE_CLIENT_ID": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"DYNAMODB_TABLE_NAME": "gsr-my-project-login-history"
}
}
}
dotenv가 실행되지 않습니다. app.py의 try: from dotenv import load_dotenv 블록은 Lambda에서 ImportError가 나서 자동으로 건너뜁니다. Lambda의 환경변수는 zappa_settings.json에서 설정한 값이 주입됩니다.truststore 설치 — GS Retail 사내망 SSL 연결
GS Retail 사내망에서 Azure AD에 HTTPS 요청을 보낼 때 회사 자체 CA가 서명한 인증서를 사용합니다. truststore를 설치하지 않으면 SSLCertVerificationError가 발생합니다.
📋 truststore 설치 및 requirements.txt 추가
# 가상환경 활성화 후 설치
pip install truststore
# requirements.txt에도 추가
echo "truststore" >> requirements.txt
app.py의 조건부 import 패턴이 자동으로 처리합니다:
try:
import truststore
truststore.inject_into_ssl() # 시스템 인증서 저장소에서 회사 CA 주입
except ImportError:
pass # Lambda: truststore 없음, AWS 자체 CA로 동작
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED]Azure AD JWKS 조회 실패 → 모든 토큰 검증 실패
프론트엔드 로컬 실행 — Next.js dev server
로컬에서 Next.js를 실행할 때는 Flask 로컬 서버(http://localhost:5000)를 API로 사용합니다.
📋 프론트엔드 로컬 실행
cd my-project/frontend
# 의존성 설치
pnpm install
# 로컬 개발 서버 실행
pnpm dev # → http://localhost:3000
pnpm dev는 .env.local을 자동으로 읽습니다. 로컬 API URL을 여기에 설정합니다.
NEXT_PUBLIC_API_URL=http://localhost:5000
NEXT_PUBLIC_AZURE_TENANT_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
NEXT_PUBLIC_AZURE_CLIENT_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
NEXT_PUBLIC_REDIRECT_URI=http://localhost:3000
NEXT_PUBLIC_API_URL=https://yyyy.execute-api.ap-northeast-2.amazonaws.com/prod
NEXT_PUBLIC_AZURE_TENANT_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
NEXT_PUBLIC_AZURE_CLIENT_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
NEXT_PUBLIC_REDIRECT_URI=https://xxxx.cloudfront.net
.env.local > .env.development > .env. pnpm build 시에는 .env.production이 사용됩니다. .env.local은 pnpm build에서도 최우선입니다 — 빌드 시에는 반드시 제거하거나 생산 값으로 교체하세요.환경변수 전환 전략
| 상황 | API URL | 환경 파일 |
|---|---|---|
| 로컬 개발 | http://localhost:5000 | .env.local |
| 스테이징 테스트 | https://staging.execute-api.../prod | .env.local 교체 또는 .env.staging |
| 프로덕션 빌드 | https://prod.execute-api.../prod | .env.production |
NEXT_PUBLIC_ prefix가 반드시 필요합니다. Next.js에서 브라우저에서 접근 가능한 환경변수는 NEXT_PUBLIC_로 시작해야 합니다. prefix 없는 환경변수는 서버사이드에서만 동작합니다 — 정적 빌드에서는 값이 비어있게 됩니다.pnpm approve-builds — @azure/msal-node 설치 오류 해결
pnpm v9+는 보안 강화를 위해 빌드 스크립트가 있는 패키지 설치 시 명시적 승인을 요구합니다. @azure/msal-node는 native 모듈을 컴파일하는 빌드 스크립트가 있어 이 승인이 필요합니다.
📋 오류 증상
$ pnpm install
WARN @azure/msal-node@2.x.x requires a build script, but a global approval is needed.
ERR_PNPM_RUN_SCRIPTS_IN_LEGACY_MODE Run "pnpm approve-builds" to approve builds.
📋 해결 방법
pnpm approve-builds
# 또는 .npmrc에 영구 설정
echo "enable-pre-post-scripts=true" >> .npmrc
# 특정 패키지만 허용 (보안상 권장)
pnpm approve-builds @azure/msal-node