This blog contains experience gained over the years of implementing (and de-implementing) large scale IT applications/software.

Best Disk Topology for SAP ASE Databases on Azure

Maybe you are considering migration of on-premise SAP ASE databases to Microsoft Azure, or you may be considering migrating from your existing database vendor to SAP ASE on Azure.
Either way, you will benefit from understanding a good, practical disk topology for SAP ASE on Azure.

In this post, I show how you can optimise use of the SAP ASE, Linux and Azure technical layers to provide a balanced approach to disk use, considering both performance and disk (ASE device) management.

The Different Layers

In an ASE on Linux on Azure (IaaS) setup, you have the following layers:

  • Azure Storage Services
  • Azure Data Disk Cache Settings
  • Linux Physical Disks
  • Linux Logical Volumes
  • Linux File Systems
  • ASE Database Data Devices
  • ASE Instance

Each layer has different options around tuning and setup, which I will highlight below.

Azure Storage Services

Starting at the bottom of the diagram we need to consider the Azure Disk Storage that we wish to use.
There are 2 design considerations here:

  • size of disk space required.
  • performance of disk device.

For performance, you are more than likely tied by the SAP requirements for running SAP on Azure.
Currently these require a minimum of Premium SSD storage, since it provides a guaranteed SLA. However, as of June 2020, Standard SSD was also given an SLA by Microsoft, potentially paving the way for cheaper disk (when certified by SAP) provided that it meets your SLA expectations.

Generally, the size of disk determines the performance (IOPS and MBps), but this can also be influenced by the quantity of data disk devices.
For example, by using 2 data disks striped together you can double the available IOPS. The IOPS are an important factor for databases, especially on high throughput database systems.

When considering multiple data disks, you also need to remember that each VM has limitations. There is a VM level IOPS limit, a VM level throughput limit (megabytes per second) plus a limit to the number of data disks that can be attached. These limit values are different for different Azure VM types.

Also remember that in Linux, each disk device has its own set of queues and buffers. Making use of multiple Linux disk devices (which translates directly to the number of Azure data disks) usually means better performance.


  • Choose minimum of Premium SSD (until Standard SSD is supported by SAP).
  • Spread database space requirements over multiple data disks.
  • Be aware of the VM level limits.

Azure Data Disk Cache Settings

Correct configuration of the Azure data disk cache settings on the Azure VM can help with performance and is an easy step to complete.
I have already documented the best practice Azure Disk Cache settings for ASE on Azure in a previous post.


  • Correctly set Azure VM disk cache settings on Azure data disks at the point of creation.

Use LVM For Managing Disks

Always use a logical volume manager, instead of formatting the Linux physical disk devices directly.
This allows the most flexibility for growing, shrinking and striping the disks for size and performance.

You should stripe the data logical volumes with a minimum of 2 physical disks and a maximum stripe size of 128KB (test it!). This fits within the window of testing that Microsoft have performed in order to achieve the designated IOPS for the underlying disk. It’s also the maximum size that ASE will read at. Depending on your DB read/write profile, you may choose a smaller stripe size such as 64KB, but it depends on the amount of Large I/O and pre-fetch. When reading the Microsoft documents, consider ASE to be the same as MS SQL Server (they are are from the same code lineage).

Stripe the transaction log logical volume(s) with a smaller stripe size, maybe start at 32KB and go lower but test it (remember HANA is 2KB stripe size for log volumes, but HANA uses Azure WriteAccelerator).


  • Use LVM to create volume groups and logical volumes.
  • Stipe the data logical volumes with (max) 128KB stripe size & test it.

Use XFS File System

You can essentially choose to use your preferred file system format; there are no restrictions – see note 405827.
However, if you already run or are planning to run HANA databases in your landscape, then choosing XFS for ASE will make your landscape architecture simpler, because HANA is recommended to run on an XFS file system (when on local disk) on Linux; again see SAP note 405827.

Where possible you will need to explicitly disable any Linux file system write barrier caching, because Azure will be handling the caching for you.
In SUSE Linux this is the “nobarrier” setting on the mount options of the XFS partition and for EXT4 partitions it is option “barrier=0”.


  • Choose disk file system wisely.
  • Disable write barriers.

Correctly Partition ASE

For SAP ASE, you should segregate the disk partitions of the database to avoid certain system specific databases or logging areas, from filling other disk locations and causing a general database system crash.

If you are using database replication (maybe SAP Replication Server a.k.a HADR for ASE), then you will have additional replication queue disk requirements, which should also be segregated.

A simple but flexible example layout is:

Mount PointDescription
vg_aselv_ase<SID>/sybase/<SID>For ASE binaries
vg_sapdatalv_sapdata<SID>_1./sapdata_1One for each ASE device for SAP SID database.
vg_saploglv_saplog<SID>_1./saplog_1One for each log device for SAP SID database.
vg_asedatalv_asesec<SID>./sybsecurityASE security database.
lv_asesyst<SID>./sybsystemASE system databases (master, sybmgmtdb).
lv_saptemp<SID>./saptempThe SAP SID temp database.
lv_asetemp<SID>./sybtempThe ASE temp database.
lv_asediag<SID>./sapdiagThe ASE saptools database.
vg_asehadrlv_repdata<SID>./repdataThe HADR queue location.
vg_backupslv_backups<SID>./backupsDisk backup location.

The above will allow each disk partition usage type to be separately expanded, but more importantly, it allows specific Azure data disk cache settings to be applied to the right locations.
For instance, you can use read-write caching on the vg_ase volume group disks, because that location is only for storing binaries, text logs and config files for the ASE instance. The vg_asedata contains all the small ASE system databases, which will not use too much space, but could still benefit from read caching on the data disks.

TIP: Depending on the size of your database, you may decide to also separate the saptemp database into its own volume group. If you use HADR you may benefit from doing this.

You may not need the backups disk area if you are using a backup utility, but you may benefit from a scratch area of disk for system copies or emergency dumps.

You should choose a good naming standard for volume groups and logical volumes, because this will help you during the check phase, where you can script the checking of disk partitioning and cache settings.


  • Segregate disk partitions correctly.
  • Use a good naming standard for volume groups and LVs.
  • Remember the underlying cache settings on those affected disks.

Add Whole New ASE Devices

Follow the usual SAP ASE database practices of adding additional ASE data devices on additional file system partitions sapdata_2, sapdata_3 etc.
Do not be tempted to constantly (or automatically) expand the ASE device on sapdata_1 by adding new disks, you will find this difficult to maintain because striped logical volumes need at least 2 disks in the stripe set.
It will get complicated and is not easy to shrink back from this.

When you add new disks to an existing volume group and then expand an existing lv_sapdata<SID>_n logical volume, it is not as clean as adding a whole new logical volume (e.g. lv_sapdata<SID>_n+1) and then adding a whole new ASE data device.
The old problem of shrinking data devices is more easily solved by being able to drop a whole ASE device, instead of trying to shrink one.

NOTE: The Microsoft notes suggest enabling automatic DB expansion, but on Azure I don’t think it makes sense from a DB administration perspective.
Yes, by adding a new ASE device, as data ages you may end up with “hot” devices, but you can always move specific devices around and add more underlying disks and re-stripe etc. Keep the layout flexible.


  • Add new disks to new logical volumes (sapdata_n+1).
  • Add big whole new ASE devices to the new LVs.


We’ve been through each of the layers in detail and now we can summarise as follows:

  • Choose a minimum of Premium SSD.
  • Spread database space requirements over multiple data disks.
  • Correctly set Azure VM disk cache settings on Azure data disks at the point of creation.
  • Use LVM to create volume groups and logical volumes.
  • Stipe the logical volumes with (max) 128KB stripe size & test it.
  • Choose disk file system wisely.
  • Disable write barriers.
  • Segregate disk partitions correctly.
  • Use a good naming standard for volume groups (and LVs).
  • Remember the underlying cache settings on those affected disks.
  • Add new disks to new logical volumes (sapdata_n).
  • Add big whole new ASE devices to the new LVs.

Useful Links:

Ultimate Active-Active SAP Web Dispatcher Architecture in Azure?

I have never been fully satisfied with the reference architecture on the Microsoft site for running active-active SAP Web Dispatchers in an Azure IaaS platform.

Don’t get me wrong, from a high-level Azure perspective they are representative of what you will be desiring. However, they just lack enough detail to make you really think about the solution more than I feel you should need to.

To re-cap, in an Active-Active SAP Web Dispatcher in Azure, you rely on the inherent capabilities of the Azure Internal Load Balancer (ILB) to provide availability routing to the active-working VMs that are running the Web Dispatcher instances.

To help you (and me) understand what needs to be configured, I’ve put together what I feel is a pretty good low-level architecture diagram.

It’s almost a version two to SAP on Azure Web Dispatcher High Availability.

Show Us the Picture or It Never Happened!

Below is the diagram that I have created.
There is quite a lot of detail in it, and also quite a lot of detail that is not included (required O/S params, instance params and config for the network layer etc). It is really not as simple as you first imagine to include the required detail in one picture.

It Happened, Now Explain Please

If we look at the diagram above, we can easily see that WD1 is the SAP System name, with 2 instances of WD1, both with an instance number of 98 but installed against 2 virtual hostnames of sapwd1 and sapwd2.

Could we have installed on the server hostname directly? Yes, we could have. But that is not inline with a SAP Adaptive Computing Design principal, which is separation of the SAP instance from the host.

Notice that we have a Highly Available NFS share that hosts our SAP system instance profile files and a single shared PSE (SAPSSLS.pse).
We don’t show that this could be from a HA fileshare or NetApp or some other technology, but please use your imagination here. For production the Azure Files service is not currently supported.

Our ILB is configured to accept HTTP and HTTPS connections on their native ports (80 and 443) and it routes these through to the 8098 and 44398 ports that the Web Dispatchers are configured to listen on. You can configure whatever ports you want, but ultimately, having separately addressable back-end ports allows you to re-use the SSL port for Web Dispatcher administration and tie-down the access to a DMZ hosted Jump Box (definitely not on the diagram).

The ILB is probing both back-end VM members on tcp/8098 to see if the Web Dispatcher is responding. It’s a basic TCP SYN check (can I open a connection – yes, OK). For a better check, you can use a HTTP health probe on tcp/8098, which would allow you to set the Web Dispatcher to “maintenance” mode, causing a HTTP “service unavailable” response to be returned to the ILB probe, which would remove that particular Web Dispatcher from the ILB routing. If you also followed the other suggestion of accessing the admin page from the 44398 port via the virtual hostname, then you will see that an administrator would still have admin control for maintenance purposes. Nice.

We have a SAN enabled SSL certificate inside our shared PSE, with 3 Common Names associated with that certificate, one for the ILB “host” name (sapwd), and 1 for each of the virtual hostnames against which we have installed the Web Dispatcher instances (sapwd1 and sapwd2).

Our “icm/host_name_full” parameter sets both Web Dispatchers to think that they are accessed through However, we have to be careful that we do not use EXTBIND in this particular case, because we do not have the IP address of the ILB bound onto the servers (although if you read my post on how to add a secondary IP address on the Loopback device I can show you how it’s possible to do this and why you may want to).

How Do We Cater for DR?

Because we do not have a high disk I/O throughput on a Web Dispatcher VM, it is perfect to be protected by Azure Site Recovery (ASR).

This means the VM is replicated across to the Azure DR region (the region of your choice).

Like this:

But wait, we’re only replicating 1 VM! Yes, we don’t need to pay for both, since a cost-optimised approach would be to just re-install the second Web Dispatcher after a DR failover.

We have a dependency on some sort of NFS share replication to exist in the DR region, but it doesn’t necessarily need to be fancy in the case of the SAP Web Dispatcher, because very little will be changing on the /sapmnt/<SID> area.

NOTE: The replicated VM is not accessible until a failover is instigated.

What Happens In a Failover to DR

In a DR scenario, the decision to failover to the DR region is manual.
The decision maker can choose to failover as soon as the primary region is unavailable, or they can choose to wait to see if the primary region is quickly recovered by Microsoft.

I’ve put together a diagram of how this could affect our simple HA Web Dispatcher setup:

The decision to failover should not be taken lightly, because it will take a lot of effort to failback (for databases).

Generally the recommendation from Microsoft is to use an Azure Automation Runbook to execute a pre-defined script of tasks.

In our case, the runbook will create the ILB above the Web Dispatcher VM and add the replicated VM to the ILB.
Our runbook will also then add secondary IP addresses to the VM and finally adjust DNS for all our hostnames and virtual host names, assigning the new IP addresses to the DNS records.

Once our Web Dispatcher is online and working, we could choose to then build out a further VM and add it into the ILB back-end pool, depending on how long we think we will be living in the DR region.


Did we successfully include more detail in the architecture diagram? Yes we sure did!
Was it all the detail? No. There’s a lot that I have not included still.
Will I be enhancing this diagram? Probably; I hate leaving holes.

I’ve shown above how an active-active SAP Web Dispatcher architecture can work in Azure and how that could be setup for a DR protection.

We also briefly touched on some good points about separation of administration traffic, using a HTTP health probe for an ILB aware Web Dispatcher maintenance capability, and how the SSL setup uses a SAN certificate.

Would this diagram be more complicated by having an active-active HA Web Dispatcher alongside an ASCS or SCS? Yes, it gets more complicated, but there are some great features in the ILB that allow simplification of the rules which allow you to use the ILB for more than one purpose, saving cost.

Update Jun-2020: This duplicate Web Dispatcher architecture is known in SAP as “Parallel Web Dispatcher” and a basic description is visible here:

Update Mar-2021: Some of you have asked about how the “Maintenance Mode” activation works with the ILB. This is siply that the WDisp returns a HTTP 503 when Wdisp maintenance mode is enabled.
By default the ILB health probe will be “http://<the-vm>:<your-port>/”, but if you don’t have a back-end service allocated to “/” then you will get a HTTP 404 constantly. You need to adjust the URL to an actual working URL location based on the config of your back-end systems.
If you don’t want the health probe to make a call to an actual back-end system (during the health probe ping) then use parameter “icm/HTTP/file_access_<xx>” to define a custom local directory and place a blank file called “health.htm”. Then just adjust the health problem URL with the path to the “health.htm” and the health probe pings will never call a back-end system URL. It also means that you can touch or remove the health.htm to permit the ILB to use or not use that specific WDisp.

Complications of using SAP ASE 16.0 in a HADR pair plus DR node Setup

Firstly, we need to clarify that HADR in SAP ASE speak, is the SAP ASE feature-set name for a HA or DR setup consisting of 2 SAP ASE database instances with a defined replication mode.

The pair can be either for HA or DR, but rarely both, due to the problem of latency.
The problem of latency is inverse to the solution of DR. The further away your second datacentre, the better, from a DR perspective.
Conversely, the worse your latency will become, meaning it can only seriously be used for DR, and not for HA.

If you can find a sweet spot between distance (better for DR) and latency (better for HA), then you would have a HADR setup. But this is unlikely.

As of ASE 16 SP03, an additional DR node is supported to be incorporated into a HADR pair of ASE database instances.
This produces a 3 node setup, with 2 nodes forming a pair (designed to be for HA), then a remote 3rd node (designed for DR).
The reason you may consider such a setup is to provide HA between the two nodes, maybe within an existing datacentre, then DR is provided by a remote 3rd node.
Since the two nodes within the HA pair would likely have low latency, they would have one replication mode (e.g synchronous replication) keeping the data better protected, with the replication mode to the third database being asynchronous, for higher latency scenarios, but less protected data.

In the scenarios and descriptions below, we are highlighting the possibility of running a two node HADR pair plus DR node in public cloud using a paired region:

Whilst an SAP application layer is also supported on the 3 node setup, there are complications that should be understood prior to implementation.
These complications will drive up both cost of implementation and also administrative overhead, so you should ensure that you fully understand how the setup will work before embarking on this solution.

Setup Process:

We will briefly describe the process for setting up the 3 nodes.
In this setup we will use the remote, co-located replication server setup, whereby the SAP SRS (replication server) is installed onto the same servers as the ASE database instances.

1, Install primary ASE database instance.

2, Install Data Movement (DM) component into the binary software installation of the primary ASE database instance.

3, Install secondary ASE database instance.

4, Install Data Movement (DM) component into the binary software installation of the secondary ASE database instance.

5, Run the setuphadr utility to configure the replication between primary and secondary.

This step involves the materialisation of the master and <SID> databases. The master database materialisation is automatic, the <SID> database is manual and requires dump & load.

Therefore, if you have a large <SID> database, then materialisation can take a while.

6, Install tertiary ASE database instance.

7, Install Data Movement (DM) component into the binary software installation of the tertiary ASE database instance.

8, Run the setuphadr utility to configure the tertiary ASE instance as a DR node.

This step involves the materialisation of the master and <SID> databases. The master database materialisation is automatic, the <SID> database is manual and requires dump & load.
Therefore, if you have a large <SID> database, then materialisation can take a while.

In the above, you can adjust the replication mode between primary and secondary, depending on your latency.
In Public cloud (Microsoft Azure), we found that the latency between paired regions was perfectly fine for asynchronous replication mode.
This also permitted the RPO to be met, so we actually went asynchronous all the way through.


Based on the above, we have our first point to make.

When doing the dump & load for the tertiary database, both master and <SID> databases are taken from the primary database, which in most cases will be in a different datacentre, so materialisation of a large <SID> database will take longer than the secondary database materialisation timings.

You will need to develop a process for quickly getting the dump across the network to the tertiary database node (before the transaction log fills up on the primary).

Developing this fast materialisation process is crucial to the operation of the 3 node setup, since you will be doing this step a lot.

Operational Process:

We now have a 3 node setup, with replication happily pushing primary database transactions from primary (they go from the Replication Agent within the primary ASE instance), to the SRS on the secondary ASE node.
The SRS on the secondary instance then pushes the transactions into the secondary ASE instance databases (master & <SID>) and also to the SRS on the tertiary ASE database instance.

While this is working, you can see the usual SRS output by connecting into the SRS DR Agent on the secondary node and issuing the “sap_status path” command.
The usual monitoring functions exist for monitoring the 3 ASE nodes. You can use the DBACockpit (DB02) in a Netweaver ABAP stack, the ASE Fault Manager or manually at the command line.

One of the critical processes with an ASE HADR setup, is the flow of transactions from primary. You will be constantly engaged trying to prevent the backlog of transactions, which could cause primary to halt database commits until transaction log space is freed.
By correctly sizing the whole chain (primary, secondary and tertiary transaction logs) plus sizing the inbound queues of the SRS, you should have little work to do on a daily basis.


It’s not the daily monitoring that will impact, but the exceptional change scenarios.
As an example, all 3 ASE database instances should have the same database device sizes, transaction log sizes and configuration settings.
Remembering to increase the device, database, transaction log, queue on each of them can be arduous and mistakes can be made.
Putting a solid change process around the database and SRS is very important to avoid primary database outages.
Since all 3 databases are independent, you can’t rely on auto-growby to grow the devices and databases in sync. So you may need to consider manually increasing the device and database sizes.

Failover Process:

During a failover, the team need to be trained in the scenario of recovery of the data to whichever database server node is active/available/healthy.
The exact scenario training could be difficult as it may involve public cloud, in which case it may not be possible to accurately simulate.
For the 3 node SAP ASE HADR + DR node, the failure scenario that you experience could make a big difference to you overall recovery time.

When we mention recovery time, we are not just talking about RPO/RTO for getting production systems working, we are talking about the time to actually recover the service to a protected state.
For example, recovery of the production database to a point where it is once again adequately protected from failure through database replication.

Loss of the primary database in a 3 node setup, means that the secondary node is the choice to become primary.
In this scenario, the secondary SRS is no longer used. Instead the SRS on the DR node would be configured to be the recipient of transactions from the Replication Agent of the secondary ASE.
If done quickly enough, then re-materialisation of the tertiary database can be avoided as both secondary and tertiary should have the same point-in-time.
In practice however, you will find more often than not, that you are just re-materialising the DR node from the secondary.
In some cases, you may decide not to both until the original primary is back in action. The effort is just too much.

Loss of the secondary database in a 3 node setup, means that the primary becomes instantly unprotected!
Both the secondary node and the tertiary node will drift out of sync.
In this scenario, you will more than likely find that you will be pushed for time and need to teardown the replication on the primary database to prevent the primary transaction lo filling.

Loss of the tertiary database in a 3 node setup, means that you no longer have DR protection for your data!
The transaction log on the primary will start to fill because secondary SRS will be unable to commit transactions in the queue to the tertiary database.
In this scenario, you will more than likely find that you will be pushed for time and need to re-materialise the DR database from the primary.
Time will be of the essence, because you will need transaction log space available in the primary database and queue space in the SRS, for the time to perform the re-materialsation.


Sizing of the production transaction log size is crucial.
The same size is needed on the secondary and tertiary databases (to allow materialisation (dump & load) to work.
The SRS queue size also needs to be a hefty size (bigger than the transaction log size) to accommodate the transactions from the transaction log.
The primary transaction log size is no longer now just about daily database transactional throughput, but is also intertwined with the requirement for the time it takes to dmp & load the DB across the network to the DR node (slowest link in the chain).
Plus, on top of the above sizings, you should accommodate some additional buffer space for added delays, troubleshooting, decision making.

You should understand your dump & load timings intricately to be able to understand your actual time to return production to a protected state. This will help you decide which is the best route to that state.

Maintenance Process:

Patching a two node ASE HADR setup, is fairly simple and doesn’t take too much effort in planning.
Patching a three node setup (HADR + DR node), involves a little more thought due to the complex way you are recommended to patch.
The basics of the process are that you should be patching the inactive portions of the HADR + DR setup.
Therefore, you end up partially patching the ASE binary stack, leaving the currently active primary SRS (on the secondary node) until last.
As well patching the ASE binaries, you will also have to patch the SAP Hostagent on each of the three nodes. Especially since the Hostagent is used to perform the ASE patching process.
Since there is also a SAP instance agent present on each database node, you will also need to patch the SAP Kernel (SAPEXE part only) on each database node.


Database patching & maintenance effort increases with each node added. Since the secondary and DR nodes have a shared nothing architecture, you patch specific items more than once across the three nodes.


The complexity of managing a two node SAP ASE HADR pair plus DR node should not be underestimated.
You can gain the ability to have HA and DR, especially in a public cloud scenario, but you will pay a heavy price in overhead from maintenance and potentially lose time during a real DR due to the complexity.
It really does depend on how rigid you can be at defining your failover processes and most importantly, testing them.

Carefully consider the cost of HA and DR, versus just DR (using a two node HADR setup with the same asynchronous replication mode).
Do you really need HA? Is your latency small enough to permit a small amount of time running across regions (in public cloud)?

CORS in a SAP Netweaver Landscape

In this brief article I’m going to try to simplify and articulate what Cross-Origin Resource Sharing (CORS) is, how it works and how in an SAP environment (we use Fiori in our example) we can get around CORS without the complexity of rigidly defining the resource associations in the landscape.

Let’s Look At What CORS Is:

Fundamentally CORS is a protection measure introduced in around 2014 inside Web browsers, to try and prevent in-browser content manipulation issues associated with JavaScipt accessing resources from other websites without the knowledge/consent of the Web browser user.

You may be thinking “Why is this a problem?”, well, it’s complex, but a simple example is that you access content on one Web server, which uses JavaScript to access content on another Web server.  You have no control over where the JavaScript is going and what it is doing.
It doesn’t mean the other Web server in our example, is malicious, it could actually be the intended victim of malicious JavaScript being executed in the context of the source Web server.

What Does “Consent” Mean?

There is no actual consent given by the Web browser user (you). You do not get asked.

It is more of an understanding, built into the Web browser which means the Web browser knows where a piece of JavaScript has been downloaded from (its origin), versus where it is trying to access content from (its target), and causes the Web browser to seek consent from the target Web server before allowing the JavaScript to make its resource request to the target.

A simple analogy:
Your parents are the Web browser.
You (the child) are the untrusted JavaScript downloaded from the source Web server.
You want to go and play at your friend’s house (the target Web server).
Your parents contact your friend’s parents to confirm it’s OK.
Your parents obtain consent for you to go and play and the type of play you will be allowed to perform, before they let you go and play at your friend’s house.

Based on the simple analogy, you can see that the Web browser is not verifying the content on the target, neither is it validating the authenticity of the target (apart from the TLS level verification if using HTTPS).
All the Web browser is doing, is recognising that the origin of the JavaScript is different to its target, and requesting consent from the target, before it lets the JavaScript make it’s resource request.

If the target Web server does not allow the request, then the Web browser will reject the JavaScript request and an error is seen in the Web browser JavaScript debugger/console.

What Does “Accessing” Mean?

When we talk about JavaScript accessing resources on the target Web server, we are saying that it is performing an HTTP call (XML HTTP), usually via the AJAX libraries using one of a range of allowed methods. These methods are the usual HTTP methods such as GET, PUT, POST, HEAD etc.

What is the flow of communication between origin Web server, Web browser and target Web server?

Below I have included a diagram that depicts the flow of communication from a user’s Web browser, between a Fiori Front-End Server (FE1) and a Back-End SAP system (BE2).

In the example, pay attention to the fact that the domain (the DNS domain) of the FE1 and BE2 SAP systems, are different.

So, for example the FE1 server could be and the BE2 server could be

1, The user of the Web browser navigates within Fiori to a tile which will load and execute a JavaScript script from FE1.

2, The JavaScript contains a call to obtain (HTTP PUT) a piece of information into the BE2 system via an XML HTTP Request (XHR) call inside the JavaScript.

3, The user’s Web browser detects the JavaScript’s intention and sends a pre-flight HTTP request to the BE2 system, including the details about the origin of the JavaScript and the HTTP method it would like to perform.

4, The BE2 system responds with an “allow” response (if it wishes to allow the JavaScript’s request).

5, The Web browser permits the JavaScript to make its request and it sends it’s HTTP request to BE2.

What Needs to Be Configured in BE2?

For the above situation to work, the BE2 system needs to be configured to permit the required HTTP methods from JavaScript on the origin FE1.

This means that a light level of trust needs to be added to configuration of BE2. This is documented in SAP notes and for NW 7.40 onwards.

Is There a Simpler Way?

An alternative method to configuring Netweaver itself, is to adjust the ICM on the target (BE2) to rewrite the inbound HTTP request to add a generic “origin” request. This means you can have many domains making the access request, without needing to maintain too much configuration at the cost of security.
I’m thinking more about what needs to be done, not just in production, but it in all DEV, TST and PrePRD systems, plus config re-work after system copies.
Not only this, but it would be difficult for your URL rewrite to be accurate, so it may end up being applied to all URL accesses, no matter where they come from.  This will impact performance of the Web Dispatcher.
You could solve the performance issue by using a different front-end IP address (service name) for your Web Dispatcher, which is used specifically for requests from your origin system (FE1).  Another option could be (if it’s your own code being called in BE2) to apply a URL path designation e.g. “/mystuff/therealstuff”, whereby the ICM on BE2 can match based on “/mystuff” and rewrite the URL to be “/therealstuff”.

How About an Even Simpler Way?

A much better way, which solves the CORS problem altogether and removes the need to place config on individual systems, is to front both the origin and the target behind the same Web Dispatcher.

This way, CORS becomes irrelevant as the domain of the Web Dispatcher is seen by the Web browser, as both the origin and the target.

To enable the above configuration, we need to ensure that we align the Web Dispatcher DNS domain to either the origin or the target.
It has to be aligned to whichever system we use the message server to load balance the HTTP call. This is a SAP requirement.

For the other back-end server (behind the Web Dispatcher), we use the EXTSRV option of the Web Dispatcher to allow it to talk to the BE2 system.
This has the capability of supplying multiple servers for HA and load balancing (round-robin).   It also means the DNS domain of that system can be different to that of the Web Dispatcher’s.