This repository contains the infrastructure as code (IaC) for my Portfolio, implemented using Terraform and deployed on Amazon Web Services (AWS). The infrastructure supports a voice agent application built with FastAPI, FastRTC, WebRTC, and LangGraph, with the backend deployed on EC2 and exposed through Cloudflare tunnel.
The portfolio infrastructure follows a modern cloud-native architecture:
- Frontend: Deployed on Vercel for optimal performance and global CDN
- Backend: Deployed on AWS EC2 with Docker containerization
- WebRTC: Utilizes Cloudflare TURN Server for voice agent functionality
- Networking: Cloudflare tunnel for secure backend access
- Container Registry: AWS ECR for Docker image management
portfolio-infrastructure/
βββ assets/ # Architecture diagrams and images
β βββ portfolio-cloud-architecture.png
β βββ portfolio-aws-architecture.png
βββ environments/ # Environment-specific configurations
β βββ dev/ # Development environment
β βββ main.tf # Main Terraform configuration
β βββ variables.tf # Variable definitions
β βββ secrets.tfvars # Secret variables (not in git)
β βββ outputs.tf # Output values
β βββ providers.tf # Provider configurations
β βββ versions.tf # Terraform and provider versions
β βββ ec2-setup.sh # EC2 instance setup script
β βββ portfolio-backend/ # Backend application configs
β β βββ docker-compose.yml # Docker Compose configuration
β βββ backend/ # Backend module configuration
βββ modules/ # Reusable Terraform modules
β βββ providers/
β βββ aws/
β βββ backend/ # EC2 instance and setup
β βββ ecr/ # Elastic Container Registry
β βββ iam/ # Identity and Access Management
β βββ network/ # VPC, subnets, and networking
β βββ security-group/ # Security group configurations
βββ README.md # This file- VPC: Creates a custom VPC with CIDR
10.0.0.0/16 - Public Subnets: Two public subnets across different AZs (
10.0.1.0/24,10.0.2.0/24) - Internet Gateway: Enables internet access for public subnets
- DNS Support: Enables DNS hostnames and support for proper name resolution
- WebRTC Ports: UDP ports 10000-20000 for media traffic
- STUN/TURN Signaling: Ports 3478 (UDP/TCP) and 5349 (TCP) for TURN over TLS
- SSH Access: Port 22 for secure shell access
- Cloudflare Tunnel: Specific egress rules for Cloudflare tunnel communication
- EC2 Instance: Amazon Linux 2 with t3.micro instance type
- Key Pair Management: Automatic SSH key generation and storage
- IAM Profile: Instance profile for ECR access
- Provisioning: Automated setup with Docker, Docker Compose, and Cloudflared
- File Deployment: Copies docker-compose.yml to
/home/ec2-user/portfolio-backend/
- Container Registry: Private ECR repository for Docker images
- VPC Integration: Repository configured within VPC
- Lifecycle Policies: Automatic cleanup of old images
- ECR Access: IAM role for EC2 instances to pull from ECR
- Least Privilege: Minimal permissions for security
-
Terraform (v1.0+)
# Download from https://www.terraform.io/downloads.html # Or use package manager brew install terraform # macOS choco install terraform # Windows
-
AWS CLI (v2.0+)
# Download from https://aws.amazon.com/cli/ # Or use package manager brew install awscli # macOS choco install awscli # Windows
-
Git (for cloning the repository)
-
Configure AWS CLI with your credentials:
aws configure --profile portfolio
-
Enter your AWS credentials:
AWS Access Key ID: [Your Access Key] AWS Secret Access Key: [Your Secret Key] Default region name: us-west-2 Default output format: json
-
Verify the profile:
aws sts get-caller-identity --profile portfolio
-
Navigate to the development environment:
cd environments/dev -
Create/Update
secrets.tfvars:project_name = "portfolio" env_name = "dev" BACKEND_KEY_PAIR_PATH = "path/to/your/key-pair.pem"
Note: Replace
BACKEND_KEY_PAIR_PATHwith the actual path where you want to store the SSH key pair. -
Initialize Terraform:
terraform init
-
Plan the deployment:
terraform plan -var-file=secrets.tfvars
-
Apply the infrastructure:
terraform apply -var-file=secrets.tfvars
After successful deployment:
-
SSH into the EC2 instance:
ssh -i path/to/your/key-pair.pem ec2-user@<EC2_PUBLIC_IP>
-
Verify Docker and Cloudflared installation:
docker --version cloudflared --version
-
Check the portfolio-backend directory:
ls -la /home/ec2-user/portfolio-backend/
- STUN/TURN Configuration: Properly configured security groups for WebRTC traffic
- Port Ranges: UDP ports 10000-20000 for media, ports 3478/5349 for signaling
- Cloudflare Integration: TURN server integration for voice agent functionality
- Security Groups: Restrictive ingress/egress rules
- IAM Roles: Least privilege access to AWS services
- SSH Key Management: Automated key pair generation and secure storage
- Multi-AZ Deployment: Resources spread across availability zones
- Container Registry: ECR for efficient image management
- Modular Design: Reusable Terraform modules for different environments
- Docker Compose: Container orchestration for easy deployment
- Cloudflared Tunnel: Secure, zero-trust access to backend services
- Automated Setup: EC2 instance provisioning with all necessary tools
-
STUN Transaction Failed (401):
- Check security group rules for WebRTC ports
- Verify Cloudflare tunnel configuration
- Ensure proper network mode in Docker Compose
-
EC2 Connection Issues:
- Verify SSH key permissions (
chmod 400 key.pem) - Check security group allows SSH (port 22)
- Ensure instance is in a public subnet
- Verify SSH key permissions (
-
Docker Issues:
- Verify Docker service is running:
sudo systemctl status docker - Check Docker Compose installation:
docker-compose --version
- Verify Docker service is running:
- The infrastructure is designed for development environment (
dev) - All sensitive information should be stored in
secrets.tfvars(not committed to git) - The EC2 instance uses Amazon Linux 2 with automatic updates
- WebRTC configuration is optimized for voice agent applications
- Cloudflare tunnel provides secure access without exposing public endpoints
This project is part of my personal portfolio infrastructure.

