Read Only or Immutable Files in AEM

Description description

Environment

Experience Manager

Issue/Symptoms

This document will describe which files are locked in and not to be changed, and how to make the desired configuration settings properly.

When Adobe Managed Services (AMS) provisions a system they roll out a baseline configuration that makes everything functional and secure.  These are things that AMS wants to ensure stay as a baseline of functionality and security. To accomplish this some files are marked as read-only and immutable to avoid you changing them.

The layout doesn’t prevent you from altering their behavior and overriding any changes you need. Instead of you changing these files, you’ll overlay your own file that supersedes the original.

This also allows you to be reassured that when AMS patches the dispatchers with the latest fixes and security enhancements, they won’t alter your files.  Then you can continue to benefit from the improvements and adopt only the changes you’d like.
Shows a bowling lane with a ball rolling down the lane. The ball has an arrow with the word showing 'you'. The gutter bumpers are raised and they have the words 'immutable files' above them.
As illustrated in the picture above, immutable files are not stopping you from playing the game.  They just stop you from hurting your performance and keep you in the lane.  This method allows us the few very key features:

  • Customizations are handled in their own safe spaces
  • Overlay of custom changes mirrors that of overlay methods in AEM
  • Patching AMS configurations can be done without altering customizations
  • Testing base install vs customized configurations can be done simultaneously to help discern if the issues are caused by customizations or something else Which Files?

Here is a typical list of files deployed with a dispatcher:

/etc/httpd/
├── conf
│   └── httpd.conf
├── conf.d
│   ├── available_vhosts
│   │   ├── 000_unhealthy_author.vhost
│   │   ├── 000_unhealthy_publish.vhost
│   │   ├── aem_author.vhost
│   │   ├── aem_flush.vhost
│   │   ├── aem_health.vhost
│   │   ├── aem_lc.vhost
│   │   └── aem_publish.vhost
│   ├── dispatcher_vhost.conf
│   ├── enabled_vhosts
│   │   ├── aem_author.vhost -> /etc/httpd/conf.d/available_vhosts/aem_author.vhost
│   │   ├── aem_flush.vhost -> /etc/httpd/conf.d/available_vhosts/aem_flush.vhost
│   │   ├── aem_health.vhost -> /etc/httpd/conf.d/available_vhosts/aem_health.vhost
│   │   └── aem_publish.vhost -> /etc/httpd/conf.d/available_vhosts/aem_publish.vhost
│   ├── logformat.conf
│   ├── remoteip.conf
│   ├── rewrites
│   │   ├── base_rewrite.rules
│   │   └── xforwarded_forcessl_rewrite.rules
│   ├── security.conf
│   ├── variables
│   │   └── ams_default.vars
│   └── whitelists
│       └── 000_base_whitelist.rules
├── conf.dispatcher.d
│   ├── available_farms
│   │   ├── 000_ams_author_farm.any
│   │   ├── 001_ams_lc_farm.any
│   │   └── 999_ams_publish_farm.any
│   ├── cache
│   │   ├── ams_author_cache.any
│   │   ├── ams_author_invalidate_allowed.any
│   │   ├── ams_publish_cache.any
│   │   └── ams_publish_invalidate_allowed.any
│   ├── clientheaders
│   │   ├── ams_author_clientheaders.any
│   │   ├── ams_common_clientheaders.any
│   │   ├── ams_lc_clientheaders.any
│   │   └── ams_publish_clientheaders.any
│   ├── dispatcher.any
│   ├── enabled_farms
│   │   ├── 000_ams_author_farm.any -> /etc/httpd/conf.dispatcher.d/available_farms/000_ams_author_farm.any

│   │   └── 999_ams_publish_farm.any -> /etc/httpd/conf.dispatcher.d/available_farms/999_ams_publish_farm.any
│   ├── filters
│   │   ├── ams_author_filters.any
│   │   ├── ams_lc_filters.any
│   │   └── ams_publish_filters.any
│   ├── renders
│   │   ├── ams_author_renders.any
│   │   ├── ams_lc_renders.any
│   │   └── ams_publish_renders.any
│   └── vhosts
│       ├── ams_author_vhosts.any
│       ├── ams_lc_vhosts.any
│       └── ams_publish_vhosts.any
├── conf.modules.d
│   ├── 01-cgi.conf
│   └── 02-dispatcher.conf
└── modules -> ../../usr/lib64/httpd/modules
    └── mod_dispatcher.so

To determine which files are immutable you can run the following command on a dispatcher to see:

$ lsattr -Rl /etc/httpd 2 > /dev/null | grep Immutable

Here is a sample response of which files are immutable:

/etc/httpd/conf/httpd.conf   Immutable
/etc/httpd/conf.d/available_vhosts/aem_author.vhost Immutable
/etc/httpd/conf.d/available_vhosts/aem_publish.vhost Immutable
/etc/httpd/conf.d/available_vhosts/aem_lc.vhost Immutable
/etc/httpd/conf.d/available_vhosts/aem_flush.vhost Immutable
/etc/httpd/conf.d/available_vhosts/aem_health.vhost Immutable
/etc/httpd/conf.d/available_vhosts/000_unhealthy_author.vhost Immutable
/etc/httpd/conf.d/available_vhosts/000_unhealthy_publish.vhost Immutable
/etc/httpd/conf.d/rewrites/base_rewrite.rules Immutable
/etc/httpd/conf.d/rewrites/xforwarded_forcessl_rewrite.rules Immutable
/etc/httpd/conf.d/whitelists/000_base_whitelist.rules Immutable
/etc/httpd/conf.d/dispatcher_vhost.conf Immutable
/etc/httpd/conf.d/logformat.conf Immutable
/etc/httpd/conf.d/security.conf Immutable
/etc/httpd/conf.modules.d/02-dispatcher.conf Immutable
/etc/httpd/conf.dispatcher.d/available_farms/000_ams_author_farm.any Immutable
/etc/httpd/conf.dispatcher.d/available_farms/999_ams_publish_farm.any Immutable
/etc/httpd/conf.dispatcher.d/available_farms/001_ams_lc_farm.any Immutable
/etc/httpd/conf.dispatcher.d/cache/ams_author_cache.any Immutable
/etc/httpd/conf.dispatcher.d/cache/ams_author_invalidate_allowed.any Immutable
/etc/httpd/conf.dispatcher.d/cache/ams_publish_cache.any Immutable
/etc/httpd/conf.dispatcher.d/cache/ams_publish_invalidate_allowed.any Immutable
/etc/httpd/conf.dispatcher.d/clientheaders/ams_author_clientheaders.any Immutable
/etc/httpd/conf.dispatcher.d/clientheaders/ams_publish_clientheaders.any Immutable
/etc/httpd/conf.dispatcher.d/clientheaders/ams_common_clientheaders.any Immutable
/etc/httpd/conf.dispatcher.d/clientheaders/ams_lc_clientheaders.any Immutable
/etc/httpd/conf.dispatcher.d/filters/ams_author_filters.any Immutable
/etc/httpd/conf.dispatcher.d/filters/ams_publish_filters.any Immutable
/etc/httpd/conf.dispatcher.d/filters/ams_lc_filters.any Immutable
/etc/httpd/conf.dispatcher.d/renders/ams_author_renders.any Immutable
/etc/httpd/conf.dispatcher.d/renders/ams_publish_renders.any Immutable
/etc/httpd/conf.dispatcher.d/renders/ams_lc_renders.any Immutable
/etc/httpd/conf.dispatcher.d/vhosts/ams_author_vhosts.any Immutable
/etc/httpd/conf.dispatcher.d/vhosts/ams_publish_vhosts.any Immutable
/etc/httpd/conf.dispatcher.d/vhosts/ams_lc_vhosts.any Immutable
/etc/httpd/conf.dispatcher.d/dispatcher.any Immutable

Resolution resolution

How to make changes?

Variables

Variables allow you to make functional changes without changing the configuration files themselves. Certain elements of the configuration can be adjusted with adjusting the values of variables.  One example we can highlight from the file /etc/httpd/conf.d/dispatcher_vhost.conf is shown here:

Include /etc/httpd/conf.d/variables/ams_default.vars
`<` IfModule disp_apache2.c`>`
    DispatcherConfig conf.dispatcher.d/dispatcher.any
    DispatcherLog    logs/dispatcher.log
    DispatcherLogLevel ${DISP_LOG_LEVEL}
    DispatcherDeclineRoot 0
    DispatcherUseProcessedURL 1
`<` /IfModule`>`

See how the DispatcherLogLevel directive has a variable of DISP_LOG_LEVEL instead of the normal value you’d see there.  Above that section of code you’ll also see an include statement to a variables file.  The variable file /etc/httpd/conf.d/variables/ams_default.vars is where we want to look next.  Here are the contents of that variables file:

Define DISP_LOG_LEVEL info
Define AUTHOR_WHITELIST_ENABLED 0
Define PUBLISH_WHITELIST_ENABLED 0
Define LIVECYCLE_WHITELIST_ENABLED 0
Define AUTHOR_FORCE_SSL 1
Define PUBLISH_FORCE_SSL 0
Define LIVECYCLE_FORCE_SSL 1

You see above that the current value of DISP_LOG_LEVEL variable is ‘info’.  We can adjust this to trace or debug, or the number value/level of your choice.  Now everywhere that controls the log level will adjust automatically.

Overlay Method

Please understand the top level include files because these will be your starting place of making any customizations. To start with a simple example, we have a scenario where we want to add a new domain name that we intend to point at this dispatcher. The domain example we will use is we-retail.adobe.com.  We will start by copying an existing configuration file to a new one where we can add our changes:

$ cp /etc/httpd/conf.d/available_vhosts/aem_publish.vhost /etc/httpd/conf.d/available_vhosts/weretail_publish.vhost

We copied the existing aem_publish.vhost file because it already has what we need to make things work and we don’t want to re-invent an already strong start.  Now we edit the new weretail.vhost file and make the needed changes.

Before:

`<` VirtualHost *:80`>`
    ServerName    publish
    ServerAlias    ${PUBLISH_DEFAULT_HOSTNAME}
    DocumentRoot    ${PUBLISH_DOCROOT}
    `<` IfModule mod_headers.c`>`
            Header always add X-Dispatcher ${DISP_ID}
            Header always add X-Vhost "publish"
            Header merge X-Frame-Options SAMEORIGIN "expr=%{resp:X-Frame-Options}!='SAMEORIGIN'"
            Header merge X-Content-Type-Options nosniff "expr=%{resp:X-Content-Type-Options}!='nosniff'"
        Header append Vary User-Agent env=!dont-vary
    `<` /IfModule`>`
....... SNIP.......
`<` /VirtualHost`>`

After:

`<` VirtualHost *:80`>`
    ServerName    weretail-publish
    ServerAlias    we-retail.adobe.com
    DocumentRoot    ${PUBLISH_DOCROOT}
    `<` IfModule mod_headers.c`>`
            Header always add X-Dispatcher ${DISP_ID}
            Header always add X-Vhost "werteail-publish"
            Header merge X-Frame-Options SAMEORIGIN "expr=%{resp:X-Frame-Options}!='SAMEORIGIN'"
            Header merge X-Content-Type-Options nosniff "expr=%{resp:X-Content-Type-Options}!='nosniff'"
        Header append Vary User-Agent env=!dont-vary
    `<` /IfModule`>`
....... SNIP.......
`<` /VirtualHost`>`

Now we have updated our ServerName and ServerAlias to match the new domain names, as well as updating other breadcrumb headers.  Let’s now enable our new file to allow apache to know to use our new file:

$ cd /etc/httpd/conf.d/enabled_vhosts/; ln -s ../available_vhosts/weretail_publish.vhost .

Now apache webserver knows that domain is something it should yield traffic for, but we still need to inform the dispatcher module it has a new domain name to honor.  We will start by creating a new *_vhost.any file /etc/httpd/conf.dispatcher.d/vhosts/weretail_vhosts.any and inside that file we will put in the domain name we want to honor:

"we-retail.adobe.com"

Now we need to make a new farm file that will use our new vhost entry file, and we’ll start by copying a strong start file to our own new one.

$ cp /etc/httpd/conf.dispatcher.d/available_farms/999_ams_publish_farm.any /etc/httpd/conf.dispatcher.d/available_farms/400_weretail_publish_farm.any

Lets show the changes we’ll need to make to this farm file

Before:

/publishfarm {
    /virtualhosts {
        $include "/etc/httpd/conf.dispatcher.d/vhosts/ams_publish_vhosts.any"
    }
........SNIP.........
}

After:

/weretailpublishfarm {
    /virtualhosts {
        $include "/etc/httpd/conf.dispatcher.d/vhosts/weretail_publish_vhosts.any"
    }
........SNIP.........
}

Now we have updated the farm name, and the include it uses in the /virtualhosts section of the farm configuration.  We need to enable this new farm file so it can use it in the running configuration:

$ cd /etc/httpd/conf.dispatcher.d/enabled_farms/; ln -s ../available_farms/400_weretail_publish_farm.any .

Now we would just reload the webserver service and use our new domain!

Note:

Notice we only changed the pieces we needed to change and leveraged the existing includes and code that came with the baseline configuration files.  We only have to delineate on the element we need to change.  Makes thing much easier and allows us to maintain less code

recommendation-more-help
3d58f420-19b5-47a0-a122-5c9dab55ec7f