Want a cloud playground that's perfect for both solo hacking and team collaboration? Let's build one together - no local Docker needed, just pure cloud-powered creativity.
What We're Building
- Your own cloud container environment (AWS/GCP/Azure)
- SSH access from anywhere
- Persistent storage for your work
- Team collaboration features
Part 1: Basic Infrastructure Setup
Project Structure
cloud-container/
├── main.tf
├── variables.tf
├── outputs.tf
├── providers.tf
├── versions.tf
├── terraform.tfvars
├── scripts/
│ └── setup-container.sh
└── modules/
├── aws/
│ ├── main.tf
│ ├── variables.tf
│ └── outputs.tf
├── gcp/
│ ├── main.tf
│ ├── variables.tf
│ └── outputs.tf
└── azure/
├── main.tf
├── variables.tf
└── outputs.tf
Core Files
- versions.tf - Define provider versions
terraform {
required_version = ">= 1.0.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
google = {
source = "hashicorp/google"
version = "~> 5.0"
}
azurerm = {
source = "hashicorp/azurerm"
version = "~> 3.0"
}
}
}
- variables.tf - Configuration variables
variable "cloud_provider" {
description = "Pick your cloud (aws/gcp/azure)"
type = string
default = "aws"
}
variable "project_name" {
description = "Name your playground"
type = string
default = "dev-playground"
}
variable "region" {
description = "Where in the world?"
type = map(string)
default = {
aws = "us-west-2"
gcp = "us-central1"
azure = "eastus"
}
}
- providers.tf - Cloud provider configurations
provider "aws" {
region = var.region["aws"]
}
provider "google" {
project = "your-project-id" # Change this
region = var.region["gcp"]
}
provider "azurerm" {
features {}
}
- main.tf - Main configuration
module "aws_container" {
source = "./modules/aws"
count = var.cloud_provider == "aws" ? 1 : 0
project_name = var.project_name
region = var.region["aws"]
}
module "gcp_container" {
source = "./modules/gcp"
count = var.cloud_provider == "gcp" ? 1 : 0
project_name = var.project_name
region = var.region["gcp"]
}
module "azure_container" {
source = "./modules/azure"
count = var.cloud_provider == "azure" ? 1 : 0
project_name = var.project_name
region = var.region["azure"]
}
Part 2: Cloud Provider Modules
AWS Module (modules/aws/main.tf)
resource "aws_security_group" "dev_container" {
name = "${var.project_name}-security-group"
description = "Security group for our playground"
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 3000
to_port = 3000
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
# EBS volume for persistent storage
resource "aws_ebs_volume" "dev_storage" {
availability_zone = aws_instance.dev_container.availability_zone
size = 20
type = "gp2"
tags = {
Name = "${var.project_name}-storage"
}
}
resource "aws_instance" "dev_container" {
ami = "ami-0735c191cf914754d" # Ubuntu 22.04
instance_type = "t2.micro"
key_name = "your-key-pair-name" # Change this
security_groups = [aws_security_group.dev_container.name]
user_data = file("${path.root}/scripts/setup-container.sh")
tags = {
Name = var.project_name
}
}
resource "aws_volume_attachment" "dev_storage_att" {
device_name = "/dev/sdh"
volume_id = aws_ebs_volume.dev_storage.id
instance_id = aws_instance.dev_container.id
}
resource "aws_eip" "dev_container" {
instance = aws_instance.dev_container.id
}
GCP Module (modules/gcp/main.tf)
resource "google_compute_firewall" "dev_container" {
name = "${var.project_name}-firewall"
network = "default"
allow {
protocol = "tcp"
ports = ["22", "3000"]
}
source_ranges = ["0.0.0.0/0"]
}
# Persistent disk
resource "google_compute_disk" "dev_storage" {
name = "${var.project_name}-disk"
type = "pd-standard"
zone = "${var.region}-a"
size = 20
}
resource "google_compute_instance" "dev_container" {
name = var.project_name
machine_type = "e2-micro"
zone = "${var.region}-a"
boot_disk {
initialize_params {
image = "ubuntu-os-cloud/ubuntu-2204-lts"
}
}
network_interface {
network = "default"
access_config {}
}
metadata_startup_script = file("${path.root}/scripts/setup-container.sh")
}
resource "google_compute_attached_disk" "dev_storage" {
disk = google_compute_disk.dev_storage.id
instance = google_compute_instance.dev_container.id
}
Azure Module (modules/azure/main.tf)
[Previous Azure module code with managed disk configuration]
Part 3: Enhanced Container Setup
The Ultimate Setup Script (scripts/setup-container.sh)
#!/bin/bash
# System updates and utilities
apt-get update
apt-get install -y docker.io git nfs-common
# Start Docker
systemctl start docker
systemctl enable docker
# Create shared workspace with proper permissions
mkdir -p /home/ubuntu/shared_workspace
chmod 775 /home/ubuntu/shared_workspace
# Create developer group
groupadd developers
usermod -aG developers ubuntu
# Set up shared workspace ownership
chown -R ubuntu:developers /home/ubuntu/shared_workspace
# Create SSH key management directory
mkdir -p /home/ubuntu/.ssh/authorized_keys.d
chmod 755 /home/ubuntu/.ssh/authorized_keys.d
# Set up SSH key aggregation
cat > /home/ubuntu/.ssh/authorized_keys_script.sh <<'EOF'
#!/bin/bash
cat /home/ubuntu/.ssh/authorized_keys.d/* > /home/ubuntu/.ssh/authorized_keys
chmod 600 /home/ubuntu/.ssh/authorized_keys
EOF
chmod +x /home/ubuntu/.ssh/authorized_keys_script.sh
(crontab -l 2>/dev/null; echo "*/5 * * * * /home/ubuntu/.ssh/authorized_keys_script.sh") | crontab -
# Run development container with persistent storage
docker run -d \
--name dev-environment \
--restart unless-stopped \
-p 3000:3000 \
-p 8080:8080 \
-p 5432:5432 \
-v /home/ubuntu/shared_workspace:/workspace \
-v dev_dependencies:/usr/local/lib \
-v dev_config:/etc/dev \
node:16
# Install common development tools
docker exec dev-environment bash -c '
apt-get update && \
apt-get install -y git curl postgresql sqlite3 python3 python3-pip'
# Create welcome message
cat > /home/ubuntu/shared_workspace/README.md <<EOF
# Welcome to the Shared Development Environment!
## Quick Start
1. Your work directory is /workspace inside the container
2. Development server runs on port 3000
3. Add your SSH key to /home/ubuntu/.ssh/authorized_keys.d/
4. Docker container name is 'dev-environment'
## Useful Commands
- Enter container: docker exec -it dev-environment bash
- View logs: docker logs dev-environment
- Check disk usage: df -h /workspace
## Team Guidelines
1. Keep your work in your own directory
2. Use git for version control
3. Clean up temporary files
4. Update the team when installing new tools
Happy coding! 🚀
EOF
# Keep container running
docker exec dev-environment tail -f /dev/null
Part 4: Developer Management
Add Developer Script (add_developer.sh)
#!/bin/bash
if [ "$#" -ne 2 ]; then
echo "Usage: $0 <developer_name> <public_key>"
exit 1
fi
DEVELOPER_NAME=$1
PUBLIC_KEY=$2
INSTANCE_IP=$(terraform output -raw instance_ip)
# Add SSH key to instance
ssh ubuntu@$INSTANCE_IP "echo '$PUBLIC_KEY' > ~/.ssh/authorized_keys.d/$DEVELOPER_NAME"
echo "Developer $DEVELOPER_NAME added successfully!"
How to Use
1. Initial Setup
# Initialize Terraform
terraform init
# Deploy your environment
terraform apply
2. Solo Development
# SSH into your instance
ssh ubuntu@<instance_ip>
# Enter the container
docker exec -it dev-environment bash
# Start coding!
cd /workspace
3. Team Development
# Add team members
./add_developer.sh alice "ssh-rsa AAAA..."
# Create project structure
mkdir -p /workspace/projects/awesome-app
4. Directory Structure
/workspace/
├── projects/ # Shared projects
├── developers/ # Personal workspaces
└── shared/ # Common utilities
Pro Tips
- Money Saving
# Destroy when not in use
terraform destroy
- Permissions Fix
sudo chmod -R 775 /home/ubuntu/shared_workspace
- Container Management
# Restart container
docker restart dev-environment
# Check logs
docker logs dev-environment
Development Environment Options & Costs
1. Minimal Development Setup
Cost: ~$30-40/month
# AWS
instance_type = "t2.medium" # 2 vCPU, 4GB RAM
# GCP
instance_type = "e2-medium" # 2 vCPU, 4GB RAM
# Azure
instance_type = "Standard_B2s" # 2 vCPU, 4GB RAM
-
Suitable for:
- Single developer
- Basic React + Node.js development
- Small MongoDB datasets
-
Limitations:
- NPM installs take time
- Build processes are slower
- Limited concurrent operations
2. Standard Development Setup
Cost: ~$60-70/month
# AWS
instance_type = "t2.large" # 2 vCPU, 8GB RAM
# GCP
instance_type = "e2-standard-2" # 2 vCPU, 8GB RAM
# Azure
instance_type = "Standard_B2ms" # 2 vCPU, 8GB RAM
-
Suitable for:
- 2-3 developers
- Comfortable React + Node.js development
- Moderate MongoDB usage
- Running tests alongside development
-
Benefits:
- Faster build times
- Smooth hot reloading
- Better concurrent operations
3. Team Development Setup
Cost: ~$120-150/month
# AWS
instance_type = "t2.xlarge" # 4 vCPU, 16GB RAM
# GCP
instance_type = "e2-standard-4" # 4 vCPU, 16GB RAM
# Azure
instance_type = "Standard_B4ms" # 4 vCPU, 16GB RAM
-
Suitable for:
- 4+ developers
- Full development stack
- CI/CD pipelines
- Multiple service instances
Cost Breakdown
Compute Costs (per month)
- Minimal Setup: $25-30
- Standard Setup: $50-60
- Team Setup: $100-120
Storage Costs (per month)
- 30GB SSD: $3-5
- 50GB SSD: $5-8
- 100GB SSD: $10-15
Data Transfer (per month)
- Development usage: $2-5
- Team usage: $5-10
- Heavy usage: $10-20
Cost Optimization Strategies
1. Scheduled Shutdowns
# Add to your terraform configuration
resource "aws_autoscaling_schedule" "workday_only" {
scheduled_action_name = "start_workday"
min_size = 1
max_size = 1
desired_capacity = 1
recurrence = "0 9 * * MON-FRI" # 9 AM weekdays
}
resource "aws_autoscaling_schedule" "workday_end" {
scheduled_action_name = "stop_workday"
min_size = 0
max_size = 0
desired_capacity = 0
recurrence = "0 18 * * MON-FRI" # 6 PM weekdays
}
Potential Savings: 60-65% on compute costs
2. Resource Optimization
# Monitor resource usage
docker stats dev-environment
# Adjust container limits based on actual usage
docker update --memory=4g --cpus=1.5 dev-environment
3. Storage Management
# Clean up unused Docker images
docker system prune -a
# Monitor disk usage
df -h /workspace
Choosing the Right Setup
For Solo Developers
- Start with Minimal Setup
- Schedule shutdowns during non-work hours
- Upgrade if build times become a bottleneck
For Small Teams (2-3 developers)
- Start with Standard Setup
- Monitor resource usage
- Use scheduling for non-work hours
For Larger Teams
- Use Team Setup
- Consider separate environments for CI/CD
- Implement proper resource monitoring
Resource Usage Alerts
# Add CloudWatch monitoring (AWS example)
resource "aws_cloudwatch_metric_alarm" "high_cpu" {
alarm_name = "high-cpu-usage"
comparison_operator = "GreaterThanThreshold"
evaluation_periods = "2"
metric_name = "CPUUtilization"
namespace = "AWS/EC2"
period = "300"
statistic = "Average"
threshold = "80"
alarm_description = "CPU usage above 80%"
alarm_actions = [aws_sns_topic.alerts.arn]
}
Remember: Development environment costs are usually a fraction of developer time costs. A smoother development experience often pays for itself in improved productivity.
Happy coding! 🎉
Top comments (0)