diff --git a/.claude/settings.local.json b/.claude/settings.local.json
new file mode 100644
index 0000000..a6fc47d
--- /dev/null
+++ b/.claude/settings.local.json
@@ -0,0 +1,15 @@
+{
+ "permissions": {
+ "allow": [
+ "Bash(mkdir:*)",
+ "Bash(chmod:*)",
+ "Bash(awk:*)",
+ "Bash(for:*)",
+ "Bash(ls:*)",
+ "Bash(done)",
+ "Bash(tree:*)"
+ ],
+ "deny": [],
+ "ask": []
+ }
+}
diff --git a/.idea/copilot.data.migration.agent.xml b/.idea/copilot.data.migration.agent.xml
new file mode 100644
index 0000000..4ea72a9
--- /dev/null
+++ b/.idea/copilot.data.migration.agent.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/copilot.data.migration.ask.xml b/.idea/copilot.data.migration.ask.xml
new file mode 100644
index 0000000..7ef04e2
--- /dev/null
+++ b/.idea/copilot.data.migration.ask.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/copilot.data.migration.ask2agent.xml b/.idea/copilot.data.migration.ask2agent.xml
new file mode 100644
index 0000000..1f2ea11
--- /dev/null
+++ b/.idea/copilot.data.migration.ask2agent.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/copilot.data.migration.edit.xml b/.idea/copilot.data.migration.edit.xml
new file mode 100644
index 0000000..8648f94
--- /dev/null
+++ b/.idea/copilot.data.migration.edit.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md
new file mode 100644
index 0000000..f1ef66b
--- /dev/null
+++ b/ARCHITECTURE.md
@@ -0,0 +1,2362 @@
+# Learning Management System - Architecture Documentation
+
+**A comprehensive overview of the architecture for the Learning Management System built with the MAD Stack (MongoDB, Angular, Django).**
+
+
+
+
+
+## Table of Contents
+
+- [Overview](#overview)
+- [System Architecture](#system-architecture)
+- [Technology Stack](#technology-stack)
+- [Architecture Layers](#architecture-layers)
+- [Database Schema](#database-schema)
+- [API Architecture](#api-architecture)
+- [Frontend Architecture](#frontend-architecture)
+- [Authentication Flow](#authentication-flow)
+- [Data Flow](#data-flow)
+- [Deployment Architecture](#deployment-architecture)
+- [CI/CD Pipeline](#cicd-pipeline)
+- [Caching Strategy](#caching-strategy)
+- [Security Architecture](#security-architecture)
+- [Scalability Considerations](#scalability-considerations)
+
+---
+
+## Overview
+
+The E-Learning Management System is a full-stack web application built using the **MAD Stack** (MongoDB, Angular, Django). It provides a comprehensive platform for managing online courses, lessons, quizzes, enrollments, and user progress tracking.
+
+### Key Features
+
+- **Multi-tenant User Management**: Support for students, instructors, and administrators
+- **Course Management**: Complete CRUD operations for courses, lessons, and categories
+- **Quiz System**: Interactive quizzes with questions and multiple-choice answers
+- **Enrollment & Progress Tracking**: Track student enrollments and lesson completion
+- **Real-time Notifications**: Notification system for user updates
+- **Server-side Caching**: Redis-based caching for improved performance
+- **RESTful API**: Comprehensive API with Swagger/OpenAPI documentation
+- **Responsive Frontend**: Angular-based SPA with Bootstrap styling
+- **Containerized Deployment**: Docker and Kubernetes support
+
+---
+
+## System Architecture
+
+### High-Level Architecture
+
+```mermaid
+graph TB
+ subgraph "Client Layer"
+ A[Web Browser]
+ B[Mobile Browser]
+ end
+
+ subgraph "Frontend Layer"
+ C[Angular Application]
+ D[Bootstrap UI Components]
+ E[Angular Services]
+ F[HTTP Interceptors]
+ end
+
+ subgraph "API Gateway"
+ G[NGINX Reverse Proxy]
+ end
+
+ subgraph "Backend Layer"
+ H[Django REST Framework]
+ I[Authentication Service]
+ J[ViewSets & Serializers]
+ K[Business Logic]
+ end
+
+ subgraph "Caching Layer"
+ L[Redis Cache]
+ end
+
+ subgraph "Data Layer"
+ M[(MongoDB)]
+ N[(SQLite - Auth)]
+ end
+
+ subgraph "External Services"
+ O[MongoDB Atlas]
+ P[Redis Cloud]
+ end
+
+ A --> C
+ B --> C
+ C --> D
+ C --> E
+ E --> F
+ F --> G
+ G --> H
+ H --> I
+ H --> J
+ J --> K
+ K --> L
+ K --> M
+ I --> N
+ M -.-> O
+ L -.-> P
+```
+
+### Component Interaction Diagram
+
+```mermaid
+graph LR
+ subgraph "Frontend Components"
+ A[Login Component]
+ B[Course List Component]
+ C[Lesson List Component]
+ D[User List Component]
+ E[Enrollment Component]
+ F[Progress Component]
+ end
+
+ subgraph "Angular Services"
+ G[Auth Service]
+ H[Course Service]
+ I[Lesson Service]
+ J[User Service]
+ K[Enrollment Service]
+ L[Progress Service]
+ end
+
+ subgraph "Backend ViewSets"
+ M[UserViewSet]
+ N[CourseViewSet]
+ O[LessonViewSet]
+ P[EnrollmentViewSet]
+ Q[ProgressViewSet]
+ end
+
+ A --> G
+ B --> H
+ C --> I
+ D --> J
+ E --> K
+ F --> L
+
+ G --> M
+ H --> N
+ I --> O
+ J --> M
+ K --> P
+ L --> Q
+```
+
+---
+
+## Technology Stack
+
+### MAD Stack Visualization
+
+```mermaid
+graph TD
+ subgraph "Frontend Stack"
+ A[Angular 18+]
+ B[TypeScript]
+ C[Bootstrap 5]
+ D[RxJS]
+ E[Chart.js]
+ F[Angular Material]
+ end
+
+ subgraph "Backend Stack"
+ G[Django 4.2+]
+ H[Django REST Framework]
+ I[Python 3.12]
+ J[MongoEngine ODM]
+ K[dj-rest-auth]
+ L[drf-yasg - Swagger]
+ end
+
+ subgraph "Database Stack"
+ M[(MongoDB 5.0)]
+ N[(SQLite 3)]
+ O[(Redis 6)]
+ end
+
+ subgraph "DevOps Stack"
+ P[Docker]
+ Q[Docker Compose]
+ R[Kubernetes]
+ S[Jenkins]
+ T[GitHub Actions]
+ U[NGINX]
+ end
+
+ subgraph "Testing Stack"
+ V[Jest]
+ W[Cypress]
+ X[Pytest]
+ end
+
+ A --> B
+ A --> C
+ A --> D
+ G --> H
+ G --> I
+ H --> J
+ J --> M
+ K --> N
+ H --> O
+
+ P --> Q
+ Q --> R
+ S --> T
+
+ style A fill:#dd0031
+ style G fill:#092e20
+ style M fill:#47a248
+ style O fill:#dc382d
+ style P fill:#2496ed
+```
+
+---
+
+## Architecture Layers
+
+### Layered Architecture
+
+```mermaid
+graph TB
+ subgraph "Presentation Layer"
+ A[Angular Components]
+ B[HTML Templates]
+ C[CSS Styles]
+ end
+
+ subgraph "Service Layer"
+ D[Angular Services]
+ E[HTTP Client]
+ F[State Management]
+ end
+
+ subgraph "API Layer"
+ G[REST Endpoints]
+ H[Authentication Middleware]
+ I[CORS Middleware]
+ J[Request Validation]
+ end
+
+ subgraph "Business Logic Layer"
+ K[ViewSets]
+ L[Serializers]
+ M[Custom Business Logic]
+ N[Permissions & Authorization]
+ end
+
+ subgraph "Data Access Layer"
+ O[MongoEngine Models]
+ P[Django ORM Models]
+ Q[Cache Manager]
+ end
+
+ subgraph "Infrastructure Layer"
+ R[(MongoDB)]
+ S[(SQLite)]
+ T[Redis Cache]
+ end
+
+ A --> D
+ B --> A
+ C --> A
+ D --> E
+ E --> G
+ G --> H
+ H --> I
+ I --> J
+ J --> K
+ K --> L
+ L --> M
+ M --> N
+ N --> O
+ O --> R
+ P --> S
+ Q --> T
+ N --> Q
+```
+
+---
+
+## Database Schema
+
+### MongoDB Collections Schema
+
+```mermaid
+erDiagram
+ USER ||--o{ COURSE : instructs
+ USER ||--o{ ENROLLMENT : enrolls
+ USER ||--o{ PROGRESS : tracks
+ USER ||--o{ NOTIFICATION : receives
+
+ CATEGORY ||--o{ COURSE : categorizes
+
+ COURSE ||--o{ LESSON : contains
+ COURSE ||--o{ ENROLLMENT : has
+
+ LESSON ||--o{ QUIZ : includes
+ LESSON ||--o{ PROGRESS : tracks
+
+ QUIZ ||--o{ QUESTION : contains
+
+ QUESTION ||--o{ CHOICE : has
+
+ USER {
+ ObjectId _id PK
+ string username UK
+ string email UK
+ boolean is_instructor
+ boolean is_student
+ string bio
+ string profile_picture
+ }
+
+ CATEGORY {
+ ObjectId _id PK
+ string name
+ string description
+ }
+
+ COURSE {
+ ObjectId _id PK
+ string title
+ string description
+ ObjectId instructor_id FK
+ ObjectId category_id FK
+ datetime created_at
+ datetime updated_at
+ string image
+ decimal price
+ boolean published
+ }
+
+ LESSON {
+ ObjectId _id PK
+ string title
+ ObjectId course_id FK
+ string content
+ string video_url
+ datetime created_at
+ datetime updated_at
+ }
+
+ QUIZ {
+ ObjectId _id PK
+ ObjectId lesson_id FK
+ string title
+ datetime created_at
+ }
+
+ QUESTION {
+ ObjectId _id PK
+ ObjectId quiz_id FK
+ string text
+ string answer
+ datetime created_at
+ }
+
+ CHOICE {
+ ObjectId _id PK
+ ObjectId question_id FK
+ string text
+ boolean is_correct
+ }
+
+ ENROLLMENT {
+ ObjectId _id PK
+ ObjectId student_id FK
+ ObjectId course_id FK
+ datetime enrolled_at
+ }
+
+ PROGRESS {
+ ObjectId _id PK
+ ObjectId student_id FK
+ ObjectId lesson_id FK
+ boolean completed
+ datetime completed_at
+ }
+
+ NOTIFICATION {
+ ObjectId _id PK
+ ObjectId recipient_id FK
+ string message
+ datetime created_at
+ boolean is_read
+ }
+```
+
+### Data Relationships
+
+```mermaid
+graph TB
+ subgraph "User Management"
+ A[User]
+ end
+
+ subgraph "Course Structure"
+ B[Category]
+ C[Course]
+ D[Lesson]
+ E[Quiz]
+ F[Question]
+ G[Choice]
+ end
+
+ subgraph "Learning Tracking"
+ H[Enrollment]
+ I[Progress]
+ J[Notification]
+ end
+
+ A -->|instructs| C
+ A -->|enrolls in| H
+ A -->|tracks| I
+ A -->|receives| J
+
+ B -->|categorizes| C
+ C -->|contains| D
+ D -->|includes| E
+ E -->|has| F
+ F -->|has options| G
+
+ C -->|creates| H
+ D -->|tracks| I
+```
+
+---
+
+## API Architecture
+
+### RESTful API Endpoints
+
+```mermaid
+graph LR
+ subgraph "Authentication Endpoints"
+ A[POST /api/auth/login/]
+ B[POST /api/auth/registration/]
+ C[POST /api/auth/logout/]
+ D[GET /api/auth/user/]
+ end
+
+ subgraph "User Management"
+ E[GET /api/users/]
+ F[POST /api/users/]
+ G[GET /api/users/:id/]
+ H[PUT /api/users/:id/]
+ I[DELETE /api/users/:id/]
+ end
+
+ subgraph "Course Management"
+ J[GET /api/courses/]
+ K[POST /api/courses/]
+ L[GET /api/courses/:id/]
+ M[PUT /api/courses/:id/]
+ N[DELETE /api/courses/:id/]
+ end
+
+ subgraph "Lesson Management"
+ O[GET /api/lessons/]
+ P[POST /api/lessons/]
+ Q[GET /api/lessons/:id/]
+ R[PUT /api/lessons/:id/]
+ S[DELETE /api/lessons/:id/]
+ end
+
+ subgraph "Enrollment & Progress"
+ T[GET /api/enrollments/]
+ U[POST /api/enrollments/]
+ V[GET /api/progress/]
+ W[POST /api/progress/]
+ end
+```
+
+### API Request Flow
+
+```mermaid
+sequenceDiagram
+ participant Client
+ participant NGINX
+ participant Django
+ participant Redis
+ participant MongoDB
+ participant SQLite
+
+ Client->>NGINX: HTTP Request
+ NGINX->>Django: Forward Request
+
+ alt Authentication Required
+ Django->>SQLite: Verify Token
+ SQLite-->>Django: Token Valid
+ end
+
+ Django->>Redis: Check Cache
+
+ alt Cache Hit
+ Redis-->>Django: Cached Data
+ Django-->>Client: Response (Fast)
+ else Cache Miss
+ Django->>MongoDB: Query Data
+ MongoDB-->>Django: Data Result
+ Django->>Redis: Store Cache
+ Django-->>Client: Response
+ end
+```
+
+### ViewSet Architecture
+
+```mermaid
+graph TB
+ subgraph "Django REST Framework ViewSets"
+ A[UserViewSet]
+ B[CourseViewSet]
+ C[CategoryViewSet]
+ D[LessonViewSet]
+ E[QuizViewSet]
+ F[QuestionViewSet]
+ G[ChoiceViewSet]
+ H[EnrollmentViewSet]
+ I[ProgressViewSet]
+ J[NotificationViewSet]
+ end
+
+ subgraph "Serializers"
+ K[UserSerializer]
+ L[CourseSerializer]
+ M[CategorySerializer]
+ N[LessonSerializer]
+ O[QuizSerializer]
+ P[QuestionSerializer]
+ Q[ChoiceSerializer]
+ R[EnrollmentSerializer]
+ S[ProgressSerializer]
+ T[NotificationSerializer]
+ end
+
+ subgraph "MongoEngine Models"
+ U[(User Model)]
+ V[(Course Model)]
+ W[(Category Model)]
+ X[(Lesson Model)]
+ Y[(Quiz Model)]
+ Z[(Question Model)]
+ AA[(Choice Model)]
+ AB[(Enrollment Model)]
+ AC[(Progress Model)]
+ AD[(Notification Model)]
+ end
+
+ A --> K --> U
+ B --> L --> V
+ C --> M --> W
+ D --> N --> X
+ E --> O --> Y
+ F --> P --> Z
+ G --> Q --> AA
+ H --> R --> AB
+ I --> S --> AC
+ J --> T --> AD
+```
+
+---
+
+## Frontend Architecture
+
+### Angular Application Structure
+
+```mermaid
+graph TB
+ subgraph "App Module"
+ A[App Component]
+ B[App Routes]
+ C[App Config]
+ end
+
+ subgraph "Core Module"
+ D[Header Component]
+ E[Footer Component]
+ end
+
+ subgraph "Auth Module"
+ F[Login Component]
+ G[Register Component]
+ H[Auth Guard]
+ I[Auth Interceptor]
+ end
+
+ subgraph "Feature Modules"
+ J[Course List Component]
+ K[Lesson List Component]
+ L[User List Component]
+ M[Enrollment List Component]
+ N[Progress List Component]
+ end
+
+ subgraph "Services"
+ O[Auth Service]
+ P[Course Service]
+ Q[Lesson Service]
+ R[User Service]
+ S[Enrollment Service]
+ T[Progress Service]
+ end
+
+ subgraph "Pages"
+ U[Home Component]
+ V[Not Found Component]
+ end
+
+ A --> B
+ A --> C
+ A --> D
+ A --> E
+
+ B --> F
+ B --> G
+ B --> J
+ B --> K
+ B --> L
+ B --> M
+ B --> N
+ B --> U
+ B --> V
+
+ F --> O
+ G --> O
+ J --> P
+ K --> Q
+ L --> R
+ M --> S
+ N --> T
+
+ H --> O
+ I --> O
+```
+
+### Component Communication
+
+```mermaid
+graph LR
+ subgraph "Parent Components"
+ A[App Component]
+ end
+
+ subgraph "Smart Components"
+ B[Course List]
+ C[Lesson List]
+ D[User List]
+ end
+
+ subgraph "Presentational Components"
+ E[Course Card]
+ F[Lesson Card]
+ G[User Card]
+ end
+
+ subgraph "Services - State Management"
+ H[Course Service]
+ I[Lesson Service]
+ J[User Service]
+ end
+
+ A --> B
+ A --> C
+ A --> D
+
+ B --> E
+ C --> F
+ D --> G
+
+ B --> H
+ C --> I
+ D --> J
+
+ H -.->|Observable| B
+ I -.->|Observable| C
+ J -.->|Observable| D
+```
+
+### Service Layer Architecture
+
+```mermaid
+graph TB
+ subgraph "HTTP Services"
+ A[Auth Service]
+ B[Course Service]
+ C[Lesson Service]
+ D[User Service]
+ E[Enrollment Service]
+ F[Progress Service]
+ end
+
+ subgraph "Interceptors"
+ G[Auth Interceptor]
+ H[Error Interceptor]
+ I[Loading Interceptor]
+ end
+
+ subgraph "Guards"
+ J[Auth Guard]
+ K[Role Guard]
+ end
+
+ subgraph "HTTP Client"
+ L[Angular HttpClient]
+ end
+
+ subgraph "Backend API"
+ M[Django REST API]
+ end
+
+ A --> G
+ B --> G
+ C --> G
+ D --> G
+ E --> G
+ F --> G
+
+ G --> H
+ H --> I
+ I --> L
+
+ J --> A
+ K --> A
+
+ L --> M
+
+ style A fill:#456789
+ style G fill:#ce93d8
+ style J fill:#ba68c8
+ style L fill:#ab47bc
+ style M fill:#9c27b0
+```
+
+---
+
+## Authentication Flow
+
+### User Authentication Sequence
+
+```mermaid
+sequenceDiagram
+ participant User
+ participant Angular
+ participant AuthService
+ participant AuthInterceptor
+ participant Django
+ participant SQLite
+ participant Redis
+
+ User->>Angular: Enter Credentials
+ Angular->>AuthService: login(username, password)
+ AuthService->>Django: POST /api/auth/login/
+ Django->>SQLite: Verify Credentials
+
+ alt Valid Credentials
+ SQLite-->>Django: User Valid
+ Django->>Django: Generate JWT Token
+ Django->>Redis: Cache Token
+ Django-->>AuthService: {token, user}
+ AuthService->>AuthService: Store in localStorage
+ AuthService-->>Angular: Login Success
+ Angular-->>User: Redirect to Dashboard
+ else Invalid Credentials
+ SQLite-->>Django: Invalid User
+ Django-->>AuthService: 401 Unauthorized
+ AuthService-->>Angular: Login Failed
+ Angular-->>User: Show Error
+ end
+
+ User->>Angular: Access Protected Route
+ Angular->>AuthInterceptor: HTTP Request
+ AuthInterceptor->>AuthInterceptor: Add Authorization Header
+ AuthInterceptor->>Django: Request + Token
+ Django->>SQLite: Validate Token
+
+ alt Valid Token
+ SQLite-->>Django: Token Valid
+ Django-->>Angular: Protected Resource
+ Angular-->>User: Display Content
+ else Invalid Token
+ SQLite-->>Django: Token Invalid
+ Django-->>Angular: 401 Unauthorized
+ Angular->>AuthService: logout()
+ Angular-->>User: Redirect to Login
+ end
+```
+
+### Registration Flow
+
+```mermaid
+sequenceDiagram
+ participant User
+ participant RegisterComponent
+ participant AuthService
+ participant Django
+ participant SQLite
+ participant MongoDB
+
+ User->>RegisterComponent: Fill Registration Form
+ RegisterComponent->>RegisterComponent: Validate Form
+ RegisterComponent->>AuthService: register(userData)
+ AuthService->>Django: POST /api/auth/registration/
+
+ Django->>SQLite: Check Username/Email
+
+ alt Username/Email Available
+ Django->>SQLite: Create Auth User
+ SQLite-->>Django: User Created
+ Django->>MongoDB: Create User Profile
+ MongoDB-->>Django: Profile Created
+ Django->>Django: Generate Token
+ Django-->>AuthService: {token, user}
+ AuthService->>AuthService: Store Token
+ AuthService-->>RegisterComponent: Registration Success
+ RegisterComponent-->>User: Redirect to Dashboard
+ else Username/Email Taken
+ SQLite-->>Django: Duplicate Entry
+ Django-->>AuthService: 400 Bad Request
+ AuthService-->>RegisterComponent: Registration Failed
+ RegisterComponent-->>User: Show Error
+ end
+```
+
+### JWT Token Flow
+
+```mermaid
+graph TB
+ subgraph "Token Generation"
+ A[User Login]
+ B[Verify Credentials]
+ C[Generate JWT Token]
+ D[Store in SQLite]
+ E[Cache in Redis]
+ F[Return to Client]
+ end
+
+ subgraph "Token Validation"
+ G[Client Request]
+ H[Extract Token from Header]
+ I[Validate Token]
+ J{Token Valid?}
+ K[Allow Access]
+ L[Deny Access]
+ end
+
+ subgraph "Token Refresh"
+ M[Token Near Expiry]
+ N[Request Refresh]
+ O[Generate New Token]
+ P[Update Client]
+ end
+
+ A --> B
+ B --> C
+ C --> D
+ C --> E
+ E --> F
+
+ G --> H
+ H --> I
+ I --> J
+ J -->|Yes| K
+ J -->|No| L
+
+ M --> N
+ N --> O
+ O --> P
+```
+
+---
+
+## Data Flow
+
+### Course Enrollment Flow
+
+```mermaid
+sequenceDiagram
+ participant Student
+ participant Frontend
+ participant EnrollmentService
+ participant Django
+ participant MongoDB
+ participant Redis
+ participant NotificationService
+
+ Student->>Frontend: Click "Enroll in Course"
+ Frontend->>EnrollmentService: enroll(courseId, studentId)
+ EnrollmentService->>Django: POST /api/enrollments/
+
+ Django->>MongoDB: Check Existing Enrollment
+
+ alt Not Already Enrolled
+ Django->>MongoDB: Create Enrollment Record
+ MongoDB-->>Django: Enrollment Created
+
+ Django->>MongoDB: Create Initial Progress Records
+ MongoDB-->>Django: Progress Initialized
+
+ Django->>MongoDB: Create Notification
+ MongoDB-->>Django: Notification Created
+
+ Django->>Redis: Invalidate Course Cache
+ Django->>Redis: Cache Enrollment Data
+
+ Django-->>EnrollmentService: Enrollment Success
+ EnrollmentService-->>Frontend: Update UI
+ Frontend-->>Student: Show Success Message
+
+ Django->>NotificationService: Send Email
+ NotificationService-->>Student: Confirmation Email
+ else Already Enrolled
+ MongoDB-->>Django: Enrollment Exists
+ Django-->>EnrollmentService: 400 Already Enrolled
+ EnrollmentService-->>Frontend: Show Error
+ Frontend-->>Student: Display Error Message
+ end
+```
+
+### Progress Tracking Flow
+
+```mermaid
+graph TB
+ subgraph "Lesson Completion"
+ A[Student Views Lesson]
+ B[Mark as Complete]
+ C[Update Progress Record]
+ end
+
+ subgraph "Progress Calculation"
+ D[Get All Course Lessons]
+ E[Count Completed Lessons]
+ F[Calculate Percentage]
+ end
+
+ subgraph "Achievement System"
+ G{Check Milestones}
+ H[25% Complete]
+ I[50% Complete]
+ J[75% Complete]
+ K[100% Complete]
+ end
+
+ subgraph "Notifications"
+ L[Create Notification]
+ M[Send Email]
+ N[Update Dashboard]
+ end
+
+ A --> B
+ B --> C
+ C --> D
+ D --> E
+ E --> F
+ F --> G
+
+ G -->|25%| H
+ G -->|50%| I
+ G -->|75%| J
+ G -->|100%| K
+
+ H --> L
+ I --> L
+ J --> L
+ K --> L
+
+ L --> M
+ L --> N
+```
+
+### Quiz Submission Flow
+
+```mermaid
+sequenceDiagram
+ participant Student
+ participant Frontend
+ participant QuizService
+ participant Django
+ participant MongoDB
+
+ Student->>Frontend: Start Quiz
+ Frontend->>QuizService: getQuiz(quizId)
+ QuizService->>Django: GET /api/quizzes/:id/
+ Django->>MongoDB: Fetch Quiz with Questions
+ MongoDB-->>Django: Quiz Data
+ Django-->>QuizService: Quiz Object
+ QuizService-->>Frontend: Display Quiz
+
+ Student->>Frontend: Answer Questions
+ Student->>Frontend: Submit Quiz
+
+ Frontend->>QuizService: submitQuiz(answers)
+ QuizService->>Django: POST /api/quiz-submissions/
+
+ Django->>MongoDB: Fetch Correct Answers
+ MongoDB-->>Django: Answer Key
+
+ Django->>Django: Calculate Score
+ Django->>MongoDB: Save Submission
+ MongoDB-->>Django: Submission Saved
+
+ alt Passing Score
+ Django->>MongoDB: Update Progress (Complete)
+ Django->>MongoDB: Create Achievement Notification
+ else Failing Score
+ Django->>MongoDB: Update Progress (Incomplete)
+ Django->>MongoDB: Create Retry Notification
+ end
+
+ Django-->>QuizService: Score & Feedback
+ QuizService-->>Frontend: Display Results
+ Frontend-->>Student: Show Score & Feedback
+```
+
+---
+
+## Deployment Architecture
+
+### Docker Container Architecture
+
+```mermaid
+graph TB
+ subgraph "Docker Compose Stack"
+ A[NGINX Container]
+ B[Frontend Container]
+ C[Backend Container]
+ D[MongoDB Container]
+ E[Redis Container]
+ end
+
+ subgraph "Volumes"
+ F[mongodb_data]
+ G[backend_static]
+ H[frontend_dist]
+ end
+
+ subgraph "Networks"
+ I[lms_network]
+ end
+
+ subgraph "External Services"
+ J[MongoDB Atlas]
+ K[Redis Cloud]
+ end
+
+ A --> B
+ A --> C
+ C --> D
+ C --> E
+
+ D --> F
+ C --> G
+ B --> H
+
+ A -.-> I
+ B -.-> I
+ C -.-> I
+ D -.-> I
+ E -.-> I
+
+ C -.->|Backup| J
+ C -.->|Backup| K
+
+ style A fill:#009639
+ style B fill:#dd0031
+ style C fill:#092e20
+ style D fill:#47a248
+ style E fill:#dc382d
+```
+
+### Kubernetes Deployment
+
+```mermaid
+graph TB
+ subgraph "Kubernetes Cluster"
+ subgraph "Frontend Namespace"
+ A[Frontend Deployment]
+ B[Frontend Service]
+ C[Frontend Pods x3]
+ end
+
+ subgraph "Backend Namespace"
+ D[Backend Deployment]
+ E[Backend Service]
+ F[Backend Pods x3]
+ end
+
+ subgraph "Database Namespace"
+ G[MongoDB StatefulSet]
+ H[MongoDB Service]
+ I[Persistent Volumes]
+ end
+
+ subgraph "Cache Namespace"
+ J[Redis Deployment]
+ K[Redis Service]
+ end
+
+ subgraph "Ingress"
+ L[Ingress Controller]
+ M[SSL/TLS Termination]
+ end
+
+ subgraph "Config & Secrets"
+ N[ConfigMap]
+ O[Secrets]
+ end
+ end
+
+ L --> M
+ M --> B
+ M --> E
+
+ A --> C
+ D --> F
+ G --> I
+
+ B --> C
+ E --> F
+ H --> G
+ K --> J
+
+ F --> H
+ F --> K
+
+ N --> F
+ O --> F
+
+ style L fill:#326ce5
+ style A fill:#dd0031
+ style D fill:#092e20
+ style G fill:#47a248
+ style J fill:#dc382d
+```
+
+### AWS Production Infrastructure
+
+```mermaid
+graph TB
+ subgraph "AWS Cloud - Production Architecture"
+ subgraph "Route 53"
+ R53[DNS Management]
+ end
+
+ subgraph "CloudFront CDN"
+ CF[Global Edge Locations]
+ WAF[Web Application Firewall]
+ end
+
+ subgraph "VPC - Multi-AZ"
+ subgraph "Public Subnets"
+ ALB[Application Load Balancer]
+ NAT1[NAT Gateway AZ1]
+ NAT2[NAT Gateway AZ2]
+ end
+
+ subgraph "Private Subnets - AZ1"
+ ECS1A[ECS Backend Tasks]
+ ECS1B[ECS Frontend Tasks]
+ end
+
+ subgraph "Private Subnets - AZ2"
+ ECS2A[ECS Backend Tasks]
+ ECS2B[ECS Frontend Tasks]
+ end
+
+ subgraph "Database Subnets"
+ RDS1[RDS Primary PostgreSQL]
+ RDS2[RDS Standby PostgreSQL]
+ DOCDB[DocumentDB Cluster MongoDB-compatible]
+ REDIS[ElastiCache Redis Multi-AZ]
+ end
+ end
+
+ subgraph "Container Registry"
+ ECR[Amazon ECR Backend & Frontend Images]
+ end
+
+ subgraph "Storage"
+ S3A[S3 Static Assets]
+ S3B[S3 Backups]
+ end
+
+ subgraph "Security & Secrets"
+ SM[Secrets Manager]
+ KMS[AWS KMS]
+ SG[Security Groups]
+ end
+
+ subgraph "Monitoring & Logging"
+ CW[CloudWatch]
+ XRAY[X-Ray Tracing]
+ SNS[SNS Alerts]
+ end
+ end
+
+ R53 --> CF
+ CF --> WAF
+ WAF --> ALB
+
+ ALB --> ECS1A
+ ALB --> ECS1B
+ ALB --> ECS2A
+ ALB --> ECS2B
+
+ ECS1A --> NAT1
+ ECS1B --> NAT1
+ ECS2A --> NAT2
+ ECS2B --> NAT2
+
+ ECS1A --> RDS1
+ ECS2A --> RDS1
+ RDS1 -.->|Replication| RDS2
+
+ ECS1A --> DOCDB
+ ECS2A --> DOCDB
+
+ ECS1A --> REDIS
+ ECS2A --> REDIS
+
+ ECR -.->|Pull Images| ECS1A
+ ECR -.->|Pull Images| ECS2A
+
+ CF --> S3A
+
+ SM --> ECS1A
+ SM --> ECS2A
+ KMS --> SM
+
+ CW --> SNS
+ XRAY --> CW
+
+ ECS1A --> CW
+ ECS2A --> CW
+```
+
+### Terraform Infrastructure as Code
+
+```mermaid
+graph LR
+ subgraph "Terraform Modules"
+ VPC[VPC Module - 3 AZs - Public/Private/DB Subnets - NAT Gateways - Route Tables]
+
+ SEC[Security Module - Security Groups - NACLs - WAF Rules - IAM Roles/Policies]
+
+ ECR_MOD[ECR Module - Backend Repository - Frontend Repository - Lifecycle Policies]
+
+ RDS[RDS Module - PostgreSQL 15 - Multi-AZ - Auto Backups - Encryption]
+
+ CACHE[ElastiCache Module - Redis 7 - Cluster Mode - Multi-AZ - Snapshots]
+
+ ECS[ECS Module - Fargate Cluster - Task Definitions - Services - Auto-scaling]
+
+ ALB_MOD[ALB Module - Target Groups - Listeners - SSL/TLS - Health Checks]
+
+ S3_MOD[S3 Module - Static Assets - Backups - Versioning - Lifecycle Rules]
+
+ CF_MOD[CloudFront Module - Distribution - Origin Config - Cache Behaviors]
+
+ R53[Route53 Module - Hosted Zone - DNS Records - Health Checks]
+ end
+
+ VPC --> SEC
+ VPC --> RDS
+ VPC --> CACHE
+ VPC --> ECS
+ VPC --> ALB_MOD
+
+ SEC --> ECS
+ SEC --> RDS
+ SEC --> CACHE
+ SEC --> ALB_MOD
+
+ ECR_MOD --> ECS
+ RDS --> ECS
+ CACHE --> ECS
+ ALB_MOD --> ECS
+
+ S3_MOD --> CF_MOD
+ CF_MOD --> R53
+ ALB_MOD --> R53
+```
+
+### Cloud Infrastructure Options
+
+```mermaid
+graph TB
+ subgraph "Option 1: Vercel + Render (Current)"
+ A[Vercel CDN]
+ B[Edge Network]
+ C[Static Assets]
+ D[Render Service]
+ E[Auto-scaling]
+ F[Health Checks]
+ end
+
+ subgraph "Option 2: AWS Full Stack (Production)"
+ G[CloudFront]
+ H[ALB + ECS Fargate]
+ I[RDS + DocumentDB]
+ J[ElastiCache Redis]
+ K[S3 + CloudWatch]
+ end
+
+ subgraph "Option 3: Kubernetes (Self-Hosted)"
+ L[K8s Ingress]
+ M[K8s Services]
+ N[StatefulSets]
+ O[ConfigMaps]
+ end
+
+ subgraph "Shared Services"
+ P[MongoDB Atlas]
+ Q[Redis Cloud]
+ R[GitHub Actions]
+ S[Jenkins CI/CD]
+ end
+
+ A --> B
+ B --> C
+ D --> E
+ E --> F
+
+ G --> H
+ H --> I
+ H --> J
+ K --> H
+
+ L --> M
+ M --> N
+ O --> M
+
+ C -.->|Alternative| P
+ F -.->|Alternative| P
+ I -.->|Alternative| P
+ N -.->|Alternative| P
+
+ R --> S
+ S --> A
+ S --> D
+ S --> G
+ S --> L
+```
+
+---
+
+## AWS & Terraform Infrastructure
+
+### Infrastructure Overview
+
+The Learning Management System provides production-ready infrastructure using AWS services and Terraform for Infrastructure as Code (IaC). This enables scalable, secure, and highly available deployments.
+
+#### Key Features
+
+- **Multi-AZ Deployment**: High availability across multiple availability zones
+- **Auto-Scaling**: Automatic scaling based on demand
+- **Security**: Multiple layers of security controls
+- **Monitoring**: Comprehensive monitoring and alerting
+- **Disaster Recovery**: Automated backups and recovery procedures
+- **Cost Optimization**: Right-sized resources with optimization strategies
+
+### AWS Service Architecture
+
+```mermaid
+graph TB
+ subgraph "Compute Layer"
+ ECS[Amazon ECS Fargate Serverless Containers]
+ LAMBDA[AWS Lambda Serverless Functions]
+ end
+
+ subgraph "Data Layer"
+ RDS[Amazon RDS PostgreSQL]
+ DOCDB[Amazon DocumentDB MongoDB Compatible]
+ REDIS[Amazon ElastiCache Redis]
+ S3[Amazon S3 Object Storage]
+ end
+
+ subgraph "Network Layer"
+ VPC[Amazon VPC Isolated Network]
+ ALB[Application Load Balancer Traffic Distribution]
+ R53[Route 53 DNS]
+ CF[CloudFront CDN]
+ end
+
+ subgraph "Security Layer"
+ IAM[IAM Roles/Policies]
+ SM[Secrets Manager]
+ KMS[KMS Encryption]
+ WAF[AWS WAF]
+ SG[Security Groups]
+ end
+
+ subgraph "Operations Layer"
+ CW[CloudWatch Monitoring]
+ XRAY[X-Ray Tracing]
+ BACKUP[AWS Backup]
+ CT[CloudTrail Audit]
+ end
+
+ R53 --> CF
+ CF --> ALB
+ ALB --> ECS
+ ECS --> VPC
+
+ ECS --> RDS
+ ECS --> DOCDB
+ ECS --> REDIS
+ ECS --> S3
+
+ IAM --> ECS
+ SM --> ECS
+ KMS --> RDS
+ KMS --> DOCDB
+ WAF --> CF
+ SG --> ECS
+
+ CW --> ECS
+ XRAY --> ECS
+ BACKUP --> RDS
+ BACKUP --> DOCDB
+ CT --> IAM
+```
+
+### Terraform Module Structure
+
+```mermaid
+graph TD
+ ROOT[Root Configuration main.tf, variables.tf, outputs.tf]
+
+ ROOT --> VPC_MOD[VPC Module]
+ ROOT --> SEC_MOD[Security Module]
+ ROOT --> ECR_MOD[ECR Module]
+ ROOT --> RDS_MOD[RDS Module]
+ ROOT --> CACHE_MOD[ElastiCache Module]
+ ROOT --> ECS_MOD[ECS Module]
+ ROOT --> ALB_MOD[ALB Module]
+ ROOT --> S3_MOD[S3 Module]
+ ROOT --> CF_MOD[CloudFront Module]
+ ROOT --> R53_MOD[Route53 Module]
+
+ VPC_MOD --> VPC_RES[VPC Resources - VPC - Subnets - Route Tables - NAT Gateways - Internet Gateway]
+
+ SEC_MOD --> SEC_RES[Security Resources - Security Groups - NACLs - WAF Rules - IAM Roles]
+
+ ECR_MOD --> ECR_RES[ECR Repositories - Backend Image - Frontend Image - Lifecycle Policies]
+
+ RDS_MOD --> RDS_RES[RDS Instance - PostgreSQL - Multi-AZ - Automated Backups]
+
+ CACHE_MOD --> CACHE_RES[ElastiCache Cluster - Redis - Replication Group - Snapshots]
+
+ ECS_MOD --> ECS_RES[ECS Resources - Cluster - Task Definitions - Services - Auto-scaling]
+
+ ALB_MOD --> ALB_RES[ALB Resources - Load Balancer - Target Groups - Listeners]
+
+ S3_MOD --> S3_RES[S3 Buckets - Static Assets - Backups - Lifecycle Rules]
+
+ CF_MOD --> CF_RES[CloudFront - Distribution - Origins - Cache Behaviors]
+
+ R53_MOD --> R53_RES[Route53 Resources - Hosted Zone - DNS Records]
+
+ style ROOT fill:#764ABC
+ style VPC_MOD fill:#326CE5
+ style RDS_MOD fill:#527FFF
+ style CACHE_MOD fill:#DC382D
+```
+
+### Deployment Environments
+
+```mermaid
+graph LR
+ subgraph "Development"
+ DEV_TF[Terraform Dev environments/dev/]
+ DEV_AWS[AWS Dev Account - Single AZ - t3.micro instances - Minimal resources]
+ end
+
+ subgraph "Staging"
+ STG_TF[Terraform Staging environments/staging/]
+ STG_AWS[AWS Staging Account - Multi-AZ - t3.small instances - Production-like]
+ end
+
+ subgraph "Production"
+ PROD_TF[Terraform Production environments/production/]
+ PROD_AWS[AWS Production Account - Multi-AZ - Production instances - Full redundancy]
+ end
+
+ subgraph "Shared State"
+ S3_STATE[S3 Backend Terraform State]
+ DYNAMO[DynamoDB State Locking]
+ end
+
+ DEV_TF --> DEV_AWS
+ STG_TF --> STG_AWS
+ PROD_TF --> PROD_AWS
+
+ DEV_TF --> S3_STATE
+ STG_TF --> S3_STATE
+ PROD_TF --> S3_STATE
+
+ S3_STATE --> DYNAMO
+```
+
+### Resource Tagging Strategy
+
+```mermaid
+graph TB
+ subgraph "Mandatory Tags"
+ ENV[Environment dev/staging/production]
+ PROJ[Project lms]
+ MANAGED[ManagedBy Terraform]
+ OWNER[Owner Team Name]
+ end
+
+ subgraph "Optional Tags"
+ COST[CostCenter]
+ APP[Application]
+ VERSION[Version]
+ BACKUP[BackupPolicy]
+ end
+
+ subgraph "Applied To"
+ VPC_TAG[VPC Resources]
+ ECS_TAG[ECS Resources]
+ RDS_TAG[Database Resources]
+ S3_TAG[Storage Resources]
+ end
+
+ ENV --> VPC_TAG
+ PROJ --> VPC_TAG
+ MANAGED --> VPC_TAG
+ OWNER --> VPC_TAG
+
+ ENV --> ECS_TAG
+ PROJ --> ECS_TAG
+ MANAGED --> ECS_TAG
+ OWNER --> ECS_TAG
+
+ ENV --> RDS_TAG
+ PROJ --> RDS_TAG
+ MANAGED --> RDS_TAG
+ OWNER --> RDS_TAG
+
+ ENV --> S3_TAG
+ PROJ --> S3_TAG
+ MANAGED --> S3_TAG
+ OWNER --> S3_TAG
+
+ COST -.-> VPC_TAG
+ COST -.-> ECS_TAG
+ COST -.-> RDS_TAG
+ COST -.-> S3_TAG
+
+ style ENV fill:#4CAF50
+ style PROJ fill:#2196F3
+ style MANAGED fill:#FF9800
+ style OWNER fill:#9C27B0
+```
+
+### Network Architecture Details
+
+```mermaid
+graph TB
+ subgraph "VPC 10.0.0.0/16"
+ subgraph "Availability Zone A"
+ PUB_A[Public Subnet 10.0.1.0/24]
+ PRIV_A[Private Subnet 10.0.11.0/24]
+ DB_A[Database Subnet 10.0.21.0/24]
+ end
+
+ subgraph "Availability Zone B"
+ PUB_B[Public Subnet 10.0.2.0/24]
+ PRIV_B[Private Subnet 10.0.12.0/24]
+ DB_B[Database Subnet 10.0.22.0/24]
+ end
+
+ subgraph "Availability Zone C"
+ PUB_C[Public Subnet 10.0.3.0/24]
+ PRIV_C[Private Subnet 10.0.13.0/24]
+ DB_C[Database Subnet 10.0.23.0/24]
+ end
+
+ IGW[Internet Gateway]
+ NAT_A[NAT Gateway A]
+ NAT_B[NAT Gateway B]
+ NAT_C[NAT Gateway C]
+ end
+
+ INTERNET[Internet]
+
+ INTERNET --> IGW
+ IGW --> PUB_A
+ IGW --> PUB_B
+ IGW --> PUB_C
+
+ PUB_A --> NAT_A
+ PUB_B --> NAT_B
+ PUB_C --> NAT_C
+
+ NAT_A --> PRIV_A
+ NAT_B --> PRIV_B
+ NAT_C --> PRIV_C
+
+ PRIV_A --> DB_A
+ PRIV_B --> DB_B
+ PRIV_C --> DB_C
+```
+
+### Infrastructure Provisioning Workflow
+
+```mermaid
+sequenceDiagram
+ participant DEV as Developer
+ participant GIT as Git Repository
+ participant TF as Terraform
+ participant AWS as AWS Cloud
+
+ DEV->>GIT: 1. Commit Infrastructure Code
+ GIT->>TF: 2. Trigger Terraform Plan
+ TF->>TF: 3. Initialize Backend
+ TF->>TF: 4. Validate Configuration
+ TF->>AWS: 5. Read Current State
+ AWS-->>TF: 6. Return State
+ TF->>TF: 7. Generate Execution Plan
+ TF-->>DEV: 8. Show Plan Output
+
+ alt Plan Approved
+ DEV->>TF: 9. Approve & Apply
+ TF->>AWS: 10. Create VPC Resources
+ AWS-->>TF: 11. VPC Created
+ TF->>AWS: 12. Create Security Groups
+ AWS-->>TF: 13. SGs Created
+ TF->>AWS: 14. Create RDS/Redis
+ AWS-->>TF: 15. DBs Created
+ TF->>AWS: 16. Create ECS Cluster
+ AWS-->>TF: 17. ECS Created
+ TF->>AWS: 18. Create ALB
+ AWS-->>TF: 19. ALB Created
+ TF->>TF: 20. Update State
+ TF-->>DEV: 21. Deployment Complete
+ else Plan Rejected
+ DEV->>GIT: 22. Update Code
+ end
+```
+
+### Cost Optimization Strategies
+
+```mermaid
+graph TD
+ OPTIMIZE[Cost Optimization]
+
+ OPTIMIZE --> COMPUTE[Compute Optimization]
+ OPTIMIZE --> STORAGE[Storage Optimization]
+ OPTIMIZE --> NETWORK[Network Optimization]
+ OPTIMIZE --> DATABASE[Database Optimization]
+
+ COMPUTE --> RIGHTSIZE[Right-sizing EC2/ECS]
+ COMPUTE --> SPOT[Spot Instances Non-prod]
+ COMPUTE --> RESERVED[Reserved Instances Predictable workloads]
+ COMPUTE --> AUTOSCALE[Auto-scaling Match demand]
+
+ STORAGE --> LIFECYCLE[S3 Lifecycle Policies]
+ STORAGE --> IA[Infrequent Access Storage class]
+ STORAGE --> GLACIER[Glacier Long-term backups]
+
+ NETWORK --> NAT_OPT[NAT Gateway Optimization]
+ NETWORK --> ENDPOINT[VPC Endpoints S3, DynamoDB]
+ NETWORK --> CF_OPT[CloudFront Reduce data transfer]
+
+ DATABASE --> RDS_SIZE[RDS Right-sizing]
+ DATABASE --> REDIS_OPT[ElastiCache Reserved nodes]
+ DATABASE --> BACKUP_OPT[Backup Retention policy]
+
+ style OPTIMIZE fill:#4CAF50
+ style COMPUTE fill:#2196F3
+ style STORAGE fill:#FF9800
+ style NETWORK fill:#9C27B0
+ style DATABASE fill:#F44336
+```
+
+---
+
+## CI/CD Pipeline
+
+### Jenkins Pipeline
+
+```mermaid
+graph LR
+ subgraph "Source Control"
+ A[GitHub Repository]
+ B[Webhook Trigger]
+ end
+
+ subgraph "CI Pipeline"
+ C[Checkout Code]
+ D[Install Dependencies]
+ E[Run Linters]
+ F[Run Unit Tests]
+ G[Run Integration Tests]
+ H[Build Docker Images]
+ end
+
+ subgraph "CD Pipeline"
+ I[Push to Registry]
+ J[Deploy to Staging]
+ K[Run E2E Tests]
+ L{Tests Pass?}
+ M[Deploy to Production]
+ N[Rollback]
+ end
+
+ subgraph "Notifications"
+ O[Slack Notification]
+ P[Email Notification]
+ end
+
+ A --> B
+ B --> C
+ C --> D
+ D --> E
+ E --> F
+ F --> G
+ G --> H
+ H --> I
+ I --> J
+ J --> K
+ K --> L
+ L -->|Yes| M
+ L -->|No| N
+ M --> O
+ N --> P
+
+ style A fill:#181717
+ style H fill:#2496ed
+ style M fill:#4caf50
+ style N fill:#f44336
+```
+
+### GitHub Actions Workflow
+
+```mermaid
+graph TB
+ subgraph "Trigger Events"
+ A[Push to Main]
+ B[Pull Request]
+ C[Manual Trigger]
+ end
+
+ subgraph "Frontend Workflow"
+ D[Checkout Frontend]
+ E[Setup Node.js]
+ F[Install Dependencies]
+ G[Lint Code]
+ H[Run Tests]
+ I[Build Application]
+ J[Deploy to Vercel]
+ end
+
+ subgraph "Backend Workflow"
+ K[Checkout Backend]
+ L[Setup Python]
+ M[Install Dependencies]
+ N[Run Pytest]
+ O[Build Docker Image]
+ P[Deploy to Render]
+ end
+
+ subgraph "Quality Gates"
+ Q{Code Coverage}
+ R{Lint Pass}
+ S{Tests Pass}
+ end
+
+ A --> D
+ A --> K
+ B --> D
+ B --> K
+ C --> D
+ C --> K
+
+ D --> E
+ E --> F
+ F --> G
+ G --> H
+ H --> I
+ I --> J
+
+ K --> L
+ L --> M
+ M --> N
+ N --> O
+ O --> P
+
+ H --> Q
+ G --> R
+ H --> S
+ N --> S
+```
+
+### Deployment Stages
+
+```mermaid
+graph LR
+ subgraph "Development"
+ A[Local Development]
+ B[Feature Branch]
+ C[Unit Tests]
+ end
+
+ subgraph "Staging"
+ D[Merge to Develop]
+ E[Integration Tests]
+ F[Staging Environment]
+ G[QA Testing]
+ end
+
+ subgraph "Production"
+ H[Merge to Main]
+ I[Production Build]
+ J[Smoke Tests]
+ K[Production Deployment]
+ L[Health Checks]
+ end
+
+ subgraph "Monitoring"
+ M[Performance Monitoring]
+ N[Error Tracking]
+ O[User Analytics]
+ end
+
+ A --> B
+ B --> C
+ C --> D
+ D --> E
+ E --> F
+ F --> G
+ G --> H
+ H --> I
+ I --> J
+ J --> K
+ K --> L
+ L --> M
+ L --> N
+ L --> O
+```
+
+---
+
+## Caching Strategy
+
+### Multi-Level Caching Architecture
+
+```mermaid
+graph TB
+ subgraph "Client-Side Cache"
+ A[Browser Cache]
+ B[LocalStorage]
+ C[Service Worker]
+ end
+
+ subgraph "CDN Cache"
+ D[Vercel Edge Cache]
+ E[Static Assets]
+ end
+
+ subgraph "Application Cache"
+ F[Angular HTTP Cache]
+ G[Component State]
+ end
+
+ subgraph "Server Cache - Redis"
+ H[User Session Cache]
+ I[Query Result Cache]
+ J[API Response Cache]
+ K[Object Cache]
+ end
+
+ subgraph "Database"
+ L[(MongoDB)]
+ M[Indexes]
+ N[Query Optimization]
+ end
+
+ A --> D
+ B --> F
+ C --> E
+
+ F --> H
+ F --> I
+ F --> J
+
+ H --> L
+ I --> L
+ J --> L
+ K --> L
+
+ L --> M
+ M --> N
+```
+
+### Cache Invalidation Strategy
+
+```mermaid
+sequenceDiagram
+ participant Client
+ participant Redis
+ participant Django
+ participant MongoDB
+
+ Note over Client,MongoDB: Read Operation (Cache Hit)
+ Client->>Django: GET /api/courses/
+ Django->>Redis: Check Cache
+ Redis-->>Django: Cache Hit - Return Data
+ Django-->>Client: Cached Response (Fast)
+
+ Note over Client,MongoDB: Read Operation (Cache Miss)
+ Client->>Django: GET /api/users/
+ Django->>Redis: Check Cache
+ Redis-->>Django: Cache Miss
+ Django->>MongoDB: Query Database
+ MongoDB-->>Django: Fresh Data
+ Django->>Redis: Store in Cache (TTL: 5 min)
+ Django-->>Client: Response
+
+ Note over Client,MongoDB: Write Operation (Invalidation)
+ Client->>Django: POST /api/courses/
+ Django->>MongoDB: Create Course
+ MongoDB-->>Django: Course Created
+ Django->>Redis: Invalidate Related Caches
+ Redis-->>Django: Cache Cleared
+ Django->>Redis: Update Cache with New Data
+ Django-->>Client: Response
+```
+
+### Cache Key Strategy
+
+```mermaid
+graph TB
+ subgraph "Cache Key Patterns"
+ A["user:{user_id}"]
+ B["course:{course_id}"]
+ C["lessons:course:{course_id}"]
+ D["enrollments:user:{user_id}"]
+ E["progress:user:{user_id}:lesson:{lesson_id}"]
+ F["notifications:user:{user_id}"]
+ end
+
+ subgraph "TTL Strategy"
+ G[Static Content: 1 hour]
+ H[User Data: 15 minutes]
+ I[Course Data: 30 minutes]
+ J[Progress Data: 5 minutes]
+ K[Notifications: 2 minutes]
+ end
+
+ subgraph "Invalidation Events"
+ L[User Update]
+ M[Course Update]
+ N[Lesson Complete]
+ O[Enrollment Created]
+ end
+
+ A --> H
+ B --> I
+ C --> I
+ D --> H
+ E --> J
+ F --> K
+
+ L -.->|Invalidate| A
+ M -.->|Invalidate| B
+ N -.->|Invalidate| E
+ O -.->|Invalidate| D
+```
+
+---
+
+## Security Architecture
+
+### Security Layers
+
+```mermaid
+graph TB
+ subgraph "Frontend Security"
+ A[XSS Protection]
+ B[CSRF Protection]
+ C[Input Validation]
+ D[Secure Storage]
+ E[HTTPS Enforcement]
+ end
+
+ subgraph "API Security"
+ F[JWT Authentication]
+ G[Token Validation]
+ H[Rate Limiting]
+ I[CORS Configuration]
+ J[Request Validation]
+ end
+
+ subgraph "Backend Security"
+ K[SQL Injection Prevention]
+ L[Authorization Checks]
+ M[Secure Password Hashing]
+ N[Environment Variables]
+ O[Secret Management]
+ end
+
+ subgraph "Database Security"
+ P[MongoDB Authentication]
+ Q[Encrypted Connections]
+ R[Role-Based Access]
+ S[Audit Logging]
+ end
+
+ subgraph "Infrastructure Security"
+ T[Firewall Rules]
+ U[SSL/TLS Certificates]
+ V[Network Isolation]
+ W[Container Security]
+ end
+
+ A --> F
+ B --> F
+ C --> F
+ D --> F
+ E --> F
+
+ F --> K
+ G --> K
+ H --> K
+ I --> K
+ J --> K
+
+ K --> P
+ L --> P
+ M --> P
+ N --> P
+ O --> P
+
+ P --> T
+ Q --> T
+ R --> T
+ S --> T
+```
+
+### Authentication & Authorization Flow
+
+```mermaid
+graph TB
+ subgraph "Authentication"
+ A[Login Request]
+ B[Validate Credentials]
+ C[Generate JWT Token]
+ D[Return Token]
+ end
+
+ subgraph "Authorization"
+ E[Protected Request]
+ F[Extract Token]
+ G{Token Valid?}
+ H{Has Permission?}
+ I[Allow Access]
+ J[Deny Access]
+ end
+
+ subgraph "Role-Based Access"
+ K[Admin Role]
+ L[Instructor Role]
+ M[Student Role]
+ end
+
+ subgraph "Permissions"
+ N[Manage Users]
+ O[Create Courses]
+ P[View Courses]
+ Q[Enroll Courses]
+ end
+
+ A --> B
+ B --> C
+ C --> D
+
+ E --> F
+ F --> G
+ G -->|Yes| H
+ G -->|No| J
+ H -->|Yes| I
+ H -->|No| J
+
+ K --> N
+ K --> O
+ L --> O
+ M --> P
+ M --> Q
+```
+
+---
+
+## Scalability Considerations
+
+### Horizontal Scaling Strategy
+
+```mermaid
+graph TB
+ subgraph "Load Balancer"
+ A[NGINX Load Balancer]
+ B[Round Robin]
+ C[Health Checks]
+ end
+
+ subgraph "Frontend Tier"
+ D[Frontend Instance 1]
+ E[Frontend Instance 2]
+ F[Frontend Instance 3]
+ end
+
+ subgraph "Backend Tier"
+ G[Backend Instance 1]
+ H[Backend Instance 2]
+ I[Backend Instance 3]
+ end
+
+ subgraph "Cache Tier"
+ J[Redis Master]
+ K[Redis Replica 1]
+ L[Redis Replica 2]
+ end
+
+ subgraph "Database Tier"
+ M[MongoDB Primary]
+ N[MongoDB Secondary 1]
+ O[MongoDB Secondary 2]
+ end
+
+ A --> B
+ B --> D
+ B --> E
+ B --> F
+
+ D --> G
+ E --> H
+ F --> I
+
+ G --> J
+ H --> K
+ I --> L
+
+ J --> M
+ K --> N
+ L --> O
+
+ M --> N
+ N --> O
+
+ style A fill:#009639
+ style J fill:#dc382d
+ style M fill:#47a248
+```
+
+### Auto-Scaling Architecture
+
+```mermaid
+graph LR
+ subgraph "Metrics Collection"
+ A[CPU Usage]
+ B[Memory Usage]
+ C[Request Count]
+ D[Response Time]
+ end
+
+ subgraph "Auto-Scaler"
+ E[Kubernetes HPA]
+ F[Scale Up Trigger]
+ G[Scale Down Trigger]
+ end
+
+ subgraph "Pod Scaling"
+ H[Min Replicas: 2]
+ I[Max Replicas: 10]
+ J[Target CPU: 70%]
+ end
+
+ subgraph "Actions"
+ K[Add Pod]
+ L[Remove Pod]
+ M[Load Balance]
+ end
+
+ A --> E
+ B --> E
+ C --> E
+ D --> E
+
+ E --> F
+ E --> G
+
+ F --> H
+ G --> I
+ F --> J
+
+ F --> K
+ G --> L
+ K --> M
+ L --> M
+
+ style E fill:#326ce5
+ style K fill:#66bb6a
+ style L fill:#ef5350
+```
+
+### Performance Optimization
+
+```mermaid
+graph TB
+ subgraph "Frontend Optimization"
+ A[Code Splitting]
+ B[Lazy Loading]
+ C[Tree Shaking]
+ D[Minification]
+ E[CDN Delivery]
+ end
+
+ subgraph "Backend Optimization"
+ F[Query Optimization]
+ G[Connection Pooling]
+ H[Async Processing]
+ I[Pagination]
+ J[Redis Caching]
+ end
+
+ subgraph "Database Optimization"
+ K[Indexing Strategy]
+ L[Query Planning]
+ M[Sharding]
+ N[Replication]
+ end
+
+ subgraph "Network Optimization"
+ O[HTTP/2]
+ P[Compression]
+ Q[Keep-Alive]
+ R[DNS Prefetching]
+ end
+
+ A --> E
+ B --> E
+ C --> E
+ D --> E
+
+ F --> J
+ G --> J
+ H --> J
+ I --> J
+
+ K --> N
+ L --> N
+ M --> N
+
+ O --> R
+ P --> R
+ Q --> R
+```
+
+---
+
+## Monitoring & Observability
+
+### Monitoring Architecture
+
+```mermaid
+graph TB
+ subgraph "Application Layer"
+ A[Frontend Metrics]
+ B[Backend Metrics]
+ C[API Metrics]
+ end
+
+ subgraph "Infrastructure Layer"
+ D[Container Metrics]
+ E[Database Metrics]
+ F[Cache Metrics]
+ end
+
+ subgraph "Log Aggregation"
+ G[Application Logs]
+ H[Error Logs]
+ I[Access Logs]
+ end
+
+ subgraph "Monitoring Tools"
+ J[Prometheus]
+ K[Grafana]
+ L[ELK Stack]
+ end
+
+ subgraph "Alerting"
+ M[Email Alerts]
+ N[Slack Alerts]
+ O[PagerDuty]
+ end
+
+ A --> J
+ B --> J
+ C --> J
+ D --> J
+ E --> J
+ F --> J
+
+ G --> L
+ H --> L
+ I --> L
+
+ J --> K
+ L --> K
+
+ K --> M
+ K --> N
+ K --> O
+
+ style J fill:#e6522c
+ style K fill:#f46800
+ style L fill:#005571
+```
+
+---
+
+## Conclusion
+
+This architecture documentation provides a comprehensive overview of the E-Learning Management System's design, components, and interactions. The system is built with scalability, security, and maintainability in mind, leveraging modern technologies and best practices.
+
+### Key Architectural Principles
+
+1. **Separation of Concerns**: Clear separation between frontend, backend, and data layers
+2. **Microservices Ready**: Modular design allows for future microservices migration
+3. **API-First Design**: RESTful API enables multiple client applications
+4. **Security by Design**: Multiple security layers at every level
+5. **Performance Optimized**: Multi-level caching and optimization strategies
+6. **Cloud-Native**: Containerized and orchestrated for cloud deployment
+7. **CI/CD Enabled**: Automated testing and deployment pipelines
+8. **Scalable**: Horizontal scaling capabilities with load balancing
+9. **Observable**: Comprehensive monitoring and logging
+10. **Developer-Friendly**: Clear documentation and development guidelines
+
+### Future Enhancements
+
+- Microservices architecture migration
+- Real-time features with WebSockets
+- GraphQL API implementation
+- Advanced analytics and reporting
+- AI-powered recommendations
+- Mobile native applications
+- Multi-language support
+- Advanced content delivery network integration
+
+---
+
+**Document Version**: 1.0
+**Last Updated**: 2025-01-08
+**Maintained By**: Development Team
+**Contact**: hoangson091104@gmail.com
diff --git a/DEPLOYMENT.md b/DEPLOYMENT.md
new file mode 100644
index 0000000..e13815b
--- /dev/null
+++ b/DEPLOYMENT.md
@@ -0,0 +1,1643 @@
+# Learning Management System - Deployment Guide
+
+**Complete deployment documentation for all environments and platforms**
+
+
+
+
+
+## Table of Contents
+
+- [Overview](#overview)
+- [Deployment Options](#deployment-options)
+- [Prerequisites](#prerequisites)
+- [Local Development Deployment](#local-development-deployment)
+- [Docker Compose Deployment](#docker-compose-deployment)
+- [Kubernetes Deployment](#kubernetes-deployment)
+- [AWS Production Deployment](#aws-production-deployment)
+- [Terraform Infrastructure](#terraform-infrastructure)
+- [CI/CD Pipeline Setup](#cicd-pipeline-setup)
+- [Monitoring & Maintenance](#monitoring--maintenance)
+- [Troubleshooting](#troubleshooting)
+- [Cost Estimation](#cost-estimation)
+- [Security Best Practices](#security-best-practices)
+
+---
+
+## Overview
+
+This guide provides comprehensive instructions for deploying the Learning Management System across different environments, from local development to production-grade cloud infrastructure.
+
+### Deployment Architecture Comparison
+
+```mermaid
+graph TB
+ subgraph "Local Development"
+ L1[Docker Compose]
+ L2[MongoDB Local]
+ L3[Redis Local]
+ end
+
+ subgraph "Kubernetes Deployment"
+ K1[K8s Cluster]
+ K2[Ingress Controller]
+ K3[StatefulSets]
+ K4[Services]
+ end
+
+ subgraph "AWS Production"
+ A1[CloudFront CDN]
+ A2[ALB + ECS Fargate]
+ A3[RDS + DocumentDB]
+ A4[ElastiCache Redis]
+ A5[S3 + CloudWatch]
+ end
+
+ subgraph "Managed Services"
+ M1[Vercel Frontend]
+ M2[Render Backend]
+ M3[MongoDB Atlas]
+ M4[Redis Cloud]
+ end
+
+ L1 --> L2
+ L2 --> L3
+
+ K2 --> K1
+ K1 --> K3
+ K3 --> K4
+
+ A1 --> A2
+ A2 --> A3
+ A3 --> A4
+ A2 --> A5
+
+ M1 --> M2
+ M2 --> M3
+ M2 --> M4
+```
+
+### Feature Comparison
+
+| Feature | Docker Compose | Kubernetes | AWS (Terraform) | Vercel + Render |
+|---------|---------------|------------|-----------------|-----------------|
+| **Setup Time** | 5-10 min | 30-60 min | 1-2 hours | 15-30 min |
+| **Scalability** | Low | High | Very High | Medium |
+| **High Availability** | No | Yes | Yes | Yes |
+| **Auto-scaling** | No | Yes | Yes | Limited |
+| **Cost (Monthly)** | $0 | $50-200 | $1000-1500 | $25-50 |
+| **SSL/TLS** | Manual | cert-manager | ACM | Included |
+| **Monitoring** | Basic | Custom | CloudWatch | Built-in |
+| **Backup** | Manual | Manual/Automated | Automated | Automated |
+| **Complexity** | Low | Medium | High | Low |
+
+---
+
+## Deployment Options
+
+### Option 1: Docker Compose (Development)
+
+**Best For**: Local development, testing, small demos
+
+**Pros**:
+- Quick setup
+- No cloud costs
+- Easy to debug
+- Full control
+
+**Cons**:
+- Not scalable
+- No high availability
+- Manual updates
+- Local resources only
+
+### Option 2: Kubernetes (Self-Hosted Production)
+
+**Best For**: Self-hosted production, hybrid cloud, on-premises
+
+**Pros**:
+- Portable across clouds
+- High availability
+- Auto-healing
+- Extensive ecosystem
+
+**Cons**:
+- Complex setup
+- Requires K8s expertise
+- Infrastructure management
+- Security responsibility
+
+### Option 3: AWS with Terraform (Enterprise Production)
+
+**Best For**: Large-scale production, enterprise deployments
+
+**Pros**:
+- Fully managed services
+- Auto-scaling
+- Global reach
+- Enterprise support
+- Comprehensive monitoring
+
+**Cons**:
+- Higher costs
+- AWS lock-in
+- Complex pricing
+- Requires AWS expertise
+
+### Option 4: Vercel + Render (Managed Services)
+
+**Best For**: Startups, MVPs, small to medium projects
+
+**Pros**:
+- Simple deployment
+- Low cost
+- Automatic SSL
+- Built-in CI/CD
+
+**Cons**:
+- Limited control
+- Vendor lock-in
+- Performance limits
+- Less customization
+
+---
+
+## Prerequisites
+
+### General Requirements
+
+- Git installed
+- Basic command-line knowledge
+- Text editor or IDE
+- Understanding of environment variables
+
+### For Docker Compose
+
+- Docker Engine 20.10+
+- Docker Compose 2.0+
+- 4GB RAM minimum
+- 10GB disk space
+
+### For Kubernetes
+
+- kubectl CLI tool
+- Kubernetes cluster (1.24+)
+- Helm 3.x (optional)
+- 8GB RAM minimum
+- 20GB disk space
+
+### For AWS Deployment
+
+- AWS Account with appropriate permissions
+- AWS CLI v2
+- Terraform 1.5+
+- Docker for building images
+- Valid domain name (optional)
+
+### For Managed Services
+
+- Vercel account
+- Render account
+- MongoDB Atlas account
+- Redis Cloud account (optional)
+
+---
+
+## Local Development Deployment
+
+### Quick Start
+
+```mermaid
+sequenceDiagram
+ participant Dev as Developer
+ participant Git as Repository
+ participant Local as Local Machine
+ participant Mongo as MongoDB
+ participant Redis as Redis
+
+ Dev->>Git: 1. Clone Repository
+ Git-->>Dev: Source Code
+ Dev->>Local: 2. Install Dependencies
+ Dev->>Mongo: 3. Start MongoDB
+ Dev->>Redis: 4. Start Redis
+ Dev->>Local: 5. Configure Environment
+ Dev->>Local: 6. Run Backend
+ Dev->>Local: 7. Run Frontend
+ Local-->>Dev: App Running
+```
+
+### Step-by-Step Instructions
+
+#### 1. Clone Repository
+
+```bash
+git clone https://github.com/hoangsonww/Learning-Management-System-Fullstack.git
+cd Learning-Management-System-Fullstack
+```
+
+#### 2. Backend Setup
+
+```bash
+# Navigate to backend
+cd LMS-Backend
+
+# Create virtual environment
+python -m venv .venv
+source .venv/bin/activate # On Windows: .venv\Scripts\activate
+
+# Install dependencies
+pip install -r requirements.txt
+
+# Configure environment
+cp .env.example .env
+# Edit .env with your settings
+
+# Run migrations
+python manage.py makemigrations
+python manage.py migrate
+
+# Create superuser
+python manage.py createsuperuser
+
+# Seed sample data (optional)
+python manage.py seed_sample_data
+
+# Start backend server
+python manage.py runserver
+```
+
+Backend will be available at `http://localhost:8000`
+
+#### 3. Frontend Setup
+
+```bash
+# Navigate to frontend (new terminal)
+cd LMS-Frontend/app
+
+# Install dependencies
+npm install
+
+# Start development server
+ng serve
+```
+
+Frontend will be available at `http://localhost:4200`
+
+#### 4. Verify Deployment
+
+- Frontend: http://localhost:4200
+- Backend API: http://localhost:8000
+- Admin Panel: http://localhost:8000/admin
+- API Docs: http://localhost:8000/swagger
+
+---
+
+## Docker Compose Deployment
+
+### Architecture
+
+```mermaid
+graph TB
+ subgraph "Docker Compose Stack"
+ subgraph "Frontend Service"
+ ANGULAR[Angular App Port 8080]
+ end
+
+ subgraph "Backend Service"
+ DJANGO[Django API Port 8000]
+ end
+
+ subgraph "Database Service"
+ MONGO[MongoDB Port 27017]
+ end
+
+ subgraph "Cache Service"
+ REDIS[Redis Port 6379]
+ end
+
+ subgraph "Reverse Proxy"
+ NGINX[NGINX Port 80/443]
+ end
+ end
+
+ NGINX --> ANGULAR
+ NGINX --> DJANGO
+ DJANGO --> MONGO
+ DJANGO --> REDIS
+
+ style NGINX fill:#009639
+ style ANGULAR fill:#DD0031
+ style DJANGO fill:#092E20
+ style MONGO fill:#47A248
+ style REDIS fill:#DC382D
+```
+
+### Deployment Steps
+
+#### 1. Configure Environment
+
+Create `.env` file in project root:
+
+```env
+# Django Configuration
+DJANGO_SECRET_KEY=your-secret-key-here
+DJANGO_DEBUG=False
+DJANGO_ALLOWED_HOSTS=localhost,127.0.0.1
+
+# MongoDB Configuration
+MONGO_HOST=mongodb
+MONGO_PORT=27017
+MONGO_DB_NAME=lms_database
+MONGO_DB_USERNAME=lmsuser
+MONGO_DB_PASSWORD=secure-password-here
+
+# Redis Configuration
+REDIS_HOST=redis
+REDIS_PORT=6379
+
+# Application URLs
+BACKEND_URL=http://localhost:8000
+FRONTEND_URL=http://localhost:4200
+```
+
+#### 2. Build and Run
+
+```bash
+# Build and start all services
+docker-compose up --build
+
+# Run in detached mode
+docker-compose up -d
+
+# View logs
+docker-compose logs -f
+
+# Stop services
+docker-compose down
+
+# Remove volumes (clean slate)
+docker-compose down -v
+```
+
+#### 3. Access Services
+
+- Frontend: http://localhost:8080
+- Backend API: http://localhost:8000
+- MongoDB: localhost:27017
+- Redis: localhost:6379
+
+#### 4. Production Considerations
+
+```yaml
+# docker-compose.prod.yml
+version: '3.8'
+
+services:
+ backend:
+ restart: always
+ environment:
+ - DJANGO_DEBUG=False
+ deploy:
+ resources:
+ limits:
+ cpus: '1'
+ memory: 1G
+
+ frontend:
+ restart: always
+ deploy:
+ resources:
+ limits:
+ cpus: '0.5'
+ memory: 512M
+
+ mongodb:
+ restart: always
+ volumes:
+ - mongodb_data:/data/db
+ - ./backups:/backups
+ deploy:
+ resources:
+ limits:
+ cpus: '2'
+ memory: 2G
+
+ redis:
+ restart: always
+ command: redis-server --appendonly yes
+ volumes:
+ - redis_data:/data
+```
+
+Run production compose:
+
+```bash
+docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d
+```
+
+---
+
+## Kubernetes Deployment
+
+### Cluster Architecture
+
+```mermaid
+graph TB
+ subgraph "Kubernetes Cluster"
+ subgraph "Ingress Layer"
+ ING[Ingress Controller NGINX/Traefik]
+ CERT[cert-manager SSL Certificates]
+ end
+
+ subgraph "Application Layer"
+ subgraph "Frontend"
+ FE_DEP[Deployment 3 Replicas]
+ FE_SVC[Service ClusterIP]
+ FE_HPA[HPA Auto-scaling]
+ end
+
+ subgraph "Backend"
+ BE_DEP[Deployment 3 Replicas]
+ BE_SVC[Service ClusterIP]
+ BE_HPA[HPA Auto-scaling]
+ end
+ end
+
+ subgraph "Data Layer"
+ MONGO_SS[MongoDB StatefulSet]
+ MONGO_SVC[MongoDB Headless Service]
+ MONGO_PVC[PersistentVolumeClaim]
+
+ REDIS_DEP[Redis Deployment]
+ REDIS_SVC[Redis Service]
+ end
+
+ subgraph "Configuration"
+ CM[ConfigMap App Config]
+ SEC[Secrets Credentials]
+ end
+ end
+
+ ING --> FE_SVC
+ ING --> BE_SVC
+ CERT --> ING
+
+ FE_SVC --> FE_DEP
+ BE_SVC --> BE_DEP
+
+ FE_HPA --> FE_DEP
+ BE_HPA --> BE_DEP
+
+ BE_DEP --> MONGO_SVC
+ BE_DEP --> REDIS_SVC
+
+ MONGO_SVC --> MONGO_SS
+ MONGO_SS --> MONGO_PVC
+
+ REDIS_SVC --> REDIS_DEP
+
+ CM --> FE_DEP
+ CM --> BE_DEP
+ SEC --> BE_DEP
+
+ style ING fill:#326CE5
+ style FE_DEP fill:#DD0031
+ style BE_DEP fill:#092E20
+ style MONGO_SS fill:#47A248
+ style REDIS_DEP fill:#DC382D
+```
+
+### Prerequisites
+
+```bash
+# Verify kubectl
+kubectl version --client
+
+# Verify cluster access
+kubectl cluster-info
+
+# Create namespace
+kubectl create namespace lms-production
+```
+
+### Deployment Steps
+
+#### 1. Configure Secrets
+
+```bash
+# Create secret for MongoDB
+kubectl create secret generic mongodb-secret \
+ --from-literal=username=lmsadmin \
+ --from-literal=password=secure-password \
+ -n lms-production
+
+# Create secret for Django
+kubectl create secret generic django-secret \
+ --from-literal=secret-key=your-django-secret-key \
+ -n lms-production
+```
+
+#### 2. Deploy ConfigMap
+
+```bash
+cd kubernetes
+kubectl apply -f configmap.yaml -n lms-production
+```
+
+#### 3. Deploy MongoDB
+
+```bash
+kubectl apply -f mongodb-statefulset.yaml -n lms-production
+kubectl apply -f mongodb-service.yaml -n lms-production
+
+# Wait for MongoDB to be ready
+kubectl wait --for=condition=ready pod -l app=mongodb -n lms-production --timeout=300s
+```
+
+#### 4. Deploy Redis
+
+```bash
+kubectl apply -f redis-deployment.yaml -n lms-production
+kubectl apply -f redis-service.yaml -n lms-production
+```
+
+#### 5. Deploy Backend
+
+```bash
+kubectl apply -f backend-deployment.yaml -n lms-production
+kubectl apply -f backend-service.yaml -n lms-production
+
+# Wait for backend pods
+kubectl wait --for=condition=ready pod -l app=backend -n lms-production --timeout=300s
+```
+
+#### 6. Deploy Frontend
+
+```bash
+kubectl apply -f frontend-deployment.yaml -n lms-production
+kubectl apply -f frontend-service.yaml -n lms-production
+```
+
+#### 7. Deploy Ingress
+
+```bash
+# Install ingress controller (if not installed)
+kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.1/deploy/static/provider/cloud/deploy.yaml
+
+# Deploy ingress resource
+kubectl apply -f ingress.yaml -n lms-production
+
+# Get ingress IP
+kubectl get ingress -n lms-production
+```
+
+### Scaling
+
+```bash
+# Manual scaling
+kubectl scale deployment backend --replicas=5 -n lms-production
+
+# Enable auto-scaling
+kubectl autoscale deployment backend \
+ --cpu-percent=70 \
+ --min=2 \
+ --max=10 \
+ -n lms-production
+```
+
+### Monitoring
+
+```bash
+# View pods
+kubectl get pods -n lms-production
+
+# View logs
+kubectl logs -f deployment/backend -n lms-production
+
+# Describe pod
+kubectl describe pod -n lms-production
+
+# Execute command in pod
+kubectl exec -it -n lms-production -- /bin/bash
+```
+
+---
+
+## AWS Production Deployment
+
+### Infrastructure Overview
+
+```mermaid
+graph TB
+ subgraph "Global Infrastructure"
+ R53[Route 53 DNS Management]
+ CF[CloudFront CDN + WAF]
+ end
+
+ subgraph "Region: us-east-1"
+ subgraph "VPC 10.0.0.0/16"
+ subgraph "Availability Zone 1"
+ PUB1[Public Subnet 10.0.1.0/24]
+ PRIV1[Private Subnet 10.0.11.0/24]
+ DB1[Database Subnet 10.0.21.0/24]
+
+ NAT1[NAT Gateway]
+ ECS1[ECS Tasks]
+ RDS1[RDS Primary]
+ end
+
+ subgraph "Availability Zone 2"
+ PUB2[Public Subnet 10.0.2.0/24]
+ PRIV2[Private Subnet 10.0.12.0/24]
+ DB2[Database Subnet 10.0.22.0/24]
+
+ NAT2[NAT Gateway]
+ ECS2[ECS Tasks]
+ RDS2[RDS Standby]
+ end
+
+ ALB[Application Load Balancer]
+ DOCDB[DocumentDB Cluster]
+ REDIS[ElastiCache Redis]
+ end
+
+ ECR[Amazon ECR Container Registry]
+ S3[S3 Buckets Assets + Backups]
+ SM[Secrets Manager]
+ CW[CloudWatch Logs + Metrics]
+ end
+
+ R53 --> CF
+ CF --> ALB
+
+ ALB --> ECS1
+ ALB --> ECS2
+
+ PUB1 --> NAT1
+ PUB2 --> NAT2
+
+ NAT1 --> ECS1
+ NAT2 --> ECS2
+
+ ECS1 --> DOCDB
+ ECS2 --> DOCDB
+ ECS1 --> REDIS
+ ECS2 --> REDIS
+ ECS1 --> RDS1
+ ECS2 --> RDS1
+
+ RDS1 -.->|Replication| RDS2
+
+ ECR -.->|Pull Images| ECS1
+ ECR -.->|Pull Images| ECS2
+
+ SM -.->|Credentials| ECS1
+ SM -.->|Credentials| ECS2
+
+ ECS1 --> CW
+ ECS2 --> CW
+
+ CF --> S3
+```
+
+### Deployment Workflow
+
+```mermaid
+sequenceDiagram
+ participant DEV as Developer
+ participant GIT as GitHub
+ participant ECR as Amazon ECR
+ participant TF as Terraform
+ participant AWS as AWS Services
+ participant ECS as ECS Cluster
+
+ DEV->>GIT: 1. Push Code
+ GIT->>TF: 2. Trigger Terraform
+ TF->>AWS: 3. Create VPC & Networking
+ AWS-->>TF: 4. VPC Ready
+ TF->>AWS: 5. Create RDS & Redis
+ AWS-->>TF: 6. Databases Ready
+ TF->>AWS: 7. Create ECR Repositories
+ AWS-->>TF: 8. ECR Ready
+ DEV->>DEV: 9. Build Docker Images
+ DEV->>ECR: 10. Push Images
+ TF->>AWS: 11. Create ECS Cluster
+ AWS-->>TF: 12. ECS Ready
+ TF->>ECS: 13. Deploy Services
+ ECS-->>AWS: 14. Pull Images from ECR
+ ECS->>AWS: 15. Connect to Databases
+ AWS-->>DEV: 16. Deployment Complete
+```
+
+### Quick Deploy with AWS Scripts
+
+#### 1. Prerequisites Setup
+
+```bash
+# Install AWS CLI
+curl "https://awscli.amazonaws.com/AWSCLIV2.pkg" -o "AWSCLIV2.pkg"
+sudo installer -pkg AWSCLIV2.pkg -target /
+
+# Configure AWS credentials
+aws configure
+# AWS Access Key ID: YOUR_ACCESS_KEY
+# AWS Secret Access Key: YOUR_SECRET_KEY
+# Default region: us-east-1
+# Default output format: json
+
+# Verify configuration
+aws sts get-caller-identity
+```
+
+#### 2. Set Environment Variables
+
+```bash
+export AWS_REGION=us-east-1
+export ENVIRONMENT=production
+export PROJECT_NAME=lms
+export DOMAIN_NAME=yourdomain.com # Optional
+```
+
+#### 3. Deploy Infrastructure
+
+```bash
+cd aws/scripts
+
+# Make scripts executable
+chmod +x *.sh
+
+# Deploy all infrastructure
+./deploy.sh
+
+# This will:
+# - Create VPC and networking
+# - Set up RDS PostgreSQL
+# - Create ElastiCache Redis
+# - Deploy ECS cluster
+# - Configure ALB
+# - Build and push Docker images
+# - Deploy ECS services
+```
+
+#### 4. Verify Deployment
+
+```bash
+# Check ECS services
+aws ecs list-services --cluster lms-production-cluster
+
+# Check ALB
+aws elbv2 describe-load-balancers --names lms-production-alb
+
+# Get application URL
+aws elbv2 describe-load-balancers \
+ --names lms-production-alb \
+ --query 'LoadBalancers[0].DNSName' \
+ --output text
+```
+
+### Manual Rollback
+
+```bash
+cd aws/scripts
+./rollback.sh
+```
+
+---
+
+## Terraform Infrastructure
+
+### Infrastructure Components
+
+```mermaid
+graph LR
+ MAIN[main.tf Root Module]
+
+ MAIN --> VPC[VPC Module Network Infrastructure]
+ MAIN --> SEC[Security Module Groups & Rules]
+ MAIN --> ECR[ECR Module Container Registry]
+ MAIN --> RDS[RDS Module PostgreSQL]
+ MAIN --> CACHE[ElastiCache Redis]
+ MAIN --> ECS[ECS Module Fargate Services]
+ MAIN --> ALB[ALB Module Load Balancer]
+ MAIN --> S3[S3 Module Storage]
+ MAIN --> CF[CloudFront CDN]
+ MAIN --> R53[Route53 DNS]
+
+ style MAIN fill:#764ABC
+ style VPC fill:#326CE5
+ style ECS fill:#FF9900
+ style RDS fill:#527FFF
+ style CACHE fill:#DC382D
+```
+
+### Terraform Deployment Steps
+
+#### 1. Initialize Terraform Backend
+
+```bash
+# Create S3 bucket for state
+AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
+aws s3 mb s3://lms-terraform-state-${AWS_ACCOUNT_ID} --region us-east-1
+
+# Enable versioning
+aws s3api put-bucket-versioning \
+ --bucket lms-terraform-state-${AWS_ACCOUNT_ID} \
+ --versioning-configuration Status=Enabled
+
+# Create DynamoDB table for state locking
+aws dynamodb create-table \
+ --table-name lms-terraform-locks \
+ --attribute-definitions AttributeName=LockID,AttributeType=S \
+ --key-schema AttributeName=LockID,KeyType=HASH \
+ --billing-mode PAY_PER_REQUEST \
+ --region us-east-1
+```
+
+#### 2. Configure Variables
+
+```bash
+cd terraform
+
+# Copy example variables
+cp terraform.tfvars.example terraform.tfvars
+
+# Edit variables
+vim terraform.tfvars
+```
+
+Example `terraform.tfvars`:
+
+```hcl
+project_name = "lms"
+environment = "production"
+aws_region = "us-east-1"
+
+vpc_cidr = "10.0.0.0/16"
+availability_zones = ["us-east-1a", "us-east-1b", "us-east-1c"]
+
+ecs_backend_cpu = 512
+ecs_backend_memory = 1024
+ecs_backend_count = 2
+
+ecs_frontend_cpu = 256
+ecs_frontend_memory = 512
+ecs_frontend_count = 2
+
+rds_instance_class = "db.t3.medium"
+redis_node_type = "cache.t3.medium"
+
+domain_name = "yourdomain.com"
+create_route53_zone = true
+enable_cloudfront = true
+
+tags = {
+ Project = "Learning Management System"
+ Environment = "production"
+ ManagedBy = "Terraform"
+}
+```
+
+#### 3. Initialize and Plan
+
+```bash
+# Initialize Terraform
+terraform init
+
+# Validate configuration
+terraform validate
+
+# Format code
+terraform fmt -recursive
+
+# Plan deployment
+terraform plan -out=tfplan
+
+# Review plan output carefully
+```
+
+#### 4. Apply Infrastructure
+
+```bash
+# Apply plan
+terraform apply tfplan
+
+# Or apply directly (not recommended for production)
+terraform apply -auto-approve
+```
+
+This will take 15-30 minutes to complete.
+
+#### 5. Get Outputs
+
+```bash
+# View all outputs
+terraform output
+
+# Get specific output
+terraform output alb_dns_name
+
+# Export outputs to environment variables
+export ALB_DNS=$(terraform output -raw alb_dns_name)
+export ECR_BACKEND=$(terraform output -raw ecr_backend_repository_url)
+export ECR_FRONTEND=$(terraform output -raw ecr_frontend_repository_url)
+```
+
+#### 6. Build and Push Images
+
+```bash
+# Login to ECR
+aws ecr get-login-password --region us-east-1 | \
+ docker login --username AWS --password-stdin $ECR_BACKEND
+
+# Build backend
+cd ../../LMS-Backend
+docker build -t lms-backend:latest .
+docker tag lms-backend:latest ${ECR_BACKEND}:latest
+docker push ${ECR_BACKEND}:latest
+
+# Build frontend
+cd ../LMS-Frontend
+docker build -t lms-frontend:latest .
+docker tag lms-frontend:latest ${ECR_FRONTEND}:latest
+docker push ${ECR_FRONTEND}:latest
+```
+
+#### 7. Update ECS Services
+
+```bash
+# Force new deployment
+aws ecs update-service \
+ --cluster lms-production-cluster \
+ --service lms-production-backend-service \
+ --force-new-deployment
+
+aws ecs update-service \
+ --cluster lms-production-cluster \
+ --service lms-production-frontend-service \
+ --force-new-deployment
+
+# Wait for services to stabilize
+aws ecs wait services-stable \
+ --cluster lms-production-cluster \
+ --services lms-production-backend-service lms-production-frontend-service
+```
+
+### Environment Management
+
+```bash
+# Development environment
+cd terraform/environments/dev
+terraform init
+terraform apply -var-file=terraform.tfvars
+
+# Staging environment
+cd terraform/environments/staging
+terraform init
+terraform apply -var-file=terraform.tfvars
+
+# Production environment
+cd terraform/environments/production
+terraform init
+terraform apply -var-file=terraform.tfvars
+```
+
+### Infrastructure Updates
+
+```bash
+# Update specific module
+terraform apply -target=module.ecs
+
+# Refresh state
+terraform refresh
+
+# Import existing resource
+terraform import module.vpc.aws_vpc.main vpc-xxxxx
+
+# Destroy specific resource
+terraform destroy -target=module.s3
+```
+
+### State Management
+
+```bash
+# List state resources
+terraform state list
+
+# Show specific resource
+terraform state show module.vpc.aws_vpc.main
+
+# Move resource
+terraform state mv module.old.resource module.new.resource
+
+# Remove resource from state
+terraform state rm module.resource
+
+# Pull remote state
+terraform state pull > terraform.tfstate.backup
+```
+
+---
+
+## CI/CD Pipeline Setup
+
+### GitHub Actions Workflow
+
+```mermaid
+graph LR
+ PUSH[Git Push] --> BUILD[Build Stage]
+ BUILD --> TEST[Test Stage]
+ TEST --> DOCKER[Docker Build]
+ DOCKER --> PUSH_ECR[Push to ECR]
+ PUSH_ECR --> DEPLOY[Deploy to ECS]
+ DEPLOY --> VERIFY[Health Check]
+
+ BUILD --> LINT[Lint Code]
+ BUILD --> UNIT[Unit Tests]
+
+ TEST --> INTEGRATION[Integration Tests]
+ TEST --> E2E[E2E Tests]
+
+ VERIFY --> SUCCESS[Deployment Success]
+ VERIFY --> ROLLBACK[Rollback on Failure]
+
+ style BUILD fill:#4CAF50
+ style TEST fill:#2196F3
+ style DEPLOY fill:#FF9800
+ style SUCCESS fill:#4CAF50
+ style ROLLBACK fill:#F44336
+```
+
+### GitHub Actions Configuration
+
+Create `.github/workflows/deploy.yml`:
+
+```yaml
+name: Deploy to AWS
+
+on:
+ push:
+ branches: [main, master]
+ pull_request:
+ branches: [main, master]
+
+env:
+ AWS_REGION: us-east-1
+ ECR_BACKEND_REPOSITORY: lms-backend
+ ECR_FRONTEND_REPOSITORY: lms-frontend
+ ECS_CLUSTER: lms-production-cluster
+ ECS_BACKEND_SERVICE: lms-production-backend-service
+ ECS_FRONTEND_SERVICE: lms-production-frontend-service
+
+jobs:
+ test:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+
+ - name: Set up Python
+ uses: actions/setup-python@v4
+ with:
+ python-version: '3.12'
+
+ - name: Install backend dependencies
+ run: |
+ cd LMS-Backend
+ pip install -r requirements.txt
+
+ - name: Run backend tests
+ run: |
+ cd LMS-Backend
+ pytest
+
+ - name: Set up Node.js
+ uses: actions/setup-node@v3
+ with:
+ node-version: '18'
+
+ - name: Install frontend dependencies
+ run: |
+ cd LMS-Frontend/app
+ npm install
+
+ - name: Run frontend tests
+ run: |
+ cd LMS-Frontend/app
+ npm run test:ci
+
+ build-and-deploy:
+ needs: test
+ runs-on: ubuntu-latest
+ if: github.ref == 'refs/heads/main'
+
+ steps:
+ - uses: actions/checkout@v3
+
+ - name: Configure AWS credentials
+ uses: aws-actions/configure-aws-credentials@v2
+ with:
+ aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
+ aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
+ aws-region: ${{ env.AWS_REGION }}
+
+ - name: Login to Amazon ECR
+ id: login-ecr
+ uses: aws-actions/amazon-ecr-login@v1
+
+ - name: Build, tag, and push backend image
+ env:
+ ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
+ IMAGE_TAG: ${{ github.sha }}
+ run: |
+ cd LMS-Backend
+ docker build -t $ECR_REGISTRY/$ECR_BACKEND_REPOSITORY:$IMAGE_TAG .
+ docker tag $ECR_REGISTRY/$ECR_BACKEND_REPOSITORY:$IMAGE_TAG $ECR_REGISTRY/$ECR_BACKEND_REPOSITORY:latest
+ docker push $ECR_REGISTRY/$ECR_BACKEND_REPOSITORY:$IMAGE_TAG
+ docker push $ECR_REGISTRY/$ECR_BACKEND_REPOSITORY:latest
+
+ - name: Build, tag, and push frontend image
+ env:
+ ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
+ IMAGE_TAG: ${{ github.sha }}
+ run: |
+ cd LMS-Frontend
+ docker build -t $ECR_REGISTRY/$ECR_FRONTEND_REPOSITORY:$IMAGE_TAG .
+ docker tag $ECR_REGISTRY/$ECR_FRONTEND_REPOSITORY:$IMAGE_TAG $ECR_REGISTRY/$ECR_FRONTEND_REPOSITORY:latest
+ docker push $ECR_REGISTRY/$ECR_FRONTEND_REPOSITORY:$IMAGE_TAG
+ docker push $ECR_REGISTRY/$ECR_FRONTEND_REPOSITORY:latest
+
+ - name: Deploy to ECS
+ run: |
+ aws ecs update-service --cluster $ECS_CLUSTER --service $ECS_BACKEND_SERVICE --force-new-deployment
+ aws ecs update-service --cluster $ECS_CLUSTER --service $ECS_FRONTEND_SERVICE --force-new-deployment
+
+ - name: Wait for deployment
+ run: |
+ aws ecs wait services-stable --cluster $ECS_CLUSTER --services $ECS_BACKEND_SERVICE $ECS_FRONTEND_SERVICE
+
+ - name: Verify deployment
+ run: |
+ # Add health check verification here
+ echo "Deployment verified successfully"
+```
+
+### Jenkins Pipeline
+
+Create `Jenkinsfile`:
+
+```groovy
+pipeline {
+ agent any
+
+ environment {
+ AWS_REGION = 'us-east-1'
+ ECR_BACKEND_REPO = 'lms-backend'
+ ECR_FRONTEND_REPO = 'lms-frontend'
+ ECS_CLUSTER = 'lms-production-cluster'
+ }
+
+ stages {
+ stage('Checkout') {
+ steps {
+ checkout scm
+ }
+ }
+
+ stage('Test Backend') {
+ steps {
+ dir('LMS-Backend') {
+ sh 'pip install -r requirements.txt'
+ sh 'pytest'
+ }
+ }
+ }
+
+ stage('Test Frontend') {
+ steps {
+ dir('LMS-Frontend/app') {
+ sh 'npm install'
+ sh 'npm run test:ci'
+ }
+ }
+ }
+
+ stage('Build Docker Images') {
+ parallel {
+ stage('Build Backend') {
+ steps {
+ dir('LMS-Backend') {
+ script {
+ docker.build("${ECR_BACKEND_REPO}:${BUILD_NUMBER}")
+ }
+ }
+ }
+ }
+ stage('Build Frontend') {
+ steps {
+ dir('LMS-Frontend') {
+ script {
+ docker.build("${ECR_FRONTEND_REPO}:${BUILD_NUMBER}")
+ }
+ }
+ }
+ }
+ }
+ }
+
+ stage('Push to ECR') {
+ steps {
+ script {
+ docker.withRegistry("https://${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com", 'ecr:us-east-1:aws-credentials') {
+ docker.image("${ECR_BACKEND_REPO}:${BUILD_NUMBER}").push()
+ docker.image("${ECR_FRONTEND_REPO}:${BUILD_NUMBER}").push()
+ }
+ }
+ }
+ }
+
+ stage('Deploy to ECS') {
+ steps {
+ sh """
+ aws ecs update-service --cluster ${ECS_CLUSTER} --service lms-backend-service --force-new-deployment
+ aws ecs update-service --cluster ${ECS_CLUSTER} --service lms-frontend-service --force-new-deployment
+ """
+ }
+ }
+
+ stage('Verify Deployment') {
+ steps {
+ sh """
+ aws ecs wait services-stable --cluster ${ECS_CLUSTER} --services lms-backend-service lms-frontend-service
+ """
+ }
+ }
+ }
+
+ post {
+ success {
+ echo 'Deployment successful!'
+ // Send notification
+ }
+ failure {
+ echo 'Deployment failed!'
+ // Trigger rollback
+ // Send alert
+ }
+ }
+}
+```
+
+---
+
+## Monitoring & Maintenance
+
+### CloudWatch Dashboards
+
+```mermaid
+graph TB
+ subgraph "Monitoring Stack"
+ CW[CloudWatch]
+ XRAY[X-Ray]
+ SNS[SNS Topics]
+ end
+
+ subgraph "Metrics"
+ ECS_M[ECS Metrics CPU, Memory]
+ ALB_M[ALB Metrics Requests, Latency]
+ RDS_M[RDS Metrics Connections, IOPS]
+ REDIS_M[Redis Metrics Hit Rate, Memory]
+ end
+
+ subgraph "Logs"
+ ECS_L[ECS Logs]
+ ALB_L[ALB Access Logs]
+ APP_L[Application Logs]
+ end
+
+ subgraph "Alarms"
+ HIGH_CPU[High CPU Alarm]
+ HIGH_MEM[High Memory Alarm]
+ ERROR_RATE[Error Rate Alarm]
+ LATENCY[High Latency Alarm]
+ end
+
+ ECS_M --> CW
+ ALB_M --> CW
+ RDS_M --> CW
+ REDIS_M --> CW
+
+ ECS_L --> CW
+ ALB_L --> CW
+ APP_L --> CW
+
+ CW --> HIGH_CPU
+ CW --> HIGH_MEM
+ CW --> ERROR_RATE
+ CW --> LATENCY
+
+ HIGH_CPU --> SNS
+ HIGH_MEM --> SNS
+ ERROR_RATE --> SNS
+ LATENCY --> SNS
+
+ XRAY --> CW
+
+ style CW fill:#FF4F8B
+ style SNS fill:#FF9900
+```
+
+### Monitoring Commands
+
+```bash
+# View ECS service metrics
+aws cloudwatch get-metric-statistics \
+ --namespace AWS/ECS \
+ --metric-name CPUUtilization \
+ --dimensions Name=ServiceName,Value=lms-backend-service Name=ClusterName,Value=lms-production-cluster \
+ --start-time 2025-01-01T00:00:00Z \
+ --end-time 2025-01-02T00:00:00Z \
+ --period 3600 \
+ --statistics Average
+
+# View logs
+aws logs tail /ecs/lms-production/backend --follow
+
+# Create alarm
+aws cloudwatch put-metric-alarm \
+ --alarm-name lms-high-cpu \
+ --alarm-description "Alarm when CPU exceeds 80%" \
+ --metric-name CPUUtilization \
+ --namespace AWS/ECS \
+ --statistic Average \
+ --period 300 \
+ --threshold 80 \
+ --comparison-operator GreaterThanThreshold \
+ --evaluation-periods 2
+```
+
+### Backup Procedures
+
+```bash
+# Backup RDS
+aws rds create-db-snapshot \
+ --db-instance-identifier lms-production-db \
+ --db-snapshot-identifier lms-backup-$(date +%Y%m%d-%H%M%S)
+
+# Backup DocumentDB
+aws docdb create-db-cluster-snapshot \
+ --db-cluster-identifier lms-production-docdb \
+ --db-cluster-snapshot-identifier lms-docdb-backup-$(date +%Y%m%d-%H%M%S)
+
+# Backup Redis (if not using AWS Backup)
+aws elasticache create-snapshot \
+ --replication-group-id lms-production-redis \
+ --snapshot-name lms-redis-backup-$(date +%Y%m%d-%H%M%S)
+```
+
+---
+
+## Troubleshooting
+
+### Common Issues and Solutions
+
+#### ECS Tasks Not Starting
+
+```bash
+# Check task logs
+aws ecs describe-tasks \
+ --cluster lms-production-cluster \
+ --tasks $(aws ecs list-tasks --cluster lms-production-cluster --query 'taskArns[0]' --output text)
+
+# Check CloudWatch logs
+aws logs tail /ecs/lms-production/backend --since 1h
+
+# Common causes:
+# - Incorrect environment variables
+# - Missing secrets in Secrets Manager
+# - Insufficient IAM permissions
+# - Image pull errors
+```
+
+#### Database Connection Issues
+
+```bash
+# Test RDS connectivity
+aws rds describe-db-instances \
+ --db-instance-identifier lms-production-db \
+ --query 'DBInstances[0].Endpoint'
+
+# Check security groups
+aws ec2 describe-security-groups \
+ --group-ids sg-xxxxx
+
+# Verify from ECS task
+aws ecs execute-command \
+ --cluster lms-production-cluster \
+ --task task-id \
+ --container backend \
+ --interactive \
+ --command "pg_isready -h rds-endpoint -p 5432"
+```
+
+#### High Costs
+
+```bash
+# Analyze costs by service
+aws ce get-cost-and-usage \
+ --time-period Start=2025-01-01,End=2025-01-31 \
+ --granularity MONTHLY \
+ --metrics BlendedCost \
+ --group-by Type=SERVICE
+
+# Common cost optimizations:
+# - Use Reserved Instances for RDS
+# - Optimize ECS task sizes
+# - Enable S3 lifecycle policies
+# - Use single NAT Gateway for non-prod
+# - Stop non-prod environments after hours
+```
+
+---
+
+## Cost Estimation
+
+### Production Monthly Costs
+
+```mermaid
+graph TD
+ TOTAL[Total: ~$1,403/month]
+
+ TOTAL --> COMPUTE[Compute: $100]
+ TOTAL --> DATABASE[Databases: $950]
+ TOTAL --> NETWORK[Networking: $115]
+ TOTAL --> STORAGE[Storage: $88]
+ TOTAL --> OTHER[Other: $150]
+
+ COMPUTE --> ECS[ECS Fargate 4 tasks @ 0.5 vCPU, 1GB $25/task]
+
+ DATABASE --> RDS[RDS PostgreSQL db.t3.medium $150]
+ DATABASE --> DOCDB[DocumentDB 3 x db.r5.large $800]
+
+ NETWORK --> NAT[NAT Gateway 2 x $45 $90]
+ NETWORK --> ALB[ALB $25]
+
+ STORAGE --> S3_STORE[S3 Storage 100GB $3]
+ STORAGE --> CF[CloudFront 1TB transfer $85]
+
+ OTHER --> XFER[Data Transfer: $50]
+ OTHER --> LOGS[CloudWatch Logs: $30]
+ OTHER --> BACKUP[Backups: $20]
+ OTHER --> MISC[Misc Services: $50]
+
+ style TOTAL fill:#4CAF50
+ style DATABASE fill:#F44336
+ style COMPUTE fill:#2196F3
+ style NETWORK fill:#FF9800
+```
+
+### Cost Optimization Tips
+
+1. **Use Reserved Instances** (40-60% savings)
+ - RDS Reserved Instances
+ - ElastiCache Reserved Nodes
+ - Compute Savings Plans
+
+2. **Optimize Compute Resources**
+ - Right-size ECS tasks
+ - Use Spot Instances for non-critical workloads
+ - Enable auto-scaling to match demand
+
+3. **Storage Optimization**
+ - S3 Lifecycle policies (move to Glacier)
+ - Delete old CloudWatch logs
+ - Compress database backups
+
+4. **Network Optimization**
+ - Use VPC Endpoints for S3/DynamoDB
+ - Single NAT Gateway for non-prod
+ - CloudFront to reduce data transfer costs
+
+5. **Monitoring & Budgets**
+ - Set up AWS Budgets
+ - Enable Cost Explorer
+ - Regular cost reviews
+
+---
+
+## Security Best Practices
+
+### Security Checklist
+
+```mermaid
+graph TB
+ SEC[Security Measures]
+
+ SEC --> NET[Network Security]
+ SEC --> DATA[Data Security]
+ SEC --> ACCESS[Access Control]
+ SEC --> APP[Application Security]
+ SEC --> MONITOR[Monitoring]
+
+ NET --> VPC[Private Subnets]
+ NET --> SG[Security Groups]
+ NET --> NACL[NACLs]
+ NET --> WAF_SEC[WAF Rules]
+
+ DATA --> ENCRYPT[Encryption at Rest]
+ DATA --> TLS[TLS in Transit]
+ DATA --> KMS_SEC[KMS Keys]
+ DATA --> BACKUP_SEC[Encrypted Backups]
+
+ ACCESS --> IAM[IAM Roles]
+ ACCESS --> MFA[MFA Enabled]
+ ACCESS --> LEAST[Least Privilege]
+ ACCESS --> SECRETS[Secrets Manager]
+
+ APP --> VULN[Vulnerability Scanning]
+ APP --> DEPS[Dependency Updates]
+ APP --> CODE_SEC[Code Review]
+ APP --> OWASP[OWASP Top 10]
+
+ MONITOR --> TRAIL[CloudTrail]
+ MONITOR --> GUARD[GuardDuty]
+ MONITOR --> CONFIG[AWS Config]
+ MONITOR --> ALERTS[Security Alerts]
+
+ style SEC fill:#F44336
+ style NET fill:#4CAF50
+ style DATA fill:#2196F3
+ style ACCESS fill:#FF9800
+ style APP fill:#9C27B0
+ style MONITOR fill:#00BCD4
+```
+
+### Implementation
+
+1. **Enable Encryption**
+ ```bash
+ # RDS encryption
+ --storage-encrypted \
+ --kms-key-id arn:aws:kms:region:account:key/key-id
+
+ # S3 encryption
+ --server-side-encryption aws:kms
+ ```
+
+2. **Configure Security Groups**
+ ```bash
+ # Allow only necessary traffic
+ # Backend security group
+ aws ec2 authorize-security-group-ingress \
+ --group-id sg-backend \
+ --protocol tcp \
+ --port 8000 \
+ --source-group sg-alb
+
+ # Database security group
+ aws ec2 authorize-security-group-ingress \
+ --group-id sg-rds \
+ --protocol tcp \
+ --port 5432 \
+ --source-group sg-backend
+ ```
+
+3. **Enable CloudTrail**
+ ```bash
+ aws cloudtrail create-trail \
+ --name lms-audit-trail \
+ --s3-bucket-name lms-cloudtrail-logs
+ ```
+
+4. **Regular Security Audits**
+ - Review IAM policies monthly
+ - Update dependencies weekly
+ - Scan containers for vulnerabilities
+ - Penetration testing quarterly
+
+---
+
+## Support and Resources
+
+### Getting Help
+
+- **Documentation**: [Project README](README.md)
+- **Issues**: [GitHub Issues](https://github.com/hoangsonww/Learning-Management-System-Fullstack/issues)
+- **Email**: hoangson091104@gmail.com
+- **Architecture**: [ARCHITECTURE.md](ARCHITECTURE.md)
+
+### Additional Resources
+
+- [AWS Well-Architected Framework](https://aws.amazon.com/architecture/well-architected/)
+- [Terraform AWS Provider Docs](https://registry.terraform.io/providers/hashicorp/aws/latest/docs)
+- [Kubernetes Documentation](https://kubernetes.io/docs/home/)
+- [Docker Documentation](https://docs.docker.com/)
+- [ECS Best Practices](https://docs.aws.amazon.com/AmazonECS/latest/bestpracticesguide/)
+
+---
+
+**Last Updated**: 2025-10-08
+**Version**: 1.0.0
+**Maintained By**: Son Nguyen
+
+---
+
+[⬆ Back to Top](#learning-management-system---deployment-guide)
diff --git a/LMS-Backend/tests/__pycache__/conftest.cpython-312-pytest-8.4.1.pyc b/LMS-Backend/tests/__pycache__/conftest.cpython-312-pytest-8.4.1.pyc
new file mode 100644
index 0000000..d5eca9b
Binary files /dev/null and b/LMS-Backend/tests/__pycache__/conftest.cpython-312-pytest-8.4.1.pyc differ
diff --git a/LMS-Backend/tests/__pycache__/test_core_views_contract.cpython-312-pytest-8.4.1.pyc b/LMS-Backend/tests/__pycache__/test_core_views_contract.cpython-312-pytest-8.4.1.pyc
new file mode 100644
index 0000000..abddb56
Binary files /dev/null and b/LMS-Backend/tests/__pycache__/test_core_views_contract.cpython-312-pytest-8.4.1.pyc differ
diff --git a/LMS-Backend/tests/__pycache__/test_runtime_basics.cpython-312-pytest-8.4.1.pyc b/LMS-Backend/tests/__pycache__/test_runtime_basics.cpython-312-pytest-8.4.1.pyc
new file mode 100644
index 0000000..0c04d4f
Binary files /dev/null and b/LMS-Backend/tests/__pycache__/test_runtime_basics.cpython-312-pytest-8.4.1.pyc differ
diff --git a/LMS-Backend/tests/__pycache__/test_viewsets.cpython-312-pytest-8.4.1.pyc b/LMS-Backend/tests/__pycache__/test_viewsets.cpython-312-pytest-8.4.1.pyc
new file mode 100644
index 0000000..e16c4d7
Binary files /dev/null and b/LMS-Backend/tests/__pycache__/test_viewsets.cpython-312-pytest-8.4.1.pyc differ
diff --git a/README.md b/README.md
index 64ead4f..4acce59 100644
--- a/README.md
+++ b/README.md
@@ -8,67 +8,7 @@ Welcome to the **E-Learning Management System (LMS)**! This project consists of
-## Table of Contents
-
-- [Project Overview](#project-overview)
- - [The MAD-Stack](#the-mad-stack)
-- [Features](#features)
-- [Live Deployment](#live-deployment)
-- [Detailed Project Information](#detailed-project-information)
- - [Frontend User Interfaces](#frontend-user-interfaces)
- - [Available API Endpoints](#available-api-endpoints)
- - [Unit Tests for APIs](#unit-tests-for-apis)
-- [File Structure](#file-structure)
-- [Getting Started](#getting-started)
- - [Prerequisites](#prerequisites)
- - [Backend Setup (Django)](#backend-setup)
- - [Frontend Setup (Angular)](#frontend-setup)
-- [API Documentation](#api-documentation)
- - [Authentication](#authentication)
- - [Testing the APIs](#testing-the-apis)
- - [Seeding Sample Data](#seeding-sample-data)
- - [Recommended GUI Tools](#recommended-gui-tools)
- - [MongoDB Atlas](#mongodb-atlas)
-- [Containerization](#containerization)
-- [Kubernetes](#kubernetes)
-- [Testing](#testing)
- - [Backend Tests](#backend-tests)
- - [Frontend Tests](#frontend-tests)
-- [OpenAPI Specification](#openapi-specification)
-- [Jenkins CI/CD](#jenkins-cicd)
-- [Troubleshooting](#troubleshooting)
- - [Common Issues](#common-issues)
- - [Debugging Tips](#debugging-tips)
-- [Additional Information](#additional-information)
-- [Contributing](#contributing)
-- [License](#license)
-- [Contact](#contact)
-
-## Project Overview
-
-The **E-Learning Management System** is a web-based platform designed to facilitate online education and training. It provides a comprehensive set of features for managing courses, lessons, users, quizzes, and more. The system is composed of:
-
-- **Frontend**: Built with **Angular** and **Bootstrap**, it offers a user-friendly interface for interacting with the platform.
-- **Backend**: Developed using **Django** and **Django REST Framework**, it provides robust **REST APIs** for all the operations.
-- **Database**: The system uses **MongoDB** to store data and **Redis** for efficient server-side caching, as well as **SQLite** for user authentication with Django Auth.
-- **CI/CD**: The project includes a `Dockerfile` and `docker-compose.yml` for containerization and deployment, as well as a `Jenkinsfile` for CI/CD pipelines and `Kubernetes` configuration files for orchestration.
-
-Because we use **MongoDB**, **Angular**, and **Django**, we call this a **MAD-Stack** application! _(Just a fun name to remember the technologies used)_
-
-Currently live at **[learning-manangement-system.vercel.app](https://learning-manangement-system.vercel.app).** ✨
-
-### The MAD-Stack
-
-The **MAD-Stack** is a modern web development stack that combines the following technologies:
-
-- **MongoDB**: A NoSQL database used to store course, lessons, enrollments, users, and other data.
-- **Angular**: A frontend framework for building web applications.
-- **Django**: A high-level Python web framework for backend development.
-
-The **MAD-Stack** is a powerful combination that allows developers to build scalable, responsive, and feature-rich web applications. It leverages the strengths of each technology to create a seamless user experience.
-
-> [!NOTE]
-> Sounds mad, but it's actually a great stack for building modern web applications!
+**Visit the live demo app here: [E-Learning Management System](https://learning-manangement-system.vercel.app)**
@@ -115,15 +55,27 @@ The **MAD-Stack** is a powerful combination that allows developers to build scal
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
@@ -146,8 +98,470 @@ The **MAD-Stack** is a powerful combination that allows developers to build scal
+## Table of Contents
+
+- [Project Overview](#project-overview)
+ - [The MAD-Stack](#the-mad-stack)
+- [System Architecture](#system-architecture)
+ - [High-Level Architecture](#high-level-architecture)
+ - [Technology Stack](#technology-stack)
+ - [Database Schema](#database-schema)
+ - [Authentication Flow](#authentication-flow)
+ - [Component Architecture](#component-architecture)
+ - [Deployment Architecture](#deployment-architecture)
+ - [API Request Flow with Caching](#api-request-flow-with-caching)
+ - [CI/CD Pipeline](#cicd-pipeline)
+- [Features](#features)
+- [Live Deployment](#live-deployment)
+- [Detailed Project Information](#detailed-project-information)
+ - [Frontend User Interfaces](#frontend-user-interfaces)
+ - [Available API Endpoints](#available-api-endpoints)
+ - [Unit Tests for APIs](#unit-tests-for-apis)
+- [File Structure](#file-structure)
+- [Getting Started](#getting-started)
+ - [Prerequisites](#prerequisites)
+ - [Backend Setup (Django)](#backend-setup)
+ - [Frontend Setup (Angular)](#frontend-setup)
+- [API Documentation](#api-documentation)
+ - [Authentication](#authentication)
+ - [Testing the APIs](#testing-the-apis)
+ - [Seeding Sample Data](#seeding-sample-data)
+ - [Recommended GUI Tools](#recommended-gui-tools)
+ - [MongoDB Atlas](#mongodb-atlas)
+- [Deployment](#deployment)
+- [Containerization](#containerization)
+- [Kubernetes](#kubernetes)
+- [Testing](#testing)
+ - [Backend Tests](#backend-tests)
+ - [Frontend Tests](#frontend-tests)
+- [OpenAPI Specification](#openapi-specification)
+- [Jenkins CI/CD](#jenkins-cicd)
+- [Troubleshooting](#troubleshooting)
+ - [Common Issues](#common-issues)
+ - [Debugging Tips](#debugging-tips)
+- [Additional Information](#additional-information)
+- [Contributing](#contributing)
+- [License](#license)
+- [Contact](#contact)
+
+## Project Overview
+
+The **E-Learning Management System** is a web-based platform designed to facilitate online education and training. It provides a comprehensive set of features for managing courses, lessons, users, quizzes, and more. The system is composed of:
+
+- **Frontend**: Built with **Angular** and **Bootstrap**, it offers a user-friendly interface for interacting with the platform.
+- **Backend**: Developed using **Django** and **Django REST Framework**, it provides robust **REST APIs** for all the operations.
+- **Database**: The system uses **MongoDB** to store data and **Redis** for efficient server-side caching, as well as **SQLite** for user authentication with Django Auth.
+- **CI/CD**: The project includes a `Dockerfile` and `docker-compose.yml` for containerization and deployment, as well as a `Jenkinsfile` for CI/CD pipelines and `Kubernetes` configuration files for orchestration.
+
+Because we use **MongoDB**, **Angular**, and **Django**, we call this a **MAD-Stack** application! _(Just a fun name to remember the technologies used)_
+
+### The MAD-Stack
+
+The **MAD-Stack** is a modern web development stack that combines the following technologies:
+
+- **MongoDB**: A NoSQL database used to store course, lessons, enrollments, users, and other data.
+- **Angular**: A frontend framework for building web applications.
+- **Django**: A high-level Python web framework for backend development.
+
+The **MAD-Stack** is a powerful combination that allows developers to build scalable, responsive, and feature-rich web applications. It leverages the strengths of each technology to create a seamless user experience.
+
+> Sounds mad, but it's actually a great stack for building modern web applications!
+
+## System Architecture
+
+For a comprehensive and detailed architecture documentation, please refer to [ARCHITECTURE.md](ARCHITECTURE.md).
+
+### High-Level Architecture
+
+The system follows a modern three-tier architecture with clear separation of concerns:
+
+```mermaid
+graph TB
+ subgraph "Client Layer"
+ A[Web Browser]
+ B[Mobile Browser]
+ end
+
+ subgraph "Frontend - Angular SPA"
+ C[Angular Components]
+ D[Angular Services]
+ E[HTTP Interceptors]
+ F[State Management]
+ end
+
+ subgraph "API Gateway"
+ G[NGINX Reverse Proxy]
+ end
+
+ subgraph "Backend - Django REST API"
+ H[Django REST Framework]
+ I[Authentication Layer]
+ J[Business Logic]
+ K[Serializers & ViewSets]
+ end
+
+ subgraph "Caching Layer"
+ L[Redis Cache]
+ end
+
+ subgraph "Data Persistence"
+ M[(MongoDB - Course Data)]
+ N[(SQLite - Auth Data)]
+ end
+
+ A --> C
+ B --> C
+ C --> D
+ D --> E
+ E --> G
+ G --> H
+ H --> I
+ I --> J
+ J --> K
+ K --> L
+ K --> M
+ I --> N
+```
+
+### Technology Stack
+
+```mermaid
+graph LR
+ subgraph "Frontend Stack"
+ A[Angular 18]
+ B[TypeScript]
+ C[Bootstrap 5]
+ D[RxJS]
+ end
+
+ subgraph "Backend Stack"
+ E[Django 4.2]
+ F[Django REST Framework]
+ G[Python 3.12]
+ H[MongoEngine ODM]
+ end
+
+ subgraph "Database Stack"
+ I[(MongoDB 5.0)]
+ J[(SQLite 3)]
+ K[(Redis 6)]
+ end
+
+ subgraph "DevOps Stack"
+ L[Docker]
+ M[Kubernetes]
+ N[Jenkins]
+ O[GitHub Actions]
+ end
+
+ A --> E
+ E --> I
+ E --> J
+ E --> K
+ L --> M
+ N --> O
+
+ style A fill:#dd0031
+ style E fill:#092e20
+ style I fill:#47a248
+ style K fill:#dc382d
+ style L fill:#2496ed
+```
+
+### Database Schema
+
+The system uses MongoDB for storing course-related data with the following entity relationships:
+
+```mermaid
+erDiagram
+ USER ||--o{ COURSE : instructs
+ USER ||--o{ ENROLLMENT : enrolls
+ USER ||--o{ PROGRESS : tracks
+ USER ||--o{ NOTIFICATION : receives
+
+ CATEGORY ||--o{ COURSE : categorizes
+
+ COURSE ||--o{ LESSON : contains
+ COURSE ||--o{ ENROLLMENT : has
+
+ LESSON ||--o{ QUIZ : includes
+ LESSON ||--o{ PROGRESS : tracks
+
+ QUIZ ||--o{ QUESTION : contains
+ QUESTION ||--o{ CHOICE : has
+
+ USER {
+ ObjectId id PK
+ string username UK
+ string email UK
+ boolean is_instructor
+ boolean is_student
+ string bio
+ string profile_picture
+ }
+
+ COURSE {
+ ObjectId id PK
+ string title
+ string description
+ ObjectId instructor_id FK
+ ObjectId category_id FK
+ decimal price
+ boolean published
+ datetime created_at
+ }
+
+ LESSON {
+ ObjectId id PK
+ string title
+ ObjectId course_id FK
+ string content
+ string video_url
+ datetime created_at
+ }
+
+ ENROLLMENT {
+ ObjectId id PK
+ ObjectId student_id FK
+ ObjectId course_id FK
+ datetime enrolled_at
+ }
+
+ PROGRESS {
+ ObjectId id PK
+ ObjectId student_id FK
+ ObjectId lesson_id FK
+ boolean completed
+ datetime completed_at
+ }
+```
+
+### Authentication Flow
+
+The system uses JWT-based authentication with token storage:
+
+```mermaid
+sequenceDiagram
+ participant User
+ participant Angular
+ participant Django
+ participant SQLite
+ participant Redis
+
+ User->>Angular: Enter Credentials
+ Angular->>Django: POST /api/auth/login/
+ Django->>SQLite: Verify Credentials
+
+ alt Valid Credentials
+ SQLite-->>Django: User Valid
+ Django->>Django: Generate JWT Token
+ Django->>Redis: Cache Token
+ Django-->>Angular: {token, user}
+ Angular->>Angular: Store in localStorage
+ Angular-->>User: Redirect to Dashboard
+ else Invalid Credentials
+ SQLite-->>Django: Invalid
+ Django-->>Angular: 401 Unauthorized
+ Angular-->>User: Show Error
+ end
+
+ Note over User,Redis: Subsequent Requests
+
+ User->>Angular: Access Protected Route
+ Angular->>Django: Request + Bearer Token
+ Django->>SQLite: Validate Token
+
+ alt Valid Token
+ Django->>Redis: Check Cache
+ Redis-->>Django: Data
+ Django-->>Angular: Protected Resource
+ Angular-->>User: Display Content
+ else Invalid Token
+ Django-->>Angular: 401 Unauthorized
+ Angular-->>User: Redirect to Login
+ end
+```
+
+### Component Architecture
+
+```mermaid
+graph TB
+ subgraph "Frontend Components"
+ A[Login Component]
+ B[Course List Component]
+ C[Lesson List Component]
+ D[Enrollment Component]
+ E[Progress Component]
+ end
+
+ subgraph "Angular Services"
+ F[Auth Service]
+ G[Course Service]
+ H[Lesson Service]
+ I[Enrollment Service]
+ J[Progress Service]
+ end
+
+ subgraph "Backend ViewSets"
+ K[CourseViewSet]
+ L[LessonViewSet]
+ M[EnrollmentViewSet]
+ N[ProgressViewSet]
+ end
+
+ subgraph "Data Models"
+ O[(Course Model)]
+ P[(Lesson Model)]
+ Q[(Enrollment Model)]
+ R[(Progress Model)]
+ end
+
+ A --> F
+ B --> G
+ C --> H
+ D --> I
+ E --> J
+
+ F --> K
+ G --> K
+ H --> L
+ I --> M
+ J --> N
+
+ K --> O
+ L --> P
+ M --> Q
+ N --> R
+```
+
+### Deployment Architecture
+
+```mermaid
+graph TB
+ subgraph "Cloud Infrastructure"
+ subgraph "Frontend Hosting - Vercel"
+ A[Vercel CDN]
+ B[Static Assets]
+ end
+
+ subgraph "Backend Hosting - Render"
+ C[Django Application]
+ D[Auto-scaling]
+ end
+
+ subgraph "Database Services"
+ E[(MongoDB Atlas)]
+ F[(Redis Cloud)]
+ end
+ end
+
+ subgraph "CI/CD Pipeline"
+ G[GitHub]
+ H[GitHub Actions]
+ I[Jenkins]
+ end
+
+ subgraph "Containerization"
+ J[Docker Images]
+ K[Kubernetes Cluster]
+ end
+
+ A --> B
+ C --> D
+ E --> F
+
+ G --> H
+ H --> I
+ I --> J
+ J --> K
+
+ B --> C
+ D --> E
+ D --> F
+
+ style A fill:#000000
+ style E fill:#47a248
+ style F fill:#dc382d
+ style G fill:#181717
+```
+
+### API Request Flow with Caching
+
+```mermaid
+sequenceDiagram
+ participant Client
+ participant NGINX
+ participant Django
+ participant Redis
+ participant MongoDB
+
+ Client->>NGINX: HTTP Request
+ NGINX->>Django: Forward Request
+
+ alt Cache Hit
+ Django->>Redis: Check Cache
+ Redis-->>Django: Cached Data
+ Django-->>Client: Response (Fast)
+ else Cache Miss
+ Django->>Redis: Check Cache
+ Redis-->>Django: Cache Miss
+ Django->>MongoDB: Query Database
+ MongoDB-->>Django: Fresh Data
+ Django->>Redis: Store Cache (TTL)
+ Django-->>Client: Response
+ end
+
+ Note over Client,MongoDB: Write Operations Invalidate Cache
+
+ Client->>Django: POST/PUT/DELETE Request
+ Django->>MongoDB: Update Database
+ MongoDB-->>Django: Success
+ Django->>Redis: Invalidate Related Caches
+ Django-->>Client: Response
+```
+
+### CI/CD Pipeline
+
+```mermaid
+graph LR
+ subgraph "Source Control"
+ A[GitHub Repository]
+ B[Push/PR]
+ end
+
+ subgraph "CI Pipeline"
+ C[Run Tests]
+ D[Lint Code]
+ E[Build Docker Image]
+ end
+
+ subgraph "CD Pipeline"
+ F[Deploy to Staging]
+ G{Tests Pass?}
+ H[Deploy to Production]
+ end
+
+ subgraph "Monitoring"
+ I[Health Checks]
+ J[Performance Monitoring]
+ end
+
+ A --> B
+ B --> C
+ C --> D
+ D --> E
+ E --> F
+ F --> G
+ G -->|Yes| H
+ G -->|No| A
+ H --> I
+ I --> J
+```
+
## Features
+Our E-Learning Management System comes packed with a variety of features to enhance the learning experience:
+
- **User Authentication**: Token-based authentication for secure login, built with Django Auth.
- **Server-Side Caching**: Redis caching for improved performance and reduced server load.
- **Course Management**: Create, update, delete, and display courses.
@@ -168,13 +582,13 @@ The **MAD-Stack** is a powerful combination that allows developers to build scal
## Live Deployment
-The project is currently deployed live on Vercel and Render. You can access the live deployment using the following link: **[E-Learning Management System](https://learning-manangement-system.vercel.app).**
+The project is currently deployed live! You can access the live deployment using the following link: **[E-Learning Management System](https://learning-manangement-system.vercel.app).**
The backend is deployed on Render: **[Backend API](https://learning-management-system-fullstack.onrender.com/).**
Feel free to explore the platform, create an account, and test out the features!
-> [!IMPORTANT]
+> [!IMPORTANT]
> **Note:** Our backend server may spin down due to inactivity, so you may experience delays in loading data initially as the backend is hosted on the free tier of Render. If you encounter any issues, please let me know.
## Detailed Project Information:
@@ -776,6 +1190,57 @@ This project is set up to use MongoDB Atlas as the cloud database. You can creat
Alternatively, you can use the local MongoDB server for development and testing purposes.
+## Deployment
+
+The Learning Management System supports multiple deployment options, from local development to production-grade cloud infrastructure.
+
+### Deployment Options Overview
+
+| Option | Environment | Complexity | Cost | Scalability | Best For |
+|--------|-------------|------------|------|-------------|----------|
+| **Docker Compose** | Local/Dev | Low | Free | Limited | Development, Testing |
+| **Kubernetes** | Any | Medium | Variable | High | Self-hosted Production |
+| **AWS (Terraform)** | Cloud | Medium-High | ~$1400/mo | Very High | Enterprise Production |
+| **Vercel + Render** | Cloud | Low | ~$25/mo | Medium | Small-Medium Projects |
+
+### Quick Deployment Links
+
+- **Current Live Deployment**: [https://learning-manangement-system.vercel.app](https://learning-manangement-system.vercel.app)
+- **Backend API**: [https://learning-management-system-fullstack.onrender.com](https://learning-management-system-fullstack.onrender.com)
+- **Deployment Guide**: [DEPLOYMENT.md](DEPLOYMENT.md) - Comprehensive deployment documentation
+
+### Deployment Architecture
+
+```mermaid
+graph TB
+ subgraph "Development"
+ LOCAL[Local Development Docker Compose]
+ end
+
+ subgraph "Staging/Testing"
+ K8S[Kubernetes Self-Hosted]
+ end
+
+ subgraph "Production Options"
+ AWS[AWS Full Stack ECS + RDS + DocumentDB]
+ VERCEL[Vercel + Render Managed Services]
+ end
+
+ LOCAL --> K8S
+ K8S --> AWS
+ K8S --> VERCEL
+```
+
+### Infrastructure as Code
+
+The project includes production-ready Infrastructure as Code:
+
+- **`/aws`** - AWS deployment scripts and CloudFormation templates
+- **`/terraform`** - Terraform modules for complete AWS infrastructure
+- **`/kubernetes`** - Kubernetes manifests for container orchestration
+
+See [DEPLOYMENT.md](DEPLOYMENT.md) for detailed deployment instructions for each option.
+
## Containerization
The project can be containerized using Docker. The `Dockerfile` and `docker-compose.yml` files are provided in the repository. To containerize the project, follow these steps:
diff --git a/aws/README.md b/aws/README.md
new file mode 100644
index 0000000..3a2085a
--- /dev/null
+++ b/aws/README.md
@@ -0,0 +1,427 @@
+# AWS Deployment Scripts
+
+Production-ready deployment automation for the Learning Management System.
+
+## Overview
+
+This directory contains scripts and tools for deploying the LMS to AWS infrastructure.
+
+## Directory Structure
+
+```
+aws/
+├── scripts/
+│ ├── deploy.sh # Complete deployment automation
+│ ├── destroy.sh # Infrastructure teardown
+│ └── rollback.sh # Rollback script (to be created)
+└── README.md
+```
+
+## Prerequisites
+
+1. **AWS CLI** configured with appropriate credentials
+2. **Terraform** >= 1.5.0
+3. **Docker** installed and running
+4. **jq** for JSON processing
+5. **Git** for version tracking
+
+## Quick Start
+
+### Deploy Everything
+
+```bash
+cd aws/scripts
+./deploy.sh
+```
+
+This will:
+1. Validate prerequisites
+2. Set up Terraform backend (S3 + DynamoDB)
+3. Initialize Terraform
+4. Plan infrastructure changes
+5. Ask for confirmation
+6. Deploy infrastructure
+7. Build Docker images
+8. Push images to ECR
+9. Deploy ECS services
+10. Display deployment summary
+
+### Environment Variables
+
+Configure deployment using environment variables:
+
+```bash
+export AWS_REGION=us-east-1
+export ENVIRONMENT=production
+export PROJECT_NAME=lms
+./deploy.sh
+```
+
+### Destroy Infrastructure
+
+```bash
+./destroy.sh
+```
+
+**WARNING**: This will destroy ALL infrastructure. Type 'destroy' to confirm.
+
+## Deployment Scripts
+
+### deploy.sh
+
+Full deployment automation script.
+
+**Features**:
+- Prerequisite checking
+- Terraform backend setup
+- Infrastructure deployment
+- Docker image management
+- ECS service deployment
+- Comprehensive error handling
+- Deployment summary
+
+**Usage**:
+```bash
+# Deploy to production
+ENVIRONMENT=production ./deploy.sh
+
+# Deploy to dev
+ENVIRONMENT=dev AWS_REGION=us-east-1 ./deploy.sh
+```
+
+### destroy.sh
+
+Safe infrastructure destruction.
+
+**Features**:
+- Confirmation prompt
+- Deletion protection handling
+- Skip final snapshots for faster teardown
+
+**Usage**:
+```bash
+./destroy.sh
+```
+
+### rollback.sh
+
+Rollback to previous deployment (create this if needed).
+
+## Manual Deployment Steps
+
+### 1. Setup Terraform Backend
+
+```bash
+# Create S3 bucket for state
+aws s3 mb s3://lms-terraform-state-$(aws sts get-caller-identity --query Account --output text)
+
+# Enable versioning
+aws s3api put-bucket-versioning \
+ --bucket lms-terraform-state-ACCOUNT_ID \
+ --versioning-configuration Status=Enabled
+
+# Create DynamoDB table for locking
+aws dynamodb create-table \
+ --table-name lms-terraform-locks \
+ --attribute-definitions AttributeName=LockID,AttributeType=S \
+ --key-schema AttributeName=LockID,KeyType=HASH \
+ --provisioned-throughput ReadCapacityUnits=5,WriteCapacityUnits=5
+```
+
+### 2. Deploy Infrastructure
+
+```bash
+cd ../../terraform
+terraform init
+terraform plan -var-file="terraform.tfvars"
+terraform apply -var-file="terraform.tfvars"
+```
+
+### 3. Build and Push Images
+
+```bash
+# Get ECR URLs
+BACKEND_REPO=$(terraform output -raw ecr_backend_repository_url)
+FRONTEND_REPO=$(terraform output -raw ecr_frontend_repository_url)
+ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
+REGION=us-east-1
+
+# Login to ECR
+aws ecr get-login-password --region $REGION | \
+ docker login --username AWS --password-stdin $ACCOUNT_ID.dkr.ecr.$REGION.amazonaws.com
+
+# Build and push backend
+cd ../LMS-Backend
+docker build -t $BACKEND_REPO:latest .
+docker push $BACKEND_REPO:latest
+
+# Build and push frontend
+cd ../LMS-Frontend
+docker build -t $FRONTEND_REPO:latest .
+docker push $FRONTEND_REPO:latest
+```
+
+### 4. Deploy ECS Services
+
+```bash
+cd ../terraform
+CLUSTER=$(terraform output -raw ecs_cluster_name)
+BACKEND_SERVICE=$(terraform output -raw ecs_backend_service_name)
+FRONTEND_SERVICE=$(terraform output -raw ecs_frontend_service_name)
+
+# Force new deployment
+aws ecs update-service \
+ --cluster $CLUSTER \
+ --service $BACKEND_SERVICE \
+ --force-new-deployment
+
+aws ecs update-service \
+ --cluster $CLUSTER \
+ --service $FRONTEND_SERVICE \
+ --force-new-deployment
+
+# Wait for services to stabilize
+aws ecs wait services-stable \
+ --cluster $CLUSTER \
+ --services $BACKEND_SERVICE $FRONTEND_SERVICE
+```
+
+## Deployment Strategies
+
+### Blue-Green Deployment
+
+1. Deploy new version alongside old version
+2. Test new version
+3. Switch traffic
+4. Monitor
+5. Rollback if needed
+
+```bash
+# Deploy new task definition
+aws ecs register-task-definition --cli-input-json file://task-def.json
+
+# Update service with new task definition
+aws ecs update-service \
+ --cluster lms-production \
+ --service backend \
+ --task-definition backend:NEW_VERSION \
+ --deployment-configuration "maximumPercent=200,minimumHealthyPercent=100"
+```
+
+### Rolling Deployment
+
+ECS automatically performs rolling deployments:
+- Default: 200% maximum, 100% minimum
+- No downtime
+- Gradual traffic shift
+
+### Canary Deployment
+
+Use ALB target group weighting:
+
+```bash
+# Create new target group
+# Deploy to new target group
+# Gradually shift traffic
+aws elbv2 modify-listener \
+ --listener-arn LISTENER_ARN \
+ --default-actions file://weighted-targets.json
+```
+
+## Monitoring Deployment
+
+### View Deployment Status
+
+```bash
+aws ecs describe-services \
+ --cluster lms-production \
+ --services backend frontend \
+ --query 'services[*].[serviceName,status,runningCount,desiredCount]' \
+ --output table
+```
+
+### View Deployment Events
+
+```bash
+aws ecs describe-services \
+ --cluster lms-production \
+ --services backend \
+ --query 'services[0].events[:10]' \
+ --output table
+```
+
+### View Logs
+
+```bash
+aws logs tail /ecs/lms-production/backend --follow
+```
+
+## Troubleshooting
+
+### Deployment Stuck
+
+```bash
+# Check service events
+aws ecs describe-services \
+ --cluster lms-production \
+ --services backend \
+ --query 'services[0].events[:5]'
+
+# Check task status
+aws ecs list-tasks \
+ --cluster lms-production \
+ --service-name backend
+
+# Describe specific task
+aws ecs describe-tasks \
+ --cluster lms-production \
+ --tasks TASK_ARN
+```
+
+### Container Fails to Start
+
+```bash
+# Check CloudWatch logs
+aws logs tail /ecs/lms-production/backend --since 10m
+
+# Access container
+aws ecs execute-command \
+ --cluster lms-production \
+ --task TASK_ARN \
+ --container backend \
+ --interactive \
+ --command "/bin/bash"
+```
+
+### Database Connection Issues
+
+```bash
+# Test RDS connectivity from ECS
+aws ecs execute-command \
+ --cluster lms-production \
+ --task TASK_ARN \
+ --container backend \
+ --interactive \
+ --command "nc -zv RDS_ENDPOINT 5432"
+
+# Check security groups
+aws ec2 describe-security-groups \
+ --filters "Name=tag:Name,Values=lms-production-*"
+```
+
+## CI/CD Integration
+
+### GitHub Actions Example
+
+```yaml
+name: Deploy to AWS
+on:
+ push:
+ branches: [main]
+
+jobs:
+ deploy:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ - uses: aws-actions/configure-aws-credentials@v2
+ with:
+ aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
+ aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
+ aws-region: us-east-1
+ - name: Deploy
+ run: ./aws/scripts/deploy.sh
+```
+
+### Jenkins Pipeline Example
+
+```groovy
+pipeline {
+ agent any
+ environment {
+ AWS_REGION = 'us-east-1'
+ ENVIRONMENT = 'production'
+ }
+ stages {
+ stage('Deploy') {
+ steps {
+ sh './aws/scripts/deploy.sh'
+ }
+ }
+ }
+}
+```
+
+## Security
+
+### IAM Permissions Required
+
+Minimum IAM permissions needed:
+- EC2 (VPC, Security Groups, Subnets)
+- ECS (Clusters, Services, Tasks)
+- ECR (Repositories, Images)
+- RDS (DB Instances)
+- DocumentDB (Clusters)
+- ElastiCache (Replication Groups)
+- S3 (Buckets, Objects)
+- CloudWatch (Logs, Alarms, Dashboards)
+- IAM (Roles, Policies)
+- Secrets Manager (Secrets)
+- ALB (Load Balancers, Target Groups, Listeners)
+
+### Secrets Management
+
+All sensitive data is stored in AWS Secrets Manager:
+- Database passwords
+- API keys
+- Environment-specific secrets
+
+Access secrets:
+```bash
+aws secretsmanager get-secret-value \
+ --secret-id lms-production-rds-password
+```
+
+## Cost Optimization
+
+### Monitor Costs
+
+```bash
+# Daily costs
+aws ce get-cost-and-usage \
+ --time-period Start=2025-01-01,End=2025-01-31 \
+ --granularity DAILY \
+ --metrics BlendedCost \
+ --group-by Type=SERVICE
+
+# By tag
+aws ce get-cost-and-usage \
+ --time-period Start=2025-01-01,End=2025-01-31 \
+ --granularity MONTHLY \
+ --metrics BlendedCost \
+ --group-by Type=TAG,Key=Environment
+```
+
+### Optimization Tips
+
+1. Use Spot Instances for dev/staging
+2. Enable S3 Intelligent-Tiering
+3. Use Reserved Instances for production
+4. Delete old snapshots
+5. Enable ECS container insights selectively
+6. Use CloudFront for static content
+7. Enable RDS Performance Insights only when needed
+8. Review and delete old CloudWatch logs
+
+## Support
+
+For deployment issues:
+1. Check CloudWatch logs
+2. Review ECS service events
+3. Verify security group rules
+4. Test database connectivity
+5. Check IAM permissions
+
+## License
+
+MIT License - see [LICENSE](../LICENSE) file for details
diff --git a/aws/scripts/deploy.sh b/aws/scripts/deploy.sh
new file mode 100755
index 0000000..092010e
--- /dev/null
+++ b/aws/scripts/deploy.sh
@@ -0,0 +1,263 @@
+#!/bin/bash
+###############################################################################
+# Production-Grade AWS Deployment Script for LMS
+###############################################################################
+
+set -euo pipefail
+IFS=$'\n\t'
+
+# Colors
+RED='\033[0;31m'
+GREEN='\033[0;32m'
+YELLOW='\033[1;33m'
+BLUE='\033[0;34m'
+NC='\033[0m'
+
+# Configuration
+SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
+TERRAFORM_DIR="$PROJECT_ROOT/terraform"
+
+AWS_REGION="${AWS_REGION:-us-east-1}"
+ENVIRONMENT="${ENVIRONMENT:-production}"
+PROJECT_NAME="${PROJECT_NAME:-lms}"
+
+# Functions
+log_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
+log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
+log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
+log_step() { echo -e "${BLUE}[STEP]${NC} $1"; }
+
+check_prerequisites() {
+ log_step "Checking prerequisites..."
+
+ local missing=()
+
+ command -v aws >/dev/null 2>&1 || missing+=("aws-cli")
+ command -v terraform >/dev/null 2>&1 || missing+=("terraform")
+ command -v docker >/dev/null 2>&1 || missing+=("docker")
+ command -v jq >/dev/null 2>&1 || missing+=("jq")
+
+ if [ ${#missing[@]} -gt 0 ]; then
+ log_error "Missing required tools: ${missing[*]}"
+ exit 1
+ fi
+
+ if ! aws sts get-caller-identity &>/dev/null; then
+ log_error "AWS credentials not configured"
+ exit 1
+ fi
+
+ log_info "Prerequisites check passed"
+}
+
+setup_terraform_backend() {
+ log_step "Setting up Terraform backend..."
+
+ local bucket_name="${PROJECT_NAME}-terraform-state-$(aws sts get-caller-identity --query Account --output text)"
+ local table_name="${PROJECT_NAME}-terraform-locks"
+
+ # Create S3 bucket for state
+ if ! aws s3 ls "s3://$bucket_name" 2>/dev/null; then
+ log_info "Creating S3 bucket: $bucket_name"
+ aws s3 mb "s3://$bucket_name" --region "$AWS_REGION"
+ aws s3api put-bucket-versioning \
+ --bucket "$bucket_name" \
+ --versioning-configuration Status=Enabled
+ aws s3api put-bucket-encryption \
+ --bucket "$bucket_name" \
+ --server-side-encryption-configuration '{
+ "Rules": [{
+ "ApplyServerSideEncryptionByDefault": {
+ "SSEAlgorithm": "AES256"
+ }
+ }]
+ }'
+ aws s3api put-public-access-block \
+ --bucket "$bucket_name" \
+ --public-access-block-configuration \
+ "BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true"
+ else
+ log_info "S3 bucket already exists: $bucket_name"
+ fi
+
+ # Create DynamoDB table for locking
+ if ! aws dynamodb describe-table --table-name "$table_name" &>/dev/null; then
+ log_info "Creating DynamoDB table: $table_name"
+ aws dynamodb create-table \
+ --table-name "$table_name" \
+ --attribute-definitions AttributeName=LockID,AttributeType=S \
+ --key-schema AttributeName=LockID,KeyType=HASH \
+ --provisioned-throughput ReadCapacityUnits=5,WriteCapacityUnits=5 \
+ --region "$AWS_REGION" \
+ --tags "Key=Project,Value=$PROJECT_NAME" "Key=Environment,Value=$ENVIRONMENT"
+
+ log_info "Waiting for DynamoDB table to be active..."
+ aws dynamodb wait table-exists --table-name "$table_name"
+ else
+ log_info "DynamoDB table already exists: $table_name"
+ fi
+
+ # Update backend config
+ cat > "$TERRAFORM_DIR/backend.tf" </dev/null
+
+ log_info "Updating frontend service..."
+ aws ecs update-service \
+ --cluster "$cluster_name" \
+ --service "$frontend_service" \
+ --force-new-deployment \
+ --region "$AWS_REGION" >/dev/null
+
+ log_info "Waiting for services to stabilize..."
+ aws ecs wait services-stable \
+ --cluster "$cluster_name" \
+ --services "$backend_service" "$frontend_service" \
+ --region "$AWS_REGION"
+
+ log_info "ECS services deployed"
+}
+
+show_outputs() {
+ log_step "Deployment Summary"
+
+ cd "$TERRAFORM_DIR"
+
+ echo ""
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
+ echo " DEPLOYMENT COMPLETE"
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
+ echo ""
+ echo "Application URL: $(terraform output -raw application_url)"
+ echo "API URL: $(terraform output -raw api_url)"
+ echo ""
+ echo "Backend Repository: $(terraform output -raw ecr_backend_repository_url)"
+ echo "Frontend Repository: $(terraform output -raw ecr_frontend_repository_url)"
+ echo ""
+ echo "RDS Endpoint: $(terraform output -raw rds_endpoint)"
+ echo "Redis Endpoint: $(terraform output -raw redis_endpoint)"
+ echo "DocumentDB Endpoint: $(terraform output documentdb_endpoint)"
+ echo ""
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
+ echo ""
+}
+
+main() {
+ log_info "Starting deployment for $PROJECT_NAME ($ENVIRONMENT) in $AWS_REGION"
+ echo ""
+
+ check_prerequisites
+ setup_terraform_backend
+ init_terraform
+ plan_terraform
+
+ read -p "Apply Terraform changes? (yes/no): " confirm
+ if [[ "$confirm" != "yes" ]]; then
+ log_warn "Deployment cancelled"
+ exit 0
+ fi
+
+ apply_terraform
+ build_and_push_images
+ deploy_ecs_services
+ show_outputs
+
+ log_info "Deployment completed successfully!"
+}
+
+main "$@"
diff --git a/aws/scripts/destroy.sh b/aws/scripts/destroy.sh
new file mode 100755
index 0000000..e2aaf23
--- /dev/null
+++ b/aws/scripts/destroy.sh
@@ -0,0 +1,40 @@
+#!/bin/bash
+###############################################################################
+# AWS Infrastructure Destruction Script
+###############################################################################
+
+set -euo pipefail
+
+RED='\033[0;31m'
+YELLOW='\033[1;33m'
+NC='\033[0m'
+
+SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
+TERRAFORM_DIR="$PROJECT_ROOT/terraform"
+
+echo -e "${RED}WARNING: This will destroy ALL AWS infrastructure!${NC}"
+echo -e "${YELLOW}This action cannot be undone!${NC}"
+echo ""
+read -p "Type 'destroy' to confirm: " confirm
+
+if [[ "$confirm" != "destroy" ]]; then
+ echo "Destruction cancelled"
+ exit 0
+fi
+
+cd "$TERRAFORM_DIR"
+
+echo "Disabling deletion protection on RDS and DocumentDB..."
+terraform state list | grep -E 'aws_(db_instance|docdb_cluster)' | while read resource; do
+ terraform state show "$resource" | grep -q 'deletion_protection.*true' && \
+ terraform apply -target="$resource" -var='rds_deletion_protection=false' -var='documentdb_deletion_protection=false' -auto-approve || true
+done
+
+echo "Destroying infrastructure..."
+terraform destroy \
+ -auto-approve \
+ -var="rds_skip_final_snapshot=true" \
+ -var="documentdb_skip_final_snapshot=true"
+
+echo -e "${RED}Infrastructure destroyed${NC}"
diff --git a/aws/scripts/rollback.sh b/aws/scripts/rollback.sh
new file mode 100755
index 0000000..e58a2f6
--- /dev/null
+++ b/aws/scripts/rollback.sh
@@ -0,0 +1,152 @@
+#!/bin/bash
+###############################################################################
+# Rollback Script for LMS
+# Rolls back ECS services to previous task definition
+###############################################################################
+
+set -euo pipefail
+
+RED='\033[0;31m'
+GREEN='\033[0;32m'
+YELLOW='\033[1;33m'
+BLUE='\033[0;34m'
+NC='\033[0m'
+
+SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
+TERRAFORM_DIR="$PROJECT_ROOT/terraform"
+
+AWS_REGION="${AWS_REGION:-us-east-1}"
+ENVIRONMENT="${ENVIRONMENT:-production}"
+
+log_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
+log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
+log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
+log_step() { echo -e "${BLUE}[STEP]${NC} $1"; }
+
+rollback_service() {
+ local cluster=$1
+ local service=$2
+ local service_type=$3
+
+ log_step "Rolling back $service_type service: $service"
+
+ # Get current task definition
+ local current_task=$(aws ecs describe-services \
+ --cluster "$cluster" \
+ --services "$service" \
+ --region "$AWS_REGION" \
+ --query 'services[0].taskDefinition' \
+ --output text)
+
+ log_info "Current task definition: $current_task"
+
+ # List previous task definitions
+ local family=$(echo "$current_task" | cut -d':' -f6 | cut -d'/' -f2)
+ log_info "Task definition family: $family"
+
+ echo ""
+ echo "Available versions:"
+ aws ecs list-task-definitions \
+ --family-prefix "$family" \
+ --region "$AWS_REGION" \
+ --sort DESC \
+ --max-items 10 \
+ --query 'taskDefinitionArns[]' \
+ --output table
+
+ echo ""
+ read -p "Enter task definition ARN to rollback to (or 'cancel'): " target_task
+
+ if [[ "$target_task" == "cancel" ]]; then
+ log_warn "Rollback cancelled for $service"
+ return
+ fi
+
+ # Validate task definition exists
+ if ! aws ecs describe-task-definition \
+ --task-definition "$target_task" \
+ --region "$AWS_REGION" &>/dev/null; then
+ log_error "Invalid task definition: $target_task"
+ return 1
+ fi
+
+ log_info "Rolling back to: $target_task"
+
+ # Update service
+ aws ecs update-service \
+ --cluster "$cluster" \
+ --service "$service" \
+ --task-definition "$target_task" \
+ --region "$AWS_REGION" \
+ --query 'service.[serviceName,taskDefinition,desiredCount,runningCount]' \
+ --output table
+
+ log_info "Waiting for service to stabilize..."
+ aws ecs wait services-stable \
+ --cluster "$cluster" \
+ --services "$service" \
+ --region "$AWS_REGION"
+
+ log_info "✓ Rollback completed for $service"
+}
+
+main() {
+ log_info "Starting rollback for $ENVIRONMENT environment"
+
+ cd "$TERRAFORM_DIR"
+
+ # Get cluster and service names from Terraform
+ if ! terraform output &>/dev/null; then
+ log_error "Terraform state not found. Run 'terraform init' first."
+ exit 1
+ fi
+
+ local cluster=$(terraform output -raw ecs_cluster_name 2>/dev/null)
+ local backend_service=$(terraform output -raw ecs_backend_service_name 2>/dev/null)
+ local frontend_service=$(terraform output -raw ecs_frontend_service_name 2>/dev/null)
+
+ if [[ -z "$cluster" ]]; then
+ log_error "Could not determine ECS cluster name"
+ exit 1
+ fi
+
+ log_info "Cluster: $cluster"
+ log_info "Backend Service: $backend_service"
+ log_info "Frontend Service: $frontend_service"
+
+ echo ""
+ echo "Which service do you want to rollback?"
+ echo "1) Backend only"
+ echo "2) Frontend only"
+ echo "3) Both services"
+ echo "4) Cancel"
+ read -p "Selection: " choice
+
+ case $choice in
+ 1)
+ rollback_service "$cluster" "$backend_service" "Backend"
+ ;;
+ 2)
+ rollback_service "$cluster" "$frontend_service" "Frontend"
+ ;;
+ 3)
+ rollback_service "$cluster" "$backend_service" "Backend"
+ rollback_service "$cluster" "$frontend_service" "Frontend"
+ ;;
+ 4)
+ log_warn "Rollback cancelled"
+ exit 0
+ ;;
+ *)
+ log_error "Invalid selection"
+ exit 1
+ ;;
+ esac
+
+ echo ""
+ log_info "Rollback completed successfully!"
+ log_info "Monitor services at: https://console.aws.amazon.com/ecs/home?region=$AWS_REGION#/clusters/$cluster/services"
+}
+
+main "$@"
diff --git a/aws/scripts/verify.sh b/aws/scripts/verify.sh
new file mode 100755
index 0000000..74d78b6
--- /dev/null
+++ b/aws/scripts/verify.sh
@@ -0,0 +1,203 @@
+#!/bin/bash
+###############################################################################
+# Infrastructure Verification Script
+# Validates Terraform configuration and AWS prerequisites
+###############################################################################
+
+set -euo pipefail
+
+GREEN='\033[0;32m'
+RED='\033[0;31m'
+YELLOW='\033[1;33m'
+BLUE='\033[0;34m'
+NC='\033[0m'
+
+SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
+TERRAFORM_DIR="$PROJECT_ROOT/terraform"
+
+errors=0
+warnings=0
+
+log_ok() { echo -e "${GREEN}✓${NC} $1"; }
+log_error() { echo -e "${RED}✗${NC} $1"; ((errors++)); }
+log_warn() { echo -e "${YELLOW}!${NC} $1"; ((warnings++)); }
+log_info() { echo -e "${BLUE}ℹ${NC} $1"; }
+
+echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
+echo " LMS Infrastructure Verification"
+echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
+echo ""
+
+# Check prerequisites
+echo "Checking prerequisites..."
+if command -v aws >/dev/null 2>&1; then
+ log_ok "AWS CLI installed ($(aws --version))"
+else
+ log_error "AWS CLI not installed"
+fi
+
+if command -v terraform >/dev/null 2>&1; then
+ log_ok "Terraform installed ($(terraform version | head -1))"
+else
+ log_error "Terraform not installed"
+fi
+
+if command -v docker >/dev/null 2>&1; then
+ log_ok "Docker installed ($(docker --version))"
+else
+ log_error "Docker not installed"
+fi
+
+if command -v jq >/dev/null 2>&1; then
+ log_ok "jq installed ($(jq --version))"
+else
+ log_warn "jq not installed (optional but recommended)"
+fi
+
+# Check AWS credentials
+echo ""
+echo "Checking AWS credentials..."
+if aws sts get-caller-identity &>/dev/null; then
+ ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
+ USERNAME=$(aws sts get-caller-identity --query Arn --output text | cut -d'/' -f2)
+ log_ok "AWS credentials configured"
+ log_info "Account: $ACCOUNT_ID"
+ log_info "User: $USERNAME"
+else
+ log_error "AWS credentials not configured"
+fi
+
+# Check Terraform files
+echo ""
+echo "Checking Terraform configuration..."
+cd "$TERRAFORM_DIR"
+
+if [[ -f "main.tf" ]]; then
+ log_ok "main.tf exists"
+else
+ log_error "main.tf not found"
+fi
+
+if [[ -f "variables.tf" ]]; then
+ log_ok "variables.tf exists"
+else
+ log_error "variables.tf not found"
+fi
+
+if [[ -f "outputs.tf" ]]; then
+ log_ok "outputs.tf exists"
+else
+ log_error "outputs.tf not found"
+fi
+
+# Check modules
+module_count=$(find modules -name "main.tf" | wc -l | tr -d ' ')
+if [[ $module_count -eq 12 ]]; then
+ log_ok "All 12 modules present"
+else
+ log_error "Expected 12 modules, found $module_count"
+fi
+
+# Check for terraform.tfvars
+if [[ -f "terraform.tfvars" ]]; then
+ log_ok "terraform.tfvars configured"
+else
+ log_warn "terraform.tfvars not found (copy from terraform.tfvars.example)"
+fi
+
+# Validate Terraform syntax
+echo ""
+echo "Validating Terraform syntax..."
+if terraform fmt -check -recursive >/dev/null 2>&1; then
+ log_ok "Terraform formatting correct"
+else
+ log_warn "Terraform files need formatting (run: terraform fmt -recursive)"
+fi
+
+if terraform init -backend=false >/dev/null 2>&1; then
+ log_ok "Terraform initialization successful"
+
+ if terraform validate >/dev/null 2>&1; then
+ log_ok "Terraform configuration valid"
+ else
+ log_error "Terraform validation failed"
+ terraform validate
+ fi
+else
+ log_error "Terraform initialization failed"
+fi
+
+# Check deployment scripts
+echo ""
+echo "Checking deployment scripts..."
+cd "$PROJECT_ROOT/aws/scripts"
+
+for script in deploy.sh destroy.sh rollback.sh verify.sh; do
+ if [[ -f "$script" ]]; then
+ if [[ -x "$script" ]]; then
+ log_ok "$script exists and is executable"
+ else
+ log_warn "$script exists but is not executable"
+ fi
+ else
+ log_error "$script not found"
+ fi
+done
+
+# Check Docker configuration
+echo ""
+echo "Checking Docker configuration..."
+if [[ -f "$PROJECT_ROOT/LMS-Backend/Dockerfile" ]]; then
+ log_ok "Backend Dockerfile exists"
+else
+ log_error "Backend Dockerfile not found"
+fi
+
+if [[ -f "$PROJECT_ROOT/LMS-Frontend/Dockerfile" ]]; then
+ log_ok "Frontend Dockerfile exists"
+else
+ log_error "Frontend Dockerfile not found"
+fi
+
+# Check documentation
+echo ""
+echo "Checking documentation..."
+docs=("$PROJECT_ROOT/DEPLOYMENT.md" "$PROJECT_ROOT/INFRASTRUCTURE_SUMMARY.md" "$TERRAFORM_DIR/README.md" "$PROJECT_ROOT/aws/README.md")
+for doc in "${docs[@]}"; do
+ if [[ -f "$doc" ]]; then
+ log_ok "$(basename $doc) exists"
+ else
+ log_error "$(basename $doc) not found"
+ fi
+done
+
+# Summary
+echo ""
+echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
+echo " Verification Summary"
+echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
+echo ""
+
+if [[ $errors -eq 0 ]]; then
+ echo -e "${GREEN}✓ All checks passed!${NC}"
+ if [[ $warnings -gt 0 ]]; then
+ echo -e "${YELLOW}! $warnings warnings found${NC}"
+ fi
+ echo ""
+ echo "Infrastructure is ready for deployment!"
+ echo ""
+ echo "Next steps:"
+ echo " 1. Configure terraform.tfvars (if not done)"
+ echo " 2. Run: cd aws/scripts && ./deploy.sh"
+ echo ""
+ exit 0
+else
+ echo -e "${RED}✗ $errors errors found${NC}"
+ if [[ $warnings -gt 0 ]]; then
+ echo -e "${YELLOW}! $warnings warnings found${NC}"
+ fi
+ echo ""
+ echo "Please fix the errors before deploying."
+ exit 1
+fi
diff --git a/terraform/README.md b/terraform/README.md
new file mode 100644
index 0000000..39558af
--- /dev/null
+++ b/terraform/README.md
@@ -0,0 +1,277 @@
+# LMS Terraform Infrastructure
+
+Production-grade AWS infrastructure for the Learning Management System using Terraform.
+
+## Architecture
+
+This Terraform configuration deploys a complete, production-ready infrastructure on AWS:
+
+- **VPC** with public, private, and database subnets across 3 AZs
+- **Security Groups** and **WAF** for application security
+- **ECR** repositories for Docker images
+- **RDS PostgreSQL** for Django authentication
+- **ElastiCache Redis** for caching
+- **DocumentDB** for MongoDB-compatible application data
+- **ALB** for load balancing with SSL/TLS
+- **ECS Fargate** for containerized applications
+- **S3** for static assets and backups
+- **CloudFront** CDN (optional)
+- **Route53** DNS management (optional)
+- **CloudWatch** monitoring and logging
+
+## Prerequisites
+
+- AWS CLI configured with appropriate credentials
+- Terraform >= 1.5.0
+- Docker
+- jq (for deployment scripts)
+
+## Quick Start
+
+### 1. Clone and Configure
+
+```bash
+cd terraform
+cp terraform.tfvars.example terraform.tfvars
+# Edit terraform.tfvars with your configuration
+```
+
+### 2. Initialize Terraform
+
+```bash
+terraform init
+```
+
+### 3. Plan Deployment
+
+```bash
+terraform plan -var-file="terraform.tfvars"
+```
+
+### 4. Deploy Infrastructure
+
+```bash
+terraform apply -var-file="terraform.tfvars"
+```
+
+## Using Deployment Scripts
+
+The `aws/scripts/` directory contains production-ready deployment automation:
+
+```bash
+# Deploy everything (infrastructure + applications)
+cd ../aws/scripts
+./deploy.sh
+
+# Destroy infrastructure
+./destroy.sh
+```
+
+The `deploy.sh` script will:
+1. Check prerequisites
+2. Set up Terraform backend (S3 + DynamoDB)
+3. Initialize and plan Terraform
+4. Deploy infrastructure (with your confirmation)
+5. Build and push Docker images to ECR
+6. Deploy ECS services
+7. Display deployment information
+
+## Environment-Specific Configurations
+
+Use environment-specific variable files:
+
+### Development
+```bash
+terraform apply -var-file="environments/dev.tfvars"
+```
+
+### Production
+```bash
+terraform apply -var-file="environments/production.tfvars"
+```
+
+## Cost Estimates
+
+### Development Environment (~$150-200/month)
+- Single NAT Gateway: $32/month
+- t3.small RDS: $25/month
+- t3.small Redis: $15/month
+- DocumentDB t3.medium: $50/month
+- ECS Fargate: $30-50/month
+- ALB: $16/month
+- Data transfer: $10-15/month
+
+### Production Environment (~$1200-1500/month)
+- 3x NAT Gateways: $96/month
+- r5.xlarge RDS Multi-AZ: $450/month
+- r5.large Redis cluster: $200/month
+- 3x r5.xlarge DocumentDB: $650/month
+- ECS Fargate: $200-300/month
+- ALB + WAF: $30/month
+- CloudFront: $50-100/month
+- Data transfer: $100-150/month
+
+## Module Structure
+
+```
+terraform/
+├── main.tf # Main infrastructure configuration
+├── variables.tf # Input variables
+├── outputs.tf # Output values
+├── terraform.tfvars.example
+├── environments/
+│ ├── dev.tfvars # Development configuration
+│ └── production.tfvars # Production configuration
+└── modules/
+ ├── vpc/ # VPC and networking
+ ├── security/ # Security groups and WAF
+ ├── ecr/ # Container registries
+ ├── rds/ # PostgreSQL database
+ ├── elasticache/ # Redis cluster
+ ├── documentdb/ # MongoDB-compatible database
+ ├── alb/ # Load balancer
+ ├── ecs/ # Container orchestration
+ ├── s3/ # Object storage
+ ├── cloudfront/ # CDN
+ ├── route53/ # DNS
+ └── monitoring/ # CloudWatch dashboards
+```
+
+## Important Outputs
+
+After deployment, Terraform provides:
+
+```bash
+terraform output application_url # Main application URL
+terraform output api_url # API endpoint
+terraform output rds_endpoint # PostgreSQL endpoint
+terraform output redis_endpoint # Redis endpoint
+terraform output documentdb_endpoint # MongoDB endpoint
+```
+
+View all outputs:
+```bash
+terraform output
+```
+
+## Secrets Management
+
+Database passwords are automatically generated and stored in AWS Secrets Manager:
+- RDS password: `lms-{environment}-rds-password`
+- DocumentDB password: `lms-{environment}-documentdb-password`
+
+Retrieve secrets:
+```bash
+aws secretsmanager get-secret-value \
+ --secret-id lms-production-rds-password \
+ --query SecretString --output text | jq .
+```
+
+## Updating Services
+
+### Update Docker Images
+```bash
+# Build and push new images
+./aws/scripts/deploy.sh
+
+# Or manually:
+aws ecr get-login-password --region us-east-1 | docker login ...
+docker build -t REPO_URL:latest ./LMS-Backend
+docker push REPO_URL:latest
+
+# Force ECS service update
+aws ecs update-service \
+ --cluster lms-production-cluster \
+ --service lms-production-backend \
+ --force-new-deployment
+```
+
+### Update Infrastructure
+```bash
+# Modify terraform.tfvars or module files
+terraform plan
+terraform apply
+```
+
+## Troubleshooting
+
+### Access ECS Container
+```bash
+aws ecs execute-command \
+ --cluster lms-production-cluster \
+ --task TASK_ID \
+ --container backend \
+ --interactive \
+ --command "/bin/bash"
+```
+
+### View Logs
+```bash
+aws logs tail /ecs/lms-production/backend --follow
+```
+
+### RDS Connection Test
+```bash
+psql -h $(terraform output -raw rds_endpoint) \
+ -U lmsadmin \
+ -d lmsdb
+```
+
+## Security Best Practices
+
+1. **Never commit `terraform.tfvars` to version control**
+2. Use AWS Secrets Manager for sensitive data
+3. Enable deletion protection for production databases
+4. Restrict `alb_ingress_cidrs` to known IPs in production
+5. Use SSL/TLS certificates for all public endpoints
+6. Enable WAF in production
+7. Regular backup testing
+8. Multi-AZ deployments for production
+9. Enable enhanced monitoring
+10. Review CloudWatch alarms regularly
+
+## Backup and Disaster Recovery
+
+### Automated Backups
+- RDS: 7-day retention (configurable)
+- DocumentDB: 7-day retention (configurable)
+- Redis: Daily snapshots
+- S3: Versioning enabled
+
+### Manual Backup
+```bash
+# RDS Snapshot
+aws rds create-db-snapshot \
+ --db-instance-identifier lms-production-postgres \
+ --db-snapshot-identifier manual-backup-$(date +%Y%m%d)
+
+# DocumentDB Snapshot
+aws docdb create-db-cluster-snapshot \
+ --db-cluster-identifier lms-production-docdb \
+ --db-cluster-snapshot-identifier manual-backup-$(date +%Y%m%d)
+```
+
+## Monitoring
+
+Access CloudWatch Dashboard:
+```bash
+open "https://console.aws.amazon.com/cloudwatch/home?region=us-east-1#dashboards:name=lms-production"
+```
+
+Key metrics to monitor:
+- ECS CPU/Memory utilization
+- ALB response time and error rate
+- RDS connections and CPU
+- Redis cache hit ratio
+- DocumentDB CPU and connections
+
+## Support
+
+For issues or questions:
+- Review Terraform documentation: https://terraform.io/docs
+- Check AWS documentation: https://docs.aws.amazon.com
+- Open an issue in the project repository
+
+## License
+
+MIT License - see [LICENSE](../LICENSE) file for details
diff --git a/terraform/environments/dev.tfvars b/terraform/environments/dev.tfvars
new file mode 100644
index 0000000..48fb373
--- /dev/null
+++ b/terraform/environments/dev.tfvars
@@ -0,0 +1,41 @@
+# Development Environment Configuration
+environment = "dev"
+project_name = "lms"
+aws_region = "us-east-1"
+
+# Cost-optimized settings for dev
+single_nat_gateway = true
+enable_waf = false
+enable_monitoring = true
+enable_vpc_flow_logs = false
+
+# Smaller instances for dev
+rds_instance_class = "db.t3.small"
+rds_multi_az = false
+rds_deletion_protection = false
+rds_skip_final_snapshot = true
+
+redis_node_type = "cache.t3.small"
+redis_num_cache_nodes = 1
+redis_automatic_failover = false
+redis_multi_az = false
+
+documentdb_instance_class = "db.t3.medium"
+documentdb_instance_count = 1
+documentdb_deletion_protection = false
+documentdb_skip_final_snapshot = true
+
+ecs_backend_cpu = 256
+ecs_backend_memory = 512
+ecs_backend_count = 1
+
+ecs_frontend_cpu = 256
+ecs_frontend_memory = 512
+ecs_frontend_count = 1
+
+enable_ecs_autoscaling = false
+enable_https = false
+alb_enable_deletion_protection = false
+
+enable_cloudfront = false
+create_route53_zone = false
diff --git a/terraform/environments/production.tfvars b/terraform/environments/production.tfvars
new file mode 100644
index 0000000..6cfda1f
--- /dev/null
+++ b/terraform/environments/production.tfvars
@@ -0,0 +1,51 @@
+# Production Environment Configuration
+environment = "production"
+project_name = "lms"
+aws_region = "us-east-1"
+
+# Production-grade settings
+single_nat_gateway = false
+enable_waf = true
+enable_monitoring = true
+enable_vpc_flow_logs = true
+
+# Production instances
+rds_instance_class = "db.r5.xlarge"
+rds_multi_az = true
+rds_deletion_protection = true
+rds_skip_final_snapshot = false
+rds_allocated_storage = 200
+rds_max_allocated_storage = 1000
+
+redis_node_type = "cache.r5.large"
+redis_num_cache_nodes = 3
+redis_automatic_failover = true
+redis_multi_az = true
+
+documentdb_instance_class = "db.r5.xlarge"
+documentdb_instance_count = 3
+documentdb_deletion_protection = true
+documentdb_skip_final_snapshot = false
+
+ecs_backend_cpu = 2048
+ecs_backend_memory = 4096
+ecs_backend_count = 3
+
+ecs_frontend_cpu = 1024
+ecs_frontend_memory = 2048
+ecs_frontend_count = 3
+
+enable_ecs_autoscaling = true
+ecs_autoscaling_min_capacity = 3
+ecs_autoscaling_max_capacity = 20
+
+enable_https = true
+alb_enable_deletion_protection = true
+
+enable_cloudfront = true
+cloudfront_price_class = "PriceClass_All"
+
+create_route53_zone = true
+
+backup_retention_days = 30
+ecs_log_retention_days = 90
diff --git a/terraform/main.tf b/terraform/main.tf
new file mode 100644
index 0000000..d9a99e9
--- /dev/null
+++ b/terraform/main.tf
@@ -0,0 +1,391 @@
+# ============================================================================
+# Main Terraform Configuration for Learning Management System
+# ============================================================================
+
+terraform {
+ required_version = ">= 1.5.0"
+
+ required_providers {
+ aws = {
+ source = "hashicorp/aws"
+ version = "~> 5.0"
+ }
+ random = {
+ source = "hashicorp/random"
+ version = "~> 3.5"
+ }
+ }
+
+ backend "s3" {
+ bucket = "lms-terraform-state"
+ key = "production/terraform.tfstate"
+ region = "us-east-1"
+ encrypt = true
+ dynamodb_table = "lms-terraform-locks"
+ }
+}
+
+# ============================================================================
+# Provider Configuration
+# ============================================================================
+
+provider "aws" {
+ region = var.aws_region
+
+ default_tags {
+ tags = merge(
+ var.tags,
+ {
+ Project = var.project_name
+ Environment = var.environment
+ ManagedBy = "Terraform"
+ }
+ )
+ }
+}
+
+# ============================================================================
+# Data Sources
+# ============================================================================
+
+data "aws_caller_identity" "current" {}
+
+data "aws_availability_zones" "available" {
+ state = "available"
+}
+
+# ============================================================================
+# Local Variables
+# ============================================================================
+
+locals {
+ name_prefix = "${var.project_name}-${var.environment}"
+ account_id = data.aws_caller_identity.current.account_id
+
+ common_tags = merge(
+ var.tags,
+ {
+ Name = local.name_prefix
+ Environment = var.environment
+ ManagedBy = "Terraform"
+ Project = var.project_name
+ }
+ )
+}
+
+# ============================================================================
+# VPC Module
+# ============================================================================
+
+module "vpc" {
+ source = "./modules/vpc"
+
+ project_name = var.project_name
+ environment = var.environment
+
+ vpc_cidr = var.vpc_cidr
+ availability_zones = var.availability_zones
+ public_subnet_cidrs = var.public_subnet_cidrs
+ private_subnet_cidrs = var.private_subnet_cidrs
+ database_subnet_cidrs = var.database_subnet_cidrs
+
+ enable_nat_gateway = var.enable_nat_gateway
+ single_nat_gateway = var.single_nat_gateway
+ enable_dns_hostnames = true
+ enable_dns_support = true
+ enable_flow_logs = var.enable_vpc_flow_logs
+
+ tags = local.common_tags
+}
+
+# ============================================================================
+# Security Module
+# ============================================================================
+
+module "security" {
+ source = "./modules/security"
+
+ project_name = var.project_name
+ environment = var.environment
+ vpc_id = module.vpc.vpc_id
+
+ alb_ingress_cidrs = var.alb_ingress_cidrs
+ enable_waf = var.enable_waf
+
+ tags = local.common_tags
+}
+
+# ============================================================================
+# ECR Module
+# ============================================================================
+
+module "ecr" {
+ source = "./modules/ecr"
+
+ project_name = var.project_name
+ environment = var.environment
+
+ image_tag_mutability = var.ecr_image_tag_mutability
+ scan_on_push = var.ecr_scan_on_push
+ lifecycle_policy_enabled = var.ecr_lifecycle_policy_enabled
+
+ tags = local.common_tags
+}
+
+# ============================================================================
+# RDS Module (PostgreSQL for Django Auth)
+# ============================================================================
+
+module "rds" {
+ source = "./modules/rds"
+
+ project_name = var.project_name
+ environment = var.environment
+
+ vpc_id = module.vpc.vpc_id
+ database_subnet_ids = module.vpc.database_subnet_ids
+ security_group_ids = [module.security.rds_security_group_id]
+
+ instance_class = var.rds_instance_class
+ allocated_storage = var.rds_allocated_storage
+ max_allocated_storage = var.rds_max_allocated_storage
+ engine_version = var.rds_engine_version
+ database_name = var.rds_database_name
+ master_username = var.rds_master_username
+
+ backup_retention_period = var.backup_retention_days
+ backup_window = var.rds_backup_window
+ maintenance_window = var.rds_maintenance_window
+ enabled_cloudwatch_logs_exports = var.rds_enabled_cloudwatch_logs_exports
+
+ multi_az = var.rds_multi_az
+ deletion_protection = var.rds_deletion_protection
+ skip_final_snapshot = var.rds_skip_final_snapshot
+ final_snapshot_identifier = "${local.name_prefix}-rds-final-snapshot"
+
+ tags = local.common_tags
+}
+
+# ============================================================================
+# ElastiCache Module (Redis)
+# ============================================================================
+
+module "elasticache" {
+ source = "./modules/elasticache"
+
+ project_name = var.project_name
+ environment = var.environment
+
+ vpc_id = module.vpc.vpc_id
+ subnet_ids = module.vpc.database_subnet_ids
+ security_group_ids = [module.security.redis_security_group_id]
+
+ node_type = var.redis_node_type
+ num_cache_nodes = var.redis_num_cache_nodes
+ parameter_group_family = var.redis_parameter_group_family
+ engine_version = var.redis_engine_version
+ port = var.redis_port
+
+ automatic_failover_enabled = var.redis_automatic_failover
+ multi_az_enabled = var.redis_multi_az
+
+ snapshot_retention_limit = var.redis_snapshot_retention_limit
+ snapshot_window = var.redis_snapshot_window
+ maintenance_window = var.redis_maintenance_window
+
+ tags = local.common_tags
+}
+
+# ============================================================================
+# DocumentDB Module (MongoDB Compatible)
+# ============================================================================
+
+module "documentdb" {
+ source = "./modules/documentdb"
+
+ project_name = var.project_name
+ environment = var.environment
+
+ vpc_id = module.vpc.vpc_id
+ subnet_ids = module.vpc.database_subnet_ids
+ security_group_ids = [module.security.documentdb_security_group_id]
+
+ instance_class = var.documentdb_instance_class
+ instance_count = var.documentdb_instance_count
+ engine_version = var.documentdb_engine_version
+ master_username = var.documentdb_master_username
+
+ deletion_protection = var.documentdb_deletion_protection
+ skip_final_snapshot = var.documentdb_skip_final_snapshot
+ backup_retention_period = var.backup_retention_days
+ backup_window = var.documentdb_backup_window
+ maintenance_window = var.documentdb_maintenance_window
+
+ tags = local.common_tags
+}
+
+# ============================================================================
+# Application Load Balancer Module
+# ============================================================================
+
+module "alb" {
+ source = "./modules/alb"
+
+ project_name = var.project_name
+ environment = var.environment
+
+ vpc_id = module.vpc.vpc_id
+ public_subnet_ids = module.vpc.public_subnet_ids
+ security_group_ids = [module.security.alb_security_group_id]
+
+ enable_deletion_protection = var.alb_enable_deletion_protection
+ enable_http2 = var.alb_enable_http2
+ enable_cross_zone_load_balancing = var.alb_enable_cross_zone_load_balancing
+
+ ssl_certificate_arn = var.ssl_certificate_arn
+ enable_https = var.enable_https
+
+ health_check_path = var.alb_health_check_path
+ health_check_interval = var.alb_health_check_interval
+ health_check_timeout = var.alb_health_check_timeout
+
+ tags = local.common_tags
+}
+
+# ============================================================================
+# ECS Module
+# ============================================================================
+
+module "ecs" {
+ source = "./modules/ecs"
+
+ project_name = var.project_name
+ environment = var.environment
+
+ vpc_id = module.vpc.vpc_id
+ private_subnet_ids = module.vpc.private_subnet_ids
+ security_group_ids = [module.security.ecs_security_group_id]
+
+ # Backend configuration
+ backend_image = "${module.ecr.backend_repository_url}:${var.backend_image_tag}"
+ backend_cpu = var.ecs_backend_cpu
+ backend_memory = var.ecs_backend_memory
+ backend_desired_count = var.ecs_backend_count
+ backend_target_group_arn = module.alb.backend_target_group_arn
+
+ # Frontend configuration
+ frontend_image = "${module.ecr.frontend_repository_url}:${var.frontend_image_tag}"
+ frontend_cpu = var.ecs_frontend_cpu
+ frontend_memory = var.ecs_frontend_memory
+ frontend_desired_count = var.ecs_frontend_count
+ frontend_target_group_arn = module.alb.frontend_target_group_arn
+
+ # Environment variables
+ backend_environment_variables = {
+ DJANGO_DEBUG = "False"
+ DJANGO_ALLOWED_HOSTS = var.domain_name
+ ENVIRONMENT = var.environment
+ AWS_REGION = var.aws_region
+ RDS_ENDPOINT = module.rds.endpoint
+ RDS_DATABASE_NAME = module.rds.database_name
+ REDIS_ENDPOINT = module.elasticache.endpoint
+ REDIS_PORT = tostring(module.elasticache.port)
+ MONGODB_ENDPOINT = module.documentdb.endpoint
+ MONGODB_PORT = tostring(module.documentdb.port)
+ }
+
+ frontend_environment_variables = {
+ API_URL = "https://${var.domain_name}/api"
+ ENVIRONMENT = var.environment
+ }
+
+ # Auto-scaling
+ enable_autoscaling = var.enable_ecs_autoscaling
+ autoscaling_min_capacity = var.ecs_autoscaling_min_capacity
+ autoscaling_max_capacity = var.ecs_autoscaling_max_capacity
+ autoscaling_target_cpu_percent = var.ecs_autoscaling_target_cpu
+ autoscaling_target_memory_percent = var.ecs_autoscaling_target_memory
+
+ # Logging
+ log_retention_days = var.ecs_log_retention_days
+
+ tags = local.common_tags
+
+ depends_on = [module.alb]
+}
+
+# ============================================================================
+# S3 Module (Static Assets and Backups)
+# ============================================================================
+
+module "s3" {
+ source = "./modules/s3"
+
+ project_name = var.project_name
+ environment = var.environment
+
+ enable_versioning = var.s3_enable_versioning
+ enable_lifecycle_rules = var.s3_enable_lifecycle_rules
+ lifecycle_glacier_days = var.s3_lifecycle_glacier_days
+ lifecycle_expiration_days = var.s3_lifecycle_expiration_days
+
+ enable_replication = var.s3_enable_replication
+ replication_region = var.s3_replication_region
+
+ tags = local.common_tags
+}
+
+# ============================================================================
+# CloudFront Module (Optional)
+# ============================================================================
+
+module "cloudfront" {
+ count = var.enable_cloudfront ? 1 : 0
+ source = "./modules/cloudfront"
+
+ project_name = var.project_name
+ environment = var.environment
+
+ alb_domain_name = module.alb.dns_name
+ s3_bucket_domain_name = module.s3.bucket_regional_domain_name
+ ssl_certificate_arn = var.cloudfront_certificate_arn
+
+ price_class = var.cloudfront_price_class
+ enable_ipv6 = var.cloudfront_enable_ipv6
+ minimum_protocol_version = var.cloudfront_minimum_protocol_version
+
+ tags = local.common_tags
+}
+
+# ============================================================================
+# Route53 Module (Optional)
+# ============================================================================
+
+module "route53" {
+ count = var.create_route53_zone ? 1 : 0
+ source = "./modules/route53"
+
+ domain_name = var.domain_name
+ alb_dns_name = module.alb.dns_name
+ alb_zone_id = module.alb.zone_id
+
+ cloudfront_domain_name = var.enable_cloudfront ? module.cloudfront[0].domain_name : ""
+ cloudfront_zone_id = var.enable_cloudfront ? module.cloudfront[0].hosted_zone_id : ""
+
+ use_cloudfront = var.enable_cloudfront
+
+ tags = local.common_tags
+}
+
+# ============================================================================
+# Monitoring Module
+# ============================================================================
+
+module "monitoring" {
+ source = "./modules/monitoring"
+
+ project_name = var.project_name
+ environment = var.environment
+
+ tags = local.common_tags
+}
diff --git a/terraform/modules/alb/main.tf b/terraform/modules/alb/main.tf
new file mode 100644
index 0000000..a556a37
--- /dev/null
+++ b/terraform/modules/alb/main.tf
@@ -0,0 +1,201 @@
+# S3 Bucket for ALB Logs
+resource "aws_s3_bucket" "alb_logs" {
+ bucket = "${var.project_name}-${var.environment}-alb-logs-${data.aws_caller_identity.current.account_id}"
+
+ tags = merge(var.tags, {
+ Name = "${var.project_name}-${var.environment}-alb-logs"
+ })
+}
+
+resource "aws_s3_bucket_lifecycle_configuration" "alb_logs" {
+ bucket = aws_s3_bucket.alb_logs.id
+
+ rule {
+ id = "delete-old-logs"
+ status = "Enabled"
+
+ expiration {
+ days = 90
+ }
+ }
+}
+
+resource "aws_s3_bucket_public_access_block" "alb_logs" {
+ bucket = aws_s3_bucket.alb_logs.id
+
+ block_public_acls = true
+ block_public_policy = true
+ ignore_public_acls = true
+ restrict_public_buckets = true
+}
+
+resource "aws_s3_bucket_policy" "alb_logs" {
+ bucket = aws_s3_bucket.alb_logs.id
+
+ policy = jsonencode({
+ Version = "2012-10-17"
+ Statement = [{
+ Sid = "AWSLogDeliveryWrite"
+ Effect = "Allow"
+ Principal = {
+ Service = "elasticloadbalancing.amazonaws.com"
+ }
+ Action = "s3:PutObject"
+ Resource = "${aws_s3_bucket.alb_logs.arn}/*"
+ }]
+ })
+}
+
+# Application Load Balancer
+resource "aws_lb" "main" {
+ name = "${var.project_name}-${var.environment}-alb"
+ internal = false
+ load_balancer_type = "application"
+ security_groups = var.security_group_ids
+ subnets = var.public_subnet_ids
+
+ enable_deletion_protection = var.enable_deletion_protection
+ enable_http2 = var.enable_http2
+ enable_cross_zone_load_balancing = var.enable_cross_zone_load_balancing
+
+ access_logs {
+ bucket = aws_s3_bucket.alb_logs.bucket
+ enabled = true
+ }
+
+ tags = merge(var.tags, {
+ Name = "${var.project_name}-${var.environment}-alb"
+ })
+}
+
+# Target Group for Backend
+resource "aws_lb_target_group" "backend" {
+ name = "${var.project_name}-${var.environment}-backend-tg"
+ port = 8000
+ protocol = "HTTP"
+ vpc_id = var.vpc_id
+ target_type = "ip"
+
+ health_check {
+ enabled = true
+ healthy_threshold = 2
+ unhealthy_threshold = 3
+ timeout = 5
+ interval = var.health_check_interval
+ path = var.health_check_path
+ matcher = "200"
+ }
+
+ deregistration_delay = 30
+
+ tags = merge(var.tags, {
+ Name = "${var.project_name}-${var.environment}-backend-tg"
+ })
+}
+
+# Target Group for Frontend
+resource "aws_lb_target_group" "frontend" {
+ name = "${var.project_name}-${var.environment}-frontend-tg"
+ port = 80
+ protocol = "HTTP"
+ vpc_id = var.vpc_id
+ target_type = "ip"
+
+ health_check {
+ enabled = true
+ healthy_threshold = 2
+ unhealthy_threshold = 3
+ timeout = 5
+ interval = var.health_check_interval
+ path = "/"
+ matcher = "200"
+ }
+
+ deregistration_delay = 30
+
+ tags = merge(var.tags, {
+ Name = "${var.project_name}-${var.environment}-frontend-tg"
+ })
+}
+
+# HTTP Listener (redirect to HTTPS if enabled)
+resource "aws_lb_listener" "http" {
+ load_balancer_arn = aws_lb.main.arn
+ port = "80"
+ protocol = "HTTP"
+
+ default_action {
+ type = var.enable_https ? "redirect" : "forward"
+
+ dynamic "redirect" {
+ for_each = var.enable_https ? [1] : []
+ content {
+ port = "443"
+ protocol = "HTTPS"
+ status_code = "HTTP_301"
+ }
+ }
+
+ dynamic "forward" {
+ for_each = var.enable_https ? [] : [1]
+ content {
+ target_group {
+ arn = aws_lb_target_group.frontend.arn
+ }
+ }
+ }
+ }
+}
+
+# HTTPS Listener
+resource "aws_lb_listener" "https" {
+ count = var.enable_https ? 1 : 0
+ load_balancer_arn = aws_lb.main.arn
+ port = "443"
+ protocol = "HTTPS"
+ ssl_policy = "ELBSecurityPolicy-TLS-1-2-2017-01"
+ certificate_arn = var.ssl_certificate_arn
+
+ default_action {
+ type = "forward"
+ target_group_arn = aws_lb_target_group.frontend.arn
+ }
+}
+
+# Listener Rule for API traffic to backend
+resource "aws_lb_listener_rule" "api" {
+ count = var.enable_https ? 1 : 0
+ listener_arn = aws_lb_listener.https[0].arn
+ priority = 100
+
+ action {
+ type = "forward"
+ target_group_arn = aws_lb_target_group.backend.arn
+ }
+
+ condition {
+ path_pattern {
+ values = ["/api/*", "/admin/*", "/swagger/*", "/redoc/*"]
+ }
+ }
+}
+
+# HTTP Listener Rule for API (if HTTPS not enabled)
+resource "aws_lb_listener_rule" "api_http" {
+ count = var.enable_https ? 0 : 1
+ listener_arn = aws_lb_listener.http.arn
+ priority = 100
+
+ action {
+ type = "forward"
+ target_group_arn = aws_lb_target_group.backend.arn
+ }
+
+ condition {
+ path_pattern {
+ values = ["/api/*", "/admin/*", "/swagger/*", "/redoc/*"]
+ }
+ }
+}
+
+data "aws_caller_identity" "current" {}
diff --git a/terraform/modules/alb/outputs.tf b/terraform/modules/alb/outputs.tf
new file mode 100644
index 0000000..f45087b
--- /dev/null
+++ b/terraform/modules/alb/outputs.tf
@@ -0,0 +1,34 @@
+output "dns_name" {
+ description = "DNS name of the ALB"
+ value = aws_lb.main.dns_name
+}
+
+output "arn" {
+ description = "ARN of the ALB"
+ value = aws_lb.main.arn
+}
+
+output "zone_id" {
+ description = "Zone ID of the ALB"
+ value = aws_lb.main.zone_id
+}
+
+output "backend_target_group_arn" {
+ description = "ARN of backend target group"
+ value = aws_lb_target_group.backend.arn
+}
+
+output "frontend_target_group_arn" {
+ description = "ARN of frontend target group"
+ value = aws_lb_target_group.frontend.arn
+}
+
+output "http_listener_arn" {
+ description = "ARN of HTTP listener"
+ value = aws_lb_listener.http.arn
+}
+
+output "https_listener_arn" {
+ description = "ARN of HTTPS listener"
+ value = var.enable_https ? aws_lb_listener.https[0].arn : null
+}
diff --git a/terraform/modules/alb/variables.tf b/terraform/modules/alb/variables.tf
new file mode 100644
index 0000000..17ce524
--- /dev/null
+++ b/terraform/modules/alb/variables.tf
@@ -0,0 +1,64 @@
+variable "project_name" {
+ type = string
+}
+
+variable "environment" {
+ type = string
+}
+
+variable "vpc_id" {
+ type = string
+}
+
+variable "public_subnet_ids" {
+ type = list(string)
+}
+
+variable "security_group_ids" {
+ type = list(string)
+}
+
+variable "enable_deletion_protection" {
+ type = bool
+ default = true
+}
+
+variable "enable_http2" {
+ type = bool
+ default = true
+}
+
+variable "enable_cross_zone_load_balancing" {
+ type = bool
+ default = true
+}
+
+variable "enable_https" {
+ type = bool
+ default = true
+}
+
+variable "ssl_certificate_arn" {
+ type = string
+ default = ""
+}
+
+variable "health_check_path" {
+ type = string
+ default = "/health"
+}
+
+variable "health_check_interval" {
+ type = number
+ default = 30
+}
+
+variable "health_check_timeout" {
+ type = number
+ default = 5
+}
+
+variable "tags" {
+ type = map(string)
+ default = {}
+}
diff --git a/terraform/modules/cloudfront/main.tf b/terraform/modules/cloudfront/main.tf
new file mode 100644
index 0000000..53a025c
--- /dev/null
+++ b/terraform/modules/cloudfront/main.tf
@@ -0,0 +1,89 @@
+# CloudFront Origin Access Identity
+resource "aws_cloudfront_origin_access_identity" "main" {
+ comment = "${var.project_name}-${var.environment}"
+}
+
+# CloudFront Distribution
+resource "aws_cloudfront_distribution" "main" {
+ enabled = true
+ is_ipv6_enabled = var.enable_ipv6
+ comment = "${var.project_name}-${var.environment}"
+ default_root_object = "index.html"
+ price_class = var.price_class
+
+ origin {
+ domain_name = var.alb_domain_name
+ origin_id = "alb"
+
+ custom_origin_config {
+ http_port = 80
+ https_port = 443
+ origin_protocol_policy = "https-only"
+ origin_ssl_protocols = ["TLSv1.2"]
+ }
+ }
+
+ origin {
+ domain_name = var.s3_bucket_domain_name
+ origin_id = "s3"
+
+ s3_origin_config {
+ origin_access_identity = aws_cloudfront_origin_access_identity.main.cloudfront_access_identity_path
+ }
+ }
+
+ default_cache_behavior {
+ allowed_methods = ["GET", "HEAD", "OPTIONS", "PUT", "POST", "PATCH", "DELETE"]
+ cached_methods = ["GET", "HEAD", "OPTIONS"]
+ target_origin_id = "alb"
+
+ forwarded_values {
+ query_string = true
+ headers = ["Host", "Origin", "Authorization"]
+ cookies {
+ forward = "all"
+ }
+ }
+
+ viewer_protocol_policy = "redirect-to-https"
+ min_ttl = 0
+ default_ttl = 3600
+ max_ttl = 86400
+ compress = true
+ }
+
+ ordered_cache_behavior {
+ path_pattern = "/static/*"
+ allowed_methods = ["GET", "HEAD", "OPTIONS"]
+ cached_methods = ["GET", "HEAD"]
+ target_origin_id = "s3"
+
+ forwarded_values {
+ query_string = false
+ cookies {
+ forward = "none"
+ }
+ }
+
+ viewer_protocol_policy = "redirect-to-https"
+ min_ttl = 0
+ default_ttl = 86400
+ max_ttl = 31536000
+ compress = true
+ }
+
+ viewer_certificate {
+ cloudfront_default_certificate = var.ssl_certificate_arn == "" ? true : false
+ acm_certificate_arn = var.ssl_certificate_arn != "" ? var.ssl_certificate_arn : null
+ ssl_support_method = var.ssl_certificate_arn != "" ? "sni-only" : null
+ minimum_protocol_version = var.minimum_protocol_version
+ }
+
+ restrictions {
+ geo_restriction {
+ restriction_type = "none"
+ }
+ }
+
+ tags = var.tags
+}
diff --git a/terraform/modules/cloudfront/outputs.tf b/terraform/modules/cloudfront/outputs.tf
new file mode 100644
index 0000000..50a7407
--- /dev/null
+++ b/terraform/modules/cloudfront/outputs.tf
@@ -0,0 +1,4 @@
+output "distribution_id" { value = aws_cloudfront_distribution.main.id }
+output "domain_name" { value = aws_cloudfront_distribution.main.domain_name }
+output "hosted_zone_id" { value = aws_cloudfront_distribution.main.hosted_zone_id }
+output "arn" { value = aws_cloudfront_distribution.main.arn }
diff --git a/terraform/modules/cloudfront/variables.tf b/terraform/modules/cloudfront/variables.tf
new file mode 100644
index 0000000..dcada1c
--- /dev/null
+++ b/terraform/modules/cloudfront/variables.tf
@@ -0,0 +1,9 @@
+variable "project_name" { type = string }
+variable "environment" { type = string }
+variable "alb_domain_name" { type = string }
+variable "s3_bucket_domain_name" { type = string }
+variable "ssl_certificate_arn" { type = string; default = "" }
+variable "price_class" { type = string; default = "PriceClass_100" }
+variable "enable_ipv6" { type = bool; default = true }
+variable "minimum_protocol_version" { type = string; default = "TLSv1.2_2021" }
+variable "tags" { type = map(string); default = {} }
diff --git a/terraform/modules/documentdb/main.tf b/terraform/modules/documentdb/main.tf
new file mode 100644
index 0000000..020692b
--- /dev/null
+++ b/terraform/modules/documentdb/main.tf
@@ -0,0 +1,111 @@
+# DocumentDB Subnet Group
+resource "aws_docdb_subnet_group" "main" {
+ name = "${var.project_name}-${var.environment}-docdb-subnet-group"
+ subnet_ids = var.subnet_ids
+
+ tags = merge(var.tags, {
+ Name = "${var.project_name}-${var.environment}-docdb-subnet-group"
+ })
+}
+
+# DocumentDB Cluster Parameter Group
+resource "aws_docdb_cluster_parameter_group" "main" {
+ family = "docdb5.0"
+ name = "${var.project_name}-${var.environment}-docdb-params"
+
+ parameter {
+ name = "tls"
+ value = "enabled"
+ }
+
+ parameter {
+ name = "audit_logs"
+ value = "enabled"
+ }
+
+ tags = var.tags
+}
+
+# Random password for DocumentDB
+resource "random_password" "documentdb" {
+ length = 32
+ special = false # DocumentDB doesn't support all special characters
+}
+
+# Store DocumentDB password in Secrets Manager
+resource "aws_secretsmanager_secret" "documentdb_password" {
+ name = "${var.project_name}-${var.environment}-documentdb-password"
+ recovery_window_in_days = var.deletion_protection ? 30 : 0
+
+ tags = var.tags
+}
+
+resource "aws_secretsmanager_secret_version" "documentdb_password" {
+ secret_id = aws_secretsmanager_secret.documentdb_password.id
+ secret_string = jsonencode({
+ username = var.master_username
+ password = random_password.documentdb.result
+ engine = "docdb"
+ host = aws_docdb_cluster.main.endpoint
+ port = aws_docdb_cluster.main.port
+ })
+}
+
+# DocumentDB Cluster
+resource "aws_docdb_cluster" "main" {
+ cluster_identifier = "${var.project_name}-${var.environment}-docdb"
+ engine = "docdb"
+ engine_version = var.engine_version
+ master_username = var.master_username
+ master_password = random_password.documentdb.result
+ db_subnet_group_name = aws_docdb_subnet_group.main.name
+ db_cluster_parameter_group_name = aws_docdb_cluster_parameter_group.main.name
+ vpc_security_group_ids = var.security_group_ids
+
+ backup_retention_period = var.backup_retention_period
+ preferred_backup_window = var.backup_window
+ preferred_maintenance_window = var.maintenance_window
+
+ storage_encrypted = true
+ deletion_protection = var.deletion_protection
+ skip_final_snapshot = var.skip_final_snapshot
+ final_snapshot_identifier = var.skip_final_snapshot ? null : "${var.project_name}-${var.environment}-docdb-final-${formatdate("YYYY-MM-DD-hhmm", timestamp())}"
+
+ enabled_cloudwatch_logs_exports = ["audit", "profiler"]
+
+ tags = merge(var.tags, {
+ Name = "${var.project_name}-${var.environment}-docdb-cluster"
+ })
+}
+
+# DocumentDB Cluster Instances
+resource "aws_docdb_cluster_instance" "main" {
+ count = var.instance_count
+ identifier = "${var.project_name}-${var.environment}-docdb-${count.index + 1}"
+ cluster_identifier = aws_docdb_cluster.main.id
+ instance_class = var.instance_class
+
+ auto_minor_version_upgrade = true
+
+ tags = merge(var.tags, {
+ Name = "${var.project_name}-${var.environment}-docdb-instance-${count.index + 1}"
+ })
+}
+
+# CloudWatch Alarms
+resource "aws_cloudwatch_metric_alarm" "documentdb_cpu" {
+ alarm_name = "${var.project_name}-${var.environment}-docdb-cpu"
+ comparison_operator = "GreaterThanThreshold"
+ evaluation_periods = "2"
+ metric_name = "CPUUtilization"
+ namespace = "AWS/DocDB"
+ period = "300"
+ statistic = "Average"
+ threshold = "80"
+
+ dimensions = {
+ DBClusterIdentifier = aws_docdb_cluster.main.id
+ }
+
+ tags = var.tags
+}
diff --git a/terraform/modules/documentdb/outputs.tf b/terraform/modules/documentdb/outputs.tf
new file mode 100644
index 0000000..44f8c72
--- /dev/null
+++ b/terraform/modules/documentdb/outputs.tf
@@ -0,0 +1,30 @@
+output "endpoint" {
+ description = "DocumentDB cluster endpoint"
+ value = aws_docdb_cluster.main.endpoint
+}
+
+output "reader_endpoint" {
+ description = "DocumentDB reader endpoint"
+ value = aws_docdb_cluster.main.reader_endpoint
+}
+
+output "port" {
+ description = "DocumentDB port"
+ value = aws_docdb_cluster.main.port
+}
+
+output "cluster_id" {
+ description = "DocumentDB cluster ID"
+ value = aws_docdb_cluster.main.id
+}
+
+output "arn" {
+ description = "DocumentDB ARN"
+ value = aws_docdb_cluster.main.arn
+}
+
+output "password_secret_arn" {
+ description = "ARN of the secret containing DocumentDB password"
+ value = aws_secretsmanager_secret.documentdb_password.arn
+ sensitive = true
+}
diff --git a/terraform/modules/documentdb/variables.tf b/terraform/modules/documentdb/variables.tf
new file mode 100644
index 0000000..47afcc8
--- /dev/null
+++ b/terraform/modules/documentdb/variables.tf
@@ -0,0 +1,69 @@
+variable "project_name" {
+ type = string
+}
+
+variable "environment" {
+ type = string
+}
+
+variable "vpc_id" {
+ type = string
+}
+
+variable "subnet_ids" {
+ type = list(string)
+}
+
+variable "security_group_ids" {
+ type = list(string)
+}
+
+variable "instance_class" {
+ type = string
+ default = "db.t3.medium"
+}
+
+variable "instance_count" {
+ type = number
+ default = 3
+}
+
+variable "engine_version" {
+ type = string
+ default = "5.0.0"
+}
+
+variable "master_username" {
+ type = string
+ default = "lmsadmin"
+}
+
+variable "deletion_protection" {
+ type = bool
+ default = true
+}
+
+variable "skip_final_snapshot" {
+ type = bool
+ default = false
+}
+
+variable "backup_retention_period" {
+ type = number
+ default = 7
+}
+
+variable "backup_window" {
+ type = string
+ default = "02:00-03:00"
+}
+
+variable "maintenance_window" {
+ type = string
+ default = "sun:03:00-sun:04:00"
+}
+
+variable "tags" {
+ type = map(string)
+ default = {}
+}
diff --git a/terraform/modules/ecr/main.tf b/terraform/modules/ecr/main.tf
new file mode 100644
index 0000000..d2024d3
--- /dev/null
+++ b/terraform/modules/ecr/main.tf
@@ -0,0 +1,105 @@
+# Backend ECR Repository
+resource "aws_ecr_repository" "backend" {
+ name = "${var.project_name}-backend"
+ image_tag_mutability = var.image_tag_mutability
+
+ image_scanning_configuration {
+ scan_on_push = var.scan_on_push
+ }
+
+ encryption_configuration {
+ encryption_type = "AES256"
+ }
+
+ tags = merge(var.tags, {
+ Name = "${var.project_name}-${var.environment}-backend-repo"
+ })
+}
+
+# Frontend ECR Repository
+resource "aws_ecr_repository" "frontend" {
+ name = "${var.project_name}-frontend"
+ image_tag_mutability = var.image_tag_mutability
+
+ image_scanning_configuration {
+ scan_on_push = var.scan_on_push
+ }
+
+ encryption_configuration {
+ encryption_type = "AES256"
+ }
+
+ tags = merge(var.tags, {
+ Name = "${var.project_name}-${var.environment}-frontend-repo"
+ })
+}
+
+# Lifecycle Policy for Backend
+resource "aws_ecr_lifecycle_policy" "backend" {
+ count = var.lifecycle_policy_enabled ? 1 : 0
+ repository = aws_ecr_repository.backend.name
+
+ policy = jsonencode({
+ rules = [{
+ rulePriority = 1
+ description = "Keep last 10 images"
+ selection = {
+ tagStatus = "tagged"
+ tagPrefixList = ["v"]
+ countType = "imageCountMoreThan"
+ countNumber = 10
+ }
+ action = {
+ type = "expire"
+ }
+ },
+ {
+ rulePriority = 2
+ description = "Remove untagged images after 7 days"
+ selection = {
+ tagStatus = "untagged"
+ countType = "sinceImagePushed"
+ countUnit = "days"
+ countNumber = 7
+ }
+ action = {
+ type = "expire"
+ }
+ }]
+ })
+}
+
+# Lifecycle Policy for Frontend
+resource "aws_ecr_lifecycle_policy" "frontend" {
+ count = var.lifecycle_policy_enabled ? 1 : 0
+ repository = aws_ecr_repository.frontend.name
+
+ policy = jsonencode({
+ rules = [{
+ rulePriority = 1
+ description = "Keep last 10 images"
+ selection = {
+ tagStatus = "tagged"
+ tagPrefixList = ["v"]
+ countType = "imageCountMoreThan"
+ countNumber = 10
+ }
+ action = {
+ type = "expire"
+ }
+ },
+ {
+ rulePriority = 2
+ description = "Remove untagged images after 7 days"
+ selection = {
+ tagStatus = "untagged"
+ countType = "sinceImagePushed"
+ countUnit = "days"
+ countNumber = 7
+ }
+ action = {
+ type = "expire"
+ }
+ }]
+ })
+}
diff --git a/terraform/modules/ecr/outputs.tf b/terraform/modules/ecr/outputs.tf
new file mode 100644
index 0000000..d4fd0e3
--- /dev/null
+++ b/terraform/modules/ecr/outputs.tf
@@ -0,0 +1,19 @@
+output "backend_repository_url" {
+ description = "URL of backend ECR repository"
+ value = aws_ecr_repository.backend.repository_url
+}
+
+output "frontend_repository_url" {
+ description = "URL of frontend ECR repository"
+ value = aws_ecr_repository.frontend.repository_url
+}
+
+output "backend_repository_arn" {
+ description = "ARN of backend ECR repository"
+ value = aws_ecr_repository.backend.arn
+}
+
+output "frontend_repository_arn" {
+ description = "ARN of frontend ECR repository"
+ value = aws_ecr_repository.frontend.arn
+}
diff --git a/terraform/modules/ecr/variables.tf b/terraform/modules/ecr/variables.tf
new file mode 100644
index 0000000..62cf109
--- /dev/null
+++ b/terraform/modules/ecr/variables.tf
@@ -0,0 +1,33 @@
+variable "project_name" {
+ description = "Name of the project"
+ type = string
+}
+
+variable "environment" {
+ description = "Environment name"
+ type = string
+}
+
+variable "image_tag_mutability" {
+ description = "Image tag mutability setting"
+ type = string
+ default = "MUTABLE"
+}
+
+variable "scan_on_push" {
+ description = "Enable image scanning on push"
+ type = bool
+ default = true
+}
+
+variable "lifecycle_policy_enabled" {
+ description = "Enable lifecycle policy"
+ type = bool
+ default = true
+}
+
+variable "tags" {
+ description = "Tags to apply to resources"
+ type = map(string)
+ default = {}
+}
diff --git a/terraform/modules/ecs/main.tf b/terraform/modules/ecs/main.tf
new file mode 100644
index 0000000..e039f23
--- /dev/null
+++ b/terraform/modules/ecs/main.tf
@@ -0,0 +1,303 @@
+# ECS Cluster
+resource "aws_ecs_cluster" "main" {
+ name = "${var.project_name}-${var.environment}-cluster"
+
+ setting {
+ name = "containerInsights"
+ value = "enabled"
+ }
+
+ tags = var.tags
+}
+
+# CloudWatch Log Groups
+resource "aws_cloudwatch_log_group" "backend" {
+ name = "/ecs/${var.project_name}-${var.environment}/backend"
+ retention_in_days = var.log_retention_days
+ tags = var.tags
+}
+
+resource "aws_cloudwatch_log_group" "frontend" {
+ name = "/ecs/${var.project_name}-${var.environment}/frontend"
+ retention_in_days = var.log_retention_days
+ tags = var.tags
+}
+
+# ECS Task Execution Role
+resource "aws_iam_role" "ecs_execution" {
+ name = "${var.project_name}-${var.environment}-ecs-execution-role"
+
+ assume_role_policy = jsonencode({
+ Version = "2012-10-17"
+ Statement = [{
+ Action = "sts:AssumeRole"
+ Effect = "Allow"
+ Principal = {
+ Service = "ecs-tasks.amazonaws.com"
+ }
+ }]
+ })
+
+ tags = var.tags
+}
+
+resource "aws_iam_role_policy_attachment" "ecs_execution" {
+ role = aws_iam_role.ecs_execution.name
+ policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy"
+}
+
+resource "aws_iam_role_policy" "ecs_execution_secrets" {
+ name = "secrets-access"
+ role = aws_iam_role.ecs_execution.id
+
+ policy = jsonencode({
+ Version = "2012-10-17"
+ Statement = [{
+ Effect = "Allow"
+ Action = [
+ "secretsmanager:GetSecretValue",
+ "kms:Decrypt"
+ ]
+ Resource = "*"
+ }]
+ })
+}
+
+# ECS Task Role
+resource "aws_iam_role" "ecs_task" {
+ name = "${var.project_name}-${var.environment}-ecs-task-role"
+
+ assume_role_policy = jsonencode({
+ Version = "2012-10-17"
+ Statement = [{
+ Action = "sts:AssumeRole"
+ Effect = "Allow"
+ Principal = {
+ Service = "ecs-tasks.amazonaws.com"
+ }
+ }]
+ })
+
+ tags = var.tags
+}
+
+resource "aws_iam_role_policy" "ecs_task_s3" {
+ name = "s3-access"
+ role = aws_iam_role.ecs_task.id
+
+ policy = jsonencode({
+ Version = "2012-10-17"
+ Statement = [{
+ Effect = "Allow"
+ Action = [
+ "s3:GetObject",
+ "s3:PutObject",
+ "s3:DeleteObject",
+ "s3:ListBucket"
+ ]
+ Resource = "*"
+ }]
+ })
+}
+
+# Backend Task Definition
+resource "aws_ecs_task_definition" "backend" {
+ family = "${var.project_name}-${var.environment}-backend"
+ network_mode = "awsvpc"
+ requires_compatibilities = ["FARGATE"]
+ cpu = var.backend_cpu
+ memory = var.backend_memory
+ execution_role_arn = aws_iam_role.ecs_execution.arn
+ task_role_arn = aws_iam_role.ecs_task.arn
+
+ container_definitions = jsonencode([{
+ name = "backend"
+ image = var.backend_image
+
+ portMappings = [{
+ containerPort = 8000
+ protocol = "tcp"
+ }]
+
+ environment = [
+ for k, v in var.backend_environment_variables : {
+ name = k
+ value = v
+ }
+ ]
+
+ logConfiguration = {
+ logDriver = "awslogs"
+ options = {
+ "awslogs-group" = aws_cloudwatch_log_group.backend.name
+ "awslogs-region" = data.aws_region.current.name
+ "awslogs-stream-prefix" = "ecs"
+ }
+ }
+
+ healthCheck = {
+ command = ["CMD-SHELL", "curl -f http://localhost:8000/health || exit 1"]
+ interval = 30
+ timeout = 5
+ retries = 3
+ startPeriod = 60
+ }
+ }])
+
+ tags = var.tags
+}
+
+# Frontend Task Definition
+resource "aws_ecs_task_definition" "frontend" {
+ family = "${var.project_name}-${var.environment}-frontend"
+ network_mode = "awsvpc"
+ requires_compatibilities = ["FARGATE"]
+ cpu = var.frontend_cpu
+ memory = var.frontend_memory
+ execution_role_arn = aws_iam_role.ecs_execution.arn
+ task_role_arn = aws_iam_role.ecs_task.arn
+
+ container_definitions = jsonencode([{
+ name = "frontend"
+ image = var.frontend_image
+
+ portMappings = [{
+ containerPort = 80
+ protocol = "tcp"
+ }]
+
+ environment = [
+ for k, v in var.frontend_environment_variables : {
+ name = k
+ value = v
+ }
+ ]
+
+ logConfiguration = {
+ logDriver = "awslogs"
+ options = {
+ "awslogs-group" = aws_cloudwatch_log_group.frontend.name
+ "awslogs-region" = data.aws_region.current.name
+ "awslogs-stream-prefix" = "ecs"
+ }
+ }
+ }])
+
+ tags = var.tags
+}
+
+# Backend ECS Service
+resource "aws_ecs_service" "backend" {
+ name = "${var.project_name}-${var.environment}-backend"
+ cluster = aws_ecs_cluster.main.id
+ task_definition = aws_ecs_task_definition.backend.arn
+ desired_count = var.backend_desired_count
+ launch_type = "FARGATE"
+
+ network_configuration {
+ subnets = var.private_subnet_ids
+ security_groups = var.security_group_ids
+ assign_public_ip = false
+ }
+
+ load_balancer {
+ target_group_arn = var.backend_target_group_arn
+ container_name = "backend"
+ container_port = 8000
+ }
+
+ deployment_configuration {
+ maximum_percent = 200
+ minimum_healthy_percent = 100
+ }
+
+ enable_execute_command = true
+
+ tags = var.tags
+
+ depends_on = [var.backend_target_group_arn]
+}
+
+# Frontend ECS Service
+resource "aws_ecs_service" "frontend" {
+ name = "${var.project_name}-${var.environment}-frontend"
+ cluster = aws_ecs_cluster.main.id
+ task_definition = aws_ecs_task_definition.frontend.arn
+ desired_count = var.frontend_desired_count
+ launch_type = "FARGATE"
+
+ network_configuration {
+ subnets = var.private_subnet_ids
+ security_groups = var.security_group_ids
+ assign_public_ip = false
+ }
+
+ load_balancer {
+ target_group_arn = var.frontend_target_group_arn
+ container_name = "frontend"
+ container_port = 80
+ }
+
+ deployment_configuration {
+ maximum_percent = 200
+ minimum_healthy_percent = 100
+ }
+
+ enable_execute_command = true
+
+ tags = var.tags
+
+ depends_on = [var.frontend_target_group_arn]
+}
+
+# Auto Scaling for Backend
+resource "aws_appautoscaling_target" "backend" {
+ count = var.enable_autoscaling ? 1 : 0
+ max_capacity = var.autoscaling_max_capacity
+ min_capacity = var.autoscaling_min_capacity
+ resource_id = "service/${aws_ecs_cluster.main.name}/${aws_ecs_service.backend.name}"
+ scalable_dimension = "ecs:service:DesiredCount"
+ service_namespace = "ecs"
+}
+
+resource "aws_appautoscaling_policy" "backend_cpu" {
+ count = var.enable_autoscaling ? 1 : 0
+ name = "${var.project_name}-${var.environment}-backend-cpu-scaling"
+ policy_type = "TargetTrackingScaling"
+ resource_id = aws_appautoscaling_target.backend[0].resource_id
+ scalable_dimension = aws_appautoscaling_target.backend[0].scalable_dimension
+ service_namespace = aws_appautoscaling_target.backend[0].service_namespace
+
+ target_tracking_scaling_policy_configuration {
+ target_value = var.autoscaling_target_cpu_percent
+
+ predefined_metric_specification {
+ predefined_metric_type = "ECSServiceAverageCPUUtilization"
+ }
+
+ scale_in_cooldown = 300
+ scale_out_cooldown = 60
+ }
+}
+
+resource "aws_appautoscaling_policy" "backend_memory" {
+ count = var.enable_autoscaling ? 1 : 0
+ name = "${var.project_name}-${var.environment}-backend-memory-scaling"
+ policy_type = "TargetTrackingScaling"
+ resource_id = aws_appautoscaling_target.backend[0].resource_id
+ scalable_dimension = aws_appautoscaling_target.backend[0].scalable_dimension
+ service_namespace = aws_appautoscaling_target.backend[0].service_namespace
+
+ target_tracking_scaling_policy_configuration {
+ target_value = var.autoscaling_target_memory_percent
+
+ predefined_metric_specification {
+ predefined_metric_type = "ECSServiceAverageMemoryUtilization"
+ }
+
+ scale_in_cooldown = 300
+ scale_out_cooldown = 60
+ }
+}
+
+data "aws_region" "current" {}
diff --git a/terraform/modules/ecs/outputs.tf b/terraform/modules/ecs/outputs.tf
new file mode 100644
index 0000000..3d483d7
--- /dev/null
+++ b/terraform/modules/ecs/outputs.tf
@@ -0,0 +1,9 @@
+output "cluster_id" { value = aws_ecs_cluster.main.id }
+output "cluster_name" { value = aws_ecs_cluster.main.name }
+output "cluster_arn" { value = aws_ecs_cluster.main.arn }
+output "backend_service_name" { value = aws_ecs_service.backend.name }
+output "frontend_service_name" { value = aws_ecs_service.frontend.name }
+output "backend_task_definition_arn" { value = aws_ecs_task_definition.backend.arn }
+output "frontend_task_definition_arn" { value = aws_ecs_task_definition.frontend.arn }
+output "execution_role_arn" { value = aws_iam_role.ecs_execution.arn }
+output "task_role_arn" { value = aws_iam_role.ecs_task.arn }
diff --git a/terraform/modules/ecs/variables.tf b/terraform/modules/ecs/variables.tf
new file mode 100644
index 0000000..b5bcfb0
--- /dev/null
+++ b/terraform/modules/ecs/variables.tf
@@ -0,0 +1,24 @@
+variable "project_name" { type = string }
+variable "environment" { type = string }
+variable "vpc_id" { type = string }
+variable "private_subnet_ids" { type = list(string) }
+variable "security_group_ids" { type = list(string) }
+variable "backend_image" { type = string }
+variable "backend_cpu" { type = number; default = 512 }
+variable "backend_memory" { type = number; default = 1024 }
+variable "backend_desired_count" { type = number; default = 2 }
+variable "backend_target_group_arn" { type = string }
+variable "frontend_image" { type = string }
+variable "frontend_cpu" { type = number; default = 256 }
+variable "frontend_memory" { type = number; default = 512 }
+variable "frontend_desired_count" { type = number; default = 2 }
+variable "frontend_target_group_arn" { type = string }
+variable "backend_environment_variables" { type = map(string); default = {} }
+variable "frontend_environment_variables" { type = map(string); default = {} }
+variable "enable_autoscaling" { type = bool; default = true }
+variable "autoscaling_min_capacity" { type = number; default = 2 }
+variable "autoscaling_max_capacity" { type = number; default = 10 }
+variable "autoscaling_target_cpu_percent" { type = number; default = 70 }
+variable "autoscaling_target_memory_percent" { type = number; default = 80 }
+variable "log_retention_days" { type = number; default = 30 }
+variable "tags" { type = map(string); default = {} }
diff --git a/terraform/modules/elasticache/main.tf b/terraform/modules/elasticache/main.tf
new file mode 100644
index 0000000..d06f9d4
--- /dev/null
+++ b/terraform/modules/elasticache/main.tf
@@ -0,0 +1,110 @@
+# ElastiCache Subnet Group
+resource "aws_elasticache_subnet_group" "main" {
+ name = "${var.project_name}-${var.environment}-redis-subnet-group"
+ subnet_ids = var.subnet_ids
+
+ tags = merge(var.tags, {
+ Name = "${var.project_name}-${var.environment}-redis-subnet-group"
+ })
+}
+
+# ElastiCache Parameter Group
+resource "aws_elasticache_parameter_group" "main" {
+ name = "${var.project_name}-${var.environment}-redis7"
+ family = var.parameter_group_family
+
+ parameter {
+ name = "maxmemory-policy"
+ value = "allkeys-lru"
+ }
+
+ parameter {
+ name = "timeout"
+ value = "300"
+ }
+
+ tags = var.tags
+}
+
+# ElastiCache Replication Group
+resource "aws_elasticache_replication_group" "main" {
+ replication_group_id = "${var.project_name}-${var.environment}-redis"
+ description = "Redis cluster for ${var.project_name} ${var.environment}"
+
+ engine = "redis"
+ engine_version = var.engine_version
+ node_type = var.node_type
+ port = var.port
+ parameter_group_name = aws_elasticache_parameter_group.main.name
+
+ num_cache_clusters = var.num_cache_nodes
+ automatic_failover_enabled = var.automatic_failover_enabled
+ multi_az_enabled = var.multi_az_enabled
+
+ subnet_group_name = aws_elasticache_subnet_group.main.name
+ security_group_ids = var.security_group_ids
+
+ at_rest_encryption_enabled = true
+ transit_encryption_enabled = true
+ auth_token_enabled = false
+
+ snapshot_retention_limit = var.snapshot_retention_limit
+ snapshot_window = var.snapshot_window
+ maintenance_window = var.maintenance_window
+
+ auto_minor_version_upgrade = true
+
+ log_delivery_configuration {
+ destination = aws_cloudwatch_log_group.redis_slow.name
+ destination_type = "cloudwatch-logs"
+ log_format = "json"
+ log_type = "slow-log"
+ }
+
+ tags = merge(var.tags, {
+ Name = "${var.project_name}-${var.environment}-redis"
+ })
+}
+
+# CloudWatch Log Group for Redis
+resource "aws_cloudwatch_log_group" "redis_slow" {
+ name = "/aws/elasticache/${var.project_name}-${var.environment}/redis-slow-log"
+ retention_in_days = 7
+
+ tags = var.tags
+}
+
+# CloudWatch Alarms
+resource "aws_cloudwatch_metric_alarm" "redis_cpu" {
+ alarm_name = "${var.project_name}-${var.environment}-redis-cpu"
+ comparison_operator = "GreaterThanThreshold"
+ evaluation_periods = "2"
+ metric_name = "CPUUtilization"
+ namespace = "AWS/ElastiCache"
+ period = "300"
+ statistic = "Average"
+ threshold = "75"
+
+ dimensions = {
+ ReplicationGroupId = aws_elasticache_replication_group.main.id
+ }
+
+ tags = var.tags
+}
+
+resource "aws_cloudwatch_metric_alarm" "redis_memory" {
+ alarm_name = "${var.project_name}-${var.environment}-redis-memory"
+ comparison_operator = "GreaterThanThreshold"
+ evaluation_periods = "2"
+ metric_name = "DatabaseMemoryUsagePercentage"
+ namespace = "AWS/ElastiCache"
+ period = "300"
+ statistic = "Average"
+ threshold = "90"
+
+ dimensions = {
+ ReplicationGroupId = aws_elasticache_replication_group.main.id
+ }
+
+ tags = var.tags
+}
diff --git a/terraform/modules/elasticache/outputs.tf b/terraform/modules/elasticache/outputs.tf
new file mode 100644
index 0000000..5b06101
--- /dev/null
+++ b/terraform/modules/elasticache/outputs.tf
@@ -0,0 +1,24 @@
+output "endpoint" {
+ description = "Redis primary endpoint"
+ value = aws_elasticache_replication_group.main.primary_endpoint_address
+}
+
+output "reader_endpoint" {
+ description = "Redis reader endpoint"
+ value = aws_elasticache_replication_group.main.reader_endpoint_address
+}
+
+output "port" {
+ description = "Redis port"
+ value = aws_elasticache_replication_group.main.port
+}
+
+output "id" {
+ description = "Redis replication group ID"
+ value = aws_elasticache_replication_group.main.id
+}
+
+output "arn" {
+ description = "Redis ARN"
+ value = aws_elasticache_replication_group.main.arn
+}
diff --git a/terraform/modules/elasticache/variables.tf b/terraform/modules/elasticache/variables.tf
new file mode 100644
index 0000000..e489e65
--- /dev/null
+++ b/terraform/modules/elasticache/variables.tf
@@ -0,0 +1,74 @@
+variable "project_name" {
+ type = string
+}
+
+variable "environment" {
+ type = string
+}
+
+variable "vpc_id" {
+ type = string
+}
+
+variable "subnet_ids" {
+ type = list(string)
+}
+
+variable "security_group_ids" {
+ type = list(string)
+}
+
+variable "node_type" {
+ type = string
+ default = "cache.t3.medium"
+}
+
+variable "num_cache_nodes" {
+ type = number
+ default = 2
+}
+
+variable "parameter_group_family" {
+ type = string
+ default = "redis7"
+}
+
+variable "engine_version" {
+ type = string
+ default = "7.0"
+}
+
+variable "port" {
+ type = number
+ default = 6379
+}
+
+variable "automatic_failover_enabled" {
+ type = bool
+ default = true
+}
+
+variable "multi_az_enabled" {
+ type = bool
+ default = true
+}
+
+variable "snapshot_retention_limit" {
+ type = number
+ default = 7
+}
+
+variable "snapshot_window" {
+ type = string
+ default = "03:00-05:00"
+}
+
+variable "maintenance_window" {
+ type = string
+ default = "sun:05:00-sun:07:00"
+}
+
+variable "tags" {
+ type = map(string)
+ default = {}
+}
diff --git a/terraform/modules/monitoring/main.tf b/terraform/modules/monitoring/main.tf
new file mode 100644
index 0000000..1078079
--- /dev/null
+++ b/terraform/modules/monitoring/main.tf
@@ -0,0 +1,54 @@
+# SNS Topic for Alarms
+resource "aws_sns_topic" "alarms" {
+ name = "${var.project_name}-${var.environment}-alarms"
+ tags = var.tags
+}
+
+# CloudWatch Dashboard
+resource "aws_cloudwatch_dashboard" "main" {
+ dashboard_name = "${var.project_name}-${var.environment}"
+
+ dashboard_body = jsonencode({
+ widgets = [
+ {
+ type = "metric"
+ properties = {
+ metrics = [
+ ["AWS/ECS", "CPUUtilization", { stat = "Average" }],
+ [".", "MemoryUtilization", { stat = "Average" }]
+ ]
+ period = 300
+ stat = "Average"
+ region = data.aws_region.current.name
+ title = "ECS Metrics"
+ }
+ },
+ {
+ type = "metric"
+ properties = {
+ metrics = [
+ ["AWS/ApplicationELB", "TargetResponseTime", { stat = "Average" }],
+ [".", "RequestCount", { stat = "Sum" }]
+ ]
+ period = 300
+ region = data.aws_region.current.name
+ title = "ALB Metrics"
+ }
+ },
+ {
+ type = "metric"
+ properties = {
+ metrics = [
+ ["AWS/RDS", "CPUUtilization", { stat = "Average" }],
+ [".", "DatabaseConnections", { stat = "Average" }]
+ ]
+ period = 300
+ region = data.aws_region.current.name
+ title = "RDS Metrics"
+ }
+ }
+ ]
+ })
+}
+
+data "aws_region" "current" {}
diff --git a/terraform/modules/monitoring/outputs.tf b/terraform/modules/monitoring/outputs.tf
new file mode 100644
index 0000000..72e47f7
--- /dev/null
+++ b/terraform/modules/monitoring/outputs.tf
@@ -0,0 +1,2 @@
+output "sns_topic_arn" { value = aws_sns_topic.alarms.arn }
+output "dashboard_name" { value = aws_cloudwatch_dashboard.main.dashboard_name }
diff --git a/terraform/modules/monitoring/variables.tf b/terraform/modules/monitoring/variables.tf
new file mode 100644
index 0000000..0245bfd
--- /dev/null
+++ b/terraform/modules/monitoring/variables.tf
@@ -0,0 +1,3 @@
+variable "project_name" { type = string }
+variable "environment" { type = string }
+variable "tags" { type = map(string); default = {} }
diff --git a/terraform/modules/rds/main.tf b/terraform/modules/rds/main.tf
new file mode 100644
index 0000000..4b1a70f
--- /dev/null
+++ b/terraform/modules/rds/main.tf
@@ -0,0 +1,144 @@
+# RDS Subnet Group
+resource "aws_db_subnet_group" "main" {
+ name = "${var.project_name}-${var.environment}-rds-subnet-group"
+ subnet_ids = var.database_subnet_ids
+
+ tags = merge(var.tags, {
+ Name = "${var.project_name}-${var.environment}-rds-subnet-group"
+ })
+}
+
+# RDS Parameter Group
+resource "aws_db_parameter_group" "main" {
+ name = "${var.project_name}-${var.environment}-pg15"
+ family = "postgres15"
+
+ parameter {
+ name = "log_connections"
+ value = "1"
+ }
+
+ parameter {
+ name = "log_disconnections"
+ value = "1"
+ }
+
+ parameter {
+ name = "log_duration"
+ value = "1"
+ }
+
+ parameter {
+ name = "shared_preload_libraries"
+ value = "pg_stat_statements"
+ }
+
+ tags = var.tags
+}
+
+# Random password for RDS
+resource "random_password" "rds" {
+ length = 32
+ special = true
+}
+
+# Store RDS password in Secrets Manager
+resource "aws_secretsmanager_secret" "rds_password" {
+ name = "${var.project_name}-${var.environment}-rds-password"
+ recovery_window_in_days = var.deletion_protection ? 30 : 0
+
+ tags = var.tags
+}
+
+resource "aws_secretsmanager_secret_version" "rds_password" {
+ secret_id = aws_secretsmanager_secret.rds_password.id
+ secret_string = jsonencode({
+ username = var.master_username
+ password = random_password.rds.result
+ engine = "postgres"
+ host = aws_db_instance.main.address
+ port = aws_db_instance.main.port
+ dbname = var.database_name
+ })
+}
+
+# RDS Instance
+resource "aws_db_instance" "main" {
+ identifier = "${var.project_name}-${var.environment}-postgres"
+ engine = "postgres"
+ engine_version = var.engine_version
+ instance_class = var.instance_class
+
+ allocated_storage = var.allocated_storage
+ max_allocated_storage = var.max_allocated_storage
+ storage_type = "gp3"
+ storage_encrypted = true
+ iops = 3000
+
+ db_name = var.database_name
+ username = var.master_username
+ password = random_password.rds.result
+
+ db_subnet_group_name = aws_db_subnet_group.main.name
+ parameter_group_name = aws_db_parameter_group.main.name
+ vpc_security_group_ids = var.security_group_ids
+
+ multi_az = var.multi_az
+ publicly_accessible = false
+ deletion_protection = var.deletion_protection
+ skip_final_snapshot = var.skip_final_snapshot
+ final_snapshot_identifier = var.skip_final_snapshot ? null : "${var.project_name}-${var.environment}-final-snapshot-${formatdate("YYYY-MM-DD-hhmm", timestamp())}"
+
+ backup_retention_period = var.backup_retention_period
+ backup_window = var.backup_window
+ maintenance_window = var.maintenance_window
+
+ enabled_cloudwatch_logs_exports = var.enabled_cloudwatch_logs_exports
+
+ performance_insights_enabled = true
+ performance_insights_retention_period = 7
+
+ auto_minor_version_upgrade = true
+ copy_tags_to_snapshot = true
+
+ tags = merge(var.tags, {
+ Name = "${var.project_name}-${var.environment}-postgres"
+ })
+}
+
+# CloudWatch Alarms
+resource "aws_cloudwatch_metric_alarm" "database_cpu" {
+ alarm_name = "${var.project_name}-${var.environment}-rds-cpu"
+ comparison_operator = "GreaterThanThreshold"
+ evaluation_periods = "2"
+ metric_name = "CPUUtilization"
+ namespace = "AWS/RDS"
+ period = "300"
+ statistic = "Average"
+ threshold = "80"
+ alarm_description = "This metric monitors RDS CPU utilization"
+
+ dimensions = {
+ DBInstanceIdentifier = aws_db_instance.main.id
+ }
+
+ tags = var.tags
+}
+
+resource "aws_cloudwatch_metric_alarm" "database_storage" {
+ alarm_name = "${var.project_name}-${var.environment}-rds-storage"
+ comparison_operator = "LessThanThreshold"
+ evaluation_periods = "1"
+ metric_name = "FreeStorageSpace"
+ namespace = "AWS/RDS"
+ period = "300"
+ statistic = "Average"
+ threshold = "10737418240" # 10 GB in bytes
+ alarm_description = "This metric monitors RDS free storage space"
+
+ dimensions = {
+ DBInstanceIdentifier = aws_db_instance.main.id
+ }
+
+ tags = var.tags
+}
diff --git a/terraform/modules/rds/outputs.tf b/terraform/modules/rds/outputs.tf
new file mode 100644
index 0000000..74f9c18
--- /dev/null
+++ b/terraform/modules/rds/outputs.tf
@@ -0,0 +1,30 @@
+output "endpoint" {
+ description = "RDS endpoint"
+ value = aws_db_instance.main.endpoint
+}
+
+output "address" {
+ description = "RDS address"
+ value = aws_db_instance.main.address
+}
+
+output "port" {
+ description = "RDS port"
+ value = aws_db_instance.main.port
+}
+
+output "database_name" {
+ description = "Database name"
+ value = aws_db_instance.main.db_name
+}
+
+output "arn" {
+ description = "RDS ARN"
+ value = aws_db_instance.main.arn
+}
+
+output "password_secret_arn" {
+ description = "ARN of the secret containing RDS password"
+ value = aws_secretsmanager_secret.rds_password.arn
+ sensitive = true
+}
diff --git a/terraform/modules/rds/variables.tf b/terraform/modules/rds/variables.tf
new file mode 100644
index 0000000..e9ff79e
--- /dev/null
+++ b/terraform/modules/rds/variables.tf
@@ -0,0 +1,89 @@
+variable "project_name" {
+ type = string
+}
+
+variable "environment" {
+ type = string
+}
+
+variable "vpc_id" {
+ type = string
+}
+
+variable "database_subnet_ids" {
+ type = list(string)
+}
+
+variable "security_group_ids" {
+ type = list(string)
+}
+
+variable "instance_class" {
+ type = string
+ default = "db.t3.medium"
+}
+
+variable "allocated_storage" {
+ type = number
+ default = 100
+}
+
+variable "max_allocated_storage" {
+ type = number
+ default = 500
+}
+
+variable "engine_version" {
+ type = string
+ default = "15.3"
+}
+
+variable "database_name" {
+ type = string
+ default = "lmsdb"
+}
+
+variable "master_username" {
+ type = string
+ default = "lmsadmin"
+}
+
+variable "multi_az" {
+ type = bool
+ default = true
+}
+
+variable "deletion_protection" {
+ type = bool
+ default = true
+}
+
+variable "skip_final_snapshot" {
+ type = bool
+ default = false
+}
+
+variable "backup_retention_period" {
+ type = number
+ default = 7
+}
+
+variable "backup_window" {
+ type = string
+ default = "03:00-04:00"
+}
+
+variable "maintenance_window" {
+ type = string
+ default = "sun:04:00-sun:05:00"
+}
+
+variable "enabled_cloudwatch_logs_exports" {
+ type = list(string)
+ default = ["postgresql", "upgrade"]
+}
+
+variable "tags" {
+ type = map(string)
+ default = {}
+}
diff --git a/terraform/modules/route53/main.tf b/terraform/modules/route53/main.tf
new file mode 100644
index 0000000..d3bd64f
--- /dev/null
+++ b/terraform/modules/route53/main.tf
@@ -0,0 +1,31 @@
+# Route53 Hosted Zone
+resource "aws_route53_zone" "main" {
+ name = var.domain_name
+ tags = var.tags
+}
+
+# A Record pointing to ALB or CloudFront
+resource "aws_route53_record" "main" {
+ zone_id = aws_route53_zone.main.zone_id
+ name = var.domain_name
+ type = "A"
+
+ alias {
+ name = var.use_cloudfront ? var.cloudfront_domain_name : var.alb_dns_name
+ zone_id = var.use_cloudfront ? var.cloudfront_zone_id : var.alb_zone_id
+ evaluate_target_health = true
+ }
+}
+
+# WWW Record
+resource "aws_route53_record" "www" {
+ zone_id = aws_route53_zone.main.zone_id
+ name = "www.${var.domain_name}"
+ type = "A"
+
+ alias {
+ name = var.use_cloudfront ? var.cloudfront_domain_name : var.alb_dns_name
+ zone_id = var.use_cloudfront ? var.cloudfront_zone_id : var.alb_zone_id
+ evaluate_target_health = true
+ }
+}
diff --git a/terraform/modules/route53/outputs.tf b/terraform/modules/route53/outputs.tf
new file mode 100644
index 0000000..c46129d
--- /dev/null
+++ b/terraform/modules/route53/outputs.tf
@@ -0,0 +1,2 @@
+output "zone_id" { value = aws_route53_zone.main.zone_id }
+output "name_servers" { value = aws_route53_zone.main.name_servers }
diff --git a/terraform/modules/route53/variables.tf b/terraform/modules/route53/variables.tf
new file mode 100644
index 0000000..44968f5
--- /dev/null
+++ b/terraform/modules/route53/variables.tf
@@ -0,0 +1,7 @@
+variable "domain_name" { type = string }
+variable "alb_dns_name" { type = string }
+variable "alb_zone_id" { type = string }
+variable "cloudfront_domain_name" { type = string; default = "" }
+variable "cloudfront_zone_id" { type = string; default = "" }
+variable "use_cloudfront" { type = bool; default = false }
+variable "tags" { type = map(string); default = {} }
diff --git a/terraform/modules/s3/main.tf b/terraform/modules/s3/main.tf
new file mode 100644
index 0000000..c10814c
--- /dev/null
+++ b/terraform/modules/s3/main.tf
@@ -0,0 +1,114 @@
+# S3 Bucket for Static Assets
+resource "aws_s3_bucket" "static_assets" {
+ bucket = "${var.project_name}-${var.environment}-static-assets-${data.aws_caller_identity.current.account_id}"
+ tags = merge(var.tags, { Name = "${var.project_name}-${var.environment}-static-assets" })
+}
+
+resource "aws_s3_bucket_versioning" "static_assets" {
+ bucket = aws_s3_bucket.static_assets.id
+ versioning_configuration {
+ status = var.enable_versioning ? "Enabled" : "Disabled"
+ }
+}
+
+resource "aws_s3_bucket_server_side_encryption_configuration" "static_assets" {
+ bucket = aws_s3_bucket.static_assets.id
+ rule {
+ apply_server_side_encryption_by_default {
+ sse_algorithm = "AES256"
+ }
+ }
+}
+
+resource "aws_s3_bucket_public_access_block" "static_assets" {
+ bucket = aws_s3_bucket.static_assets.id
+ block_public_acls = true
+ block_public_policy = true
+ ignore_public_acls = true
+ restrict_public_buckets = true
+}
+
+resource "aws_s3_bucket_cors_configuration" "static_assets" {
+ bucket = aws_s3_bucket.static_assets.id
+
+ cors_rule {
+ allowed_headers = ["*"]
+ allowed_methods = ["GET", "HEAD"]
+ allowed_origins = ["*"]
+ max_age_seconds = 3000
+ }
+}
+
+resource "aws_s3_bucket_lifecycle_configuration" "static_assets" {
+ count = var.enable_lifecycle_rules ? 1 : 0
+ bucket = aws_s3_bucket.static_assets.id
+
+ rule {
+ id = "transition-old-versions"
+ status = "Enabled"
+
+ transition {
+ days = var.lifecycle_glacier_days
+ storage_class = "GLACIER"
+ }
+
+ expiration {
+ days = var.lifecycle_expiration_days
+ }
+ }
+}
+
+# S3 Bucket for Backups
+resource "aws_s3_bucket" "backups" {
+ bucket = "${var.project_name}-${var.environment}-backups-${data.aws_caller_identity.current.account_id}"
+ tags = merge(var.tags, { Name = "${var.project_name}-${var.environment}-backups" })
+}
+
+resource "aws_s3_bucket_versioning" "backups" {
+ bucket = aws_s3_bucket.backups.id
+ versioning_configuration {
+ status = "Enabled"
+ }
+}
+
+resource "aws_s3_bucket_server_side_encryption_configuration" "backups" {
+ bucket = aws_s3_bucket.backups.id
+ rule {
+ apply_server_side_encryption_by_default {
+ sse_algorithm = "AES256"
+ }
+ }
+}
+
+resource "aws_s3_bucket_public_access_block" "backups" {
+ bucket = aws_s3_bucket.backups.id
+ block_public_acls = true
+ block_public_policy = true
+ ignore_public_acls = true
+ restrict_public_buckets = true
+}
+
+resource "aws_s3_bucket_lifecycle_configuration" "backups" {
+ bucket = aws_s3_bucket.backups.id
+
+ rule {
+ id = "archive-old-backups"
+ status = "Enabled"
+
+ transition {
+ days = 30
+ storage_class = "GLACIER"
+ }
+
+ transition {
+ days = 90
+ storage_class = "DEEP_ARCHIVE"
+ }
+
+ expiration {
+ days = 365
+ }
+ }
+}
+
+data "aws_caller_identity" "current" {}
diff --git a/terraform/modules/s3/outputs.tf b/terraform/modules/s3/outputs.tf
new file mode 100644
index 0000000..a0c5eb5
--- /dev/null
+++ b/terraform/modules/s3/outputs.tf
@@ -0,0 +1,5 @@
+output "static_assets_bucket" { value = aws_s3_bucket.static_assets.id }
+output "static_assets_bucket_arn" { value = aws_s3_bucket.static_assets.arn }
+output "backups_bucket" { value = aws_s3_bucket.backups.id }
+output "backups_bucket_arn" { value = aws_s3_bucket.backups.arn }
+output "bucket_regional_domain_name" { value = aws_s3_bucket.static_assets.bucket_regional_domain_name }
diff --git a/terraform/modules/s3/variables.tf b/terraform/modules/s3/variables.tf
new file mode 100644
index 0000000..2358615
--- /dev/null
+++ b/terraform/modules/s3/variables.tf
@@ -0,0 +1,9 @@
+variable "project_name" { type = string }
+variable "environment" { type = string }
+variable "enable_versioning" { type = bool; default = true }
+variable "enable_lifecycle_rules" { type = bool; default = true }
+variable "lifecycle_glacier_days" { type = number; default = 90 }
+variable "lifecycle_expiration_days" { type = number; default = 365 }
+variable "enable_replication" { type = bool; default = false }
+variable "replication_region" { type = string; default = "us-west-2" }
+variable "tags" { type = map(string); default = {} }
diff --git a/terraform/modules/security/main.tf b/terraform/modules/security/main.tf
new file mode 100644
index 0000000..6e604a9
--- /dev/null
+++ b/terraform/modules/security/main.tf
@@ -0,0 +1,274 @@
+# ALB Security Group
+resource "aws_security_group" "alb" {
+ name_prefix = "${var.project_name}-${var.environment}-alb-"
+ description = "Security group for Application Load Balancer"
+ vpc_id = var.vpc_id
+
+ ingress {
+ from_port = 80
+ to_port = 80
+ protocol = "tcp"
+ cidr_blocks = var.alb_ingress_cidrs
+ description = "Allow HTTP"
+ }
+
+ ingress {
+ from_port = 443
+ to_port = 443
+ protocol = "tcp"
+ cidr_blocks = var.alb_ingress_cidrs
+ description = "Allow HTTPS"
+ }
+
+ egress {
+ from_port = 0
+ to_port = 0
+ protocol = "-1"
+ cidr_blocks = ["0.0.0.0/0"]
+ description = "Allow all outbound"
+ }
+
+ tags = merge(var.tags, {
+ Name = "${var.project_name}-${var.environment}-alb-sg"
+ })
+
+ lifecycle {
+ create_before_destroy = true
+ }
+}
+
+# ECS Security Group
+resource "aws_security_group" "ecs" {
+ name_prefix = "${var.project_name}-${var.environment}-ecs-"
+ description = "Security group for ECS tasks"
+ vpc_id = var.vpc_id
+
+ ingress {
+ from_port = 0
+ to_port = 65535
+ protocol = "tcp"
+ security_groups = [aws_security_group.alb.id]
+ description = "Allow traffic from ALB"
+ }
+
+ egress {
+ from_port = 0
+ to_port = 0
+ protocol = "-1"
+ cidr_blocks = ["0.0.0.0/0"]
+ description = "Allow all outbound"
+ }
+
+ tags = merge(var.tags, {
+ Name = "${var.project_name}-${var.environment}-ecs-sg"
+ })
+
+ lifecycle {
+ create_before_destroy = true
+ }
+}
+
+# RDS Security Group
+resource "aws_security_group" "rds" {
+ name_prefix = "${var.project_name}-${var.environment}-rds-"
+ description = "Security group for RDS PostgreSQL"
+ vpc_id = var.vpc_id
+
+ ingress {
+ from_port = 5432
+ to_port = 5432
+ protocol = "tcp"
+ security_groups = [aws_security_group.ecs.id]
+ description = "Allow PostgreSQL from ECS"
+ }
+
+ egress {
+ from_port = 0
+ to_port = 0
+ protocol = "-1"
+ cidr_blocks = ["0.0.0.0/0"]
+ description = "Allow all outbound"
+ }
+
+ tags = merge(var.tags, {
+ Name = "${var.project_name}-${var.environment}-rds-sg"
+ })
+
+ lifecycle {
+ create_before_destroy = true
+ }
+}
+
+# Redis Security Group
+resource "aws_security_group" "redis" {
+ name_prefix = "${var.project_name}-${var.environment}-redis-"
+ description = "Security group for ElastiCache Redis"
+ vpc_id = var.vpc_id
+
+ ingress {
+ from_port = 6379
+ to_port = 6379
+ protocol = "tcp"
+ security_groups = [aws_security_group.ecs.id]
+ description = "Allow Redis from ECS"
+ }
+
+ egress {
+ from_port = 0
+ to_port = 0
+ protocol = "-1"
+ cidr_blocks = ["0.0.0.0/0"]
+ description = "Allow all outbound"
+ }
+
+ tags = merge(var.tags, {
+ Name = "${var.project_name}-${var.environment}-redis-sg"
+ })
+
+ lifecycle {
+ create_before_destroy = true
+ }
+}
+
+# DocumentDB Security Group
+resource "aws_security_group" "documentdb" {
+ name_prefix = "${var.project_name}-${var.environment}-documentdb-"
+ description = "Security group for DocumentDB"
+ vpc_id = var.vpc_id
+
+ ingress {
+ from_port = 27017
+ to_port = 27017
+ protocol = "tcp"
+ security_groups = [aws_security_group.ecs.id]
+ description = "Allow MongoDB from ECS"
+ }
+
+ egress {
+ from_port = 0
+ to_port = 0
+ protocol = "-1"
+ cidr_blocks = ["0.0.0.0/0"]
+ description = "Allow all outbound"
+ }
+
+ tags = merge(var.tags, {
+ Name = "${var.project_name}-${var.environment}-documentdb-sg"
+ })
+
+ lifecycle {
+ create_before_destroy = true
+ }
+}
+
+# WAF Web ACL
+resource "aws_wafv2_web_acl" "main" {
+ count = var.enable_waf ? 1 : 0
+
+ name = "${var.project_name}-${var.environment}-waf"
+ scope = "REGIONAL"
+
+ default_action {
+ allow {}
+ }
+
+ # Rate limiting rule
+ rule {
+ name = "rate-limit"
+ priority = 1
+
+ action {
+ block {}
+ }
+
+ statement {
+ rate_based_statement {
+ limit = 2000
+ aggregate_key_type = "IP"
+ }
+ }
+
+ visibility_config {
+ cloudwatch_metrics_enabled = true
+ metric_name = "RateLimitRule"
+ sampled_requests_enabled = true
+ }
+ }
+
+ # AWS Managed Rules - Common Rule Set
+ rule {
+ name = "aws-managed-common-rules"
+ priority = 2
+
+ override_action {
+ none {}
+ }
+
+ statement {
+ managed_rule_group_statement {
+ name = "AWSManagedRulesCommonRuleSet"
+ vendor_name = "AWS"
+ }
+ }
+
+ visibility_config {
+ cloudwatch_metrics_enabled = true
+ metric_name = "AWSManagedCommonRules"
+ sampled_requests_enabled = true
+ }
+ }
+
+ # AWS Managed Rules - Known Bad Inputs
+ rule {
+ name = "aws-managed-known-bad-inputs"
+ priority = 3
+
+ override_action {
+ none {}
+ }
+
+ statement {
+ managed_rule_group_statement {
+ name = "AWSManagedRulesKnownBadInputsRuleSet"
+ vendor_name = "AWS"
+ }
+ }
+
+ visibility_config {
+ cloudwatch_metrics_enabled = true
+ metric_name = "AWSManagedKnownBadInputs"
+ sampled_requests_enabled = true
+ }
+ }
+
+ # SQL Injection Protection
+ rule {
+ name = "aws-managed-sql-injection"
+ priority = 4
+
+ override_action {
+ none {}
+ }
+
+ statement {
+ managed_rule_group_statement {
+ name = "AWSManagedRulesSQLiRuleSet"
+ vendor_name = "AWS"
+ }
+ }
+
+ visibility_config {
+ cloudwatch_metrics_enabled = true
+ metric_name = "AWSManagedSQLInjection"
+ sampled_requests_enabled = true
+ }
+ }
+
+ visibility_config {
+ cloudwatch_metrics_enabled = true
+ metric_name = "${var.project_name}-${var.environment}-waf"
+ sampled_requests_enabled = true
+ }
+
+ tags = var.tags
+}
diff --git a/terraform/modules/security/outputs.tf b/terraform/modules/security/outputs.tf
new file mode 100644
index 0000000..4b19432
--- /dev/null
+++ b/terraform/modules/security/outputs.tf
@@ -0,0 +1,34 @@
+output "alb_security_group_id" {
+ description = "ID of ALB security group"
+ value = aws_security_group.alb.id
+}
+
+output "ecs_security_group_id" {
+ description = "ID of ECS security group"
+ value = aws_security_group.ecs.id
+}
+
+output "rds_security_group_id" {
+ description = "ID of RDS security group"
+ value = aws_security_group.rds.id
+}
+
+output "redis_security_group_id" {
+ description = "ID of Redis security group"
+ value = aws_security_group.redis.id
+}
+
+output "documentdb_security_group_id" {
+ description = "ID of DocumentDB security group"
+ value = aws_security_group.documentdb.id
+}
+
+output "waf_web_acl_id" {
+ description = "ID of WAF Web ACL"
+ value = var.enable_waf ? aws_wafv2_web_acl.main[0].id : null
+}
+
+output "waf_web_acl_arn" {
+ description = "ARN of WAF Web ACL"
+ value = var.enable_waf ? aws_wafv2_web_acl.main[0].arn : null
+}
diff --git a/terraform/modules/security/variables.tf b/terraform/modules/security/variables.tf
new file mode 100644
index 0000000..1aa9408
--- /dev/null
+++ b/terraform/modules/security/variables.tf
@@ -0,0 +1,32 @@
+variable "project_name" {
+ description = "Name of the project"
+ type = string
+}
+
+variable "environment" {
+ description = "Environment name"
+ type = string
+}
+
+variable "vpc_id" {
+ description = "VPC ID"
+ type = string
+}
+
+variable "alb_ingress_cidrs" {
+ description = "CIDR blocks allowed to access ALB"
+ type = list(string)
+ default = ["0.0.0.0/0"]
+}
+
+variable "enable_waf" {
+ description = "Enable AWS WAF"
+ type = bool
+ default = true
+}
+
+variable "tags" {
+ description = "Tags to apply to resources"
+ type = map(string)
+ default = {}
+}
diff --git a/terraform/modules/vpc/main.tf b/terraform/modules/vpc/main.tf
new file mode 100644
index 0000000..e6ce23c
--- /dev/null
+++ b/terraform/modules/vpc/main.tf
@@ -0,0 +1,227 @@
+# VPC
+resource "aws_vpc" "main" {
+ cidr_block = var.vpc_cidr
+ enable_dns_hostnames = var.enable_dns_hostnames
+ enable_dns_support = var.enable_dns_support
+
+ tags = merge(var.tags, {
+ Name = "${var.project_name}-${var.environment}-vpc"
+ })
+}
+
+# Internet Gateway
+resource "aws_internet_gateway" "main" {
+ vpc_id = aws_vpc.main.id
+
+ tags = merge(var.tags, {
+ Name = "${var.project_name}-${var.environment}-igw"
+ })
+}
+
+# Public Subnets
+resource "aws_subnet" "public" {
+ count = length(var.availability_zones)
+ vpc_id = aws_vpc.main.id
+ cidr_block = var.public_subnet_cidrs[count.index]
+ availability_zone = var.availability_zones[count.index]
+ map_public_ip_on_launch = true
+
+ tags = merge(var.tags, {
+ Name = "${var.project_name}-${var.environment}-public-${var.availability_zones[count.index]}"
+ Type = "public"
+ })
+}
+
+# Private Subnets
+resource "aws_subnet" "private" {
+ count = length(var.availability_zones)
+ vpc_id = aws_vpc.main.id
+ cidr_block = var.private_subnet_cidrs[count.index]
+ availability_zone = var.availability_zones[count.index]
+
+ tags = merge(var.tags, {
+ Name = "${var.project_name}-${var.environment}-private-${var.availability_zones[count.index]}"
+ Type = "private"
+ })
+}
+
+# Database Subnets
+resource "aws_subnet" "database" {
+ count = length(var.availability_zones)
+ vpc_id = aws_vpc.main.id
+ cidr_block = var.database_subnet_cidrs[count.index]
+ availability_zone = var.availability_zones[count.index]
+
+ tags = merge(var.tags, {
+ Name = "${var.project_name}-${var.environment}-database-${var.availability_zones[count.index]}"
+ Type = "database"
+ })
+}
+
+# Elastic IPs for NAT Gateways
+resource "aws_eip" "nat" {
+ count = var.enable_nat_gateway ? (var.single_nat_gateway ? 1 : length(var.availability_zones)) : 0
+ domain = "vpc"
+
+ tags = merge(var.tags, {
+ Name = "${var.project_name}-${var.environment}-nat-eip-${count.index + 1}"
+ })
+
+ depends_on = [aws_internet_gateway.main]
+}
+
+# NAT Gateways
+resource "aws_nat_gateway" "main" {
+ count = var.enable_nat_gateway ? (var.single_nat_gateway ? 1 : length(var.availability_zones)) : 0
+ allocation_id = aws_eip.nat[count.index].id
+ subnet_id = aws_subnet.public[count.index].id
+
+ tags = merge(var.tags, {
+ Name = "${var.project_name}-${var.environment}-nat-${count.index + 1}"
+ })
+
+ depends_on = [aws_internet_gateway.main]
+}
+
+# Public Route Table
+resource "aws_route_table" "public" {
+ vpc_id = aws_vpc.main.id
+
+ tags = merge(var.tags, {
+ Name = "${var.project_name}-${var.environment}-public-rt"
+ })
+}
+
+# Public Route
+resource "aws_route" "public" {
+ route_table_id = aws_route_table.public.id
+ destination_cidr_block = "0.0.0.0/0"
+ gateway_id = aws_internet_gateway.main.id
+}
+
+# Public Route Table Associations
+resource "aws_route_table_association" "public" {
+ count = length(var.availability_zones)
+ subnet_id = aws_subnet.public[count.index].id
+ route_table_id = aws_route_table.public.id
+}
+
+# Private Route Tables
+resource "aws_route_table" "private" {
+ count = var.enable_nat_gateway ? length(var.availability_zones) : 0
+ vpc_id = aws_vpc.main.id
+
+ tags = merge(var.tags, {
+ Name = "${var.project_name}-${var.environment}-private-rt-${count.index + 1}"
+ })
+}
+
+# Private Routes
+resource "aws_route" "private" {
+ count = var.enable_nat_gateway ? length(var.availability_zones) : 0
+ route_table_id = aws_route_table.private[count.index].id
+ destination_cidr_block = "0.0.0.0/0"
+ nat_gateway_id = var.single_nat_gateway ? aws_nat_gateway.main[0].id : aws_nat_gateway.main[count.index].id
+}
+
+# Private Route Table Associations
+resource "aws_route_table_association" "private" {
+ count = length(var.availability_zones)
+ subnet_id = aws_subnet.private[count.index].id
+ route_table_id = var.enable_nat_gateway ? aws_route_table.private[count.index].id : aws_route_table.public.id
+}
+
+# Database Route Table
+resource "aws_route_table" "database" {
+ vpc_id = aws_vpc.main.id
+
+ tags = merge(var.tags, {
+ Name = "${var.project_name}-${var.environment}-database-rt"
+ })
+}
+
+# Database Route Table Associations
+resource "aws_route_table_association" "database" {
+ count = length(var.availability_zones)
+ subnet_id = aws_subnet.database[count.index].id
+ route_table_id = aws_route_table.database.id
+}
+
+# VPC Flow Logs
+resource "aws_flow_log" "main" {
+ count = var.enable_flow_logs ? 1 : 0
+ iam_role_arn = aws_iam_role.flow_logs[0].arn
+ log_destination = aws_cloudwatch_log_group.flow_logs[0].arn
+ traffic_type = "ALL"
+ vpc_id = aws_vpc.main.id
+ max_aggregation_interval = 60
+
+ tags = merge(var.tags, {
+ Name = "${var.project_name}-${var.environment}-vpc-flow-logs"
+ })
+}
+
+resource "aws_cloudwatch_log_group" "flow_logs" {
+ count = var.enable_flow_logs ? 1 : 0
+ name = "/aws/vpc/${var.project_name}-${var.environment}"
+ retention_in_days = 30
+
+ tags = var.tags
+}
+
+resource "aws_iam_role" "flow_logs" {
+ count = var.enable_flow_logs ? 1 : 0
+ name = "${var.project_name}-${var.environment}-vpc-flow-logs"
+
+ assume_role_policy = jsonencode({
+ Version = "2012-10-17"
+ Statement = [{
+ Action = "sts:AssumeRole"
+ Effect = "Allow"
+ Principal = {
+ Service = "vpc-flow-logs.amazonaws.com"
+ }
+ }]
+ })
+
+ tags = var.tags
+}
+
+resource "aws_iam_role_policy" "flow_logs" {
+ count = var.enable_flow_logs ? 1 : 0
+ name = "flow-logs-policy"
+ role = aws_iam_role.flow_logs[0].id
+
+ policy = jsonencode({
+ Version = "2012-10-17"
+ Statement = [{
+ Action = [
+ "logs:CreateLogGroup",
+ "logs:CreateLogStream",
+ "logs:PutLogEvents",
+ "logs:DescribeLogGroups",
+ "logs:DescribeLogStreams"
+ ]
+ Effect = "Allow"
+ Resource = "*"
+ }]
+ })
+}
+
+# VPC Endpoints for S3
+resource "aws_vpc_endpoint" "s3" {
+ vpc_id = aws_vpc.main.id
+ service_name = "com.amazonaws.${data.aws_region.current.name}.s3"
+
+ route_table_ids = concat(
+ [aws_route_table.public.id],
+ var.enable_nat_gateway ? aws_route_table.private[*].id : [],
+ [aws_route_table.database.id]
+ )
+
+ tags = merge(var.tags, {
+ Name = "${var.project_name}-${var.environment}-s3-endpoint"
+ })
+}
+
+data "aws_region" "current" {}
diff --git a/terraform/modules/vpc/outputs.tf b/terraform/modules/vpc/outputs.tf
new file mode 100644
index 0000000..4ed7686
--- /dev/null
+++ b/terraform/modules/vpc/outputs.tf
@@ -0,0 +1,34 @@
+output "vpc_id" {
+ description = "ID of the VPC"
+ value = aws_vpc.main.id
+}
+
+output "vpc_cidr" {
+ description = "CIDR block of the VPC"
+ value = aws_vpc.main.cidr_block
+}
+
+output "public_subnet_ids" {
+ description = "IDs of public subnets"
+ value = aws_subnet.public[*].id
+}
+
+output "private_subnet_ids" {
+ description = "IDs of private subnets"
+ value = aws_subnet.private[*].id
+}
+
+output "database_subnet_ids" {
+ description = "IDs of database subnets"
+ value = aws_subnet.database[*].id
+}
+
+output "nat_gateway_ids" {
+ description = "IDs of NAT Gateways"
+ value = aws_nat_gateway.main[*].id
+}
+
+output "internet_gateway_id" {
+ description = "ID of the Internet Gateway"
+ value = aws_internet_gateway.main.id
+}
diff --git a/terraform/modules/vpc/variables.tf b/terraform/modules/vpc/variables.tf
new file mode 100644
index 0000000..2ddb42d
--- /dev/null
+++ b/terraform/modules/vpc/variables.tf
@@ -0,0 +1,70 @@
+variable "project_name" {
+ description = "Name of the project"
+ type = string
+}
+
+variable "environment" {
+ description = "Environment name"
+ type = string
+}
+
+variable "vpc_cidr" {
+ description = "CIDR block for VPC"
+ type = string
+}
+
+variable "availability_zones" {
+ description = "List of availability zones"
+ type = list(string)
+}
+
+variable "public_subnet_cidrs" {
+ description = "CIDR blocks for public subnets"
+ type = list(string)
+}
+
+variable "private_subnet_cidrs" {
+ description = "CIDR blocks for private subnets"
+ type = list(string)
+}
+
+variable "database_subnet_cidrs" {
+ description = "CIDR blocks for database subnets"
+ type = list(string)
+}
+
+variable "enable_nat_gateway" {
+ description = "Enable NAT Gateway for private subnets"
+ type = bool
+ default = true
+}
+
+variable "single_nat_gateway" {
+ description = "Use single NAT Gateway for all private subnets"
+ type = bool
+ default = false
+}
+
+variable "enable_dns_hostnames" {
+ description = "Enable DNS hostnames in the VPC"
+ type = bool
+ default = true
+}
+
+variable "enable_dns_support" {
+ description = "Enable DNS support in the VPC"
+ type = bool
+ default = true
+}
+
+variable "enable_flow_logs" {
+ description = "Enable VPC Flow Logs"
+ type = bool
+ default = true
+}
+
+variable "tags" {
+ description = "Tags to apply to resources"
+ type = map(string)
+ default = {}
+}
diff --git a/terraform/outputs.tf b/terraform/outputs.tf
new file mode 100644
index 0000000..be698cc
--- /dev/null
+++ b/terraform/outputs.tf
@@ -0,0 +1,304 @@
+# ============================================================================
+# Outputs for Learning Management System Terraform Configuration
+# ============================================================================
+
+# ----------------------------------------------------------------------------
+# VPC Outputs
+# ----------------------------------------------------------------------------
+
+output "vpc_id" {
+ description = "ID of the VPC"
+ value = module.vpc.vpc_id
+}
+
+output "vpc_cidr" {
+ description = "CIDR block of the VPC"
+ value = module.vpc.vpc_cidr
+}
+
+output "public_subnet_ids" {
+ description = "IDs of public subnets"
+ value = module.vpc.public_subnet_ids
+}
+
+output "private_subnet_ids" {
+ description = "IDs of private subnets"
+ value = module.vpc.private_subnet_ids
+}
+
+output "database_subnet_ids" {
+ description = "IDs of database subnets"
+ value = module.vpc.database_subnet_ids
+}
+
+# ----------------------------------------------------------------------------
+# ECR Outputs
+# ----------------------------------------------------------------------------
+
+output "ecr_backend_repository_url" {
+ description = "URL of the backend ECR repository"
+ value = module.ecr.backend_repository_url
+}
+
+output "ecr_frontend_repository_url" {
+ description = "URL of the frontend ECR repository"
+ value = module.ecr.frontend_repository_url
+}
+
+output "ecr_backend_repository_arn" {
+ description = "ARN of the backend ECR repository"
+ value = module.ecr.backend_repository_arn
+}
+
+output "ecr_frontend_repository_arn" {
+ description = "ARN of the frontend ECR repository"
+ value = module.ecr.frontend_repository_arn
+}
+
+# ----------------------------------------------------------------------------
+# RDS Outputs
+# ----------------------------------------------------------------------------
+
+output "rds_endpoint" {
+ description = "RDS instance endpoint"
+ value = module.rds.endpoint
+ sensitive = true
+}
+
+output "rds_database_name" {
+ description = "Name of the RDS database"
+ value = module.rds.database_name
+}
+
+output "rds_arn" {
+ description = "ARN of the RDS instance"
+ value = module.rds.arn
+}
+
+output "rds_security_group_id" {
+ description = "Security group ID for RDS"
+ value = module.security.rds_security_group_id
+}
+
+# ----------------------------------------------------------------------------
+# ElastiCache Outputs
+# ----------------------------------------------------------------------------
+
+output "redis_endpoint" {
+ description = "Redis cluster endpoint"
+ value = module.elasticache.endpoint
+ sensitive = true
+}
+
+output "redis_port" {
+ description = "Redis port"
+ value = module.elasticache.port
+}
+
+output "redis_security_group_id" {
+ description = "Security group ID for Redis"
+ value = module.security.redis_security_group_id
+}
+
+# ----------------------------------------------------------------------------
+# DocumentDB Outputs
+# ----------------------------------------------------------------------------
+
+output "documentdb_endpoint" {
+ description = "DocumentDB cluster endpoint"
+ value = module.documentdb.endpoint
+ sensitive = true
+}
+
+output "documentdb_port" {
+ description = "DocumentDB port"
+ value = module.documentdb.port
+}
+
+output "documentdb_cluster_id" {
+ description = "DocumentDB cluster ID"
+ value = module.documentdb.cluster_id
+}
+
+# ----------------------------------------------------------------------------
+# ALB Outputs
+# ----------------------------------------------------------------------------
+
+output "alb_dns_name" {
+ description = "DNS name of the Application Load Balancer"
+ value = module.alb.dns_name
+}
+
+output "alb_arn" {
+ description = "ARN of the Application Load Balancer"
+ value = module.alb.arn
+}
+
+output "alb_zone_id" {
+ description = "Zone ID of the Application Load Balancer"
+ value = module.alb.zone_id
+}
+
+output "backend_target_group_arn" {
+ description = "ARN of the backend target group"
+ value = module.alb.backend_target_group_arn
+}
+
+output "frontend_target_group_arn" {
+ description = "ARN of the frontend target group"
+ value = module.alb.frontend_target_group_arn
+}
+
+# ----------------------------------------------------------------------------
+# ECS Outputs
+# ----------------------------------------------------------------------------
+
+output "ecs_cluster_id" {
+ description = "ID of the ECS cluster"
+ value = module.ecs.cluster_id
+}
+
+output "ecs_cluster_name" {
+ description = "Name of the ECS cluster"
+ value = module.ecs.cluster_name
+}
+
+output "ecs_backend_service_name" {
+ description = "Name of the backend ECS service"
+ value = module.ecs.backend_service_name
+}
+
+output "ecs_frontend_service_name" {
+ description = "Name of the frontend ECS service"
+ value = module.ecs.frontend_service_name
+}
+
+output "ecs_backend_task_definition_arn" {
+ description = "ARN of the backend task definition"
+ value = module.ecs.backend_task_definition_arn
+}
+
+output "ecs_frontend_task_definition_arn" {
+ description = "ARN of the frontend task definition"
+ value = module.ecs.frontend_task_definition_arn
+}
+
+# ----------------------------------------------------------------------------
+# S3 Outputs
+# ----------------------------------------------------------------------------
+
+output "s3_static_assets_bucket" {
+ description = "Name of the S3 bucket for static assets"
+ value = module.s3.static_assets_bucket
+}
+
+output "s3_backups_bucket" {
+ description = "Name of the S3 bucket for backups"
+ value = module.s3.backups_bucket
+}
+
+output "s3_bucket_regional_domain_name" {
+ description = "Regional domain name of the S3 bucket"
+ value = module.s3.bucket_regional_domain_name
+}
+
+# ----------------------------------------------------------------------------
+# CloudFront Outputs (if enabled)
+# ----------------------------------------------------------------------------
+
+output "cloudfront_distribution_id" {
+ description = "ID of the CloudFront distribution"
+ value = var.enable_cloudfront ? module.cloudfront[0].distribution_id : null
+}
+
+output "cloudfront_domain_name" {
+ description = "Domain name of the CloudFront distribution"
+ value = var.enable_cloudfront ? module.cloudfront[0].domain_name : null
+}
+
+# ----------------------------------------------------------------------------
+# Route53 Outputs (if enabled)
+# ----------------------------------------------------------------------------
+
+output "route53_zone_id" {
+ description = "ID of the Route53 hosted zone"
+ value = var.create_route53_zone ? module.route53[0].zone_id : null
+}
+
+output "route53_name_servers" {
+ description = "Name servers for the Route53 hosted zone"
+ value = var.create_route53_zone ? module.route53[0].name_servers : null
+}
+
+# ----------------------------------------------------------------------------
+# Application URLs
+# ----------------------------------------------------------------------------
+
+output "application_url" {
+ description = "URL to access the application"
+ value = var.enable_cloudfront && var.create_route53_zone ? "https://${var.domain_name}" : var.create_route53_zone ? "https://${var.domain_name}" : "http://${module.alb.dns_name}"
+}
+
+output "api_url" {
+ description = "URL to access the API"
+ value = var.enable_cloudfront && var.create_route53_zone ? "https://${var.domain_name}/api" : var.create_route53_zone ? "https://${var.domain_name}/api" : "http://${module.alb.dns_name}/api"
+}
+
+# ----------------------------------------------------------------------------
+# Connection Information
+# ----------------------------------------------------------------------------
+
+output "connection_info" {
+ description = "Connection information for services"
+ value = {
+ rds_endpoint = module.rds.endpoint
+ redis_endpoint = "${module.elasticache.endpoint}:${module.elasticache.port}"
+ documentdb_endpoint = module.documentdb.endpoint
+ alb_dns = module.alb.dns_name
+ ecr_backend_repo = module.ecr.backend_repository_url
+ ecr_frontend_repo = module.ecr.frontend_repository_url
+ }
+ sensitive = true
+}
+
+# ----------------------------------------------------------------------------
+# Security Group IDs
+# ----------------------------------------------------------------------------
+
+output "security_group_ids" {
+ description = "IDs of all security groups"
+ value = {
+ alb_sg = module.security.alb_security_group_id
+ ecs_sg = module.security.ecs_security_group_id
+ rds_sg = module.security.rds_security_group_id
+ redis_sg = module.security.redis_security_group_id
+ }
+}
+
+# ----------------------------------------------------------------------------
+# Deployment Commands
+# ----------------------------------------------------------------------------
+
+output "deployment_commands" {
+ description = "Useful commands for deployment"
+ value = <<-EOT
+ # Login to ECR
+ aws ecr get-login-password --region ${var.aws_region} | docker login --username AWS --password-stdin ${local.account_id}.dkr.ecr.${var.aws_region}.amazonaws.com
+
+ # Build and push backend
+ docker build -t ${module.ecr.backend_repository_url}:latest ./LMS-Backend
+ docker push ${module.ecr.backend_repository_url}:latest
+
+ # Build and push frontend
+ docker build -t ${module.ecr.frontend_repository_url}:latest ./LMS-Frontend
+ docker push ${module.ecr.frontend_repository_url}:latest
+
+ # Update ECS services
+ aws ecs update-service --cluster ${module.ecs.cluster_name} --service ${module.ecs.backend_service_name} --force-new-deployment
+ aws ecs update-service --cluster ${module.ecs.cluster_name} --service ${module.ecs.frontend_service_name} --force-new-deployment
+
+ # View logs
+ aws logs tail /ecs/${local.name_prefix}/backend --follow
+ aws logs tail /ecs/${local.name_prefix}/frontend --follow
+ EOT
+}
diff --git a/terraform/terraform.tfvars.example b/terraform/terraform.tfvars.example
new file mode 100644
index 0000000..61af95a
--- /dev/null
+++ b/terraform/terraform.tfvars.example
@@ -0,0 +1,107 @@
+# ============================================================================
+# LMS Terraform Configuration Example
+# Copy this file to terraform.tfvars and customize for your environment
+# ============================================================================
+
+# General Configuration
+project_name = "lms"
+environment = "production" # dev, staging, production
+aws_region = "us-east-1"
+
+# Network Configuration
+vpc_cidr = "10.0.0.0/16"
+availability_zones = ["us-east-1a", "us-east-1b", "us-east-1c"]
+public_subnet_cidrs = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"]
+private_subnet_cidrs = ["10.0.11.0/24", "10.0.12.0/24", "10.0.13.0/24"]
+database_subnet_cidrs = ["10.0.21.0/24", "10.0.22.0/24", "10.0.23.0/24"]
+
+# NAT Gateway Configuration
+enable_nat_gateway = true
+single_nat_gateway = false # Set to true to save costs (not recommended for production)
+
+# Security
+alb_ingress_cidrs = ["0.0.0.0/0"] # Restrict this in production
+enable_waf = true
+
+# RDS PostgreSQL Configuration
+rds_instance_class = "db.t3.medium" # Use db.r5.large for production
+rds_allocated_storage = 100
+rds_max_allocated_storage = 500
+rds_engine_version = "15.3"
+rds_database_name = "lmsdb"
+rds_master_username = "lmsadmin"
+rds_multi_az = true
+rds_deletion_protection = true
+
+# ElastiCache Redis Configuration
+redis_node_type = "cache.t3.medium" # Use cache.r5.large for production
+redis_num_cache_nodes = 2
+redis_engine_version = "7.0"
+redis_automatic_failover = true
+redis_multi_az = true
+
+# DocumentDB (MongoDB) Configuration
+documentdb_instance_class = "db.t3.medium" # Use db.r5.large for production
+documentdb_instance_count = 3
+documentdb_engine_version = "5.0.0"
+documentdb_master_username = "lmsadmin"
+documentdb_deletion_protection = true
+documentdb_skip_final_snapshot = false
+
+# ECS Fargate Configuration
+# Backend
+ecs_backend_cpu = 512 # Use 1024-2048 for production
+ecs_backend_memory = 1024 # Use 2048-4096 for production
+ecs_backend_count = 2
+backend_image_tag = "latest"
+
+# Frontend
+ecs_frontend_cpu = 256 # Use 512-1024 for production
+ecs_frontend_memory = 512 # Use 1024-2048 for production
+ecs_frontend_count = 2
+frontend_image_tag = "latest"
+
+# Auto-scaling
+enable_ecs_autoscaling = true
+ecs_autoscaling_min_capacity = 2
+ecs_autoscaling_max_capacity = 10
+ecs_autoscaling_target_cpu = 70
+ecs_autoscaling_target_memory = 80
+
+# ALB Configuration
+alb_enable_deletion_protection = true
+alb_enable_http2 = true
+enable_https = true
+# ssl_certificate_arn = "arn:aws:acm:us-east-1:ACCOUNT:certificate/CERT_ID" # Required for HTTPS
+
+# S3 Configuration
+s3_enable_versioning = true
+s3_enable_lifecycle_rules = true
+s3_lifecycle_glacier_days = 90
+s3_lifecycle_expiration_days = 365
+
+# CloudFront (Optional)
+enable_cloudfront = false
+cloudfront_price_class = "PriceClass_100"
+# cloudfront_certificate_arn = "arn:aws:acm:us-east-1:ACCOUNT:certificate/CERT_ID"
+
+# Route53 (Optional)
+create_route53_zone = false
+# domain_name = "lms.yourdomain.com"
+
+# Monitoring
+enable_monitoring = true
+enable_vpc_flow_logs = true
+ecs_log_retention_days = 30
+
+# Backup Configuration
+enable_backup = true
+backup_retention_days = 7
+
+# Tags
+tags = {
+ Project = "Learning Management System"
+ Team = "DevOps"
+ CostCenter = "Engineering"
+ Compliance = "HIPAA" # Adjust as needed
+}
diff --git a/terraform/variables.tf b/terraform/variables.tf
new file mode 100644
index 0000000..871dd7c
--- /dev/null
+++ b/terraform/variables.tf
@@ -0,0 +1,575 @@
+# ============================================================================
+# Variables for Learning Management System Terraform Configuration
+# ============================================================================
+
+# ----------------------------------------------------------------------------
+# General Configuration
+# ----------------------------------------------------------------------------
+
+variable "project_name" {
+ description = "Name of the project"
+ type = string
+ default = "lms"
+}
+
+variable "environment" {
+ description = "Environment name (dev, staging, production)"
+ type = string
+ default = "production"
+}
+
+variable "aws_region" {
+ description = "AWS region to deploy resources"
+ type = string
+ default = "us-east-1"
+}
+
+variable "tags" {
+ description = "Additional tags to apply to all resources"
+ type = map(string)
+ default = {}
+}
+
+# ----------------------------------------------------------------------------
+# Network Configuration
+# ----------------------------------------------------------------------------
+
+variable "vpc_cidr" {
+ description = "CIDR block for VPC"
+ type = string
+ default = "10.0.0.0/16"
+}
+
+variable "availability_zones" {
+ description = "List of availability zones"
+ type = list(string)
+ default = ["us-east-1a", "us-east-1b", "us-east-1c"]
+}
+
+variable "public_subnet_cidrs" {
+ description = "CIDR blocks for public subnets"
+ type = list(string)
+ default = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"]
+}
+
+variable "private_subnet_cidrs" {
+ description = "CIDR blocks for private subnets"
+ type = list(string)
+ default = ["10.0.11.0/24", "10.0.12.0/24", "10.0.13.0/24"]
+}
+
+variable "database_subnet_cidrs" {
+ description = "CIDR blocks for database subnets"
+ type = list(string)
+ default = ["10.0.21.0/24", "10.0.22.0/24", "10.0.23.0/24"]
+}
+
+variable "enable_nat_gateway" {
+ description = "Enable NAT Gateway for private subnets"
+ type = bool
+ default = true
+}
+
+variable "single_nat_gateway" {
+ description = "Use single NAT Gateway for all private subnets"
+ type = bool
+ default = false
+}
+
+variable "enable_vpc_flow_logs" {
+ description = "Enable VPC Flow Logs"
+ type = bool
+ default = true
+}
+
+# ----------------------------------------------------------------------------
+# Security Configuration
+# ----------------------------------------------------------------------------
+
+variable "alb_ingress_cidrs" {
+ description = "CIDR blocks allowed to access ALB"
+ type = list(string)
+ default = ["0.0.0.0/0"]
+}
+
+variable "enable_waf" {
+ description = "Enable AWS WAF for ALB"
+ type = bool
+ default = true
+}
+
+# ----------------------------------------------------------------------------
+# ECR Configuration
+# ----------------------------------------------------------------------------
+
+variable "ecr_image_tag_mutability" {
+ description = "Image tag mutability setting for ECR repositories"
+ type = string
+ default = "MUTABLE"
+}
+
+variable "ecr_scan_on_push" {
+ description = "Enable image scanning on push"
+ type = bool
+ default = true
+}
+
+variable "ecr_lifecycle_policy_enabled" {
+ description = "Enable lifecycle policy for ECR"
+ type = bool
+ default = true
+}
+
+# ----------------------------------------------------------------------------
+# RDS Configuration
+# ----------------------------------------------------------------------------
+
+variable "rds_instance_class" {
+ description = "RDS instance class"
+ type = string
+ default = "db.t3.medium"
+}
+
+variable "rds_allocated_storage" {
+ description = "Allocated storage for RDS in GB"
+ type = number
+ default = 100
+}
+
+variable "rds_max_allocated_storage" {
+ description = "Maximum allocated storage for RDS auto-scaling"
+ type = number
+ default = 500
+}
+
+variable "rds_engine_version" {
+ description = "PostgreSQL engine version"
+ type = string
+ default = "15.3"
+}
+
+variable "rds_database_name" {
+ description = "Name of the default database"
+ type = string
+ default = "lmsdb"
+}
+
+variable "rds_master_username" {
+ description = "Master username for RDS"
+ type = string
+ default = "lmsadmin"
+}
+
+variable "rds_multi_az" {
+ description = "Enable Multi-AZ deployment for RDS"
+ type = bool
+ default = true
+}
+
+variable "rds_deletion_protection" {
+ description = "Enable deletion protection for RDS"
+ type = bool
+ default = true
+}
+
+variable "rds_skip_final_snapshot" {
+ description = "Skip final snapshot on deletion"
+ type = bool
+ default = false
+}
+
+variable "rds_backup_window" {
+ description = "Preferred backup window"
+ type = string
+ default = "03:00-04:00"
+}
+
+variable "rds_maintenance_window" {
+ description = "Preferred maintenance window"
+ type = string
+ default = "sun:04:00-sun:05:00"
+}
+
+variable "rds_enabled_cloudwatch_logs_exports" {
+ description = "List of log types to export to CloudWatch"
+ type = list(string)
+ default = ["postgresql", "upgrade"]
+}
+
+# ----------------------------------------------------------------------------
+# ElastiCache Configuration
+# ----------------------------------------------------------------------------
+
+variable "redis_node_type" {
+ description = "Node type for Redis cluster"
+ type = string
+ default = "cache.t3.medium"
+}
+
+variable "redis_num_cache_nodes" {
+ description = "Number of cache nodes"
+ type = number
+ default = 2
+}
+
+variable "redis_parameter_group_family" {
+ description = "Redis parameter group family"
+ type = string
+ default = "redis7"
+}
+
+variable "redis_engine_version" {
+ description = "Redis engine version"
+ type = string
+ default = "7.0"
+}
+
+variable "redis_port" {
+ description = "Redis port"
+ type = number
+ default = 6379
+}
+
+variable "redis_automatic_failover" {
+ description = "Enable automatic failover"
+ type = bool
+ default = true
+}
+
+variable "redis_multi_az" {
+ description = "Enable Multi-AZ for Redis"
+ type = bool
+ default = true
+}
+
+variable "redis_snapshot_retention_limit" {
+ description = "Number of days to retain snapshots"
+ type = number
+ default = 7
+}
+
+variable "redis_snapshot_window" {
+ description = "Snapshot window"
+ type = string
+ default = "03:00-05:00"
+}
+
+variable "redis_maintenance_window" {
+ description = "Maintenance window"
+ type = string
+ default = "sun:05:00-sun:07:00"
+}
+
+# ----------------------------------------------------------------------------
+# ALB Configuration
+# ----------------------------------------------------------------------------
+
+variable "alb_enable_deletion_protection" {
+ description = "Enable deletion protection for ALB"
+ type = bool
+ default = true
+}
+
+variable "alb_enable_http2" {
+ description = "Enable HTTP/2 on ALB"
+ type = bool
+ default = true
+}
+
+variable "alb_enable_cross_zone_load_balancing" {
+ description = "Enable cross-zone load balancing"
+ type = bool
+ default = true
+}
+
+variable "alb_health_check_path" {
+ description = "Health check path"
+ type = string
+ default = "/health"
+}
+
+variable "alb_health_check_interval" {
+ description = "Health check interval in seconds"
+ type = number
+ default = 30
+}
+
+variable "alb_health_check_timeout" {
+ description = "Health check timeout in seconds"
+ type = number
+ default = 5
+}
+
+variable "enable_https" {
+ description = "Enable HTTPS listener on ALB"
+ type = bool
+ default = true
+}
+
+variable "ssl_certificate_arn" {
+ description = "ARN of SSL certificate for ALB"
+ type = string
+ default = ""
+}
+
+# ----------------------------------------------------------------------------
+# ECS Configuration
+# ----------------------------------------------------------------------------
+
+variable "ecs_backend_cpu" {
+ description = "CPU units for backend task"
+ type = number
+ default = 512
+}
+
+variable "ecs_backend_memory" {
+ description = "Memory for backend task in MB"
+ type = number
+ default = 1024
+}
+
+variable "ecs_backend_count" {
+ description = "Desired count of backend tasks"
+ type = number
+ default = 2
+}
+
+variable "ecs_frontend_cpu" {
+ description = "CPU units for frontend task"
+ type = number
+ default = 256
+}
+
+variable "ecs_frontend_memory" {
+ description = "Memory for frontend task in MB"
+ type = number
+ default = 512
+}
+
+variable "ecs_frontend_count" {
+ description = "Desired count of frontend tasks"
+ type = number
+ default = 2
+}
+
+variable "backend_image_tag" {
+ description = "Docker image tag for backend"
+ type = string
+ default = "latest"
+}
+
+variable "frontend_image_tag" {
+ description = "Docker image tag for frontend"
+ type = string
+ default = "latest"
+}
+
+variable "enable_ecs_autoscaling" {
+ description = "Enable auto-scaling for ECS services"
+ type = bool
+ default = true
+}
+
+variable "ecs_autoscaling_min_capacity" {
+ description = "Minimum number of tasks for auto-scaling"
+ type = number
+ default = 2
+}
+
+variable "ecs_autoscaling_max_capacity" {
+ description = "Maximum number of tasks for auto-scaling"
+ type = number
+ default = 10
+}
+
+variable "ecs_autoscaling_target_cpu" {
+ description = "Target CPU utilization percentage for auto-scaling"
+ type = number
+ default = 70
+}
+
+variable "ecs_autoscaling_target_memory" {
+ description = "Target memory utilization percentage for auto-scaling"
+ type = number
+ default = 80
+}
+
+variable "ecs_log_retention_days" {
+ description = "CloudWatch log retention in days"
+ type = number
+ default = 30
+}
+
+# ----------------------------------------------------------------------------
+# S3 Configuration
+# ----------------------------------------------------------------------------
+
+variable "s3_enable_versioning" {
+ description = "Enable versioning for S3 buckets"
+ type = bool
+ default = true
+}
+
+variable "s3_enable_lifecycle_rules" {
+ description = "Enable lifecycle rules for S3 buckets"
+ type = bool
+ default = true
+}
+
+variable "s3_lifecycle_glacier_days" {
+ description = "Days before transitioning to Glacier"
+ type = number
+ default = 90
+}
+
+variable "s3_lifecycle_expiration_days" {
+ description = "Days before object expiration"
+ type = number
+ default = 365
+}
+
+variable "s3_enable_replication" {
+ description = "Enable cross-region replication"
+ type = bool
+ default = false
+}
+
+variable "s3_replication_region" {
+ description = "Region for S3 replication"
+ type = string
+ default = "us-west-2"
+}
+
+# ----------------------------------------------------------------------------
+# CloudFront Configuration
+# ----------------------------------------------------------------------------
+
+variable "enable_cloudfront" {
+ description = "Enable CloudFront distribution"
+ type = bool
+ default = false
+}
+
+variable "cloudfront_price_class" {
+ description = "CloudFront price class"
+ type = string
+ default = "PriceClass_100"
+}
+
+variable "cloudfront_enable_ipv6" {
+ description = "Enable IPv6 for CloudFront"
+ type = bool
+ default = true
+}
+
+variable "cloudfront_minimum_protocol_version" {
+ description = "Minimum TLS protocol version"
+ type = string
+ default = "TLSv1.2_2021"
+}
+
+variable "cloudfront_certificate_arn" {
+ description = "ARN of ACM certificate for CloudFront"
+ type = string
+ default = ""
+}
+
+# ----------------------------------------------------------------------------
+# Route53 Configuration
+# ----------------------------------------------------------------------------
+
+variable "create_route53_zone" {
+ description = "Create Route53 hosted zone"
+ type = bool
+ default = false
+}
+
+variable "domain_name" {
+ description = "Domain name for the application"
+ type = string
+ default = ""
+}
+
+# ----------------------------------------------------------------------------
+# DocumentDB Configuration
+# ----------------------------------------------------------------------------
+
+variable "documentdb_instance_class" {
+ description = "DocumentDB instance class"
+ type = string
+ default = "db.t3.medium"
+}
+
+variable "documentdb_instance_count" {
+ description = "Number of DocumentDB instances"
+ type = number
+ default = 3
+}
+
+variable "documentdb_engine_version" {
+ description = "DocumentDB engine version"
+ type = string
+ default = "5.0.0"
+}
+
+variable "documentdb_master_username" {
+ description = "Master username for DocumentDB"
+ type = string
+ default = "lmsadmin"
+}
+
+variable "documentdb_deletion_protection" {
+ description = "Enable deletion protection for DocumentDB"
+ type = bool
+ default = true
+}
+
+variable "documentdb_skip_final_snapshot" {
+ description = "Skip final snapshot on deletion"
+ type = bool
+ default = false
+}
+
+variable "documentdb_backup_window" {
+ description = "Preferred backup window for DocumentDB"
+ type = string
+ default = "02:00-03:00"
+}
+
+variable "documentdb_maintenance_window" {
+ description = "Preferred maintenance window for DocumentDB"
+ type = string
+ default = "sun:03:00-sun:04:00"
+}
+
+# ----------------------------------------------------------------------------
+# Backup Configuration
+# ----------------------------------------------------------------------------
+
+variable "enable_backup" {
+ description = "Enable AWS Backup"
+ type = bool
+ default = true
+}
+
+variable "backup_retention_days" {
+ description = "Number of days to retain backups"
+ type = number
+ default = 7
+}
+
+# ----------------------------------------------------------------------------
+# Monitoring Configuration
+# ----------------------------------------------------------------------------
+
+variable "enable_monitoring" {
+ description = "Enable enhanced monitoring"
+ type = bool
+ default = true
+}
+
+variable "enable_enhanced_monitoring" {
+ description = "Enable RDS enhanced monitoring"
+ type = bool
+ default = true
+}