Secure, scalable cloud storage for 250+ medical VR video files using Azure Blob Storage. Includes Terraform IaC to provision storage and a TypeScript/Express API that issues time-limited SAS URLs for upload and playback, eliminating reliance on internal headset storage.
- Azure Storage Account with a private Blob container (
videosby default) - SAS API (Express/TypeScript) to mint short-lived upload and read URLs
- Private by default: No public container access; only SAS-scoped access
- Node.js 18+
- Terraform 1.6+
- Azure subscription and
az login
- Infrastructure (Terraform)
cd infra/terraform
terraform init
terraform apply -auto-approve \
-var="resource_group_name=cloudmed-rg" \
-var="location=westeurope" \
-var="storage_account_name=cloudmedstorxyz" \
-var="container_name=videos"After apply, note the outputs. You will need the storage account name and container name for the API.
- API Setup (SAS server)
cd api
# Create .env with your configuration
cat > .env << 'EOF'
PORT=4000
STORAGE_ACCOUNT_NAME=youraccount
CONTAINER_NAME=videos
SAS_EXPIRY_MINUTES=15
ALLOWED_ORIGINS=*
# Optional: AZURE_STORAGE_CONNECTION_STRING=...
# Optional: AZURE_STORAGE_ACCOUNT_KEY=...
EOF
npm install
npm run devThe server runs on http://localhost:4000 by default.
POST /sas/upload?blobName={file.mp4}→ returns a SAS URL to upload a blobGET /sas/read?blobName={file.mp4}→ returns a SAS URL to stream/download
Both endpoints return JSON with a url you can use directly from headsets.
Upload from device (or companion app):
curl -X PUT "{uploadSasUrl}" \
-H "x-ms-blob-type: BlockBlob" \
--data-binary @local_video.mp4Stream from device player using the read SAS URL directly as the media source.
- Storage account public access: disabled
- Container access: private
- SAS duration: 15 minutes (configurable via env)
- HTTPS only
Environment (api/.env):
PORT=4000
STORAGE_ACCOUNT_NAME=youraccount
CONTAINER_NAME=videos
SAS_EXPIRY_MINUTES=15
ALLOWED_ORIGINS=*
- Private endpoint for Storage Account, limit access from API only
- Customer-managed keys (CMK) via Key Vault
- CORS tighten to specific domains/devices
- Lifecycle policies (tier to Cool/Archive after N days)
cd infra/terraform
terraform destroy -auto-approve