Module 06

로컬 개발 환경 — 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
ℹ️ 로컬에서는 Lambda cold start가 없습니다. 코드를 변경하면 Flask가 자동으로 재시작합니다(FLASK_ENV=development). 빠른 반복 개발이 가능합니다.

.env 파일 구성 — 로컬용 환경변수

로컬 개발에는 .env 파일을 사용합니다. Lambda 배포 시에는 zappa_settings.jsonenvironment_variables 섹션에서 환경변수를 주입합니다.

api/.env (로컬 개발용 — .gitignore에 반드시 추가)
# 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
⚠️ .env를 git에 커밋하지 마세요. .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"
    }
  }
}
ℹ️ Lambda에서는 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로 동작
사내망 + truststore 없음
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED]
Azure AD JWKS 조회 실패 → 모든 토큰 검증 실패
사내망 + truststore 있음
시스템 인증서 저장소의 회사 CA를 Python이 신뢰. Azure AD HTTPS 연결 성공.

프론트엔드 로컬 실행 — 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을 여기에 설정합니다.

frontend/.env.local (로컬 개발용)
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
frontend/.env.production (프로덕션 빌드용)
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
ℹ️ Next.js 환경변수 우선순위: .env.local > .env.development > .env. pnpm build 시에는 .env.production이 사용됩니다. .env.localpnpm 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
이 모듈을 마쳤습니다. Flask 로컬 실행, .env 파일 구성과 주의사항, truststore 설치, Next.js 로컬 실행, 환경변수 전환 전략, pnpm approve-builds까지 — 로컬 개발 환경 설정의 전 과정을 이해했습니다.
🎉 과정 완료! 개요(00)부터 로컬 개발(06)까지 전 모듈을 마쳤습니다. 실제 오류 상황이 생기면 트러블슈팅 레퍼런스를 참고하세요.