AEM Content Migrations – How to Simplify and Automate Them

At Valtech Munich we run lots of AEM projects that require content migrations from time to time. This happens especially in legacy projects when cleanups or refactorings are done. Our AEM Easy Content Upgrade (AECU) tool simplifies content migrations by executing migration scripts during package installation. It keeps a history and ships with a GUI to visualize the status of the migration runs. Scripts can also be (re)run via the GUI.

What are we talking about regarding content migrations?

Content migration means that you need to do adjustments to your production content. This is required when you deploy a new software release that is partially incompatible with your existing content. Typical migration tasks are:

  • Change resource types because components were split/merged or renamed
  • Move nodes/attributes to a different place caused by a component refactoring
  • Set default settings based on location in content tree (e.g. tenant specific)
  • Fix content issues

I already use Groovy Console – why should I move to a new tool?

Groovy Console is a great tool for migrations. We used it a lot in the past. But we had some advanced requirements that required to develop a new tool based on Groovy Console. These are:

  • Consolidated history: we want to see the status of all our migration scripts grouped by deployment. This way we get an easy report to check if all migration tasks were successful.
  • Automation: there should be no need to document script runs for system engineers. Manual tasks are time-consuming and error-prone. Scripts should be run with a standard content package deploy.
  • Run mode support: some scripts are just for the author instance or just for test environments.
  • Error handling: if a script fails with an exception we need to be able to react on that.
  • Methods for common tasks: simple tasks like resource type changes should not require more than a few lines of code.

All these requirements are met by our new AECU tool.

So how does it work?

Files and folder structure

AECU is based on Groovy Console. This means you can still write and reuse the same code as before. There is no need to learn a new scripting language etc.

The files are located in /etc/groovyconsole/scripts/aecu. The “aecu” subfolder is important as other scripts (e.g. your old ones) will be ignored by AECU. Below the “aecu” folder you can have any number of files and folders. There are just a few naming conventions:

  • Run modes: folders can contain run modes similar to what you use for configurations. E.g. the “” folder will only be evaluated on an author instance.
  • Fallback scripts: if there is a script “myscript.groovy” and a script “myscript.fallback.groovy” then the second one will only be called in case of an exception in “myscript.groovy”.
  • Periodic runs: Scripts with “.always.groovy” (e.g. “myscript.always.groovy”) will be executed on each deployment.

Automatic script run

AECU provides an install hook to run your migration scripts during content package installation. For this simply add the install hook to the “content-package-maven” plugin in your pom.xml file:


The hook will then be called on package installation and execute the migration scripts. It will execute scripts only once as long as you do not use the “always” selector (see above). Also, scripts that were modified will be run again.

History of migrations

The tool is fully integrated to the AEM tools section. You will see there “AEM Easy Content Upgrade” and the history tool. There you can view the results of each run. This way you have all important information on a single screen. This includes execution times, script output and status.

But will scripts also be easier to write?

Yes, we provide an extension for the Groovy code that covers typical use cases. You can build up your migration tasks in three simple steps using a builder pattern:

  • Collect nodes to check: here you can provide a list of resources, subtrees and also combine multiple collections of resources
  • Filtering: the nodes can then be filtered by property, node name or custom filters
  • Action: there are various action types such as property changes, node movement and deletion


println aecu
  .doSetProperty("newProperty", "value")

As you can see simple changes get far more readable and simpler to write.

For more sophisticated changes you can still write the Groovy code as before and benefit from AECU’s features like automated execution.

Where can I get it?

Please see our GitHub page to download the latest release. You can also find AECU on Maven Central for better integration in your development cycle.

You will find all the documentation on GitHub that also includes more advanced features like:

  • Dry run
  • Service API
  • Health Checks
  • GUI for manual execution


We plan some more enhancements in the Groovy Console extension such as page actions (activate/deactivate) and more collectors and filters. This will further simplify migrations.

Please provide feedback in form of pull requests or tickets if you have any issues or ideas. This is very much appreciated.