Migrating from Adobe Managed Services (AMS) to AEM as a Cloud Service (AEMaaCS) is not an upgrade. It’s a re-platforming. The underlying runtime, deployment model, content architecture, and operational posture all change. Teams that approach it like a version bump will struggle. Teams that treat it as a greenfield migration with an existing codebase will move faster and make fewer avoidable mistakes.
After working through this migration in enterprise contexts, here’s what I’d tell a team at the start of the journey.
Understand What Actually Changed
AEMaaCS is not AEM 6.5 running in the cloud. Adobe rebuilt the platform around a few core principles that have cascading implications for everything you’ve built:
Immutable infrastructure. There is no SSH access to author or publish. No manually dropping OSGi bundles. No CRX/DE on production. Every change goes through Cloud Manager’s CI/CD pipeline. If you’ve relied on in-place configuration tweaks in production, that workflow is gone.
Auto-scaling publish tier. Publish instances scale horizontally based on load. This means any code that assumes a single publish node — local caches, in-memory session data, node-local file writes — is broken by design.
Content repository constraints. Mutable content under /content and /conf works as before. But content under /apps, /libs, and /etc is now read-only at runtime. If your deployment has been writing to /apps dynamically, that will not work in Cloud Service.
OSGi R7 and Java 11/21. The platform has moved forward. Code written against older Sling or AEM APIs that were deprecated in 6.x is now unsupported. The migration surface area is often larger than teams expect.
The Assessment Phase Is Not Optional
Before writing a line of migration code, run Adobe’s AEM as a Cloud Service Best Practices Analyzer (BPA). It scans your repository and generates a report of patterns that are incompatible or deprecated. Take this report seriously — it’s the closest thing to a migration scope document you’ll get before digging in.
What the BPA will commonly surface:
- Custom Workflow processes using deprecated WorkflowSession APIs
- Servlet registrations using deprecated
sling.servlet.pathsinstead of resource type registration - ReplicationAction usage that needs to be replaced with Sling Distribution APIs
- Custom oak index definitions that don’t meet Cloud Service constraints
- Third-party OSGi bundles that embed outdated AEM dependencies
The BPA output maps to the Migration Effort Index — Adobe’s scoring of how complex your migration is. Do not present this to stakeholders without context. A high score does not mean the migration is impossible; it means the codebase has accumulated technical debt that the migration will now force you to pay.
Content Migration: Plan Before You Code
AEMaaCS has a Content Transfer Tool (CTT) that moves content from AMS to Cloud using an extraction-and-ingestion model. Understanding its constraints early will save significant rework:
- Versions are optional. By default CTT migrates the current content tree. Migrating full version history is possible but dramatically increases transfer size and ingestion time. Make a deliberate choice, not a default one.
- User data is separate. Users and groups come from IMS/Admin Console in AEMaaCS. You cannot migrate local CRX user accounts directly. Map your user/group structure to IMS groups before content migration begins.
- Iterative top-up migrations. CTT supports incremental migrations — initial extraction followed by delta top-ups as the source AMS environment continues to be used. Design your migration schedule around this. A single big-bang cut-over is avoidable.
- Assets require special handling. Large DAM repositories benefit from pre-migration using Azure Blob Storage or S3 bulk import before using CTT. Running CTT over 10TB of assets is slow and fragile.
Dispatcher: Almost Everything Changes
The Dispatcher configuration model in AEMaaCS is managed through Cloud Manager and follows a strictly defined folder structure. If your AMS Dispatcher config has evolved organically over years — custom includes, non-standard folder layouts, environment-specific overrides committed directly to the server — that configuration must be restructured before it can deploy to Cloud Service.
Key changes to plan for:
- Configuration must be validated locally using Adobe’s Dispatcher Docker tool before deployment
- Environment-specific variables are injected via Cloud Manager environment variables, not hardcoded in vhost files
- The
DispatcherPassErrordirective is not supported — error pages must be handled at the CDN or AEM layer - Flush agents are gone; cache invalidation is now handled by the platform automatically on publish
Budget meaningful time for Dispatcher. Teams consistently underestimate it.
Code Refactoring: Where the Real Work Lives
Once the assessment is complete and the content plan is defined, the bulk of the engineering effort falls on code refactoring. Specifically:
- Removing usage of deprecated APIs — ReplicationAction, WorkflowSession, legacy Sling servlet patterns
- Fixing mutable vs. immutable path violations — content being written to
/appsor/libsat runtime - Updating OSGi service references to use current annotation-based component declarations
- Replacing custom Lucene index definitions with Oak-compatible equivalents
- Removing container-aware patterns — anything that assumes a stable, single JVM
For a codebase that’s been running on AEM 6.3 or 6.4 since it was initially built, this is a significant body of work. A large enterprise implementation might have 200+ custom OSGi components, 50+ workflow steps, and dozens of Sling servlets that all need review.
This is where AI tooling has become a genuine accelerant.
How AI Helps With Code Refactoring
The refactoring task that migration demands is precisely the kind of work where AI coding assistants perform well: it’s pattern-based, repetitive, well-documented (Adobe’s deprecation notices are thorough), and the transformation rules are consistent.
API migration at scale. The shift from com.day.cq.replication.ReplicationAction to Sling Distribution is the same transformation every time. An AI assistant that has been given the correct target API pattern can apply that transformation across hundreds of files far faster than a developer manually working through each one. The developer’s job shifts from doing the transformation to reviewing it.
// Before: AMS-era replication trigger
replicationService.replicate(session, ReplicationActionType.ACTIVATE, path);
// After: Sling Distribution API
distributionRequestFactory.createRequest(DistributionRequestType.ADD, paths);
Identifying suppressed deprecation warnings. Production codebases often have @SuppressWarnings("deprecation") scattered across classes where a previous developer acknowledged the deprecation and moved on. AI tooling can surface all of these, explain what the deprecated call does, and propose a compliant replacement — with context about why the API was deprecated.
OSGi annotation modernisation. The shift from Felix SCR annotations (@Component, @Service, @Reference from org.apache.felix.scr.annotations) to OSGi DS annotations (org.osgi.service.component.annotations) is a mechanical transformation. AI assistants handle this well, and getting it wrong is easy to review because the structure is identical.
Writing migration tests. Before and after a refactor, you want tests that confirm the component behaves identically. AI can generate unit test scaffolding for Sling components using the AEM Mocks framework (io.wcm.testing.mock.aem), dramatically reducing the time to achieve test coverage on refactored code.
Generating Oak index definitions. Custom Lucene index definitions from AEM 6.x need to be validated and potentially restructured for AEMaaCS. Given the index definition and the query patterns it’s meant to support, AI tooling can propose a compliant equivalent and flag properties that are disallowed in Cloud Service.
What AI Does Not Replace
Be clear-eyed about the limits. AI-assisted refactoring is a multiplier on developer productivity, not a replacement for developer judgment.
- Business logic validation — the tool can transform the code, but only a developer who understands the workflow knows whether the output is semantically equivalent.
- Data migration edge cases — content structure irregularities that exist because of years of manual patches require human investigation.
- Performance characteristics — a refactored Sling query that is structurally correct might still perform poorly against the Cloud Service index configuration. Testing matters.
- Security review — new API surfaces introduced during refactoring need the same security scrutiny as any new code.
Use AI to compress the mechanical work. Keep developers in the loop for decisions.
The Migration Sequencing That Works
Based on what I’ve seen succeed:
- Run BPA, triage output into P1/P2/P3 by impact. Don’t try to fix everything simultaneously.
- Freeze feature development on the AMS codebase for the migration window. New features built on AMS APIs are new migration debt.
- Refactor code on a migration branch with CI running against AEMaaCS SDK locally. Don’t wait for Cloud Manager to discover failures.
- Migrate a non-production environment first. Use Cloud Manager’s Stage environment to validate the full stack before touching production content.
- Run parallel environments for a defined period post-cutover — AMS in read-only mode, AEMaaCS live — so rollback is possible if a critical issue surfaces.
- Decommission AMS on a schedule, not immediately. The pressure to shut off the old environment early is a cost-saving argument that creates risk. Resist it.
My Take
The AMS-to-Cloud migration is the kind of project that tests whether an organisation’s AEM investment was built on solid foundations or on accumulated workarounds. The ones built on workarounds will have a harder time — but the migration is also an opportunity to clear that debt in a structured way.
The teams I’ve seen move through it most effectively are the ones that treat it as an engineering project with a defined scope, a realistic timeline, and AI-assisted tooling applied thoughtfully to compress the mechanical refactoring work. The teams that struggle are the ones that underestimate the assessment phase, skip the Dispatcher work, and discover content migration constraints six weeks before go-live.
Start early, instrument everything, and let the AI handle the repetitive transformations so your engineers can focus on the decisions that actually require judgment.