Skill: ivangdavila/infrastructure (version 1.0.1)

--- name: Infrastructure slug: infrastructure version: 1.0.1 description: Design, provision, and connect cloud resources across servers, networks, and services. changelog: User-driven credential model, explicit tool requirements metadata: {"clawdbot":{"emoji":"🏗️","requires":{"bins":[]},"os":["linux","darwin","win32"]}} --- ## Scope This skill: - ✅ Guides architecture decisions - ✅ Provides provisioning commands for user to run - ✅ Documents infrastructure patterns **User-driven model:** - User provides cloud credentials when needed - User runs provisioning commands - Skill guides decisions and generates commands This skill does NOT: - ❌ Store or access cloud credentials directly - ❌ Run provisioning commands automatically - ❌ Modify infrastructure without user confirmation **For implementation:** User runs commands skill provides, or uses `server` skill for execution. ## Quick Reference | Topic | File | |-------|------| | Architecture patterns | `patterns.md` | | Provider commands | `providers.md` | | Backup strategies | `backups.md` | ## Core Rules ### 1. User Runs Commands Skill generates commands, user executes: ``` Agent: "To create the server, run: hcloud server create --name web1 --type cx21 --image ubuntu-24.04 This requires HCLOUD_TOKEN in your environment." User: [runs command] ``` ### 2. Required Tools (User Installs) | Provider | Tool | Install | |----------|------|---------| | Hetzner | `hcloud` | brew install hcloud | | AWS | `aws` | brew install awscli | | DigitalOcean | `doctl` | brew install doctl | | Docker | `docker` | Docker Desktop | ### 3. Credential Handling - User sets credentials in their environment - Skill never stores or logs credential values - Commands reference env vars: `$HCLOUD_TOKEN`, `$AWS_ACCESS_KEY_ID` ### 4. Architecture Guidance | Stage | Recommended | |-------|-------------| | MVP | Single VPS + Docker Compose | | Growth | Dedicated DB + load balancer | | Scale | Multi-region + CDN | ### 5. Decision Framework | Question | Answer | |----------|--------| | How to structure infra? | ✅ This skill | | Should I add another server? | ✅ This skill | | How to configure nginx? | Use `server` skill | | How to write Dockerfile? | Use `docker` skill | ### 6. Backup Strategy | Data | Method | Frequency | |------|--------|-----------| | Database | pg_dump → S3/B2 | Daily | | Volumes | Snapshots | Weekly | | Config | Git | Every change |

path: backups.md
content: # Backup Strategies

## The 3-2-1 Rule

- **3** copies of data
- **2** different storage types
- **1** offsite

Minimum viable: Primary + Daily backup to S3/B2

---

## Database Backups

### PostgreSQL to S3

```bash
#!/bin/bash
# backup-db.sh
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
BUCKET="s3://myapp-backups/postgres"

# Dump
pg_dump -Fc $DATABASE_URL > /tmp/backup_$TIMESTAMP.dump

# Upload
aws s3 cp /tmp/backup_$TIMESTAMP.dump $BUCKET/

# Cleanup local
rm /tmp/backup_$TIMESTAMP.dump

# Cleanup old backups (keep 30 days)
aws s3 ls $BUCKET/ | while read -r line; do
  createDate=$(echo $line | awk '{print $1" "$2}')
  createDate=$(date -d "$createDate" +%s)
  olderThan=$(date -d "30 days ago" +%s)
  if [[ $createDate -lt $olderThan ]]; then
    fileName=$(echo $line | awk '{print $4}')
    aws s3 rm $BUCKET/$fileName
  fi
done
```

### Cron Setup
```bash
# Daily at 3 AM
0 3 * * * /opt/scripts/backup-db.sh >> /var/log/backup.log 2>&1
```

### Restore
```bash
# Download
aws s3 cp s3://myapp-backups/postgres/backup_20240115.dump /tmp/

# Restore
pg_restore -d $DATABASE_URL /tmp/backup_20240115.dump
```

---

## Volume/Disk Backups

### Hetzner Snapshots
```bash
# Create snapshot
hcloud server create-image --type snapshot myapp \
  --description "Pre-migration $(date +%Y%m%d)"

# List snapshots
hcloud image list --type snapshot

# Restore (create new server from snapshot)
hcloud server create --name myapp-restored \
  --image snapshot-123456 --type cx22
```

### AWS EBS Snapshots
```bash
# Create
aws ec2 create-snapshot --volume-id vol-xxx \
  --description "Daily backup"

# Automate with Data Lifecycle Manager (DLM)
# Creates snapshots on schedule, manages retention
```

---

## Application Data Backups

### Docker Volumes
```bash
# Backup volume to tarball
docker run --rm -v myapp_data:/data -v $(pwd):/backup \
  alpine tar czf /backup/data_backup.tar.gz /data

# Restore
docker run --rm -v myapp_data:/data -v $(pwd):/backup \
  alpine sh -c "cd /data && tar xzf /backup/data_backup.tar.gz --strip 1"
```

---

## Storage Options

| Provider | Cost | Best For |
|----------|------|----------|
| Backblaze B2 | $0.005/GB/mo | Cheapest, S3-compatible |
| AWS S3 | $0.023/GB/mo | Integration with AWS |
| Hetzner Storage Box | €3.81/1TB | EU data residency |
| rsync.net | $0.015/GB/mo | ZFS snapshots, SSH access |

---

## Backup Verification

**Critical:** Untested backups are not backups.

Monthly checklist:
1. Download random backup
2. Restore to test environment
3. Verify data integrity
4. Document restore time (RTO)

```bash
# Quick verify pg_dump integrity
pg_restore --list backup.dump > /dev/null && echo "Valid" || echo "Corrupt"
```

---

## Disaster Recovery Checklist

Before disaster:
- [ ] Automated backups running
- [ ] Backups verified monthly
- [ ] Restore procedure documented
- [ ] Restore tested quarterly
- [ ] Offsite copy exists

During disaster:
1. Don't panic
2. Assess what's lost
3. Find latest valid backup
4. Provision new infrastructure
5. Restore from backup
6. Update DNS
7. Verify functionality
8. Post-mortem


path: patterns.md
content: # Architecture Patterns by Stage

## MVP Stage (<1K users, <$50/month)

```
┌─────────────────────────────────┐
│         Single VPS              │
│  ┌─────────┐  ┌─────────┐      │
│  │   App   │  │   DB    │      │
│  │ (Docker)│  │(Postgres)│     │
│  └─────────┘  └─────────┘      │
│         Caddy (reverse proxy)   │
└─────────────────────────────────┘
```

**Setup:**
- One VPS (Hetzner CAX11 €4/mo or equivalent)
- Docker Compose for app + db
- Caddy for auto-SSL and reverse proxy
- Daily pg_dump to S3/B2

**When to upgrade:** CPU consistently >70%, RAM consistently >80%, or need zero-downtime deploys.

---

## Growth Stage (1K-50K users, $50-500/month)

```
┌─────────────┐     ┌─────────────┐
│  App Server │     │  DB Server  │
│  (Docker)   │────▶│ (Managed or │
│  + Caddy    │     │  dedicated) │
└─────────────┘     └─────────────┘
       │
       ▼
┌─────────────┐
│   Workers   │ (background jobs, optional)
└─────────────┘
```

**Changes from MVP:**
- Separate database (managed recommended: Supabase, Neon, or dedicated VPS)
- Optional: worker server for background jobs
- Add monitoring (Uptime Kuma self-hosted or external)
- Automated backups with retention policy

**When to upgrade:** Need high availability, multiple app instances, or geographic distribution.

---

## Scale Stage (50K+ users, $500+/month)

```
                    ┌─────────────┐
                    │     CDN     │
                    │ (Cloudflare)│
                    └──────┬──────┘
                           │
                    ┌──────▼──────┐
                    │ Load Balancer│
                    └──────┬──────┘
           ┌───────────────┼───────────────┐
           │               │               │
    ┌──────▼──────┐ ┌──────▼──────┐ ┌──────▼──────┐
    │  App Node 1 │ │  App Node 2 │ │  App Node 3 │
    └─────────────┘ └─────────────┘ └─────────────┘
           │               │               │
           └───────────────┴───────────────┘
                           │
                    ┌──────▼──────┐
                    │ DB Cluster  │
                    │ (Primary +  │
                    │  Replicas)  │
                    └─────────────┘
```

**Changes from Growth:**
- Load balancer (cloud-native or HAProxy)
- Multiple app nodes (auto-scaling optional)
- Database replication (read replicas)
- CDN for static assets
- Full observability stack (Prometheus + Grafana or managed)
- Multi-region for latency-sensitive apps

---

## Anti-Patterns to Avoid

| Anti-Pattern | Why It's Bad | Do This Instead |
|--------------|--------------|-----------------|
| Kubernetes at MVP | Operational overhead kills velocity | Docker Compose until you NEED orchestration |
| Microservices early | Distributed debugging is hard | Modular monolith, split later |
| Multi-cloud | Double complexity, little benefit | Pick one, have exit plan |
| Over-provisioned instances | Wasted money | Start small, scale up |
| No backups | One mistake = game over | Automate day 1 |


path: providers.md
content: # Cloud Provider Reference

## Hetzner (Best for cost-conscious, Europe-focused)

### Create Server
```bash
# CLI
hcloud server create --name myapp --type cx22 --image ubuntu-24.04 \
  --ssh-key my-key --location nbg1

# With firewall
hcloud firewall create --name web-firewall \
  --rules-file rules.json
hcloud firewall apply-to-resource --type server \
  --server myapp web-firewall
```

### Firewall Rules (rules.json)
```json
[
  {"direction": "in", "protocol": "tcp", "port": "22", "source_ips": ["YOUR_IP/32"]},
  {"direction": "in", "protocol": "tcp", "port": "80", "source_ips": ["0.0.0.0/0"]},
  {"direction": "in", "protocol": "tcp", "port": "443", "source_ips": ["0.0.0.0/0"]}
]
```

### Pricing Reference (2024)
| Type | vCPU | RAM | Storage | Price |
|------|------|-----|---------|-------|
| CX22 | 2 | 4GB | 40GB | €4.51/mo |
| CX32 | 4 | 8GB | 80GB | €8.98/mo |
| CX42 | 8 | 16GB | 160GB | €17.85/mo |
| CAX11 (ARM) | 2 | 4GB | 40GB | €4.51/mo |

---

## AWS (Best for enterprise, global scale)

### Create EC2 Instance
```bash
aws ec2 run-instances \
  --image-id ami-0123456789abcdef0 \
  --instance-type t3.micro \
  --key-name my-key \
  --security-group-ids sg-12345678 \
  --subnet-id subnet-12345678

# Security group
aws ec2 create-security-group --group-name web-sg \
  --description "Web server"
aws ec2 authorize-security-group-ingress --group-id sg-xxx \
  --protocol tcp --port 443 --cidr 0.0.0.0/0
```

### Cost Gotchas
- **Egress:** $0.09/GB after first 100GB
- **EBS:** Charged even when instance stopped
- **NAT Gateway:** $0.045/hour + $0.045/GB processed
- **Load Balancer:** $0.0225/hour minimum

---

## DigitalOcean (Good middle ground)

### Create Droplet
```bash
doctl compute droplet create myapp \
  --size s-1vcpu-1gb \
  --image ubuntu-24-04-x64 \
  --region nyc1 \
  --ssh-keys fingerprint

# Firewall
doctl compute firewall create --name web-fw \
  --inbound-rules "protocol:tcp,ports:22,address:YOUR_IP" \
  --inbound-rules "protocol:tcp,ports:443,address:0.0.0.0/0"
```

### Pricing Reference
| Size | vCPU | RAM | Storage | Price |
|------|------|-----|---------|-------|
| s-1vcpu-1gb | 1 | 1GB | 25GB | $6/mo |
| s-2vcpu-2gb | 2 | 2GB | 50GB | $12/mo |
| s-2vcpu-4gb | 2 | 4GB | 80GB | $24/mo |

---

## Provider Selection Guide

| Priority | Best Choice | Why |
|----------|-------------|-----|
| Lowest cost | Hetzner | 50-70% cheaper than hyperscalers |
| EU data residency | Hetzner | German company, EU datacenters |
| Global presence | AWS/GCP | Regions everywhere |
| Simplicity | DigitalOcean/Render | Less knobs to turn |
| Startup credits | AWS/GCP/Azure | $5K-100K free credits available |
| ARM workloads | Hetzner CAX / AWS Graviton | Better price/performance |


Security scan verdicts — ClawScan: clean | static analysis: clean | VirusTotal: clean | SkillSpector: suspicious (HIGH)