PILOT Technology Solutions
  • Missions
  • Services
  • Pilot Book
  • About
  • Contact
PILOT BOOK GUIDES / OPERATIONAL NOTES

Pilot Book: Migration

Moving from AWS, Azure, or Microsoft 365 to private infrastructure. What it actually involves.

What is inside

  • Setup guides and real-world implementation notes
  • Tradeoffs, costs, and deployment assumptions
  • Enough detail to build, not just admire

Contents

  • Overview
  • Requirements
  • Installation
  • Cost Analysis
  • Why Fly with Us

What you're actually doing

Migration is not a single task. It is a sequence of tasks, each with dependencies, each with failure modes, some of which only reveal themselves after you've started.

This guide covers the methodology — how to assess, plan, and execute a migration from public cloud or Microsoft 365 to private infrastructure — without destroying your operations in the process.


Phase 1: Assessment (do not skip this)

Before moving anything, understand what you have.

Workload inventory For every service you're running, document:

  • What it does
  • What it depends on (databases, other services, external APIs)
  • How much data it has
  • How much traffic it receives
  • What the impact of 4 hours of downtime would be

This inventory takes longer than you expect. Budget 2–4 weeks for a medium-sized environment.

The repatriation decision framework Not everything should move. Apply this filter to each workload:

Move to private infrastructure if:

  • It runs 24/7 with predictable resource requirements
  • It handles sensitive data that shouldn't be on US-owned infrastructure
  • Its cloud costs are high relative to the compute it actually uses
  • It has no elastic demand — it doesn't need to scale from zero to 100 overnight

Keep in public cloud if:

  • It has genuinely unpredictable, spiky demand
  • It uses managed services with no good open source equivalent (some ML pipelines, some analytics)
  • The migration cost exceeds 18 months of cloud savings

Data volumes Download a cost and usage report from AWS or Azure. Find every S3 bucket, EBS volume, RDS instance, and service. Map actual usage vs. provisioned capacity. This is where you find the waste.


Phase 2: Target environment

Stand up your private infrastructure before you start migrating.

For most migrations:

  1. Proxmox cluster (or single node for small environments)
  2. OPNsense for networking
  3. Proxmox Backup Server
  4. TOWER monitoring configured and alerting
  5. SSO (Authentik/Keycloak) if replacing Azure AD

Do not migrate into an environment that isn't stable and monitored. You'll be debugging the infrastructure and the migration simultaneously.


AWS/Azure workload migration

Databases Migrate databases first — they're the riskiest and need the most validation time.

PostgreSQL:

# On AWS RDS - dump
pg_dump -h your-rds-endpoint -U username dbname > db_backup.sql

# On new server - restore
psql -h new-server -U username dbname < db_backup.sql

Run both databases in parallel. Point a test version of your application at the new database. Validate data integrity before switching production traffic.

MySQL/MariaDB — same approach with mysqldump.

Storage (S3) Use rclone for S3 bucket transfer:

# Configure rclone with AWS source and MinIO destination
rclone sync s3:your-bucket minio:your-bucket --progress

For large buckets: run the initial sync, then run it again just before cutover to catch changes. Don't try to do a single sync of a large bucket and cut over immediately — things change.

Application VMs For Linux VMs: snapshot → export → import to Proxmox.

AWS: create an AMI, export to S3 as VMDK, convert with qemu-img, import to Proxmox.

Or, better for most cases: provision a fresh VM on Proxmox, redeploy from your configuration management (Ansible/Terraform), migrate data separately. Avoid carrying forward accumulated VM cruft.

DNS cutover Reduce TTL to 60 seconds 48 hours before cutover. Make the change. Wait 15 minutes. If something is wrong, you can revert quickly while old DNS is still cached elsewhere.

After successful cutover: don't immediately terminate AWS instances. Keep them running for 48–72 hours as fallback. Then terminate.


Microsoft 365 exit

M365 exit is the most common migration we see. The mapping:

M365 Private replacement Tool
Exchange/Outlook iRedMail + Proofpoint + CrossBox imapsync
SharePoint/OneDrive Nextcloud rclone
Teams Mattermost or Matrix/Element manual
Azure AD/Entra Keycloak or Authentik manual
OneDrive sync Nextcloud desktop client —

Mail migration with imapsync

imapsync   --host1 outlook.office365.com --ssl1 --user1 user@company.com --password1 "M365pass"   --host2 your-mail-server --ssl2 --user2 user@company.com --password2 "newpass"

Run imapsync first in dry-run mode (--dry). Then run for real. Then run again at cutover time to catch mail received during migration.

File migration from SharePoint/OneDrive

rclone sync onedrive:Documents nextcloud:Documents --progress

Rclone supports OneDrive natively. Configure once, run the sync, then run again at cutover. Preserve folder structure — Nextcloud maps directly.

The hard part: Teams There is no good automated migration from Teams to Mattermost or Matrix. Message history can be exported from Teams (compliance export) but importing into Mattermost requires custom scripting.

Practical approach: don't migrate Teams history. Set a cutover date. Archive Teams export for compliance. Start fresh in Mattermost. Most teams accept this — old message history is rarely accessed after 90 days.

Azure AD No good automated migration. The approach: recreate users in Keycloak or Authentik, set temporary passwords, force password reset on first login.

If you're running hybrid AD (on-prem + Azure AD): run Keycloak with LDAP sync from your on-prem AD as a transition step.


What takes longer than you expect

DNS propagation — you know this, and you still underestimate it. 48-hour TTL reduction is not optional. Budget an extra day.

Mail deliverability warmup — a new IP sending full mail volume immediately looks like a spam operation. Warm up gradually: 10% of volume on day 1, 25% on day 3, 50% on day 7, 100% on day 14. This matters.

User acceptance — the new interface is not Outlook. Budget time for user questions, training, and the inevitable "can we go back" conversations. They pass within 2 weeks.

Edge cases in SharePoint — SharePoint custom column types, metadata, and permissions don't map cleanly to Nextcloud folder structure. Identify these before migration, not during.

Leavers and inactive accounts — every M365 tenant has accounts for people who left 3 years ago, still with mail in their mailboxes. Decide your policy for these before starting.


Honest timeline estimates

Migration scope Realistic timeline
Mail only (< 50 users) 2–4 weeks
Full M365 exit (< 50 users) 6–10 weeks
Full M365 exit (50–200 users) 3–6 months
AWS workload migration (< 20 VMs) 4–8 weeks
AWS workload migration (20+ VMs) 3–6 months

These assume part-time effort (not a dedicated migration team). Double the time estimate if this is being done alongside normal operations by the same people responsible for production.


Or let PILOT run it

Migration is complex. We've done it before. Assessment, planning, execution, validation — that's the migration service.

Request access →

PILOT PM / OPERATIONS

Built for sovereign delivery, clear handoff, and repeatable deployments.

This site is structured to keep the brand, the content, and the operational layers visually aligned.

Company

About Contact Pilot Book

Services

Infrastructure Mail Cloud

Mission

Missions AI / ML Developer

Resources

Stack Tower GPU

© 2026 PILOT Technology Solutions. All rights reserved.

Selected for teams that need the work done, not just documented.