[Project] Roomeya

Donghyeon Ko·2025년 12월 12일

[Project]

목록 보기
2/4
post-thumbnail

프로젝트 소개

Roomeya는 실제 외부 기숙사 학생의 요구사항을 기반으로 만든 대학생들의 기숙사 룸메이트 매칭을 도와주는 서비스입니다. 학생들이 설문을 작성하면, 생활 패턴과 성향을 분석하여 최적의 룸메이트를 매칭해주고 결과를 이메일로 전송합니다.

저는 이 프로젝트에서 인프라 파트를 담당하여 요구사항 분석을 통한 AWS 클라우드 아키텍처 설계와 Terraform을 활용한 IaC(Infrastructure as Code) 구현을 맡았습니다.


🏗️ 아키텍처 설계

전체 흐름

사용자 → Cognito 인증 → API Gateway → Lambda → DynamoDB
                                        ↓
                                       S3
                                        ↓
                              Step Functions (워크플로우)
                                        ↓
                                      SES (이메일)

데이터 흐름

폼 생성 플로우

사용자 → Cognito 인증 → API Gateway → CreateForm Lambda → DynamoDB (Forms)

폼 제출 플로우

학생 → API Gateway → SubmitForm Lambda → DynamoDB (FormResponses)

매칭 처리 플로우

관리자 → Step Functions 시작
  ↓
matchingProcessor (DynamoDB 조회)
  ↓
excelProcessor (결과 생성 → S3)
  ↓
emailSender (SES 이메일 발송)

사용한 AWS 서비스

카테고리서비스용도
ComputeLambda9개의 서버리스 함수
OrchestrationStep Functions매칭 처리 워크플로우
StorageS3파일 업로드/내보내기
DatabaseDynamoDB폼, 응답, 결과, 학생 데이터
APIAPI Gateway (HTTP)REST API 엔드포인트
AuthCognito사용자 인증 (OAuth 2.0)
MessagingSES매칭 결과 이메일 발송
MonitoringCloudWatch로그 관리

인프라 구성 상세

1. Serverless 아키텍처 선택 이유

처음에는 EC2 기반 아키텍처도 고려했지만, 다음 이유로 Serverless를 선택했습니다:

  • 서비스 환경 고려 : 기숙사 배정은 학기 시작 등 특정 기간 이후에는 서비스 되지 않는 상황에서 EC2 기반 아키텍처는 리소스 낭비가 크다고 판단했습니다.
  • 비용 효율성: 학생 프로젝트 특성상 트래픽이 일정하지 않음
  • 운영 부담 최소화: 서버 관리 없이 코드에만 집중
  • 자동 스케일링: 매칭 마감 시즌에 트래픽 급증 대응

2. Lambda 함수 구성 (9개)

📦 Lambda Functions
├── upload-url        # S3 Presigned URL 생성
├── getFormList       # 폼 목록 조회
├── CreateForm        # 새 폼 생성
├── SubmitForm        # 폼 응답 제출
├── identify_student  # 학생 식별
├── matchingProcessor # 매칭 알고리즘 실행
├── matchingResult    # 매칭 결과 처리
├── excelProcessor    # 엑셀 파일 생성
└── emailSender       # 이메일 발송

각 Lambda에 필요한 최소 권한만 부여하는 Least Privilege 원칙을 적용했습니다.

3. DynamoDB 테이블 설계

# 4개의 테이블, PAY_PER_REQUEST 모드로 비용 최적화

Roomeya-Forms          # PK: formId
Roomeya-FormResponses  # PK: formId, SK: studentId (복합키)
Roomeya-Results        # PK: formId
Roomeya-Students       # PK: studentId

4. Step Functions 워크플로우

매칭 프로세스를 거쳐 이메일 발송까지는 여러 단계를 거쳐야 해서 Step Functions로 오케스트레이션했습니다.

{
  "StartAt": "ProcessMatching",
  "States": {
    "ProcessMatching": { "Next": "ProcessExcel" },
    "ProcessExcel": { "Next": "SendEmail" },
    "SendEmail": { "End": true }
  }
}

장점:

  • 각 단계별 실패 시 재시도 로직 구현 용이
  • 실행 히스토리 추적 가능
  • 시각적으로 워크플로우 모니터링

5. Cognito 인증

OAuth 2.0 기반 인증을 구현했습니다.

# 지원하는 인증 플로우
- Authorization Code Flow
- Implicit Flow
- User Password Auth
- SRP Auth

콜백 URL 설정:

  • 로컬 개발: http://localhost:5173
  • 프로덕션: https://dev.d20iv4pldubgty.amplifyapp.com

Terraform으로 IaC 구현

프로젝트 구조

Roomeya-Infrastructure-Terraform/
├── main.tf           # Provider 설정
├── vpc.tf            # 네트워크
├── lambda.tf         # Lambda 함수 + IAM
├── apigateway.tf     # API Gateway
├── dynamodb.tf       # DynamoDB 테이블
├── cognito.tf        # 인증
├── stepfunctions.tf  # 워크플로우
├── s3.tf             # 스토리지
├── ses.tf            # 이메일
├── cloudwatch.tf     # 로깅
└── outputs.tf        # 출력값

배운 점 & 회고

잘한 점 (Good Point)

  1. IaC 도입

    • 인프라 변경 이력 추적 가능
    • 코드 리뷰를 통한 실수 방지
    • 환경 복제가 쉬워짐
  2. Serverless 아키텍처

    • 비용 절감 (사용한 만큼만 지불)
    • 운영 부담 최소화
    • 빠른 개발 속도
  3. 소프트웨어 공학

    • Agile 방식으로 진행
    • 요구자의 추상적인 부분을 기술적인 부분으로 해석
    • 확장방안에 대해 고민

아쉬운 점 & 개선할 점

  1. State 관리

    • 로컬 State 파일 사용 → S3 Backend로 전환 필요
    • 팀 협업 시 State Lock 기능 필요 (DynamoDB)
  2. 환경 분리

    • 현재 단일 환경 → dev/staging/prod 분리 필요
    • Terraform Workspace 또는 디렉토리 분리 고려
  3. 모니터링 강화

    • CloudWatch Alarms 추가 필요
    • X-Ray 트레이싱 도입 검토
  4. CI/CD 파이프라인

    • GitHub Actions로 자동 배포 구축 예정
    • terraform plan 결과 PR 코멘트로 자동 게시

🧐 기술적 도전과 해결

Challenge 1: Lambda 배포 파일 관리

문제: Lambda 코드와 인프라 코드가 다른 레포에 있어서 배포 경로 관리가 복잡

해결:

# 상대 경로로 배포 파일 참조
filename         = "../Roomeya-Lambda-Deployments/upload-url.zip"
source_code_hash = filebase64sha256("../Roomeya-Lambda-Deployments/upload-url.zip")

Challenge 2: CORS 설정

문제: 프론트엔드에서 API 호출 시 CORS 에러 발생

해결:

cors_configuration {
  allow_headers = ["content-type", "authorization", "x-requested-with"]
  allow_methods = ["GET", "POST", "OPTIONS", "PATCH", "PUT", "DELETE", "HEAD"]
  allow_origins = [
    "https://dev.d20iv4pldubgty.amplifyapp.com/",
    "http://localhost:5173"
  ]
}

Challenge 3: 기존 리소스 Import

문제: 이미 콘솔에서 만든 리소스를 Terraform으로 관리하고 싶음

해결:
1. terraform import로 State에 리소스 추가
2. terraform plan으로 현재 설정과 코드 비교
3. 코드를 실제 설정에 맞게 수정
4. drift 없이 terraform apply 가능한 상태로 만듦


프로젝트 성과

  • 소프트웨어 공학 : Agile, QA등 수업 중에 이론으로 배운 내용을 실무에 적용
  • 인프라 코드화: 10개 이상의 AWS 서비스를 Terraform으로 관리
  • 비용 최적화: Serverless 아키텍처로 월 예상 비용 최소화
  • 배포 자동화 기반 마련: IaC로 CI/CD 파이프라인 구축 가능한 상태

마치며

이번 프로젝트를 통해 AWS 서버리스 아키텍처와 Terraform IaC에 대해 실전 경험을 쌓을 수 있었습니다. 특히 기존에 콘솔로 만든 리소스를 Terraform으로 마이그레이션하는 과정에서 많은 것을 배웠습니다.

다음 프로젝트에서는 처음부터 Terraform으로 시작하고, CI/CD 파이프라인까지 완성하는 것이 목표입니다! 🚀

0개의 댓글