hmn
the human engineer

the migration that made us curious again

in november 2024, my team migrated macOS device management providers from Jamf Pro to Fleet Device Management. it took 9 days. it went well. and i’ve been meaning to write about it ever since.

here’s the thing about writing a migration story over a year later in my world: the landscape has already shifted. Apple shipped native MDM migration support in macOS 26, complete with admin-set deadlines and enforced re-enrollment. Jamf announced a unified Platform API ecosystem at JNUC 2025 that addresses a lot of the API fragmentation we ran into. the world has moved.

so this isn’t a “here’s why you should leave Jamf” post. Jamf served us well for years. it kept our devices in line, profiles applied, policies shipped. it did the job.

but in late 2024, our team was evolving. we were thinking less like IT administrators and more like engineers. we wanted to manage devices the way we managed everything else: through code, through automation, through workflows that didn’t require someone clicking through a UI on a Tuesday night. we were spending more time maintaining the MDM than actually helping people. and the API limitations at the time made building reliable automation harder than it needed to be.

so we went looking for something that matched where we were headed. we found Fleet.

why fleet

this wasn’t a “shiny new tool” decision. it was a “where do we want to be in two years” decision.

Fleet checked a few boxes that mattered to us:

one platform, multiple operating systems. we were running separate MDMs for macOS and Windows. that’s two admin consoles, two sets of policies, two places to check when something breaks. Fleet gave us a single pane of glass for everything. fewer tools, fewer headaches.

configure with code. we’d already gone down this road with Okta, managing our identity provider through Terraform and treating configuration like infrastructure. Fleet gave us the same option for device management. policies, profiles, and settings defined in YAML, stored in a Git repo, applied through pull requests. version-controlled configs, repeatable deployments, no more “who changed that profile last month?” and if GitOps isn’t your thing, the admin UI works just fine too.

actual transparency. Fleet is open-source. not “open-source-ish” or “we publish some things.” their entire codebase, bug tracker, and roadmap live on GitHub. when we found bugs, we reported them. when we wanted features, we requested them. and Fleet actually listened and shipped. that’s rare.

support that feels like a partnership. from the start, Fleet’s support felt less like a vendor relationship and more like having an extra teammate. our team had direct access to real people who knew our environment, and throughout the migration, that responsiveness made a real difference. Fleet’s “My Device” page also lets every employee see exactly what’s being managed on their machine. no mystery, no “what is IT doing to my laptop?” it builds trust with the people using the devices, and trust makes everything else easier.

how we pulled it off

the prep work

before we could move anything, we needed to get organized. we started by cleaning house in Jamf, trimming the cruft that accumulates when you’ve been running a platform for years. then we extracted everything that mattered: policies, configuration profiles, the settings we actually relied on. all of it got cataloged and turned into a project plan so nothing got lost in translation.

Fleet’s policy engine runs on osquery, which was new to us. learning a new query language in the middle of a migration sounds stressful, but we leaned on AI assistants to help bridge the gap between what we had in Jamf and what Fleet needed. it ended up being one of those “learn by doing” situations that actually worked.

the tracking system

we needed a single source of truth for every device in the migration. where is it, what’s its status, has it enrolled, does it need attention.

we went with an Okta Workflows table, which was a deliberate choice. we already knew Okta Workflows was going to be our automation engine for a bunch of post-migration tasks, so having the tracking data native to the same platform meant our automations could read and write without the latency of bouncing between external APIs. no round-trips to a Google Sheet, no waiting on third-party connections. just fast, direct access to the data right where the logic lived.

deploying the agent

before we could migrate anyone, we needed the Fleet agent on every Mac. so we used the tool we were migrating away from to get it done. poetic, right?

we built a custom Fleet agent package using fleetctl and pushed it out via a Jamf policy. within a few days, the majority of our fleet had the agent installed and checking in.

the announcement

we sent a company-wide Slack message. it was friendly, clear, and included links to docs and support. we told people what to expect, reassured them it would be painless, and kept the tone light. this part matters more than people think. a migration only goes smoothly if the humans involved aren’t anxious about it.

the actual migration

we updated Apple Business Manager to reassign devices from Jamf to Fleet. then, from the employee’s perspective, it was three steps:

  1. click “Migrate to Fleet” in the Fleet menu bar icon
  2. click “Start” in the migration window
  3. click “Enroll” when Apple’s Remote Management prompt appeared

that’s it. no tickets, no appointments, no “bring your laptop to IT.”

the automation layer

this is the part i’m most proud of.

once a device enrolled in Fleet, a chain of Okta Workflows kicked in automatically. the device got assigned to its proper team in Fleet. nightly scripts cleaned up leftover Jamf artifacts so nothing lingered from the old world. a health check workflow scanned for broken enrollments and quietly fixed issues before anyone had a chance to notice them. and every migration event posted to Slack in real-time, giving us a running scoreboard of where things stood.

we didn’t have to babysit the migration. we built the workflows, set them loose, and watched devices roll through. the Okta Workflows table tied it all together: at any point, we could see how many devices had migrated, who was still pending, and whether anything needed attention.

the results

the migration went smoothly. really smoothly. but the speed isn’t the real story.

what mattered was what happened after. we eventually consolidated into a single MDM (Windows came later in 2025), and our team found a new gear. it’s hard to describe without sounding like i’m knocking what came before, and i want to be clear: Jamf was the only MDM i’d ever known, and it earned its place. it kept our environment healthy for years.

but somewhere along the way, we’d stopped being curious. the tool wasn’t evolving at the pace our ambitions were, and that gap had quietly made us stagnant. Fleet gave us a breath of fresh air. not just a new tool, but a new energy. the pace of development, the open roadmap, the possibilities baked into the platform. it made us want to build again, explore again, ask “what if” again.

we went from maintaining to imagining.

that’s the part nobody tells you about a good migration. it’s not just about moving from one thing to another. it’s about what you get to do once you’re on the other side.

looking ahead (and back)

it’s funny writing about a migration that happened over a year ago. the tools have changed, Apple has made the mechanics easier, and even Jamf has evolved. if we were doing this today, some of the hoops we jumped through simply wouldn’t exist.

but the stuff that made it work? the automation strategy, the communication, the decision to bet on a platform that made our team excited to build again? that’s timeless. no OS update is going to automate that for you.

we’ve been building on Fleet ever since. this is the first post. it won’t be the last.

Back to top