ALPACO ํ”„๋กœ์ ํŠธ: Terraform ์ธํ”„๋ผ ์‚ฌ์šฉ ๊ฐ€์ด๋“œ

์ด ๋ฌธ์„œ๋Š” Terraform์„ ์‚ฌ์šฉํ•˜์—ฌ ALPACO ํ”„๋กœ์ ํŠธ์˜ AWS ์ธํ”„๋ผ๋ฅผ ์ดํ•ดํ•˜๊ณ , ๋ฐฐํฌํ•˜๋ฉฐ, ๊ด€๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ํฌ๊ด„์ ์ธ ๊ฐ€์ด๋“œ์ž…๋‹ˆ๋‹ค.

1. ์„œ๋ก 

ALPACO ํ”„๋กœ์ ํŠธ๋Š” AWS ํด๋ผ์šฐ๋“œ ์ธํ”„๋ผ๋ฅผ ์ฝ”๋“œํ™”๋˜๊ณ , ๋ฐ˜๋ณต ๊ฐ€๋Šฅํ•˜๋ฉฐ, ๋ฒ„์ „ ๊ด€๋ฆฌ๊ฐ€ ๊ฐ€๋Šฅํ•œ ๋ฐฉ์‹์œผ๋กœ ์ •์˜ํ•˜๊ณ  ํ”„๋กœ๋น„์ €๋‹ํ•˜๊ธฐ ์œ„ํ•ด Terraform์„ ํ™œ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด ์ ‘๊ทผ ๋ฐฉ์‹์€ ํ™˜๊ฒฝ ์ „๋ฐ˜์˜ ์ผ๊ด€์„ฑ์„ ๋ณด์žฅํ•˜๊ณ  ๋ณต์žกํ•œ ํด๋ผ์šฐ๋“œ ๋ฆฌ์†Œ์Šค ๊ด€๋ฆฌ๋ฅผ ๋‹จ์ˆœํ™”ํ•ฉ๋‹ˆ๋‹ค.

์ด ๊ฐ€์ด๋“œ์—์„œ๋Š” ๋‹ค์Œ ๋‚ด์šฉ์„ ๋‹ค๋ฃน๋‹ˆ๋‹ค:

  • ์‚ฌ์šฉ๋œ ํ•ต์‹ฌ ๊ธฐ์ˆ  ๋ฐ ์›์น™.
  • Terraform ์ฝ”๋“œ์˜ ๋””๋ ‰ํ† ๋ฆฌ ๊ตฌ์กฐ.
  • ๋ฐฐํฌ๋ฅผ ์œ„ํ•œ ์‚ฌ์ „ ์ค€๋น„ ์‚ฌํ•ญ.
  • ๊ฐ ์ธํ”„๋ผ ๋ชจ๋“ˆ์— ๋Œ€ํ•œ ๋‹จ๊ณ„๋ณ„ ๋ฐฐํฌ ์ง€์นจ.
  • CI/CD ํ†ตํ•ฉ ๊ณ ๋ ค ์‚ฌํ•ญ.
  • ์‹œํฌ๋ฆฟ(๋ฏผ๊ฐ ์ •๋ณด) ๊ด€๋ฆฌ.

2. ํ•ต์‹ฌ ๊ธฐ์ˆ  ๋ฐ ์›์น™

  • Terraform: ์ฃผ์š” IaC(Infrastructure as Code) ๋„๊ตฌ์ž…๋‹ˆ๋‹ค.
    • ๋ชจ๋“ˆ์„ฑ(Modularity): ์ธํ”„๋ผ๋Š” ๋…ผ๋ฆฌ์  ๋ชจ๋“ˆ(์˜ˆ: app, api, cognito, chatbot)๋กœ ๋ถ„ํ• ๋ฉ๋‹ˆ๋‹ค.
    • ์›๊ฒฉ ์ƒํƒœ(Remote State): Terraform ์ƒํƒœ๋Š” ํ˜‘์—…๊ณผ ์•ˆ์ „์„ ์œ„ํ•ด S3 ๋ฒ„ํ‚ท์— ์ €์žฅ๋˜๊ณ  DynamoDB ํ…Œ์ด๋ธ”์„ ์‚ฌ์šฉํ•˜์—ฌ ์ž ๊น๋‹ˆ๋‹ค. ์ด S3 ๋ฒ„ํ‚ท๊ณผ DynamoDB ํ…Œ์ด๋ธ”์€ backend-setup ๋ชจ๋“ˆ์— ์˜ํ•ด ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.
    • ๋ณ€์ˆ˜(Variables): ๋‹ค์–‘ํ•œ ํ™˜๊ฒฝ์ด๋‚˜ ์„ค์ •์— ๋Œ€ํ•œ ๊ตฌ์„ฑ ๋งค๊ฐœ๋ณ€์ˆ˜ํ™”.
    • ์ถœ๋ ฅ(Outputs): ๋‹ค๋ฅธ ๋ชจ๋“ˆ์ด๋‚˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ตฌ์„ฑ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ์ค‘์š”ํ•œ ๋ฆฌ์†Œ์Šค ์‹๋ณ„์ž ๋…ธ์ถœ.
  • ํ™œ์šฉ๋œ AWS ์„œ๋น„์Šค:
    • S3: Terraform ์ƒํƒœ ์ €์žฅ, ํ”„๋ก ํŠธ์—”๋“œ ์ •์  ์ž์‚ฐ ํ˜ธ์ŠคํŒ….
    • DynamoDB: Terraform ์ƒํƒœ ์ž ๊ธˆ, ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ฐ์ดํ„ฐ ์ €์žฅ (์ปค๋ฎค๋‹ˆํ‹ฐ ๊ฒŒ์‹œ๋ฌผ, ๋ฌธ์ œ, ์ œ์ถœ ๊ธฐ๋ก ๋“ฑ).
    • Cognito: ์‚ฌ์šฉ์ž ์ธ์ฆ ๋ฐ ๊ถŒํ•œ ๋ถ€์—ฌ.
    • API Gateway: ๋ฐฑ์—”๋“œ ์„œ๋น„์Šค๋ฅผ ์œ„ํ•œ RESTful API ๋…ธ์ถœ.
    • Lambda: ๋ฐฑ์—”๋“œ ๋กœ์ง์„ ์œ„ํ•œ ์„œ๋ฒ„๋ฆฌ์Šค ์ปดํ“จํŒ… (์ปค๋ฎค๋‹ˆํ‹ฐ API, ๋ฌธ์ œ API, ์ฝ”๋“œ ์‹คํ–‰, ์ฑ—๋ด‡, ๋ฌธ์ œ ์ƒ์„ฑ).
    • Lambda Layers: Lambda ํ•จ์ˆ˜๋ฅผ ์œ„ํ•œ ๊ณต์œ  Node.js ์˜์กด์„ฑ ๊ด€๋ฆฌ.
    • CloudFront:
      • ํ”„๋ก ํŠธ์—”๋“œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์œ„ํ•œ CDN(Content Delivery Network).
      • ์ฑ—๋ด‡ ๋ฐ ๋ฌธ์ œ ์ƒ์„ฑ๊ธฐ์™€ ๊ฐ™์€ ์„œ๋น„์Šค๋ฅผ ์œ„ํ•ด OAC(Origin Access Control)๋ฅผ ํ†ตํ•ด Lambda ํ•จ์ˆ˜ URL์„ ์•ˆ์ „ํ•˜๊ฒŒ ๋…ธ์ถœ.
    • IAM: ์•ˆ์ „ํ•œ ์ ‘๊ทผ ์ œ์–ด๋ฅผ ์œ„ํ•œ ์—ญํ• , ์ •์ฑ…, ๊ถŒํ•œ.
    • Route 53: ์‚ฌ์šฉ์ž ์ง€์ • ๋„๋ฉ”์ธ์„ ์œ„ํ•œ DNS ๊ด€๋ฆฌ (app ๋ชจ๋“ˆ์—์„œ ์‚ฌ์šฉ).
    • ACM (AWS Certificate Manager): ์‚ฌ์šฉ์ž ์ง€์ • ๋„๋ฉ”์ธ์„ ์œ„ํ•œ SSL/TLS ์ธ์ฆ์„œ (app ๋ชจ๋“ˆ์—์„œ ์‚ฌ์šฉ, CloudFront์šฉ ์ธ์ฆ์„œ๋Š” us-east-1 ๋ฆฌ์ „์— ์ƒ์„ฑ).
    • CloudWatch Logs: Lambda, API Gateway ๋“ฑ์˜ ๋กœ๊ทธ ์ €์žฅ.
  • Lambda ๋Ÿฐํƒ€์ž„:
    • Node.js (์ปค๋ฎค๋‹ˆํ‹ฐ API, ์ฑ—๋ด‡, ๋ฌธ์ œ ์ƒ์„ฑ๊ธฐ v3, ๋ฌธ์ œ API, ์ œ์ถœ API์šฉ)
    • Python (์ฝ”๋“œ ์‹คํ–‰ ์„œ๋น„์Šค์šฉ)
  • Lambda Layer ์˜์กด์„ฑ ๊ด€๋ฆฌ:
    • nodejs ํ•˜์œ„ ๋””๋ ‰ํ† ๋ฆฌ์— ์ง์ ‘ npm install (์˜ˆ: infrastructure/api/layers/common-deps/nodejs).
    • ๋” ๋ณต์žกํ•œ ๋ ˆ์ด์–ด์˜ ๊ฒฝ์šฐ Docker ๊ธฐ๋ฐ˜ ๋นŒ๋“œ ์‚ฌ์šฉ, nodejs ๋””๋ ‰ํ† ๋ฆฌ ๊ตฌ์กฐ๋กœ ์ถœ๋ ฅ (์˜ˆ: infrastructure/problem-generator-v3/layers/).
  • CI/CD: ์ž๋™ํ™”๋œ ํ…Œ์ŠคํŠธ ๋ฐ ๋ฐฐํฌ๋ฅผ ์œ„ํ•ด GitHub Actions๊ฐ€ ๊ณ„ํš/์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค (์„ธ๋ถ€ ์‚ฌํ•ญ์€ ๋ชจ๋“ˆ๋ณ„ README ๋˜๋Š” PLAN.md ์ฐธ์กฐ).

3. ์‚ฌ์ „ ์ค€๋น„ ์‚ฌํ•ญ

์‹œ์ž‘ํ•˜๊ธฐ ์ „์— ๋‹ค์Œ ์‚ฌํ•ญ์ด ์„ค์น˜ ๋ฐ ๊ตฌ์„ฑ๋˜์–ด ์žˆ๋Š”์ง€ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค:

  1. AWS CLI: ์ ์ ˆํ•œ ์ž๊ฒฉ ์ฆ๋ช… ๋ฐ ๊ธฐ๋ณธ ๋ฆฌ์ „์œผ๋กœ ๊ตฌ์„ฑ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

     aws configure
    
  2. Terraform: ์ตœ์‹  ์•ˆ์ • ๋ฒ„์ „ (์˜ˆ: v1.x).
  3. Node.js & npm: Node.js ํ•จ์ˆ˜์šฉ Lambda Layer ์˜์กด์„ฑ ๊ด€๋ฆฌ๋ฅผ ์œ„ํ•ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.
  4. Docker: (์„ ํƒ ์‚ฌํ•ญ์ด์ง€๋งŒ, problem-generator-v3์™€ ๊ฐ™์€ ํŠน์ • Lambda Layer ๋นŒ๋“œ์— ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค).
  5. Git: ๋ฒ„์ „ ๊ด€๋ฆฌ๋ฅผ ์œ„ํ•ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.
  6. Google Cloud ํ”„๋กœ์ ํŠธ ์ž๊ฒฉ ์ฆ๋ช…:
    • Google Client ID ๋ฐ Secret: Cognito Google ๋กœ๊ทธ์ธ์„ ์œ„ํ•ด ํ•„์š” (infrastructure/cognito).
    • Google AI API Key: Gemini ๋ชจ๋ธ์„ ์‚ฌ์šฉํ•˜๋Š” ์„œ๋น„์Šค๋ฅผ ์œ„ํ•ด ํ•„์š” (infrastructure/chatbot, infrastructure/problem-generator-v3).
  7. ์‚ฌ์šฉ์ž ์ง€์ • ๋„๋ฉ”์ธ (์„ ํƒ ์‚ฌํ•ญ): app ๋ชจ๋“ˆ์„ ์‚ฌ์šฉ์ž ์ง€์ • ๋„๋ฉ”์ธ์œผ๋กœ ๋ฐฐํฌํ•˜๋Š” ๊ฒฝ์šฐ, ํ•ด๋‹น DNS ๊ด€๋ฆฌ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค (์˜ˆ: Route 53 ํ˜ธ์ŠคํŒ… ์˜์—ญ).

4. ๋””๋ ‰ํ† ๋ฆฌ ๊ตฌ์กฐ ๊ฐœ์š”

Terraform ์ฝ”๋“œ๋Š” infrastructure/ ๋””๋ ‰ํ† ๋ฆฌ ์•„๋ž˜์— ๊ตฌ์„ฑ๋ฉ๋‹ˆ๋‹ค:

capstone-2025-04/
โ”œโ”€โ”€ infrastructure/
โ”‚   โ”œโ”€โ”€ backend-setup/          # Terraform ์ƒํƒœ ๋ฐฑ์—”๋“œ (S3, DynamoDB)
โ”‚   โ”œโ”€โ”€ cognito/                # ์‚ฌ์šฉ์ž ์ธ์ฆ (Cognito)
โ”‚   โ”œโ”€โ”€ app/                    # ํ”„๋ก ํŠธ์—”๋“œ ํ˜ธ์ŠคํŒ… (S3, CloudFront, OIDC ์—ญํ• )
โ”‚   โ”œโ”€โ”€ api/                    # ์ปค๋ฎค๋‹ˆํ‹ฐ API (API GW, Lambda, DynamoDB, Layer)
โ”‚   โ”œโ”€โ”€ problems-api/           # ๋ฌธ์ œ API (API GW, Lambda, ๋ฌธ์ œ ์ƒ์„ฑ๊ธฐ์˜ DynamoDB ์‚ฌ์šฉ)
โ”‚   โ”œโ”€โ”€ problem-generator-v3/   # ๋ฌธ์ œ ์ƒ์„ฑ ์„œ๋น„์Šค v3 (Lambda URL, CF, DynamoDB, Layer)
โ”‚   โ”œโ”€โ”€ code-execution-service/ # ์ฝ”๋“œ ์ฑ„์ ๊ธฐ ๋ฐ ์‹คํ–‰๊ธฐ (API GW, Lambdas, DynamoDB)
โ”‚   โ”œโ”€โ”€ submissions-api/        # ์ œ์ถœ API (API GW, Lambda, ์ฝ”๋“œ ์‹คํ–‰ ์„œ๋น„์Šค์˜ DynamoDB ์‚ฌ์šฉ)
โ”‚   โ”œโ”€โ”€ chatbot/                # ์ฑ—๋ด‡ ์„œ๋น„์Šค (Lambda URL, CF, Layer)
โ”‚   โ””โ”€โ”€ ... (๊ธฐํƒ€ ์ž ์žฌ์  ๋ชจ๋“ˆ ๋˜๋Š” ๊ณต์œ  ํŒŒ์ผ)
โ”œโ”€โ”€ backend/
โ”‚   โ””โ”€โ”€ lambdas/                # Lambda ํ•จ์ˆ˜ ์†Œ์Šค ์ฝ”๋“œ
โ”‚       โ”œโ”€โ”€ community-lambda-functions/
โ”‚       โ”œโ”€โ”€ chatbot-query/
โ”‚       โ”œโ”€โ”€ problem-generator-v3/
โ”‚       โ”œโ”€โ”€ code-executor/
โ”‚       โ”œโ”€โ”€ code-grader/
โ”‚       โ”œโ”€โ”€ problems-api/
โ”‚       โ””โ”€โ”€ submissions-api/
โ””โ”€โ”€ ... (ํ”„๋ก ํŠธ์—”๋“œ ์ฝ”๋“œ ๋“ฑ)

infrastructure/ ๋‚ด์˜ ๊ฐ ํ•˜์œ„ ๋””๋ ‰ํ† ๋ฆฌ๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ์ž์ฒด main.tf, variables.tf, outputs.tf ๋ฐ backend.tf(์›๊ฒฉ ์ƒํƒœ ์‚ฌ์šฉ ์‹œ)๋ฅผ ๊ฐ€์ง„ ๊ณ ์œ ํ•œ Terraform ๋ชจ๋“ˆ์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.

5. ์ „์—ญ ์„ค์ •: Terraform ์ƒํƒœ ๋ฐฑ์—”๋“œ

์ด๊ฒƒ์€ ๊ธฐ์ดˆ ๋‹จ๊ณ„์ด๋ฉฐ ๊ฐ€์žฅ ๋จผ์ € ์ˆ˜ํ–‰ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋ชจ๋“ˆ: infrastructure/backend-setup/

  1. ๋ชฉ์ : Terraform ์ƒํƒœ ํŒŒ์ผ์„ ์ €์žฅํ•  S3 ๋ฒ„ํ‚ท๊ณผ ์ƒํƒœ ์ž ๊ธˆ์„ ์œ„ํ•œ DynamoDB ํ…Œ์ด๋ธ”์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
  2. ์ƒํƒœ ๊ด€๋ฆฌ: ์ด ๋ชจ๋“ˆ ์ž์ฒด๋Š” ์›๊ฒฉ ์ƒํƒœ๋ฅผ ์œ„ํ•œ ๋ฆฌ์†Œ์Šค๋ฅผ ๋งŒ๋“ค๊ธฐ ๋•Œ๋ฌธ์— ๋กœ์ปฌ ์ƒํƒœ ํŒŒ์ผ(terraform.tfstate)์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
  3. ๋ฐฐํฌ:

     cd infrastructure/backend-setup
     terraform init
     terraform plan
     terraform apply
    
  4. ์ถœ๋ ฅ: tfstate_bucket_name๊ณผ tfstate_lock_table_name์„ ๊ธฐ๋กํ•ด ๋‘์‹ญ์‹œ์˜ค. ์ด ๊ฐ’๋“ค์€ ๋‹ค๋ฅธ ๋ชจ๋“  ๋ชจ๋“ˆ์—์„œ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. output.txt ์˜ˆ์‹œ:
    • tfstate_bucket_name = "alpaco-tfstate-bucket-kmu"
    • tfstate_lock_table_name = "alpaco-tfstate-lock-table"

6. ๋ชจ๋“ˆ๋ณ„ ๋ฐฐํฌ ์ง€์นจ

backend-setup์ด ์™„๋ฃŒ๋œ ํ›„ ๋‹ค๋ฅธ ๋ชจ๋“ˆ์„ ๋ฐฐํฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜์กด์„ฑ์œผ๋กœ ์ธํ•ด ์ˆœ์„œ๊ฐ€ ์ค‘์š”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค (์˜ˆ: API ๋ชจ๋“ˆ์€ Cognito ์ถœ๋ ฅ์— ์˜์กดํ•  ์ˆ˜ ์žˆ์Œ).

๊ฐ ๋ชจ๋“ˆ์— ๋Œ€ํ•œ ์ผ๋ฐ˜์ ์ธ Terraform ๋ช…๋ น์–ด (๋‹ฌ๋ฆฌ ๋ช…์‹œ๋˜์ง€ ์•Š๋Š” ํ•œ):

  • ๋ชจ๋“ˆ ๋””๋ ‰ํ† ๋ฆฌ๋กœ ์ด๋™: cd infrastructure/<module-name>
  • Terraform ์ดˆ๊ธฐํ™”:

      terraform init \
        -backend-config="bucket=<YOUR_TFSTATE_BUCKET_NAME_FROM_BACKEND_SETUP>" \
        -backend-config="key=<module-specific-key-from-backend.tf>" \
        -backend-config="region=<YOUR_AWS_REGION>" \
        -backend-config="dynamodb_table=<YOUR_TFSTATE_LOCK_TABLE_NAME_FROM_BACKEND_SETUP>" \
        -backend-config="encrypt=true"
    

    ํ”Œ๋ ˆ์ด์Šคํ™€๋”๋ฅผ ์‹ค์ œ ๊ฐ’์œผ๋กœ ๊ต์ฒดํ•˜์‹ญ์‹œ์˜ค. key๋Š” ๊ฐ ๋ชจ๋“ˆ์˜ backend.tf ํŒŒ์ผ์— ์ •์˜๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ์‹œ: cognito ๋ชจ๋“ˆ์˜ ๊ฒฝ์šฐ ํ‚ค๋Š” cognito/terraform.tfstate์ž…๋‹ˆ๋‹ค.

  • ์‹คํ–‰ ๊ณ„ํš ๊ฒ€ํ† : terraform plan (ํ•„์š”ํ•œ -var ์˜ต์…˜ ์ „๋‹ฌ)
  • ๋ณ€๊ฒฝ ์‚ฌํ•ญ ์ ์šฉ: terraform apply (ํ•„์š”ํ•œ -var ์˜ต์…˜ ์ „๋‹ฌ)
  • ์ถœ๋ ฅ ๊ฐ’ ๊ฒ€ํ† : terraform output

6.1. Cognito (infrastructure/cognito/)

  1. ๋ชฉ์ : AWS Cognito ์‚ฌ์šฉ์ž ํ’€์„ ์„ค์ •ํ•˜์—ฌ Google ๋กœ๊ทธ์ธ์„ ์ง€์›ํ•˜๊ณ , ์‚ฌ์šฉ์ž ๊ทธ๋ฃน ๋ฐ ์‚ฌ์šฉ์ž๋ฅผ ๊ธฐ๋ณธ ๊ทธ๋ฃน์— ์ถ”๊ฐ€ํ•˜๋Š” Lambda ํŠธ๋ฆฌ๊ฑฐ๋ฅผ ๊ตฌ์„ฑํ•ฉ๋‹ˆ๋‹ค.
  2. ์ฃผ์š” ๋ฆฌ์†Œ์Šค: aws_cognito_user_pool, aws_cognito_identity_provider (Google), aws_cognito_user_pool_client, aws_cognito_user_group, aws_lambda_function (PostConfirmation ํŠธ๋ฆฌ๊ฑฐ).
  3. ์‹œํฌ๋ฆฟ:
    • google_client_id: terraform.auto.tfvars ๋˜๋Š” ๋ช…๋ น์ค„(-var="google_client_id=...")์„ ํ†ตํ•ด ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
    • google_client_secret: terraform.auto.tfvars (์ด ํŒŒ์ผ์€ .gitignore์— ์ถ”๊ฐ€) ๋˜๋Š” ๋ช…๋ น์ค„(-var="google_client_secret=...")์„ ํ†ตํ•ด ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ์‹œ infrastructure/cognito/terraform.auto.tfvars (.gitignore์— ์ถ”๊ฐ€):
     google_client_id     = "YOUR_GOOGLE_CLIENT_ID.apps.googleusercontent.com"
     google_client_secret = "YOUR_GOOGLE_CLIENT_SECRET"
    
  4. ๋ฐฐํฌ: ์ผ๋ฐ˜์ ์ธ ๋ช…๋ น์–ด๋ฅผ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค. backend.tf๋Š” key = "cognito/terraform.tfstate"๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.
  5. ์ถœ๋ ฅ: cognito_user_pool_id, cognito_user_pool_client_id, cognito_user_pool_arn ๋“ฑ. Cognito์™€ ํ†ตํ•ฉ๋˜๋Š” ๋‹ค๋ฅธ ์„œ๋น„์Šค์— ๋งค์šฐ ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค.

6.2. ์ฝ”๋“œ ์‹คํ–‰ ์„œ๋น„์Šค (infrastructure/code-execution-service/)

  1. ๋ชฉ์ : ์ฝ”๋“œ ์‹คํ–‰ ๋ฐ ์ฑ„์  ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. code-executor Lambda (Python)์™€ API Gateway๋ฅผ ํ†ตํ•ด ๋…ธ์ถœ๋˜๋Š” code-grader Lambda (Python)๋ฅผ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค. ์ œ์ถœ ๊ธฐ๋ก์„ DynamoDB ํ…Œ์ด๋ธ”์— ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.
  2. ์ฃผ์š” ๋ฆฌ์†Œ์Šค: aws_lambda_function (x2), aws_dynamodb_table (์ œ์ถœ ๊ธฐ๋ก), aws_api_gateway_rest_api.
  3. ์˜์กด์„ฑ:
    • problem-generator-v3 ๋ชจ๋“ˆ์˜ ์›๊ฒฉ ์ƒํƒœ์—์„œ problems_table_name ๋ฐ problems_table_arn์„ ์ฝ์Šต๋‹ˆ๋‹ค.
    • API Gateway ๊ถŒํ•œ ๋ถ€์—ฌ์ž(Authorizer)๋ฅผ ์œ„ํ•ด cognito ๋ชจ๋“ˆ์˜ ์›๊ฒฉ ์ƒํƒœ์—์„œ cognito_user_pool_arn์„ ์ฝ์Šต๋‹ˆ๋‹ค.
  4. ๋ฐฐํฌ:
    • ์ˆœ์„œ ๊ณ ๋ ค: problem-generator-v3 ๋ชจ๋“ˆ์ด ๋จผ์ € ๋ฐฐํฌ๋˜์–ด problems_table์„ ์ƒ์„ฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
    • ์ผ๋ฐ˜์ ์ธ ๋ช…๋ น์–ด๋ฅผ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค. backend.tf๋Š” key = "code-execution-service/terraform.tfstate"๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.
  5. ์ถœ๋ ฅ: code_grader_api_invoke_url, submissions_table_name_output, code_executor_lambda_arn ๋“ฑ.

6.3. ๋ฌธ์ œ ์ƒ์„ฑ๊ธฐ v3 (infrastructure/problem-generator-v3/)

  1. ๋ชฉ์ : Google AI (Gemini)๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋ฌธ์ œ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  DynamoDB์— ์ €์žฅํ•ฉ๋‹ˆ๋‹ค. CloudFront๋ฅผ ํ†ตํ•ด Lambda ํ•จ์ˆ˜ URL๋กœ ๊ธฐ๋Šฅ์„ ๋…ธ์ถœํ•ฉ๋‹ˆ๋‹ค.
  2. ์ฃผ์š” ๋ฆฌ์†Œ์Šค: aws_lambda_function, aws_lambda_layer_version, aws_dynamodb_table (Problems-v3), aws_cloudfront_distribution, aws_cloudfront_origin_access_control.
  3. ์˜์กด์„ฑ:
    • code-execution-service ๋ชจ๋“ˆ์˜ code_executor_lambda_arn์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค (๋ณ€์ˆ˜๋กœ ์ „๋‹ฌ).
  4. ์‹œํฌ๋ฆฟ:
    • google_ai_api_key: terraform.auto.tfvars ๋˜๋Š” ๋ช…๋ น์ค„์„ ํ†ตํ•ด ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ์‹œ infrastructure/problem-generator-v3/terraform.auto.tfvars (.gitignore์— ์ถ”๊ฐ€):
     google_ai_api_key = "YOUR_GOOGLE_AI_API_KEY"
    
  5. Lambda Layer: ์ด ๋ชจ๋“ˆ์€ Docker ๊ธฐ๋ฐ˜ ๋นŒ๋“œ ์Šคํฌ๋ฆฝํŠธ (layers/build-layer.sh)๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Node.js ์˜์กด์„ฑ์„ ํŒจํ‚ค์ง•ํ•ฉ๋‹ˆ๋‹ค. ์ด ์Šคํฌ๋ฆฝํŠธ๋Š” package-lock.json ๋˜๋Š” ๋นŒ๋“œ ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ๋ณ€๊ฒฝ๋˜๋ฉด Terraform์— ์˜ํ•ด null_resource๋ฅผ ํ†ตํ•ด ์ž๋™์œผ๋กœ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.
    • ๋กœ์ปฌ์—์„œ ๋ฐฐํฌํ•˜๋Š” ๊ฒฝ์šฐ Docker๊ฐ€ ์‹คํ–‰ ์ค‘์ธ์ง€ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค.
    • build-layer.sh ์Šคํฌ๋ฆฝํŠธ๋Š” backend/lambdas/problem-generator-v3/์—์„œ package.json ๋ฐ package-lock.json์„ ๋ณต์‚ฌํ•˜์—ฌ ๋ ˆ์ด์–ด๋ฅผ ๋นŒ๋“œํ•ฉ๋‹ˆ๋‹ค.
  6. ์ˆœํ™˜ ์˜์กด์„ฑ ๋ฐฐํฌ ์ „๋žต (code-execution-service ๊ด€๋ จ): problem-generator-v3/readme.md์— ์–ธ๊ธ‰๋œ ๋ฐ”์™€ ๊ฐ™์ด, ์ด ๋ชจ๋“ˆ์€ code-execution-service์˜ code_executor_lambda_arn์— ์˜์กดํ•˜๊ณ , code-execution-service๋Š” ์ด ๋ชจ๋“ˆ์˜ problems_table_arn์— ์˜์กดํ•ฉ๋‹ˆ๋‹ค.
    • 1๋‹จ๊ณ„: problem-generator-v3 ๋ฐฐํฌ (์ดˆ๊ธฐ)
      • variables.tf์˜ code_executor_lambda_arn์„ ์ž„์‹œ ์œ ํšจํ•œ ARN ๋ฌธ์ž์—ด๋กœ ์„ค์ •ํ•˜๊ฑฐ๋‚˜ ๊ธฐ๋ณธ๊ฐ’์ด ํ”Œ๋ ˆ์ด์Šคํ™€๋”์ธ ๊ฒฝ์šฐ ๊ทธ๋Œ€๋กœ ๋‘๊ณ  ๋ฐฐํฌํ•ฉ๋‹ˆ๋‹ค.
      • problem-generator-v3์— ๋Œ€ํ•ด terraform apply๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด problems_table์ด ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.
    • 2๋‹จ๊ณ„: code-execution-service ๋ฐฐํฌ
      • code-execution-service์— ๋Œ€ํ•ด terraform apply๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ชจ๋“ˆ์€ problem-generator-v3์˜ ์ƒํƒœ์—์„œ problems_table_arn์„ ์ฝ์–ด code_executor_lambda๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. code_executor_lambda_arn ์ถœ๋ ฅ์„ ๊ธฐ๋กํ•ฉ๋‹ˆ๋‹ค.
    • 3๋‹จ๊ณ„: problem-generator-v3 ๋ฐฐํฌ (์—…๋ฐ์ดํŠธ)
      • 2๋‹จ๊ณ„์—์„œ ์–ป์€ ์‹ค์ œ ARN์œผ๋กœ infrastructure/problem-generator-v3/variables.tf๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๊ฑฐ๋‚˜ terraform.auto.tfvars๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ code_executor_lambda_arn์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
      • problem-generator-v3์— ๋Œ€ํ•ด ๋‹ค์‹œ terraform apply๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.
  7. ์ถœ๋ ฅ: cloudfront_distribution_domain, problems_table_name, problems_table_arn.

6.4. ์ปค๋ฎค๋‹ˆํ‹ฐ API (infrastructure/api/)

  1. ๋ชฉ์ : ์ปค๋ฎค๋‹ˆํ‹ฐ ๊ธฐ๋Šฅ(๊ฒŒ์‹œ๋ฌผ, ๋Œ“๊ธ€, ์ข‹์•„์š”)์„ ์œ„ํ•œ ํ•ต์‹ฌ ๋ฐฑ์—”๋“œ์ž…๋‹ˆ๋‹ค.
  2. ์ฃผ์š” ๋ฆฌ์†Œ์Šค: aws_api_gateway_rest_api, ๋‹ค์ˆ˜์˜ aws_lambda_function ๋ฆฌ์†Œ์Šค, aws_dynamodb_table (์ปค๋ฎค๋‹ˆํ‹ฐ), aws_lambda_layer_version.
  3. ์˜์กด์„ฑ:
    • API Gateway ๊ถŒํ•œ ๋ถ€์—ฌ์ž(Authorizer)๋ฅผ ์œ„ํ•ด cognito ๋ชจ๋“ˆ์˜ ์›๊ฒฉ ์ƒํƒœ์—์„œ cognito_user_pool_arn์„ ์ฝ์Šต๋‹ˆ๋‹ค.
  4. Lambda Layer (common-deps):
    • uuid ์˜์กด์„ฑ์„ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค.
    • terraform apply ์ „ ์ˆ˜๋™ ๋‹จ๊ณ„ (CI/CD์—์„œ ์ฒ˜๋ฆฌํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ):

        cd infrastructure/api/layers/common-deps/nodejs
        npm install
        cd ../../../.. # infrastructure/api๋กœ ๋Œ์•„๊ฐ€๊ธฐ
      
  5. ๋ฐฐํฌ: ์ผ๋ฐ˜์ ์ธ ๋ช…๋ น์–ด๋ฅผ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค. backend.tf๋Š” key = "api/community/terraform.tfstate"๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.
  6. ์ถœ๋ ฅ: api_gateway_invoke_url, community_dynamodb_table_name.

6.5. ๋ฌธ์ œ API (infrastructure/problems-api/)

  1. ๋ชฉ์ : ๋ฌธ์ œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ์ฝ๊ธฐ ์ „์šฉ API ์—”๋“œํฌ์ธํŠธ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
  2. ์ฃผ์š” ๋ฆฌ์†Œ์Šค: aws_api_gateway_rest_api, aws_lambda_function (x2: getAllProblems, getProblemById).
  3. ์˜์กด์„ฑ:
    • problem-generator-v3 ๋ชจ๋“ˆ์˜ ์›๊ฒฉ ์ƒํƒœ์—์„œ problems_table_name ๋ฐ problems_table_arn์„ ์ฝ์Šต๋‹ˆ๋‹ค.
  4. Lambda ์ฝ”๋“œ: Lambda ํ•ธ๋“ค๋Ÿฌ ์ฝ”๋“œ(getAllProblems.mjs, getProblemById.mjs)๊ฐ€ backend/lambdas/problems-api/์— ์žˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
  5. ๋ฐฐํฌ: ์ผ๋ฐ˜์ ์ธ ๋ช…๋ น์–ด๋ฅผ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค. backend.tf๋Š” key = "api/problems/terraform.tfstate"๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.
  6. ์ถœ๋ ฅ: problems_api_invoke_url.

6.6. ์ œ์ถœ API (infrastructure/submissions-api/)

  1. ๋ชฉ์ : ์ œ์ถœ ๊ธฐ๋ก ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” API ์—”๋“œํฌ์ธํŠธ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
  2. ์ฃผ์š” ๋ฆฌ์†Œ์Šค: aws_api_gateway_rest_api, aws_lambda_function (getSubmission).
  3. ์˜์กด์„ฑ:
    • code-execution-service ๋ชจ๋“ˆ์˜ ์›๊ฒฉ ์ƒํƒœ์—์„œ submissions_table_name_output ๋ฐ submissions_table_arn_output์„ ์ฝ์Šต๋‹ˆ๋‹ค.
  4. Lambda ์ฝ”๋“œ: Lambda ํ•ธ๋“ค๋Ÿฌ ์ฝ”๋“œ(getSubmission.mjs)๊ฐ€ backend/lambdas/submissions-api/์— ์žˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
  5. ๋ฐฐํฌ: ์ผ๋ฐ˜์ ์ธ ๋ช…๋ น์–ด๋ฅผ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค. backend.tf๋Š” key = "api/submissions/terraform.tfstate"๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.
  6. ์ถœ๋ ฅ: submissions_api_invoke_url.

6.7. ์ฑ—๋ด‡ (infrastructure/chatbot/)

  1. ๋ชฉ์ : Google AI (Gemini)๋ฅผ ์‚ฌ์šฉํ•˜๋Š” AI ์ฑ—๋ด‡ ๋ฐฑ์—”๋“œ ์„œ๋น„์Šค์ด๋ฉฐ, Lambda ํ•จ์ˆ˜ URL๊ณผ CloudFront๋ฅผ ํ†ตํ•ด ๋…ธ์ถœ๋ฉ๋‹ˆ๋‹ค.
  2. ์ฃผ์š” ๋ฆฌ์†Œ์Šค: aws_lambda_function, aws_lambda_layer_version, aws_cloudfront_distribution, aws_cloudfront_origin_access_control.
  3. ์˜์กด์„ฑ:
    • cognito ๋ชจ๋“ˆ์˜ ์›๊ฒฉ ์ƒํƒœ์—์„œ Cognito ์ถœ๋ ฅ(cognito_user_pool_id, cognito_user_pool_client_id ๋“ฑ)์„ ์ฝ์Šต๋‹ˆ๋‹ค.
  4. ์‹œํฌ๋ฆฟ:
    • google_ai_api_key: terraform.auto.tfvars ๋˜๋Š” ๋ช…๋ น์ค„์„ ํ†ตํ•ด ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ์‹œ infrastructure/chatbot/terraform.auto.tfvars (.gitignore์— ์ถ”๊ฐ€):
     google_ai_api_key = "YOUR_GOOGLE_AI_API_KEY"
    
  5. Lambda Layer (chatbot_deps):
    • @langchain/google-genai, jose ๋“ฑ์„ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค.
    • terraform apply ์ „ ์ˆ˜๋™ ๋‹จ๊ณ„ (CI/CD์—์„œ ์ฒ˜๋ฆฌํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ): ๋ ˆ์ด์–ด์šฉ package.json์€ infrastructure/chatbot/layers/chatbot_deps/nodejs/์— ์žˆ์Šต๋‹ˆ๋‹ค. ์ด nodejs ๋””๋ ‰ํ† ๋ฆฌ ๋‚ด์— node_modules๊ฐ€ ์ฑ„์›Œ์ง€๋„๋ก npm install์„ ์‹คํ–‰ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

        # ํ”„๋กœ์ ํŠธ ๋ฃจํŠธ์—์„œ:
        npm install --prefix ./infrastructure/chatbot/layers/chatbot_deps/nodejs ./infrastructure/chatbot/layers/chatbot_deps/nodejs
        # ๋˜๋Š” (package.json์ด backend/lambdas/chatbot-query์— ์ƒ๋Œ€์ ์œผ๋กœ ์˜์กด์„ฑ์„ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๋‚˜์—ดํ•˜๋Š” ๊ฒฝ์šฐ)
        # npm install --prefix ./infrastructure/chatbot/layers/chatbot_deps/nodejs ./backend/lambdas/chatbot-query
      

      ๊ทธ๋Ÿฌ๋ฉด layer.tf๊ฐ€ infrastructure/chatbot/layers/chatbot_deps/์˜ ๋‚ด์šฉ์„ ์••์ถ•ํ•ฉ๋‹ˆ๋‹ค.

  6. ๋ฐฐํฌ: ์ผ๋ฐ˜์ ์ธ ๋ช…๋ น์–ด๋ฅผ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค. backend.tf๋Š” key = "chatbot/terraform.tfstate"๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.
  7. ์ถœ๋ ฅ: cloudfront_distribution_domain_name.

6.8. ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ํ”„๋ก ํŠธ์—”๋“œ (infrastructure/app/)

  1. ๋ชฉ์ : Next.js ํ”„๋ก ํŠธ์—”๋“œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ S3์— ํ˜ธ์ŠคํŒ…ํ•˜๊ณ  CloudFront๋ฅผ ํ†ตํ•ด ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž ์ง€์ • ๋„๋ฉ”์ธ ์„ค์ • ๋ฐ GitHub Actions ๋ฐฐํฌ๋ฅผ ์œ„ํ•œ IAM OIDC ์—ญํ• ์„ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค.
  2. ์ฃผ์š” ๋ฆฌ์†Œ์Šค: aws_s3_bucket, aws_cloudfront_distribution, aws_route53_record, aws_acm_certificate, aws_iam_role (GitHub Actions์šฉ).
  3. ์‚ฌ์ „ ์ค€๋น„ ์‚ฌํ•ญ:
    • custom_domain_name(์˜ˆ: alpaco.us)์— ๋Œ€ํ•œ Route 53 ํผ๋ธ”๋ฆญ ํ˜ธ์ŠคํŒ… ์˜์—ญ.
  4. ์‚ฌ์šฉ์ž ์ง€์ • ๋„๋ฉ”์ธ ๋ฐ ACM ์ธ์ฆ์„œ:
    • CloudFront์šฉ ACM ์ธ์ฆ์„œ๋Š” ๋ฐ˜๋“œ์‹œ us-east-1 ๋ฆฌ์ „์— ์ƒ์„ฑ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ชจ๋“ˆ์˜ providers.tf๋Š” us-east-1์šฉ ๋ณ„์นญ ๊ณต๊ธ‰์ž๋ฅผ ๊ตฌ์„ฑํ•ฉ๋‹ˆ๋‹ค.
    • ์ธ์ฆ์„œ์šฉ DNS ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ๋ ˆ์ฝ”๋“œ๋Š” Route 53 ํ˜ธ์ŠคํŒ… ์˜์—ญ์— ์ž๋™์œผ๋กœ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.
  5. OIDC ์—ญํ• : GitHub Actions๊ฐ€ ํ”„๋ก ํŠธ์—”๋“œ ์ž์‚ฐ์„ S3์— ๋ฐฐํฌํ•˜๊ณ  CloudFront ์บ์‹œ๋ฅผ ๋ฌดํšจํ™”ํ•˜๊ธฐ ์œ„ํ•ด ๋งก์„ ์ˆ˜ ์žˆ๋Š” IAM ์—ญํ• ์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
  6. ๋ฐฐํฌ: ์ผ๋ฐ˜์ ์ธ ๋ช…๋ น์–ด๋ฅผ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค. backend.tf๋Š” key = "app/terraform.tfstate"๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.
    • ๊ธฐ๋ณธ๊ฐ’๊ณผ ๋‹ค๋ฅธ ๊ฒฝ์šฐ github_repository๋ฅผ ์ „๋‹ฌํ•ด์•ผ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  7. ์ถœ๋ ฅ: application_url (์‚ฌ์šฉ์ž ์ง€์ • ๋„๋ฉ”์ธ), cloudfront_distribution_domain_name, github_actions_deploy_role_arn.

7. ์ „์ฒด ๋ฐฐํฌ ์ „๋žต ๋ฐ ์ˆœ์„œ

๋ชจ๋“ˆ ๊ฐ„ ์˜์กด์„ฑ(์ฃผ๋กœ terraform_remote_state๋ฅผ ํ†ตํ•ด)์œผ๋กœ ์ธํ•ด ์ผ๋ฐ˜์ ์ธ ๋ฐฐํฌ ์ˆœ์„œ๊ฐ€ ๊ถŒ์žฅ๋ฉ๋‹ˆ๋‹ค:

  1. infrastructure/backend-setup: (๋กœ์ปฌ ์ƒํƒœ) ์›๊ฒฉ ์ƒํƒœ๋ฅผ ์œ„ํ•œ S3/DynamoDB ์ƒ์„ฑ.
  2. infrastructure/cognito: (์›๊ฒฉ ์ƒํƒœ ์‚ฌ์šฉ) ์‚ฌ์šฉ์ž ํ’€ ์ƒ์„ฑ.
    • google_client_id ๋ฐ google_client_secret ํ•„์š”.
  3. infrastructure/problem-generator-v3 (1๋‹จ๊ณ„): (์›๊ฒฉ ์ƒํƒœ ์‚ฌ์šฉ)
    • google_ai_api_key ํ•„์š”.
    • ํ”Œ๋ ˆ์ด์Šคํ™€๋” code_executor_lambda_arn์œผ๋กœ ๋ฐฐํฌํ•˜๊ฑฐ๋‚˜ ๊ธฐ๋ณธ๊ฐ’ ํ—ˆ์šฉ.
    • Docker๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Lambda ๋ ˆ์ด์–ด ๋นŒ๋“œ.
    • ์ถœ๋ ฅ: problems_table_arn.
  4. infrastructure/code-execution-service: (์›๊ฒฉ ์ƒํƒœ ์‚ฌ์šฉ)
    • problem-generator-v3 ์ƒํƒœ์—์„œ problems_table_arn ์ฝ๊ธฐ.
    • cognito ์ƒํƒœ์—์„œ cognito_user_pool_arn ์ฝ๊ธฐ.
    • ์ถœ๋ ฅ: code_executor_lambda_arn, submissions_table_name_output, submissions_table_arn_output.
  5. infrastructure/problem-generator-v3 (2๋‹จ๊ณ„ - ์—…๋ฐ์ดํŠธ):
    • code-execution-service ์ถœ๋ ฅ์—์„œ ์‹ค์ œ code_executor_lambda_arn์œผ๋กœ ์—…๋ฐ์ดํŠธ.
    • ๋‹ค์‹œ terraform apply ์‹คํ–‰.
  6. infrastructure/api (์ปค๋ฎค๋‹ˆํ‹ฐ API): (์›๊ฒฉ ์ƒํƒœ ์‚ฌ์šฉ)
    • ๋ ˆ์ด์–ด์— ๋Œ€ํ•ด npm install ํ•„์š”.
    • cognito ์ƒํƒœ์—์„œ cognito_user_pool_arn ์ฝ๊ธฐ.
  7. infrastructure/chatbot: (์›๊ฒฉ ์ƒํƒœ ์‚ฌ์šฉ)
    • ๋ ˆ์ด์–ด์— ๋Œ€ํ•ด npm install ํ•„์š”.
    • Cognito ์ƒํƒœ ์ฝ๊ธฐ.
    • google_ai_api_key ํ•„์š”.
  8. infrastructure/problems-api: (์›๊ฒฉ ์ƒํƒœ ์‚ฌ์šฉ)
    • problem-generator-v3 ์ƒํƒœ์—์„œ problems_table_name ์ฝ๊ธฐ.
  9. infrastructure/submissions-api: (์›๊ฒฉ ์ƒํƒœ ์‚ฌ์šฉ)
    • code-execution-service ์ƒํƒœ์—์„œ submissions_table_name_output ์ฝ๊ธฐ.
  10. infrastructure/app: (์›๊ฒฉ ์ƒํƒœ ์‚ฌ์šฉ)
    • ํ”„๋ก ํŠธ์—”๋“œ ํ˜ธ์ŠคํŒ… ์„ค์ •. OIDC ์—ญํ• ์— GitHub ์ €์žฅ์†Œ ์ด๋ฆ„ ํ•„์š”.

์ตœ์ดˆ ์ „์ฒด ๋ฐฐํฌ: ์ฒ˜์Œ ์ „์ฒด ๋ฐฐํฌ ์‹œ์—๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ์œ„ ์ˆœ์„œ๋Œ€๋กœ ๊ฐ ๋ชจ๋“ˆ์„ ์ ์šฉํ•˜์—ฌ ํ•œ ๋ชจ๋“ˆ์˜ ์ถœ๋ ฅ์ด ๋‹ค์Œ ๋ชจ๋“ˆ์—์„œ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค (์ˆ˜๋™์œผ๋กœ ๋ณ€์ˆ˜๋ฅผ ์ „๋‹ฌํ•˜๊ฑฐ๋‚˜ terraform_remote_state๋ฅผ ํ†ตํ•ด ์ž๋™์œผ๋กœ ์ฝ์Œ).

8. CI/CD (GitHub Actions)

  • ์›Œํฌํ”Œ๋กœ์šฐ ํŒŒ์ผ: GitHub Actions ์›Œํฌํ”Œ๋กœ์šฐ(์˜ˆ: .github/workflows/deploy-app.yml, .github/workflows/deploy-api.yml)๋Š” ํŠน์ • ๋ชจ๋“ˆ์˜ ๋ฐฐํฌ๋ฅผ ์ž๋™ํ™”ํ•ฉ๋‹ˆ๋‹ค.
  • OIDC ์ธ์ฆ: ์›Œํฌํ”Œ๋กœ์šฐ๋Š” AWS์™€ ์ธ์ฆํ•˜๊ธฐ ์œ„ํ•ด OIDC๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋ฉฐ, ํ•„์š”ํ•œ ๊ถŒํ•œ์„ ๊ฐ€์ง„ IAM ์—ญํ• ์„ ๋งก์Šต๋‹ˆ๋‹ค (์˜ˆ: ํ”„๋ก ํŠธ์—”๋“œ์šฉ app ๋ชจ๋“ˆ์—์„œ ์ƒ์„ฑ๋œ ์—ญํ•  ๋˜๋Š” ๋ฐฑ์—”๋“œ ์„œ๋น„์Šค์šฉ ์ „์šฉ ์—ญํ• ).
  • ์‹œํฌ๋ฆฟ:
    • AWS ์ž๊ฒฉ ์ฆ๋ช… (OIDC ์—ญํ•  ARN์„ ํ†ตํ•ด).
    • TF_STATE_BUCKET, TF_STATE_LOCK_TABLE: terraform init ๋ฐฑ์—”๋“œ ๊ตฌ์„ฑ์šฉ.
    • GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET, GOOGLE_AI_API_KEY: ํ•ด๋‹น ๋ชจ๋“ˆ์— ํ•„์š”. GitHub Secrets๋กœ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.
  • CI/CD ๋‚ด Terraform ๋ช…๋ น์–ด:
    • terraform init -backend-config=... (๋ฒ„ํ‚ท/ํ…Œ์ด๋ธ” ์ด๋ฆ„์— ์‹œํฌ๋ฆฟ ์‚ฌ์šฉ).
    • terraform plan -out=tfplan.
    • terraform apply tfplan.
  • ๋ ˆ์ด์–ด ๋นŒ๋“œ: CI/CD ํŒŒ์ดํ”„๋ผ์ธ์—๋Š” ๋‹ค์Œ ๋‹จ๊ณ„๊ฐ€ ํฌํ•จ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค:
    • ๋‹จ์ˆœ Node.js ๋ ˆ์ด์–ด(api, chatbot ๋“ฑ)์˜ ๊ฒฝ์šฐ npm install ์‹คํ–‰.
    • problem-generator-v3์˜ ๊ฒฝ์šฐ Docker ๋นŒ๋“œ ์Šคํฌ๋ฆฝํŠธ(build-layer.sh) ์‹คํ–‰. ์ด๋Š” ํ•ด๋‹น ๋ชจ๋“ˆ์— ๋Œ€ํ•œ terraform apply ์ „์— ์ˆ˜ํ–‰๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

9. ์‹œํฌ๋ฆฟ(๋ฏผ๊ฐ ์ •๋ณด) ๊ด€๋ฆฌ

  • ๋กœ์ปฌ ๊ฐœ๋ฐœ:
    • ๊ฐ ๋ชจ๋“ˆ ๋””๋ ‰ํ† ๋ฆฌ ๋‚ด์˜ terraform.auto.tfvars ํŒŒ์ผ์„ ์‚ฌ์šฉํ•˜์—ฌ API ํ‚ค๋‚˜ ํด๋ผ์ด์–ธํŠธ ์‹œํฌ๋ฆฟ๊ณผ ๊ฐ™์€ ๋ฏผ๊ฐํ•œ ๋ณ€์ˆ˜๋ฅผ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.
    • ์ค‘์š”: ์‹œํฌ๋ฆฟ ์ปค๋ฐ‹์„ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ํ”„๋กœ์ ํŠธ์˜ .gitignore ํŒŒ์ผ์— *.auto.tfvars๋ฅผ ์ถ”๊ฐ€ํ•˜์‹ญ์‹œ์˜ค.
  • CI/CD (GitHub Actions):
    • ๋ฏผ๊ฐํ•œ ๊ฐ’์„ GitHub Secrets(์˜ˆ: GOOGLE_AI_API_KEY, AWS_OIDC_ROLE_ARN)๋กœ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.
    • ์›Œํฌํ”Œ๋กœ์šฐ์˜ Terraform ๋‹จ๊ณ„์— ์ด๋Ÿฌํ•œ ์‹œํฌ๋ฆฟ์„ ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋กœ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ: TF_VAR_google_ai_api_key: $.

10. ๋ฌธ์ œ ํ•ด๊ฒฐ ๋ฐ ๋ชจ๋ฒ” ์‚ฌ๋ก€

  • terraform validate: ๊ณ„ํš ๋˜๋Š” ์ ์šฉ ์ „์— ๊ตฌ๋ฌธ์„ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.
  • terraform fmt: ์ฝ”๋“œ๋ฅผ ์ผ๊ด€๋˜๊ฒŒ ํ˜•์‹ํ™”ํ•ฉ๋‹ˆ๋‹ค.
  • ์ž‘๊ณ  ์ ์ง„์ ์ธ ๋ณ€๊ฒฝ: ๋ฌธ์ œ ํ•ด๊ฒฐ์„ ๋” ์‰ฝ๊ฒŒ ํ•˜๋ ค๋ฉด ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ์ž‘์€ ๋‹จ์œ„๋กœ ์ ์šฉํ•ฉ๋‹ˆ๋‹ค.
  • terraform_remote_state ์ดํ•ด: key์™€ bucket์ด ์˜์กด์„ฑ ๋ชจ๋“ˆ์˜ ์ƒํƒœ ํŒŒ์ผ์„ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๊ฐ€๋ฆฌํ‚ค๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ์˜์กด์„ฑ ๋ชจ๋“ˆ์€ ๋จผ์ € ์„ฑ๊ณต์ ์œผ๋กœ apply๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • IAM ๊ถŒํ•œ: terraform apply๊ฐ€ ๊ถŒํ•œ ์˜ค๋ฅ˜๋กœ ์‹คํŒจํ•˜๋ฉด ์ƒ์„ฑ๋˜๊ฑฐ๋‚˜ ๋งก๊ฒจ์ง€๋Š” IAM ์ •์ฑ… ๋ฐ ์—ญํ• ์„ ์‹ ์ค‘ํ•˜๊ฒŒ ๊ฒ€ํ† ํ•˜์‹ญ์‹œ์˜ค. AWS ์ฝ˜์†”(IAM Access Analyzer, CloudTrail)์ด ๋„์›€์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์ˆœํ™˜ ์˜์กด์„ฑ: ์ด๋Ÿฌํ•œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ๋ชจ๋“ˆ์„ ๋” ๋ถ„๋ฆฌํ•˜๊ฑฐ๋‚˜ problem-generator-v3 ๋ฐ code-execution-service์— ๋Œ€ํ•ด ๋ณด์—ฌ์ค€ ๊ฒƒ์ฒ˜๋Ÿผ ๋‹ค๋‹จ๊ณ„ ์ ์šฉ์„ ์‚ฌ์šฉํ•ด์•ผ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • CloudFront ์ „ํŒŒ: CloudFront ๋ฐฐํฌ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ์ „ ์„ธ๊ณ„์ ์œผ๋กœ ์ „ํŒŒ๋˜๋Š” ๋ฐ ๋ช‡ ๋ถ„ ์ •๋„ ๊ฑธ๋ฆด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • Lambda Layer ๊ฒฝ๋กœ: ๋ ˆ์ด์–ด์šฉ data "archive_file"์˜ source_dir์ด ์„ค์น˜๋œ ์˜์กด์„ฑ์ด ์žˆ๋Š” nodejs (๋˜๋Š” python) ํด๋”๋ฅผ ํฌํ•จํ•˜๋Š” ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๊ฐ€๋ฆฌํ‚ค๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

์ด ๊ฐ€์ด๋“œ๋Š” ALPACO ํ”„๋กœ์ ํŠธ์˜ Terraform ์ธํ”„๋ผ ์ž‘์—…์— ๋Œ€ํ•œ ํ™•์‹คํ•œ ๊ธฐ์ดˆ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ๋” ๊ตฌ์ฒด์ ์ธ ์„ธ๋ถ€ ์ •๋ณด๋Š” ๊ฐœ๋ณ„ ๋ชจ๋“ˆ README.md ํŒŒ์ผ์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.