> For AI agents: the complete documentation index is available at https://nhanbe.id.vn/llms.txt, the full documentation bundle is available at https://nhanbe.id.vn/llms-full.txt.

# AEM as a Cloud Service

## 14 – AEM as a Cloud Service

> **Target:** 3–4 years experienced AEM Developer **Syllabus point covered (23):** _"If you have worked on AEM Cloud, what is the benefit? How is it better than on-premise?"_ **Project domain:** a global energy technology company's marketing site.

***

## Before we start — the trap in this question

Your syllabus point 23 asks _"what's the benefit, how is it better than on-prem."_ That phrasing invites a sales pitch, and a sales pitch is exactly the wrong answer.

**Here's why.** The interviewer almost certainly works on a project that either runs Cloud Service, is migrating to it, or deliberately stayed on 6.5. In all three cases they know the real trade-offs. A candidate who recites "auto-scaling, always up to date, lower TCO" sounds like they read the marketing page. A candidate who says _"the biggest practical change for me was that `/apps` became read-only, which meant we had to rewrite five services that used admin sessions"_ sounds like they lived it.

**So the answer that scores is the one framed around what actually changed for a developer** — and that includes the things that got harder, not just easier.

There is also a second reason to be careful. This question is frequently a **screening question for whether you've genuinely worked on Cloud Service**. The follow-ups get specific fast: _how do you get logs? what's an RDE? what happens to `/apps` at runtime? how do you create a service user?_ Vague benefit-talk followed by "I'm not sure" on those is worse than a smaller, honest claim.

**Everything in this file has already appeared in earlier files** — immutability in file 01, Repoinit in files 01 and 13, Asset Compute in file 09, pod recycling in file 10. This file assembles it into one answer.

***

## 1. Introduction

### 1.1 The one sentence that frames everything

> **On AEM 6.5 you own a server. On Cloud Service you consume a service.**

Almost every difference follows from that.

A **server** is a machine you can log into. You can change it, restart it, put a file on its disk and expect it there tomorrow. You are also responsible for it — patching, upgrading, monitoring, backing up.

A **service** is something Adobe runs. The machines are containers created and destroyed as needed. They are **immutable** — you cannot change them while they run — and **disposable** — one might vanish and be replaced at any moment. You are not responsible for them, and you also cannot fix them.

**That trade is the honest summary:** you give up control and gain not having to care.

### 1.2 A real project example to adapt

> "We're on Cloud Service, migrated from 6.5 about two years ago. The genuine day-to-day benefits are that we stopped doing version upgrades entirely — Adobe ships updates continuously — and the publish tier scales itself during campaigns, which used to mean provisioning instances weeks ahead and then paying for them all year.
>
> The bigger change for us as developers was the discipline it forced. `/apps` is read-only at runtime, so there's no hotfixing in CRXDE — everything goes through Git and a Cloud Manager pipeline with quality gates. That's slower for a genuine emergency, but it eliminated a whole class of problem where production had drifted from what was in source control.
>
> The migration itself was mostly about removing things Cloud Service doesn't allow — admin sessions, install hooks, a custom run mode, and a service that wrote generated files to local disk."

That covers benefits, the developer-facing change, an honest cost, and migration reality — four follow-ups pre-empted.

***

## 2. Core Concepts

### 2.1 The architecture, and what's genuinely different

From file 01, but focused on what changed:

graph TD CM\["Cloud Manager\<br/>the ONLY way in"] --> AU\["Author service\<br/>clustered · DocumentNodeStore / Mongo"] CM --> PU\["Publish service\<br/>AUTO-SCALING pods · SegmentNodeStore"] AU -->|"Sling Content Distribution\<br/>pub/sub"| PU AU --> PV\["Preview service"] CDN\["Adobe-managed CDN"] --> DP\["Dispatcher\<br/>a container IN each publish pod"] DP --> PU AC\["Asset Compute microservices\<br/>processing OFF-instance"] --> AU

**Four structural changes worth naming:**

**Publish auto-scales.** Pods are added and removed based on traffic. That's the headline benefit, and it's also the source of the cluster problems in file 10 — you cannot know how many instances are running.

**Content distribution replaced replication agents.** On 6.5 the author pushed to a known list of publish instances. That can't work when pods appear and disappear, so **Sling Content Distribution** uses a pub/sub pipeline that pods subscribe to. A newly created pod pulls current content by itself. Full detail in file 18.

**The dispatcher moved into the publish pod** as a sidecar container, and its configuration lives in Git and is validated by the pipeline — rather than being hand-edited on an Apache box.

**Asset processing moved off-instance** to Asset Compute microservices, configured by Processing Profiles rather than the DAM Update Asset workflow (file 09).

**The node store detail that catches people out**, and which is worth getting right because it's a common near-miss:

> **Author uses the DocumentNodeStore backed by MongoDB, because the author tier is clustered and instances share one repository. Publish uses the SegmentNodeStore, because each pod holds its own read-only copy and speed matters more than sharing.**

Most candidates say "the cloud uses Mongo" for both. Getting the split right is a genuine differentiator.

### 2.2 The genuine benefits — and how to argue each one

**Not a list. Each one with the reason it actually matters.**

#### No more version upgrades

On 6.5, an AEM upgrade was a project — weeks of regression testing, a migration window, and often deferred so long that you ended up several versions behind and the eventual jump was worse.

On Cloud Service, Adobe ships updates continuously with no downtime. **The version problem simply stops existing.**

**Why this is the strongest benefit to lead with:** it removes recurring project cost, not just operational cost. Teams on 6.5 spend real engineering time on upgrades that produces no features.

#### Auto-scaling publish

On 6.5, capacity was provisioned for peak. So you sized for the campaign, then paid for that capacity for the other eleven months.

**A concrete framing:** our campaign traffic is roughly ten times a normal day. On 6.5 that meant provisioning ahead and running the capacity year-round. On Cloud Service the publish tier scales during the campaign and back afterwards.

#### Deployment discipline

This one is a benefit **and** a constraint, which is why it's worth being honest about.

Cloud Manager pipelines are the only route to production. Every change goes through build, code quality gates, security testing, and functional tests on stage before reaching production.

**The benefit:** production cannot drift from source control. On 6.5, someone fixing something urgently in CRXDE at 2am creates a difference between what's running and what's in Git — and nobody discovers it until the next deployment overwrites the fix.

**The cost:** there is no emergency hotfix path. A genuine production emergency waits for a pipeline. That's a real trade and pretending otherwise is what makes an answer sound rehearsed.

#### Operational work disappears

Repository maintenance — compaction, revision garbage collection, data store garbage collection, index management — is real, ongoing work on 6.5. It's also invisible until it isn't: the classic 6.5 incident is a disk filling because compaction hasn't run.

Adobe handles all of it, along with monitoring, patching and backups.

#### Asset processing off-instance

On 6.5, DAM Update Asset ran on the AEM instance. Uploading a few thousand product images meant CPU-heavy image processing competing with authors, and authors noticing.

Asset Compute runs it externally. **Authors stop being affected by asset ingestion**, which is a benefit people don't anticipate until they've experienced the alternative.

#### A CDN is included

Adobe provides and manages a CDN. On 6.5 you brought your own — another contract, another configuration, another thing to coordinate.

### 2.3 What changes for a developer — the part that scores

**This is the section that separates a real answer from a recited one.** Six things change, and they're all consequences of immutability and disposability.

#### 1. /apps and /libs are read-only at runtime

They're baked into the container image at build time. So:

- **No hotfixing in CRXDE on production.** Not restricted — impossible.
- **CRXDE Lite is only available on development environments**, not stage or production.
- No install hook can write to `/apps`.

#### 2. Service users and ACLs must come from Repoinit

There's no admin session, and install hooks can't create them. So everything structural — service users, ACLs, folder paths — is declared in **Repoinit** (files 01 and 13).

**And this is the honest reframing:** it's a constraint that turned out to be an improvement. Permissions now live in Git, get reviewed like code, and are identical across environments — instead of being clicked in per environment and drifting.

#### 3. The Maven project must cleanly separate mutable from immutable

`ui.apps` holds immutable content; `ui.content` and `ui.config` hold mutable. Mix them and the build **fails validation** — it's enforced, not advisory.

#### 4. Custom run modes don't exist

You get `author` and `publish` crossed with `dev`, `stage` and `prod`. No `config.uat`. Teams migrating from on-premise frequently had custom run modes and have to collapse them.

#### 5. Local disk is scratch space

Pods are replaced during deployment, scaling, and health events. Anything written to local disk may vanish. It belongs in the repository or an external store.

#### 6. Long-running processes are discouraged

Because pods recycle. A workflow paused on a human step survives fine — it's persisted. A step doing hours of continuous computation may not (file 09).

**The interview answer for this section:**

> "The biggest change is that `/apps` and `/libs` are immutable at runtime — baked into the container image. So there's no hotfixing in CRXDE, and CRXDE Lite isn't even available on stage or production.
>
> That has knock-on effects. Service users and ACLs have to be declared in Repoinit, because there's no admin session and no install hooks. The Maven project has to cleanly separate `ui.apps` from `ui.content` and `ui.config`, and the build fails validation if you mix them. Custom run modes are gone — you get author and publish crossed with dev, stage and prod. And because pods are recycled, local disk is scratch space and long-running processes are discouraged.
>
> The honest framing is that most of those are constraints that turned out to be improvements. Repoinit meant permissions moved into Git and stopped drifting between environments. The package separation forced us to be clear about what's code and what's content. The one genuine cost is that there's no emergency hotfix path — a real production incident waits for a pipeline."

### 2.4 The honest limitations

**Raising these unprompted is what makes the whole answer credible.**

**No emergency hotfix.** Everything through a pipeline. For a genuine production incident that's a real constraint, and the mitigation is feature flags and configuration you can change through the faster config pipeline rather than a full build.

**Less introspection.** No CRXDE on stage or production, no Felix console for editing configuration. You get the Developer Console and downloadable logs, which is less than being on the box.

**Constrained customisation.** No custom run modes, no writing to `/apps`, no admin sessions, no assuming local disk. Things that worked on 6.5 sometimes have no direct equivalent.

**Adobe's release cadence is yours.** Continuous updates mean you don't control when the platform changes. That's mostly good, and occasionally you're debugging something that changed underneath you.

**Migration isn't free.** The Best Practices Analyzer typically finds real work — admin sessions, install hooks, custom run modes, local disk writes, custom asset workflows.

**Cost is different, not automatically lower.** Whether it's cheaper depends on the workload. The honest claim is that operational _effort_ drops substantially; the licensing conversation is separate.

### 2.5 The tooling you should be able to name

Naming these is a quick check on whether you've actually worked on Cloud Service.

| Tool                                    | What it's for                                                                                                |
| --------------------------------------- | ------------------------------------------------------------------------------------------------------------ |
| **Cloud Manager**                       | Git repository, pipelines, environments, logs — the control plane                                            |
| **AEM SDK**                             | The local quickstart plus dispatcher tools                                                                   |
| **RDE** — Rapid Development Environment | A cloud environment you can deploy to in **seconds**, bypassing the full pipeline, for development iteration |
| **Developer Console**                   | Status dumps, bundles, OSGi configs on cloud environments                                                    |
| **`aio` CLI**                           | Adobe I/O CLI — RDE deployments and **live log tailing**                                                     |
| **Best Practices Analyzer**             | Run on 6.5 pre-migration; reports what will break                                                            |
| **Cloud Acceleration Manager**          | Tracks the migration plan                                                                                    |
| **Repository Modernizer**               | Restructures a Maven project into immutable/mutable                                                          |
| **Dispatcher Converter**                | Converts dispatcher config to the cloud format                                                               |
| **Content Transfer Tool**               | Moves content from 6.5 to Cloud Service                                                                      |

**RDE is the one worth understanding**, because it answers an obvious objection.

**The problem it solves:** a full Cloud Manager pipeline takes a long time. During active development, waiting that long to see a change on a cloud environment is unworkable.

**RDE** lets you deploy a bundle or content package to a cloud environment in seconds, using the `aio` CLI. It's for development iteration only — not a path to production — but it makes cloud development practical.

**Mentioning RDE unprompted is a strong signal**, because it's the thing you only know about if you've hit the problem it solves.

### 2.6 Cloud Manager pipelines

**Types worth distinguishing:**

| Pipeline       | Deploys                                  | Speed   |
| -------------- | ---------------------------------------- | ------- |
| **Full-stack** | Code and content — the whole application | Slowest |
| **Front-end**  | Only the front-end build output          | Faster  |
| **Web-tier**   | Only dispatcher configuration            | Fast    |
| **Config**     | Only certain configurations              | Fast    |

**Why several types exist:** a dispatcher rule change shouldn't require a full application build and test cycle. Knowing that web-tier and config pipelines exist — and that they're the answer to "how do you change a dispatcher rule quickly" — is a practical detail.

**Quality gates** in a full-stack pipeline: code quality via SonarQube plus Adobe's own **OakPAL** rules, security testing, and functional tests on stage. Some findings are warnings; critical ones block the deployment.

**The deployment itself is a rolling update** — old pods keep serving until new ones are healthy, so the publish tier has no downtime.

### 2.7 Migration — the honest version

If asked how you'd migrate, the tools in order:

1. **Best Practices Analyzer** on 6.5 — what will break
2. **Cloud Acceleration Manager** — track the plan
3. **Repository Modernizer** — restructure the Maven project
4. **Dispatcher Converter** — convert dispatcher config
5. **Asset Workflow Migration** — DAM workflows to Processing Profiles
6. **Content Transfer Tool** — move content, then Content Copy for deltas

**What actually breaks**, which is the more useful half of the answer:

| What                                  | Why                    | Fix                                   |
| ------------------------------------- | ---------------------- | ------------------------------------- |
| `getAdministrativeResourceResolver()` | Blocked                | Service user + Repoinit               |
| Install hooks writing to `/apps`      | Immutable              | Repoinit                              |
| Custom run modes                      | Not supported          | Collapse into the fixed set           |
| Writes to local disk                  | Pods are ephemeral     | Repository or external store          |
| Custom DAM workflows                  | Asset processing moved | Processing Profiles                   |
| Long-running workflow steps           | Pods recycle           | Async, or Sling Jobs                  |
| `/apps` and `/content` in one package | Validation fails       | Split into `ui.apps` and `ui.content` |

***

## 3. Internal Working

### 3.1 What happens during a deployment

graph TD A\["Push to the Cloud Manager Git repo"] --> B\["BUILD — Maven"] B --> C\["CODE QUALITY\<br/>SonarQube + OakPAL"] C -->|"critical findings"| X\["BLOCKED"] C --> D\["SECURITY TESTING"] D --> E\["Build container images"] E --> F\["Deploy to STAGE"] F --> G\["Functional / UI tests"] G -->|fail| X G --> H\["Deploy to PRODUCTION\<br/>ROLLING update"] H --> I\["Old pods drain,\<br/>new pods take traffic"]

**Three things worth drawing out:**

**The gates are real.** Critical findings block. That's the discipline benefit, and it's also why there's no emergency path.

**Images are built, not patched.** A deployment produces new container images — which is exactly why `/apps` is immutable at runtime.

**Rolling update means no publish downtime**, but it also means components deactivate and reactivate on every deployment. Which is why `@Deactivate` matters more here than on a server you restart occasionally (file 06).

### 3.2 Why pods being disposable changes your code

graph TD A\["A pod can vanish at any moment\<br/>deployment · scaling · health event"] --> B\["Local disk is SCRATCH"] A --> C\["In-memory state is LOST"] A --> D\["Long-running work may be INTERRUPTED"] A --> E\["A scheduler runs on EVERY pod\<br/>and the count VARIES"] B --> F\["Repository or external store"] C --> F D --> G\["Sling Jobs — persisted and retried"] E --> H\["scheduler.runOn, or keep it on author"]

**That single fact — pods are disposable — generates most of file 10's content.** A scheduler running on an unpredictable number of pods, jobs needing persistence, and idempotency mattering because work gets retried, all come from here.

***

## 8. Comparison Tables

### 8.1 The full comparison

| Aspect                 | AEM 6.5 / AMS                      | AEM as a Cloud Service              |
| ---------------------- | ---------------------------------- | ----------------------------------- |
| Hosting                | VMs you or AMS manage              | Adobe-managed containers            |
| **Upgrades**           | **A project every 2–3 years**      | **Continuous, zero-downtime**       |
| **Scaling**            | Provision for peak                 | **Publish auto-scales**             |
| Deployment             | Package Manager, Jenkins, anything | **Cloud Manager pipelines only**    |
| **`/apps` at runtime** | Writable                           | **Immutable**                       |
| CRXDE Lite             | Everywhere                         | **Dev environments only**           |
| Author → Publish       | Replication agents                 | **Sling Content Distribution**      |
| Author node store      | TarMK or Mongo cluster             | **DocumentNodeStore (Mongo)**       |
| Publish node store     | TarMK                              | **SegmentNodeStore**                |
| Asset processing       | DAM Update Asset **workflow**      | **Asset Compute microservices**     |
| Dispatcher             | A separate Apache VM               | **A container in each publish pod** |
| Dispatcher config      | Hand-edited on the box             | **In Git, pipeline-validated**      |
| CDN                    | Bring your own                     | **Adobe-managed, included**         |
| Service users / ACLs   | Install hooks, packages            | **Repoinit only**                   |
| Custom run modes       | Yes                                | **No**                              |
| Admin session          | Available                          | **Blocked**                         |
| Local disk             | Persists                           | **Ephemeral**                       |
| Repository maintenance | **Your job**                       | Adobe's                             |
| Preview tier           | Not standard                       | **Built in**                        |
| Emergency hotfix       | Possible                           | **No — pipeline only**              |
| Long-running workflows | Fine                               | **Discouraged**                     |

### 8.2 Pipeline types

| Pipeline     | Deploys                | Speed    | Use for                             |
| ------------ | ---------------------- | -------- | ----------------------------------- |
| Full-stack   | Everything             | Slowest  | Application changes                 |
| Front-end    | FE build output        | Faster   | CSS/JS only                         |
| **Web-tier** | **Dispatcher config**  | **Fast** | **A cache or filter rule**          |
| Config       | Certain configurations | Fast     | **The closest thing to a fast fix** |

### 8.3 What breaks in migration

| What                                  | Why              | Replacement                  |
| ------------------------------------- | ---------------- | ---------------------------- |
| `getAdministrativeResourceResolver()` | Blocked          | Service user + Repoinit      |
| Install hooks writing to `/apps`      | Immutable        | Repoinit                     |
| Custom run modes                      | Fixed set        | Collapse into `stage`        |
| Local disk writes                     | Ephemeral pods   | Repository or external store |
| Custom DAM workflows                  | Processing moved | Processing Profiles          |
| Long-running workflow steps           | Pods recycle     | Async, or Sling Jobs         |
| Mixed `/apps` + `/content` package    | Validation       | `ui.apps` + `ui.content`     |

### 8.4 The migration tools

| Tool                       | Stage                                      |
| -------------------------- | ------------------------------------------ |
| Best Practices Analyzer    | On 6.5 — what will break                   |
| Cloud Acceleration Manager | Track the plan                             |
| Repository Modernizer      | Restructure the Maven project              |
| Dispatcher Converter       | Convert dispatcher config                  |
| Asset Workflow Migration   | Workflows → Processing Profiles            |
| Content Transfer Tool      | Move content, then Content Copy for deltas |

***

## 9. Common Mistakes

| The mistake                                  | What happens                                            | The fix                                       |
| -------------------------------------------- | ------------------------------------------------------- | --------------------------------------------- |
| Answering with marketing points only         | Sounds recited; the follow-ups expose it                | Frame around **what changed for a developer** |
| No downsides in the answer                   | Reads as inexperience                                   | **Volunteer them**                            |
| "Cloud uses Mongo" for both tiers            | The classic near-miss                                   | **Author Mongo, publish Segment**             |
| Assuming a hotfix path exists                | There isn't one                                         | Feature flags and the config pipeline         |
| Custom run mode in a config folder           | Silently never applies                                  | The fixed set only                            |
| Admin session in new code                    | Blocked                                                 | Service user + Repoinit                       |
| Writing to local disk                        | Lost when the pod recycles                              | Repository or external store                  |
| A scheduler on publish                       | Runs an unpredictable number of times                   | Author tier, or Sling Jobs                    |
| Mixing `/apps` and `/content` in one package | Build validation fails                                  | Split the modules                             |
| Skipping `@Deactivate`                       | Leaks on every deployment — and pods recycle constantly | Release what you hold                         |
| Long-running workflow steps                  | May be interrupted mid-run                              | Async or jobs                                 |
| Expecting the same debugging access          | No CRXDE on stage or prod                               | Better logging discipline                     |
| Claiming a cost saving                       | You don't know their licensing                          | Say **operational effort** drops              |

***

## 10. Best Practices

**On the answer itself.** Frame around developer experience, not features. Volunteer the downsides. Have one concrete migration story ready, because that's what proves you were there.

**On code.** No admin sessions. Everything structural in Repoinit. Clean package separation. Never assume local disk or in-memory state survives. `@Deactivate` releases everything, because pods recycle constantly.

**On background work.** Scheduled work on author. Sling Jobs for anything substantial. Idempotent consumers, because work gets retried.

**On operations.** Feature-flag anything risky, so it can be disabled without a full build. Components should degrade rather than throw. Log well, because you can't get onto the box.

**On migration.** Best Practices Analyzer first. Start service users from zero permissions and widen on failure. Content transfer is usually the long pole.

***

## 11. Debugging on Cloud Service

**What you have:**

| Tool                              | Gives you                                      |
| --------------------------------- | ---------------------------------------------- |
| **Developer Console**             | Status dumps, bundle list, OSGi configurations |
| **Cloud Manager → Download logs** | `error.log`, `request.log`, dispatcher logs    |
| **`aio` CLI**                     | **Live log tailing**, and RDE deployment       |
| **CRXDE Lite**                    | **Development environments only**              |
| **RDE**                           | Deploy in seconds to iterate                   |

**What you don't have:** SSH, files on the box, editing OSGi configs in the Felix console on stage or production, and CRXDE on anything above dev.

**What that changes about how you work:**

**Logging discipline matters more.** You can't attach a debugger to production, so what you logged is what you get. That pushes you toward logging decisions and state transitions rather than only errors.

**Health checks matter more.** A silent failure — a scheduler that stopped, a service that's unsatisfied — is harder to notice without console access. Section 11 of file 10 makes the same point, and it's more true here.

**RDE is how you iterate.** A full pipeline is too slow for development, and RDE closes that gap.

**And the honest framing:** _"It's less introspection than being on the box, and I'd rather have both. The mitigation is being more deliberate about logging and health checks — which is better practice anyway, but it was forced rather than chosen."_

***

## Next topic

**`15-Content-Fragments`** — your syllabus points 24 and 25: what a Content Fragment is, how models work, how you read one in a Sling Model, and the headless delivery story with GraphQL.

***

_Topic 14 of the AEM Interview Preparation repository. Teaching style, energy-sector project domain._
