Skip to content

Cloud Portability

KanjiIQ's Kubernetes manifests are approximately 90% portable across cloud providers. This page details the migration path to AWS and GCP, highlighting what stays the same and what needs to change.

What Stays the Same (Everywhere)

These resources work identically on any CNCF-conformant Kubernetes cluster:

  • Deployments: Pod specs, container definitions, resource limits, health probes
  • Services: ClusterIP services, port mappings, selectors
  • Secrets: Opaque secrets with stringData
  • PersistentVolumeClaims: Storage requests (cloud provisioners handle the rest)
  • Namespaces: Isolation boundaries
  • Docker images: OCI-compliant, run on any container runtime

Migration to AWS (EKS)

Architecture Mapping

graph TB
    subgraph Current["Current: Hetzner k3s"]
        A1[k3s] --> A2[Traefik]
        A1 --> A3[PostgreSQL on k8s]
        A1 --> A4[Forgejo Registry]
        A1 --> A5[cert-manager]
    end

    subgraph AWS["Target: AWS EKS"]
        B1[EKS] --> B2[ALB Ingress Controller<br/>or Traefik]
        B1 --> B3[RDS PostgreSQL]
        B1 --> B4[ECR]
        B1 --> B5[ACM<br/>or cert-manager]
    end

    Current -.->|Migration| AWS

Component-by-Component

Current AWS Equivalent Change Required
k3s EKS Cluster provisioning (eksctl/Terraform)
Traefik ALB Ingress Controller or keep Traefik Ingress annotations change
PostgreSQL on k8s RDS Update DATABASE_URL secret; remove PG manifests
Forgejo Registry ECR Update image URLs in Deployments; update CI/CD
cert-manager ACM Replace cert-manager annotations with ACM ARN
Forgejo Actions GitHub Actions or CodePipeline Rewrite workflow files
Local PV EBS (gp3) PVC works as-is; EKS auto-provisions EBS

Manifest Changes

Ingress (if switching to ALB):

# Before (Traefik)
metadata:
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
    traefik.ingress.kubernetes.io/router.entrypoints: websecure
spec:
  ingressClassName: traefik

# After (AWS ALB)
metadata:
  annotations:
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:...
    alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}]'
spec:
  ingressClassName: alb

Database (switching to RDS):

# Update the secret with RDS endpoint
stringData:
  database-url: "postgresql://user:[email protected]:5432/jlpt_flashcard"

Then delete 02-postgres-pvc.yaml and 03-postgres-deployment.yaml — RDS handles everything.

Estimated Effort

  • Cluster setup: 1-2 days (EKS + networking)
  • Manifest adaptation: 1 day (ingress, secrets, image URLs)
  • CI/CD rewrite: 1 day (GitHub Actions or CodePipeline)
  • Data migration: 1 day (pg_dump → RDS import)
  • DNS cutover: 1 hour
  • Total: ~4-5 days

Migration to GCP (GKE)

Component Mapping

Current GCP Equivalent Change Required
k3s GKE Cluster provisioning (gcloud/Terraform)
Traefik GKE Ingress or keep Traefik Ingress annotations change
PostgreSQL on k8s Cloud SQL Update DATABASE_URL; remove PG manifests
Forgejo Registry Artifact Registry Update image URLs
cert-manager Google-managed certs or keep cert-manager Annotation change
Forgejo Actions Cloud Build or GitHub Actions Rewrite pipelines
Local PV Persistent Disk PVC works as-is

Manifest Changes

Ingress (GKE native):

metadata:
  annotations:
    networking.gke.io/managed-certificates: kanjiiq-cert
spec:
  ingressClassName: gce

Estimated Effort

  • Cluster setup: 1-2 days
  • Manifest adaptation: 1 day
  • CI/CD rewrite: 1 day
  • Data migration: 1 day
  • Total: ~4-5 days

Multi-Cloud Strategy

For organizations requiring multi-cloud deployment:

Keep Portable

  1. Keep Traefik instead of cloud-native ingress (works identically on EKS, GKE, AKS)
  2. Keep cert-manager instead of ACM/Google certs (cloud-agnostic TLS)
  3. Keep PostgreSQL on k8s if avoiding vendor lock-in (trade-off: more operational burden)
  4. Use a cloud-agnostic registry like Harbor (self-hosted, works with any k8s)

Accept Cloud Services

For simplified operations, embrace managed services per cloud:

  • Database: RDS (AWS) / Cloud SQL (GCP) — significantly less operational burden
  • Registry: ECR (AWS) / Artifact Registry (GCP) — tight integration with IAM
  • TLS: ACM (AWS) / Managed Certs (GCP) — zero-maintenance certificates

The right choice depends on whether you prioritize portability (keep cloud-agnostic) or operational simplicity (use managed services).