Provider Migrations
This document describes the steps for migrating openDesk from one cloud service provider to another. For the sake of simplicity this document assumes that the Kubernetes-Cluster is an off-the-shelf cluster of said CSP, hence no K8S-Migration occurs. We also assume that in-cluster persistence services are used (e.g. S3, PostgreSQL,…). CSP-Services may behave differently but follow similar patterns.
Provider migrations are complex operations. Plan the migration during a maintenance window and communicate expected downtime to users.
The describes approach is generic. However, the data-flow is heavily based on a central S3-Bucket. High capacity migrations ( e.g. many TB ) may require a performance focused solution.
Guidelines & Suggestions
The following values have proven effective in practice. Adjust based on your infrastructure and requirements.
| Setting | Suggested Value | Rationale |
|---|---|---|
| DNS TTL | ~300s | Short enough for quick transition, long enough for DNS provider compatibility and debugging |
| Source retention | 7-14 days | Sufficient window to detect post-migration issues |
| K8up snapshot retention | ≥14 days | Allows point-in-time recovery after migration |
| Maintenance window prep | Announce 1-2 weeks ahead | Users can plan accordingly |
| Port-forward stability | Use bastion/jump host | Avoids unstable local connections during long operations |
Timeline & Overview
What to Migrate
1. Configuration Files
| File | Purpose |
|---|---|
databases.yaml.gotmpl | Database connection settings |
objectstores.yaml.gotmpl | S3/object storage config |
cache.yaml.gotmpl | Cache service config |
secrets.yaml.gotmpl | All secrets and passwords |
smtp.yaml.gotmpl | SMTP/mail relay config |
2. Database Credentials
All database credentials are derived from the master password using the Master Password algorithm. As long as the same master password is used in the target deployment, all derived credentials will match automatically.
Database credentials in openDesk work as follows:
- Technical usernames (e.g.,
keycloak_user) are defined indatabases.yaml.gotmpl - Database passwords are derived from
MASTER_PASSWORDvia the Master Password algorithm insecrets.yaml.gotmpl - To migrate: Use the same
MASTER_PASSWORDin target deployment, then migrate only the actual data
If you must change the master password, you would need to regenerate all derived passwords manually - this is not covered in this migration guide.
3. Kubernetes Secrets
Migrate all Kubernetes Secrets from the source namespace to ensure credentials, API keys, and certificates are available in the target cluster.
Alternatively, use the K8up PreBackupPod approach:
- The PreBackupPod
secrets-pre-backup-podexports all secrets as JSON - This can be restored using K8up Restore CR
4. Object Storage (S3 Buckets)
| Bucket | Component | Content |
|---|---|---|
nextcloud | Files | User files, versioning, trash |
openproject | Projects | Project attachments |
openxchange | Groupware | Email attachments, drive files |
elementmedia | Chat | Uploaded images, files |
openxchange | Dovecot Pro EE | User mail |
5. LDAP Data
Export OpenLDAP directory from the ums-ldap-server-primary service.
Secret Service: ums-ldap-server-admin (password key)
Base DN: Get from pod environment (LDAP_BASE_DN), default: dc=swp-ldap,dc=internal
6. DNS Records
| Record Type | Purpose |
|---|---|
| A/CNAME | Main ingress, subdomains |
| MX | Mail delivery |
| TXT: SPF | Authorized mail servers |
| TXT: DKIM | Email signing keys |
| TXT: DMARC | Email authentication policy |
| SRV | Service discovery |
Migration Steps
Step 1: Reduce DNS TTLs (days before)
Consider setting DNS TTL to ~300 seconds for faster propagation and easier rollback.
Many openDesks are managed by delegated DNS-Zones. Zone-TTLs are often quite high. Depending on what exactly is migrated ( zone or record ) the shortened TTL may be the zone or the records.
Step 2: Build New Infrastructure
- Use existing configuration files to deploy openDesk on new provider. openDesk is domain-centric, hence a Test-Deployment on a different domain may be used to verify the deployment generally works but needs to be re-deployed with the correct domain for a later migration.
- Verify base deployment works.
Most openDesk setups require LetsEncrypt for certificate handling. Transfer the LE Secrets. Alternatively the DNS-Challenge may issue valid certificates to an offline-cluster.
Step 3: Maintenance Window - Disable Ingress
Consider disabling all ingresses to prevent new write traffic during migration.
The nginx.ingress.kubernetes.io/server-snippet annotation breaks Collabora ingresses because they already use a server-snippet. If you need to abort the migration, the Collabora ingress must be redeployed. Consider scaling down write-heavy services instead.
Ensure all ingresses are disabled before starting data export to prevent data inconsistencies between source and target.
Run migration commands from an infrastructure-near system (e.g., a jump host or bastion) rather than your local machine to ensure stable connections.
Step 4: Export All Data
Export all databases, LDAP, object storage, and Kubernetes Secrets to the migration S3 bucket.
Key export commands:
- PostgreSQL:
pg_dumpvia port-forward - MariaDB:
mysqldumpvia port-forward - LDAP:
ldapsearchvia port-forward - Object Storage:
aws s3 sync - Secrets:
kubectl get secrets -o json
Step 5: Import All Data
Restore all databases, LDAP, object storage, and Kubernetes Secrets to the target cluster.
Key import commands:
- PostgreSQL:
pg_restorevia port-forward - MariaDB:
mysqlvia port-forward - LDAP:
slapadd(stop StatefulSet first) - Object Storage:
aws s3 sync - Secrets:
kubectl apply -f
Step 6: Nameserver Cutover
The nameserver switch approach allows you to prepare DNS changes before the migration window, significantly reducing downtime.
DNS Records to Migrate
| Record | Source | Target | Notes |
|---|---|---|---|
| A/CNAME | Old provider’s DNS zone | New provider’s DNS zone | Main ingress IP or alias |
| MX | Old provider’s DNS zone | New provider’s DNS zone | Mail delivery target |
| SPF | Old provider’s DNS zone | New provider’s DNS zone | TXT record with v=spf1 ... |
| DKIM | OpenDKIM/Keycloak pod | New DNS zone | TXT record with v=DKIM1... |
| DMARC | Old provider’s DNS zone | New provider’s DNS zone | TXT record with _dmarc. prefix |
Copy SPF Record
- From: Query current DNS at old provider
dig TXT yourdomain.com +short # or nslookup -type=TXT yourdomain.com - To: Add identical TXT record at new DNS provider
- Verify:
dig TXT yourdomain.com +shortafter propagation
Copy DKIM Record
- From: Extract public key from OpenDKIM pod or Keycloak
# Option A: From OpenDKIM pod kubectl exec -n ${SOURCE_NS} opendkim-0 -c main -- cat /etc/opendkim/keys/${DOMAIN}/mail.txt # Option B: From Keycloak realm settings (if DKIM is managed there) # Check realm settings in Keycloak admin UI under Email -> DKIM - To: Add as TXT record at new DNS provider
- Selector: match what your current
_domainkey.yourdomain.comshows (oftendefaultormail) - Content: The full
v=DKIM1; p=...string
- Selector: match what your current
- Verify:
dig TXT default._domainkey.yourdomain.com +short
Copy DMARC Record
- From: Query current DNS
dig TXT _dmarc.yourdomain.com +short - To: Add identical TXT record at new DNS provider with prefix
_dmarc - Verify:
dig TXT _dmarc.yourdomain.com +short
Execution Order
- Before migration window (preparation): Copy all records to new DNS provider but keep old nameservers active
- During migration window: Switch authoritative nameservers to new provider
- Wait for TTL propagation (typically 5-30 minutes)
MX, SPF, DKIM, and DMARC are critical for email deliverability. Verify each record matches exactly after migration.
Step 7: Post-Migration Restart
Consider restarting applications in a logical order (databases first, then services) to ensure proper initialization.
Step 8: Verification
Consider testing using DNS-resolved hostname or test accounts.
Step 9: Open to Users
- Allow access to new environment
- Monitor for issues
- Consider keeping source cluster running for 7-14 days (rollback option)
Verification Checklist
Authentication & Identity
| Test | Description |
|---|---|
| SSO Login | Login via Keycloak |
| LDAP Sync | Check user/group sync |
| 2FA | Test two-factor authentication |
| Password Reset | Test self-service |
Mail System
| Test | Description |
|---|---|
| Mail Inbound/Outbound | Send/receive email |
| IMAP/SMTP | Mail client access |
| Calendar Sharing | Share calendar |
Applications
| Test | Description |
|---|---|
| Nextcloud | Login, upload/download files |
| OX App Suite | Webmail, calendar, contacts |
| OpenProject | View/create work packages |
| XWiki | Create/edit pages |
| Element | Send messages |
| Jitsi | Video meeting |
Federation & Integrations
| Test | Description |
|---|---|
| Matrix Federation | External Matrix room |
| CalDAV Subscription | External calendar |
| Filepicker | OX to Nextcloud |
| OpenProject-Nextcloud | Link files |
Data Integrity & DNS
| Test | Description |
|---|---|
| User Files | Verify Nextcloud files |
| Email History | Check old emails |
| Calendar Events | Verify past events |
| Project Data | Check projects |
| DNS Records | A, MX, SPF, DKIM, DMARC |
| Certificates | Check TLS validity |
Migration-Specific Tests
| Test | Description |
|---|---|
| Secrets Restore | Verify all Kubernetes Secrets migrated correctly |
| Database Connections | Confirm applications connect to databases |
| S3 Access | Verify object storage access for all components |
| LDAP Users | Test login with existing users |
| Backup Integrity | Run K8up Check job to verify backup repository |
Consider running automated restore tests in a separate environment before production migration to validate backup integrity.
RTO Calculation
Cloud Interconnect (1 Gbps) migration times with safety factor (1.4×) and overhead (~45 min):
| Data Size | Transfer Time | With Overhead |
|---|---|---|
| 10 GB | ~2 minutes | ~50 minutes |
| 100 GB | ~20 minutes | ~1.5 hours |
| 1000 GB | ~3 hours | ~4.5 hours |
Formula used: ((Data_Size_GB × 8) / 1000) × 2 × 1.4 + 0.75 (hours)
Rollback
If migration fails:
- Keep DNS pointing to source
- Keep source cluster running
- Investigate and retry
- Use K8up Restore jobs to re-sync any partial data transfers
Consider retaining source infrastructure for 7-14 days after successful migration. Suggest keeping K8up snapshots available for at least 14 days to enable point-in-time recovery if issues are discovered post-migration.