Skip to content

mrithwik/digital-twin

Repository files navigation

🤖 AI Digital Twin

A production-grade, serverless AI chatbot that acts as a personal digital twin — deployed on AWS with Infrastructure as Code, multi-environment management, and a full CI/CD pipeline.


✨ Overview

This project is a full-stack AI Digital Twin that you can converse with, powered by Amazon Bedrock. It's built with a modern serverless architecture on AWS and managed entirely through Terraform and GitHub Actions, demonstrating professional DevOps practices including:

  • Serverless backend (AWS Lambda + API Gateway)
  • Static frontend hosted on CloudFront + S3
  • Persistent conversation memory in S3
  • AI responses via Amazon Bedrock (Nova models)
  • Infrastructure as Code with Terraform workspaces
  • CI/CD pipelines with GitHub Actions and OIDC authentication

🏗️ Architecture

GitHub Repository
    ↓ (Push to main / Manual trigger)
GitHub Actions (CI/CD)
    ↓ (OIDC authentication — no long-lived keys)
AWS Infrastructure (per environment)
    ├── CloudFront  →  S3 (Next.js Frontend)
    ├── API Gateway →  Lambda (Python Backend)
    ├── Amazon Bedrock (AI — Nova Micro / Lite)
    └── S3 (Conversation Memory)

State Management:
    ├── S3 Bucket        (Terraform remote state)
    └── DynamoDB Table   (State locking)

Environments

Environment Purpose Model
dev Development & iteration amazon.nova-micro-v1:0
test Integration testing amazon.nova-micro-v1:0
prod Production (optional custom domain) amazon.nova-lite-v1:0

🗂️ Project Structure

digital-twin/
├── .github/
│   └── workflows/
│       ├── deploy.yml          # Deploy workflow (auto on push, manual for env)
│       └── destroy.yml         # Destroy workflow (manual, with confirmation)
├── backend/
│   ├── lambda_handler.py       # Lambda entry point
│   └── deploy.py               # Lambda packaging script (via uv)
├── frontend/
│   ├── components/
│   │   └── twin.tsx            # Main chat UI component
│   ├── app/                    # Next.js App Router pages
│   └── public/                 # Static assets (add avatar.png here)
├── terraform/
│   ├── versions.tf             # Provider configuration
│   ├── variables.tf            # Input variable definitions
│   ├── main.tf                 # All AWS resources
│   ├── outputs.tf              # Outputs (URLs, bucket names, etc.)
│   ├── backend.tf              # S3 remote state configuration
│   └── terraform.tfvars        # Default variable values
├── scripts/
│   ├── deploy.sh               # Mac/Linux deploy script
│   ├── deploy.ps1              # Windows deploy script
│   ├── destroy.sh              # Mac/Linux destroy script
│   └── destroy.ps1             # Windows destroy script
├── .env.example                # Environment variable template
└── .gitignore

🚀 Getting Started

Prerequisites

Local Development

  1. Clone the repository

    git clone https://github.com/mrithwik/digital-twin.git
    cd digital-twin
  2. Start the backend

    cd backend
    uv run uvicorn main:app --reload --port 8000
  3. Start the frontend

    cd frontend
    npm install
    npm run dev
  4. Open http://localhost:3000


☁️ AWS Deployment

First-Time Setup

1. Create Terraform state resources

cd terraform
terraform init
terraform apply \
  -target=aws_s3_bucket.terraform_state \
  -target=aws_s3_bucket_versioning.terraform_state \
  -target=aws_s3_bucket_server_side_encryption_configuration.terraform_state \
  -target=aws_s3_bucket_public_access_block.terraform_state \
  -target=aws_dynamodb_table.terraform_locks

2. Create the GitHub Actions IAM role (OIDC)

terraform apply \
  -target=aws_iam_openid_connect_provider.github \
  -target=aws_iam_role.github_actions \
  ... (see Day 5 guide for full command)
  -var="github_repository=mrithwik/digital-twin"

terraform output github_actions_role_arn   # Save this value

3. Add GitHub repository secrets

In your GitHub repo → Settings → Secrets and variables → Actions:

Secret Value
AWS_ROLE_ARN ARN from the previous step
AWS_ACCOUNT_ID Your 12-digit AWS account ID
DEFAULT_AWS_REGION e.g. us-east-1

Deploy via GitHub Actions

Automatic (push to main → deploys to dev):

git push origin main

Manual (choose environment):

  1. Go to ActionsDeploy Digital Twin
  2. Click Run workflow
  3. Select dev, test, or prod

Deploy Locally

Mac/Linux:

./scripts/deploy.sh dev      # or test, prod

Windows (PowerShell):

.\scripts\deploy.ps1 -Environment dev

🗑️ Destroying Environments

Via GitHub Actions (recommended):

  1. Go to ActionsDestroy Environment
  2. Select the environment and type its name to confirm

Locally — Mac/Linux:

./scripts/destroy.sh dev

Locally — Windows:

.\scripts\destroy.ps1 -Environment dev

⚠️ Destruction removes all AWS resources for that environment including Lambda, API Gateway, S3 buckets, and CloudFront. The Terraform state bucket and DynamoDB lock table are not removed automatically.


⚙️ Configuration

Key variables in terraform/terraform.tfvars:

Variable Default Description
project_name twin Resource name prefix
environment dev Target environment
bedrock_model_id amazon.nova-micro-v1:0 Bedrock model to use
lambda_timeout 60 Lambda timeout (seconds)
api_throttle_burst_limit 10 API burst limit
api_throttle_rate_limit 5 API rate limit (req/s)
use_custom_domain false Enable custom domain
root_domain "" Your domain (if enabled)

For production with a custom domain, create terraform/prod.tfvars based on the example in the Day 5 setup guide.


🔒 Security

  • No long-lived AWS credentials — GitHub Actions authenticates via OIDC
  • Secrets in GitHub — No credentials stored in code or .env files
  • S3 memory bucket is private with all public access blocked
  • Terraform state encrypted at rest in S3 with DynamoDB locking
  • IAM roles follow least-privilege principles

💰 Cost Estimate

Running all three environments simultaneously:

Service Est. Monthly Cost
Lambda (light usage) < $1
API Gateway < $1
S3 (storage) ~$0.05
CloudFront ~$0.10
Amazon Bedrock $1–$5 (usage-dependent)
DynamoDB (state lock) ~$0.00
Total ~$2–$7/month

Tip: Destroy unused environments (dev, test) when not in use to minimize costs. The Terraform state bucket (~$0.02/month) and IAM role (free) are safe to leave running.


🛠️ Troubleshooting

Could not assume role in GitHub Actions

  • Verify AWS_ROLE_ARN secret matches the Terraform output exactly
  • Confirm the OIDC trust policy references mrithwik/digital-twin

S3 bucket already exists

  • Bucket names are globally unique; change project_name in terraform.tfvars

Frontend not reflecting latest changes

  • Trigger a CloudFront invalidation:
    aws cloudfront create-invalidation --distribution-id <ID> --paths "/*"

Terraform state lock

  • Check DynamoDB for a stale lock and force-unlock if needed:
    terraform force-unlock <LOCK_ID>

Bedrock 403 / AccessDeniedException

  • Ensure the model is enabled in the Bedrock console for your region
  • Verify the Lambda IAM role has AmazonBedrockFullAccess

📚 Resources


📄 License

This project is licensed under the MIT License. See LICENSE for details.

About

AI Digital Twin version of me deployed on AWS with Terraform

Resources

License

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors