Agent SkillsAgent Skills
panaversity

building-with-multi-cloud

@panaversity/building-with-multi-cloud
panaversity
0
0 forks
Updated 3/31/2026
View on GitHub

Deploy Kubernetes workloads to real cloud providers. Use when provisioning managed Kubernetes (DOKS, AKS, GKE, EKS, Civo) or self-managed clusters (Hetzner + K3s). Covers CLI tools, cluster creation, LoadBalancers, DNS, TLS, and cost optimization.

Installation

$npx agent-skills-cli install @panaversity/building-with-multi-cloud
Claude Code
Cursor
Copilot
Codex
Antigravity

Details

Pathdocs/_skills_archive/rare/building-with-multi-cloud/SKILL.md
Branchmain
Scoped Name@panaversity/building-with-multi-cloud

Usage

After installing, this skill will be available to your AI coding assistant.

Verify installation:

npx agent-skills-cli list

Skill Instructions


name: building-with-multi-cloud description: Deploy Kubernetes workloads to real cloud providers. Use when provisioning managed Kubernetes (DOKS, AKS, GKE, EKS, Civo) or self-managed clusters (Hetzner + K3s). Covers CLI tools, cluster creation, LoadBalancers, DNS, TLS, and cost optimization. allowed-tools: Read, Grep, Glob, Edit, Write, Bash, WebSearch, WebFetch model: claude-sonnet-4-20250514

Multi-Cloud Kubernetes Deployment

Persona

You are a Cloud Platform Engineer with production experience deploying Kubernetes across DigitalOcean, Azure, GCP, AWS, Civo, and Hetzner. You understand the key insight: only cluster provisioning differs between clouds—everything else (kubectl, Helm, Dapr, Ingress, cert-manager) is identical. You help teams choose the right provider for their budget and needs, from $5/month learning labs to enterprise-grade production clusters.

When to Use This Skill

Activate when the user mentions:

  • DigitalOcean DOKS, doctl, managed Kubernetes
  • Azure AKS, az aks, Azure Kubernetes
  • Google GKE, gcloud container clusters
  • AWS EKS, eksctl, Amazon Kubernetes
  • Civo Kubernetes, civo CLI
  • Hetzner Cloud, hetzner-k3s, K3s, self-managed
  • Cloud Kubernetes pricing, cost comparison
  • Production deployment, real cloud, beyond Docker Desktop
  • LoadBalancer service, external IP, cloud DNS
  • Multi-cloud, cloud-agnostic deployment

Core Insight: The Universal Pattern

┌─────────────────────────────────────────────────────────────────┐
│              ONLY THIS DIFFERS BETWEEN CLOUDS                   │
├─────────────────────────────────────────────────────────────────┤
│  Cloud CLI → Create Cluster → Get Kubeconfig                   │
│                                                                 │
│  doctl kubernetes cluster create ...                            │
│  az aks create ... && az aks get-credentials ...               │
│  gcloud container clusters create ... && get-credentials ...   │
│  eksctl create cluster ...                                      │
│  civo kubernetes create ...                                     │
│  hetzner-k3s create --config cluster.yaml                      │
└─────────────────────────────────────────────────────────────────┘
                              ↓
┌─────────────────────────────────────────────────────────────────┐
│              EVERYTHING BELOW IS IDENTICAL                      │
├─────────────────────────────────────────────────────────────────┤
│  kubectl apply -f ...           (same on all clouds)           │
│  helm upgrade --install ...     (same on all clouds)           │
│  dapr init -k                   (same on all clouds)           │
│  traefik/ingress-nginx         (same on all clouds)            │
│  cert-manager + Let's Encrypt  (same on all clouds)            │
│  Secrets, ConfigMaps           (same on all clouds)            │
└─────────────────────────────────────────────────────────────────┘

Decision Logic: Choosing a Provider

Quick Decision Matrix

ScenarioRecommended ProviderWhy
Learning/practice (~$5/mo)Hetzner + K3sCheapest real cloud, full K8s compatibility
Startup MVP ($24+/mo)DigitalOcean DOKSSimple, fast, free control plane, $200 credit
Cost-conscious productionCivo$5/node, 90-second clusters, K3s-based
Enterprise/existing AzureAzure AKSFree control plane, Azure integration
Enterprise/existing AWSAWS EKSBest AWS integration, extensive ecosystem
Enterprise/existing GCPGoogle GKEBest autoscaling, GCP integration
Budget enterpriseHetzner + K3sSelf-managed but production-capable

Cost Comparison (December 2025)

ProviderControl Plane3-Node Cluster (min viable)Notes
Hetzner + K3s$0 (self-managed)€16/mo ($18)Cheapest, requires management
CivoFree~$15/mo (3x $5 nodes)K3s-based, fast provisioning
DigitalOcean DOKSFree~$36/mo (3x $12 nodes)$200 free credit for new users
Azure AKSFree~$45/mo$200 free credit available
Google GKEFree (Autopilot)~$50/mo$300 free credit available
AWS EKS$0.10/hr (~$73/mo)~$150/moControl plane NOT free

Managed vs Self-Managed

Need production SLA + minimal ops overhead?
├── Yes → Managed (DOKS, AKS, GKE, EKS, Civo)
│         You manage: workloads, helm charts, secrets
│         Provider manages: control plane, upgrades, HA
└── No → Self-managed (Hetzner + K3s, bare metal)
         You manage: EVERYTHING
         Benefit: Maximum cost savings, full control

Provider CLI Commands

DigitalOcean DOKS (doctl)

# Install doctl
brew install doctl  # macOS
# or: snap install doctl  # Linux

# Authenticate
doctl auth init  # Paste API token

# Create cluster
doctl kubernetes cluster create task-api-cluster \
  --region nyc1 \
  --version 1.31.4-do.0 \
  --size s-2vcpu-4gb \
  --count 3 \
  --wait

# Get kubeconfig (automatically saved)
doctl kubernetes cluster kubeconfig save task-api-cluster

# Verify
kubectl get nodes

Key Options:

  • --size: Node size (use doctl compute size list | grep kube)
  • --count: Number of nodes
  • --auto-upgrade: Enable auto-upgrades
  • --ha: Enable HA control plane ($40/mo extra)

Azure AKS (az aks)

# Install Azure CLI
brew install azure-cli  # macOS
# or: curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash  # Linux

# Authenticate
az login

# Create resource group
az group create --name task-api-rg --location eastus

# Create cluster
az aks create \
  --resource-group task-api-rg \
  --name task-api-cluster \
  --node-count 3 \
  --node-vm-size Standard_B2s \
  --generate-ssh-keys

# Get kubeconfig
az aks get-credentials --resource-group task-api-rg --name task-api-cluster

# Verify
kubectl get nodes

Key Options:

  • --node-vm-size: VM size (Standard_B2s is cheapest)
  • --enable-managed-identity: Use managed identity (recommended)
  • --zones 1 2 3: Multi-AZ deployment

Google GKE (gcloud)

# Install gcloud CLI
brew install google-cloud-sdk  # macOS

# Authenticate
gcloud auth login
gcloud config set project YOUR_PROJECT_ID

# Create cluster (Autopilot - recommended)
gcloud container clusters create-auto task-api-cluster \
  --location us-central1

# OR Standard cluster
gcloud container clusters create task-api-cluster \
  --zone us-central1-a \
  --num-nodes 3 \
  --machine-type e2-small

# Get kubeconfig
gcloud container clusters get-credentials task-api-cluster \
  --location us-central1

# Verify
kubectl get nodes

Key Options:

  • --enable-autopilot: Pay only for pods, not nodes
  • --spot: Use spot instances (up to 91% cheaper)

AWS EKS (eksctl)

# Install eksctl
brew tap weaveworks/tap
brew install weaveworks/tap/eksctl

# Create cluster (15-20 minutes)
eksctl create cluster \
  --name task-api-cluster \
  --region us-east-1 \
  --node-type t3.medium \
  --nodes 3

# kubeconfig is automatically configured

# Verify
kubectl get nodes

Key Options:

  • --enable-auto-mode: EKS Auto Mode (newer, simpler)
  • --spot: Use spot instances
  • --managed: Use managed node groups

Civo (civo)

# Install Civo CLI
brew install civo  # macOS
# or: curl -sL https://civo.com/get | sh  # Linux

# Authenticate
civo apikey save MY_KEY <your-api-key>
civo apikey current MY_KEY
civo region current NYC1

# Create cluster (90 seconds!)
civo kubernetes create task-api-cluster \
  --size g4s.kube.medium \
  --nodes 3 \
  --wait \
  --merge \
  --switch

# kubeconfig automatically merged and context switched

# Verify
kubectl get nodes

Key Options:

  • --applications: Install marketplace apps (e.g., traefik2-nodeport)
  • --cluster-type talos: Use Talos instead of K3s
  • --cni-plugin cilium: Use Cilium CNI

Hetzner + K3s (hetzner-k3s)

# Install hetzner-k3s
brew install vitobotta/tap/hetzner_k3s  # macOS
# or download binary from GitHub releases

# Create config file: cluster.yaml
cat > cluster.yaml << 'EOF'
hetzner_token: <your-hetzner-api-token>
cluster_name: task-api-cluster
kubeconfig_path: "./kubeconfig"
k3s_version: v1.31.4+k3s1

networking:
  ssh:
    port: 22
    use_agent: false
    public_key_path: "~/.ssh/id_ed25519.pub"
    private_key_path: "~/.ssh/id_ed25519"
    allowed_networks:
      ssh:
        - 0.0.0.0/0
      api:
        - 0.0.0.0/0

masters_pool:
  instance_type: cx22  # 2 vCPU, 4GB RAM
  instance_count: 1    # 1 for learning, 3 for HA
  location: fsn1

worker_node_pools:
  - name: workers
    instance_type: cx22
    instance_count: 2
    location: fsn1
EOF

# Create cluster (2-3 minutes)
hetzner-k3s create --config cluster.yaml

# Use the kubeconfig
export KUBECONFIG=./kubeconfig
kubectl get nodes

Key Options:

  • instance_type: cx22 (€5.39/mo), cx32 (€10.59/mo), cx42 (€21.29/mo)
  • autoscaling.enabled: true: Enable cluster autoscaler
  • networking.cni.cilium.enabled: true: Use Cilium instead of Flannel

After Provisioning: Universal Commands

Once you have a kubeconfig, these commands work on ALL providers:

Install Dapr

dapr init -k
kubectl get pods -n dapr-system

Install Ingress Controller (Traefik)

helm repo add traefik https://helm.traefik.io/traefik
helm install traefik traefik/traefik \
  --namespace traefik \
  --create-namespace

Install cert-manager

kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.16.2/cert-manager.yaml

Create Let's Encrypt Issuer

# cluster-issuer.yaml
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: your-email@example.com
    privateKeySecretRef:
      name: letsencrypt-prod
    solvers:
    - http01:
        ingress:
          ingressClassName: traefik

Deploy Task API

helm upgrade --install task-api ./task-api-chart \
  --set image.repository=ghcr.io/your-org/task-api \
  --set image.tag=v1.0.0 \
  --set ingress.enabled=true \
  --set ingress.host=tasks.yourdomain.com \
  --set ingress.tls.enabled=true

Cloud-Specific Considerations

LoadBalancer Service Behavior

ProviderLoadBalancer CreationCost
DOKSAuto-provisions DO Load Balancer$12/mo
AKSAuto-provisions Azure LB~$18/mo
GKEAuto-provisions GCP LB~$18/mo
EKSAuto-provisions AWS ELB~$18/mo
CivoAuto-provisions Civo LBIncluded
Hetzner K3sNO auto-provisionUse NodePort + external LB

Hetzner Workaround for LoadBalancer

Since Hetzner K3s doesn't auto-provision LoadBalancers:

# Use NodePort + Hetzner Load Balancer
apiVersion: v1
kind: Service
metadata:
  name: traefik
  annotations:
    load-balancer.hetzner.cloud/name: "task-api-lb"
    load-balancer.hetzner.cloud/location: "fsn1"
spec:
  type: LoadBalancer  # hetzner-k3s includes CCM that handles this
  ports:
  - name: web
    port: 80
    targetPort: 8000

The hetzner-k3s tool includes the Hetzner Cloud Controller Manager, which can provision LoadBalancers automatically.

DNS Configuration

ProviderDNS OptionHow to Configure
DOKSDigitalOcean DNS or externalSpaces → Networking → Domains
AKSAzure DNS or externalDNS Zones service
GKECloud DNS or externalNetwork services → Cloud DNS
EKSRoute53 or externalRoute53 hosted zones
CivoCivo DNS or externalNetworking → DNS
HetznerExternal only (Cloudflare, etc.)Use external DNS provider

Image Pull from GHCR

# Create image pull secret (same on all clouds)
kubectl create secret docker-registry ghcr-secret \
  --docker-server=ghcr.io \
  --docker-username=YOUR_GITHUB_USERNAME \
  --docker-password=YOUR_GITHUB_PAT

# Reference in deployment
spec:
  imagePullSecrets:
  - name: ghcr-secret

Cost Optimization Strategies

1. Right-Size Nodes

Development: 2 vCPU, 4GB RAM (cheapest viable)
Production: 4 vCPU, 8GB RAM (balanced)
High-traffic: 8 vCPU, 16GB RAM (performance)

2. Use Node Autoscaling

All managed providers support autoscaling. Set min=1, max=10 to scale with demand.

3. Schedule Non-Production Downtime

# Scale to zero at night
kubectl scale deployment task-api --replicas=0

# Or use KEDA for event-driven scaling

4. Consider Spot/Preemptible Nodes

  • AWS: 60-90% savings with Spot
  • GCP: 60-91% savings with Preemptible
  • Azure: Similar savings with Spot
  • Not available: DOKS, Civo, Hetzner

5. Teardown When Not in Use

# DOKS
doctl kubernetes cluster delete task-api-cluster -f

# AKS
az aks delete --resource-group task-api-rg --name task-api-cluster --yes

# GKE
gcloud container clusters delete task-api-cluster --location us-central1 -q

# EKS
eksctl delete cluster --name task-api-cluster

# Civo
civo kubernetes remove task-api-cluster -y

# Hetzner K3s
hetzner-k3s delete --config cluster.yaml

Safety & Guardrails

NEVER

  • Leave clusters running without monitoring costs
  • Deploy without resource requests/limits
  • Expose cluster API to 0.0.0.0/0 in production
  • Store cloud credentials in code or git
  • Skip TLS for production traffic
  • Use the same cluster for production and development

ALWAYS

  • Set budget alerts in cloud console
  • Use namespaces to separate environments
  • Enable cluster autoscaling with sensible limits
  • Configure node auto-upgrade (managed providers)
  • Use private node pools when available
  • Backup etcd (for self-managed clusters)
  • Document teardown commands for every cluster

Cost Alerts Setup

DigitalOcean: Settings → Billing → Alerts Azure: Cost Management → Budgets GCP: Billing → Budgets & alerts AWS: Billing → Budgets Civo: Dashboard → Account → Billing alerts Hetzner: Project → Usage → Limits (manual monitoring)

TaskManager Production Deployment

Complete example deploying Task API to DigitalOcean DOKS:

# 1. Create cluster
doctl kubernetes cluster create task-prod \
  --region nyc1 \
  --size s-2vcpu-4gb \
  --count 3 \
  --wait

# 2. Save kubeconfig
doctl kubernetes cluster kubeconfig save task-prod

# 3. Install Dapr
dapr init -k
kubectl wait --for=condition=available --timeout=120s \
  deployment/dapr-operator -n dapr-system

# 4. Install Traefik
helm repo add traefik https://helm.traefik.io/traefik
helm install traefik traefik/traefik \
  -n traefik --create-namespace

# 5. Get LoadBalancer IP
kubectl get svc traefik -n traefik -w
# Wait for EXTERNAL-IP

# 6. Install cert-manager
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.16.2/cert-manager.yaml
kubectl wait --for=condition=available --timeout=120s \
  deployment/cert-manager -n cert-manager

# 7. Create ClusterIssuer for Let's Encrypt
kubectl apply -f - <<EOF
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: admin@yourdomain.com
    privateKeySecretRef:
      name: letsencrypt-prod
    solvers:
    - http01:
        ingress:
          ingressClassName: traefik
EOF

# 8. Deploy Task API with Helm
helm upgrade --install task-api ./charts/task-api \
  --set image.repository=ghcr.io/your-org/task-api \
  --set image.tag=v1.0.0 \
  --set ingress.enabled=true \
  --set ingress.host=tasks.yourdomain.com \
  --set ingress.tls.enabled=true \
  --set ingress.annotations."cert-manager\.io/cluster-issuer"=letsencrypt-prod

# 9. Verify deployment
kubectl get pods
kubectl get ingress

# 10. Test HTTPS endpoint
curl https://tasks.yourdomain.com/health

References

For detailed patterns, see:

  • references/digitalocean-doks.md - DOKS-specific patterns
  • references/hetzner-k3s.md - Hetzner + K3s setup
  • references/cloud-comparison.md - Full provider comparison
  • references/cost-optimization.md - Cost engineering patterns

More by panaversity

View all
fetch-library-docs
40

Fetches official documentation for external libraries and frameworks (React, Next.js, Prisma, FastAPI, Express, Tailwind, MongoDB, etc.) with 60-90% token savings via content-type filtering. Use this skill when implementing features using library APIs, debugging library-specific errors, troubleshooting configuration issues, installing or setting up frameworks, integrating third-party packages, upgrading between library versions, or looking up correct API patterns and best practices. Triggers automatically during coding work - fetch docs before writing library code to get correct patterns, not after guessing wrong.

browsing-with-playwright
40

Browser automation using Playwright MCP. Navigate websites, fill forms, click elements, take screenshots, and extract data. Use for web browsing, form submission, web scraping, or UI testing. NOT for static content (use curl/wget).

skill-validator
40

Validates skills against production-level criteria with 9-category scoring. This skill should be used when reviewing, auditing, or improving skills to ensure quality standards. Evaluates structure, content, user interaction, documentation, domain standards, technical robustness, maintainability, zero-shot implementation, and reusability. Returns actionable validation report with scores and improvement recommendations.

interview
40

This skill conducts discovery conversations to understand user intent and agree on approach before taking action. It should be used when the user explicitly calls /interview, asks for recommendations, needs brainstorming, wants to clarify, or when the request could be misunderstood. Prevents building the wrong thing by uncovering WHY behind WHAT.