Customer Releases

Coding against the right AEM version

For previous AEM solutions, the most current AEM version changed infrequently (roughly annually with quarterly service packs) and customers would update the production instances to the latest quickstart on their own time, referencing the API Jar. However, applications on AEM as a Cloud Service are automatically updated to the latest version of AEM more often, so custom code for internal releases should be built against the latest AEM version.

Like for existing non-cloud AEM versions, a local, offline development based on a specific quickstart is supported and is expected to be the tool of choice for debugging usually.

NOTE
There are subtle operational differences between how the application behaves on a local machine versus the Adobe Cloud. These architectural differences must be respected during local development and could lead to a different behavior when deploying on the cloud infrastructure. Because of these differences, it is important to perform the exhaustive tests on dev and stage environments before rolling out new custom code in production.

To develop custom code for an internal release, the relevant version of the AEM as a Cloud Service SDK should be downloaded and installed. For additional information about using the AEM as a Cloud Service Dispatcher Tools, see Dispatcher in the Cloud.

The following video provides a high-level overview on how to deploy code to AEM as a Cloud Service:

Deploying Content Packages by way of Cloud Manager and Package Manager

Deployments by way of Cloud Manager

Customers deploy custom code to cloud environments through Cloud Manager. Cloud Manager transforms locally assembled content packages into an artifact conforming to the Sling Feature Model, which is how an application on AEM as a Cloud Service is described when running in a cloud environment. As a result, when looking at the packages in Package Manager on Cloud environments, the name includes “cp2fm” and the transformed packages have all metadata removed. They cannot be interacted with, meaning they cannot be downloaded, replicated, or opened. For detailed documentation about the converter see
sling-org-apache-sling-feature-cpconverter on GitHub
.

Content packages written for applications on AEM as a Cloud Service must have a clean separation between immutable and mutable content and Cloud Manager only installs the mutable content, also outputting a message like the following:

Generated content-package <PACKAGE_ID> located in file <PATH> is of MIXED type

The rest of this section describes the composition and implications of immutable and mutable packages.

Immutable Content Packages

All content and code persisted in the immutable repository must be checked into git and deployed through Cloud Manager. In other words, unlike current AEM solutions, code is never deployed directly to a running AEM instance. This workflow ensures that the code running for a given release in any Cloud environment is identical, which eliminates the risk of unintentional code variation on production. As an example, OSGI configuration should be committed to source control rather than managed at runtime by way of the AEM web console’s configuration manager.

As application changes due to the deployment pattern are enabled by a switch, they cannot depend on changes in the mutable repository except for service users, their ACLs, nodetypes, and index definition changes.

For customers with existing code bases, it is critical to go through the repository restructuring exercise described in AEM documentation to ensure that content formerly under the /etc is moved to the right location.

Some additional restrictions apply for these code packages, for example, install hooks are not supported.

OSGI Configuration

As mentioned above, OSGI configuration should be committed to source control rather than through the web console. Techniques to do so include:

  • Making the necessary changes on the developer’s local AEM environment with the AEM web console’s configuration manager and then exporting the results to the AEM project on the local file system
  • Creating the OSGI configuration manually in the AEM project on the local file system, the referencing the AEM console’s configuration manager for the property names.

Read more about OSGI configuration at Configuring OSGi for AEM as a Cloud Service.

Mutable Content

Sometimes, it might be useful to prepare content changes in source control so it can be deployed by Cloud Manager whenever an environment was updated. For example, it might be reasonable to seed certain root folder structures. Or, line up changes in editable templates to enable policies components that were updated by the application deployment.

There are two strategies to describe the content that is deployed by Cloud Manager to the mutable repository, mutable content packages and repoinit statements.

Mutable Content Packages

Content such as folder path hierarchies, service users, and access controls (ACLs) are typically committed into a maven archetype-based AEM project. Techniques include exporting from AEM or writing directly as XML. During the build and deployment process, Cloud Manager packages the resulting mutable content package. The mutable content is installed at three different times during the deploy phase in the pipeline:

Ahead of startup of new version of application:

  • index definitions (add, modify, remove)

During startup of new version of application but ahead of switchover:

  • Service Users (add)
  • Service User ACLs (add)
  • node types (add)

After switchover to new version of application:

  • All other content definable by way of Jackrabbit vault. For example:

    • Folders (add, modify, remove)
    • Editable templates (add, modify, remove)
    • Context Aware configuration (anything under /conf) (add, modify, remove)
    • Scripts (packages can trigger Install hooks at various stages of the install process of package installation. See Jackrabbit filevault documentation about install hooks. AEM CS currently uses Filevault version 3.4.0, which limits install hooks to admin users, system users, and member of the administrators group)).

It is possible to limit mutable content installation to author or publish by embedding packages in an install.author or install.publish folder under /apps. Restructuring to reflect this separation was done in AEM 6.5 and details around recommended project restructuring can be found in the AEM 6.5 documentation.

NOTE
Content packages are deployed to all environment types (dev, stage, prod). It is not possible to limit deployment to a specific environment. This limitation is in place to ensure the option of a test run of automated execution. Content that is specific to an environment requires manual installation by way of Package Manager.

Also, there is no mechanism to roll back the mutable content package changes after they’ve been applied. If customers detect a problem, they can choose to fix it in their next code release or as a last resort, restore the entire system to a point in time before the deployment.

Any included third-party packages must be validated as being AEM as a Cloud Service compatible, otherwise its inclusion results in a deployment failure.

As mentioned above, customers with existing code bases should conform to the repository restructuring exercise needed by the 6.5 repository changes described in the AEM 6.5 documentation.

Repoinit

For the following cases, it is preferable to take the approach of hand coding explicit content creation repoinit statements in OSGI factory configurations:

  • Create/delete/disable service users

  • Create/delete groups

  • Create/delete users

  • Add ACLs

    NOTE
    Definition of ACLs requires the node structures to be already present. Thus, preceding create path statements might be necessary.
  • Add path (for example, for root folder structures)

  • Add CNDs (nodetype definitions)

Repoinit is preferable for these supported content modification use cases due to the following benefits:

  • Repoinit creates resources at startup so logic can take the existence of those resources for granted. In the mutable content package approach, resources are created after startup, so application code relying on them may fail.
  • Repoinit is a relatively safe instruction set as you explicitly control the action to be taken. Also, the only supported operations are additive except for a few security-related cases which allow removal of Users, Service Users, and Groups. In contrast, a removal of something in the mutable content package approach is explicit; as you define a filter, anything present covered by a filter is deleted. Still, caution should be taken since with any content there are scenarios where the presence of new content can alter the behavior of the application.
  • Repoinit performs fast and atomic operations. Mutable content packages in contrast can highly depend performance wise on the structures covered by a filter. Even if you update a single node, a snapshot of a large tree might be created.
  • It is possible to validate repoinit statements on a local dev environment at runtime because they are run when the OSGi configuration gets registered.
  • Repoinit statements are atomic and explicit and are skipped if the state is already matching.

When Cloud Manager deploys the application, it executes these statements, independently from the installation of any content packages.

To create repoinit statements, follow the below procedure:

  1. Add OSGi configuration for factory PID org.apache.sling.jcr.repoinit.RepositoryInitializer in a configuration folder of the project. Use a descriptive name for the configuration like org.apache.sling.jcr.repoinit.RepositoryInitializer~initstructure.
  2. Add repoinit statements to the script property of the config. The syntax and options are documented in Sling documentation. There should be explicit creation of a parent folder before their child folders. For example, an explicit creation of /content before /content/myfolder, before /content/myfolder/mysubfolder. For ACLs being set on low-level structures, it is recommended to set them on a higher level and work with a rep:glob restriction. For example, (allow jcr:read on /apps restriction(rep:glob,/msm/wcm/rolloutconfigs)).
  3. Validate on the local dev environment at runtime.
WARNING
For ACLs defined for nodes underneath /apps or /libs the repoinit, execution starts on a blank repository. The packages are installed after repoinit so statements cannot rely on anything defined in the packages but must define the preconditions like the parent structures underneath.
TIP
For ACLs, the creation of deep structures might be cumbersome. Therefore, it is more reasonable to define an ACL on a higher level and constrain where it is supposed to act by way of a rep:glob restriction.

More detail about repoinit can be found in the Sling documentation

Package Manager “one offs” for Mutable Content Packages

There are use cases where a content package should be installed as a “one off”. For example, importing specific content from production on to staging to debug a production issue. For these scenarios, Package Manager can be used in environments on AEM as a Cloud Service.

Since Package Manager is a runtime concept, it is not possible to install content or code into the immutable repository, so these content packages should only consist of mutable content (mainly /content or /conf). If the content package includes content that is mixed (both mutable and immutable content), only the mutable content is installed.

IMPORTANT
The Package Manager user interface might return an undefined error message if a package takes longer than ten minutes to install.
This time is not due to an error with the installation, but to a timeout that Cloud Service has for all requests.
Do not retry the installation if you see such an error. The installation is proceeding correctly in the background. If you do restart the installation, some conflicts could be introduced by multiple concurrent import processes.

Any content-packages installed by way of Cloud Manager (both mutable and immutable) appear in a frozen state in AEM Package Manager’s user interface. These packages cannot be reinstalled, rebuilt, or even downloaded, and are listed with a “cp2fm” suffix, indicating their installation was managed by Cloud Manager.