Monday, May 1, 2023

"Keep the core clean" statement considered harmful

 

The over-simplified interpretation of "keep the core clean" is considered harmful. Nowadays I still hear a lot of SAP and non-SAP people state that all custom ABAP code is polluting the SAP ERP (ECC, S/4) application and should be cleaned, that is, removed or moved somewhere else.

Dogmatically deciding to move custom (ABAP) code elsewhere is a bad and outright costly idea.

Thinking critically how to automate, optimize and/or standardize your processes to achieve business goals in an economically viable way is a good idea, and always has been. This includes what IT tools/capabilities to employ (like custom ABAP code or BTP or new applications and many, many others). But also to look beyond IT at changing the system as a whole, for example modifying subsystems like the organization itself (departments, in- and outsourcing) and the execution of its processes.

Yes, there are trade-offs… Aren't there always?

 

Fortunately, this nuanced view is already expressed in most blogs about "keep the core clean" out there, ever since former SAP CTO Björn Goerke spoke those (in)famous words on TechEd 2018.

This blog is going to follow that nuanced trend, although it won't look like that at first. Let’s explore "clean core" and its over-simplified interpretation by outlining the context, arguments and consequences. Secondly, I will discuss the nuanced view of SAP (and many others), which SAP-Marketing cannot translate one-on-one into "for custom code, buy more BTP Cloud". All this combined might make you (re?)consider the usefulness of the "clean core"-mantra. 

In the initial draft of this blog, I provided too much detail, for example on trade-offs and characteristics (-ilities). In the (near) future, in a follow-up blog I will put in detailed considerations on -ilities and trade-offs, and maybe an architectural fitness function, just plainly ignoring the "clean core"-catchphrase. That will be a lot more boring and theoretical to read, I promise. :)

 

The Stage

So what does "keep the core clean" mean?

Some (journalists, analysts, a few SAP-employees, partner employees) have defined/described it as "back to standard application, no over-customization in that application". ChatGPT (version 20230323) describes it as "keeping the central system, or 'core', of an SAP installation as free of customizations as possible", which is a good summary of what was out there on the internet on this topic until the end of 2021. Oh, and for all the ancient SAP consultants (me included) out there, here is some typical SAP-naming-confusion: the SAP-term "customizing" (tcode SPRO) has to do with configuring the existing features of an SAP application, while the term "customization" applies to developing/modifying features yourself in an application (custom code).

So let me make it a bit more concrete. Here is my interpretation of "core" in the SAP ERP context: it is all software (code) that runs inside the application boundary (AB) of the ABAP  runtime of S/4, ECC, R/3.

(I'd like to be more precise, ie all objects in ABAP-table TADIR of SAP ERP, but there are some exceptions. For clarity I leave the (HANA-)database runtimes (HDI, or the old repo), and the UI-runtimes (like browser, SAPgui, apps) and designtime-tooling outside this boundary, but with extra cognitive effort these can be incorporated just as well. Higher-level-frameworks and executable models like Workflow and BRF+ are actually part of the AB, although this eventually might end up in philosophical discussions about "configuration" vs "customization" or "what is code?".)

Everything developed inside the AB by the SAP-company is considered "clean" according to the over-simplified interpretation above. Customer developed code inside the AB is considered "dirty"; these are all the customizations running inside the AB. I'm not sure where that leaves SAP-certified 3rd-party-addons, let's leave that out for now. So hence the over-simplified statement that started this blog. Hold your horses, I get to the nuanced part later…

Some SAP-customers even take the "clean core" concept a step further by not differentiating on who made the code. These customers have migrated away entirely from applications inside the AB of SAP ERP to "keep the core clean" ("scrape the core clean"?) . For example, a customer can move away from the SAP ERP SD module (Sales & Distribution) to a custom built sales app (or some SaaS-app) and integrate with the SAP "core" application. Maybe SAP itself is cleaning the core, look at SAP HCM (Human Capital Mgmt, aka HR). SAP sort of mostly placed this outside the "core" with its SuccessFactors SaaS (with HR-mini-master inside the "core"-AB to satisfy dependencies of other "core" modules, like Timesheets for example. The results at this time are mixed, as S/4 H4S4 inside the AB is an option (until 2040, although lacking new HR developments), as is selecting a package from a different vendor with some custom (integration) code to work with “core” S/4. I believe this all falls under the umbrella-term "best of breed".

(I've wondered whether some configuration also pollutes the "core". The catchphrase "keep the core clean" is vague and abstract enough to also encompass this. SAP is offering various configuration accelerators like "model companies", "best practices", and "fit-to-standard-workshops", implying that the rest of the configuration is "dirty". This is way too far fetched, nobody thinks of "clean core" this way.)

 

Having no custom code at all seemed to be a goal in itself many years ago or maybe still is (?). Of course, outsourcing all complex and expensive business-process-supporting application development plus software maintenance to a vendor like SAP is the main reason why orgs buy or rent common-of-the-shelf software applications in the first place. So molding/mapping/automating one's business processes by utilizing and configuring ERP's vast capabilities is considered "better" (faster, cheaper, ..) than to develop and maintain applications oneself. Yes, it's a good idea to maximize the utilization of SAP Standard.

However, applications are not easily composable, at least not with just configuration alone. Sometimes your standard software is missing a really valuable feature, that doesn't warrant getting another big standard application with 90% overlap (which also needs to integrate into 1 coherent system). Custom code could help with composing and integrating various modules and applications (of multiple software vendors/builders). The question becomes of where to run (and manage) that custom code, and which "system characteristics" are more or the most important… Here come the trade-offs again.

Custom code inside the AB can also make a solution simpler or better in a particular context than configuration. Forcing oneself only to employ configuration might require extra data entities increasing complexity. I have seen consultants configure another (order)type to solve a business issue that burdened the business users with making choices too early in the process. It was better to have no (order)type and a small ABAP-enhancement that allowed deferring that user-decision to much later time in the process (even considering the extra ABAP-maintenance that this choice caused). The alternative with custom code outside the AB had even more negative consequences. 

(In a general (multi-tenant) SaaS-context custom code inside an AB is almost always impossible or disallowed, "clean core" is already implicit. You are totally dependent on the APIs and data im-/export of the SaaS. The business process horrors I have seen, when half the SaaS data were replicated into a custom code database, because some simple piece of functionality in the SaaS was missing and not on the SaaS vendor's backlog!)

 

The Arguments

Those put in the "clean core" camp by me clearly state that custom code should be outside the AB. Let's go over the arguments. Problems with Upgradability are usually cited as the main reason why to "keep the core clean". When you upgrade a huge monolith like ECC or S/4, this software-lifecycle-event involves a lot of coordination, as it is one big tightly-coupled-cohesive piece of software (basically there is one version of everything). SAP, the company, provides this new, well-tested and integrated and tightly-coupled version of everything. If you have custom code inside the AB, really nice SAP-tooling for upgrades and code analysis can detect and sometimes correct problematic custom code. Problematic in this case means unsupported ABAP-syntax, or way more likely: incompatible ABAP-calls (into or by SAP-created ABAP) as usually only 1 version of SAP-created ABAP is present. In the majority of upgrades this can be dealt with, but under certain circumstances, it can become a real headache and cause delays. (A lot of strategies exist to alleviate those delays, but especially in multi-tenant-SaaS-contexts some aren't readily available, like an upstream beta-versioned system (sandbox tier before Dev QA Prod tiers).)

What if you had moved the custom code outside the AB and the other circumstances, like incompatible ABAP-calls, remain the same? Result: the SAP software upgrade goes smoothly, yes, so victory! Not so fast, your (integration or regression) tests fail (soon?), because of either issues in replicated data (dependencies!) or the incompatible calls made by custom code outside the AB. Hold on, you say, one should make the integration loosely coupled (ie backwards compatible, via multiple concurrent versions or something) to avoid this dependency, if moving custom code outside the AB. Well, this trade-off isn't for free, and if SAP had made it backwards compatible, then the custom ABAP code inside the AB wouldn't have failed as well. 

That leaves the problem of unsupported ABAP-syntax, but occurrence of this type of problem is even more rare, as SAP keeps (or kept?) the ABAP-language backwards compatible for decades. If your code lived outside the AB in another runtime, that other runtime might also need to be upgraded regularly, giving you similar language-statement problems. Although most non-ABAP programming languages are also very stable concerning syntax. It is the incompatible changes (or frequent/fast obsolescence) of libraries, frameworks or services that will bite you in the non-ABAP world way more often.

 

What other arguments do we see by the "clean core" camp? Occasionally, I hear that ABAP skills are in short supply. This could be a threshold, but then the "core" itself might also be at risk. Or is the "core" not being developed/modified by SAP anymore because of this lack of ABAP programmers? Could be, seeing more and more BTP-cloud-addons… 

But hey, ABAP is just another programming language, literally "open source" (though that term now more covers the concept of "free source" (as in free speech)) and is still easy to learn, even when a large part of being good at ABAP is to know how to navigate all the functional/business domains of the SAP ERP monolith. If S/4 were to be rebuilt (in T/5?) using a highly popular and abundant programming language/platform (remember Java@SAP during Shai Agassi's reign?) on par at least with current ABAP/monolith capabilities, would that in itself elicit more "dirty core" enhancements?

This argument loses even more credence, because "clean core" can also be achieved with an extra ABAP runtime outside the AB of the ERP, like BTP Cloud ABAP.

 

Another argument being used is that new technologies (BTP Cloud, low code, etc) are much more appropriate for building business applications. Wait, is SAP really refactoring S/4 using the latest "new technology" fad? I haven't noticed it, but that doesn't say much. 

(BTW, SAP already has multiple "cores" with all its many business applications ("keep the cores clean"?), some built with new technology (otherwise I would become very suspicious: a vendor promoting new technology but using old technology in its own products). How to keep those new-technology-cores clean? I digress and move away from my "core" definition above…)

Of course, new technologies offer powerful capabilities (and sometimes lack old, necessary capabilities surprisingly), but the pros and cons of new technology should be carefully weighed in light of the business outcomes you try to achieve (sorry, trade-offs again).

New (or other) technology always means building outside the AB, a distributed system (application), with all its testing, consistency and dependency management difficulties. Especially tools for (usage, call) dependencies in all involved runtimes ("dynamic coupling" (see the book Software Architecture: The Hard Parts)) are usually absent in distributed systems, although the current focus on "observability" (in microservice architectures for example) shows an evolving toolchain-environment, making it less of a problem. Not to mention the data dependencies (when having to replicate data across multiple datastores), where data-lineage-tools come into play. Perhaps one day such a distributed system will actually feel like 1 system, having similar tools we already have today inside the monolithic AB (such as SCMON, where-used-lists, ATC, and then some more) centrally available across all distributed runtimes.

 

What I myself do see as a problem with custom ABAP code inside the AB is low quality of the code. Custom code is almost always used by 1 customer (often 1 installation), so it often carries a lot of assumptions and specifics of the customer's environment and configuration. When the environment changes or the assumptions no longer hold, custom code in the AB breaks (immediately noticeable fortunately). As custom ABAP code can access almost all SAP-produced ABAP code (the surface area is huge, like tables, low-level functions which are for SAP-internal-use) and that often does, one can imagine the dependency-sprawl that could hamper the evolution of SAP ERP (the upgradability issues!). Testing is also an unpopular and difficult topic, especially given the effort of setup and the many (concurrent) side-effects in a big monolith like SAP ERP.

That SAP, the company, even allows the option of custom ABAP so gravitationally close to its own ABAP code (in the same AB), is a big show of confidence in its ABAP platform (and its customers). Customers can use the very same tooling SAP is using (very advanced "eating your own dogfood", with the ABAP platform being the dogfood). Having all these ABAP capabilities so easily accessible, also made us (customers) use it in not always in the best ways. Extending a standard SAP ERP entity with a couple of fields and abusing standard SAP ERP fields by adding different meanings to these, seems innocent and easy enough at first ("enhancement", user exit, BAdI). However, as soon as you realize that the business scope/meaning of said SAP ERP entity, is really bigger/different, you scramble to redesign the extra fields out of the ERP entity by creating a Z-entity with a relation to the SAP ERP entity (for example). This way the dependency is from custom code (Z-entity) to SAP ERP code, instead of the other way around with a SAP ERP entity having a dependency to extra custom fields. It feels like an orchestration layer on top, just like some outside the AB-tools do. Unfortunately, a lot of customer (code) projects have progressed too far down the path of adding short-term fixes (with deadlines looming), that it is considered too expensive to turn back and redesign.

SAP ERP is an extremely rich and deep application. It can be applied in very complex environments, and probably your environment isn't so complex (at least not in every part of the business). So you might want to de-complect SAP ERP by creating new relations ("shortcuts") between standard ERP-entities, ignoring all intermediate entities. Totally understandable for simplifying SAP ERP, but creating relations between standard SAP ERP entities where SAP hasn't designed them, is a bad idea. It's better to automate the heck out of all the intermediate SAP ERP entities, so your business users don't get exposed to that complexity, while the SAP-designed and -built processes are respected and utilized.

So because of low quality, custom ABAP code gets a bad rep. But hey, "moving your rubbish someplace else" (that is, "keep the core clean" by moving low quality code outside the AB), as one of my colleagues so aptly put it, won't solve this problem at all of course…

As a sidenote, incidentally one could also look at the quality of some SAP-produced-ABAP (it is very "open" after all), which could raise doubts whether that code should be in the "clean core" in the first place. Maybe we could rebrand the mantra to "keep the code clean" (in line with Uncle Bob Martin's book)? :) 


The Nuanced View 

Enough ranting on the extreme interpretation of "keep the core clean"; it's time for the nuances mentioned above.

While in 2018/19 SAP's initial messaging could be susceptible to over-simplified interpretation, in the years since you notice a much broader interpretation of "clean core" emerging in various blogs and presentations. The message is definitely not to rücksichtslos move all custom code out of SAP ERP, but to thoroughly think through all customization options, and to select the best tools for the jobs (in service to the business process). SAP's first and foremost focus is on the toolbox "BTP Cloud", which indeed hosts a plethora of services for custom code or custom modeling (anyway, for customization in general), ranging from ML-models, HANA native platforms, low-code platforms, pro-code platforms (cloud foundry), analytical tooling, ABAP Cloud (steampunk), integration middleware to Adobe Forms. SAP is using BTP itself to build and deliver higher-level services and products for customers, which is always a good and trust-inspiring sign ("eat your own dogfood"). For similar and different services there are also non-SAP or non-cloud options on the market, so pick your favorites (or poison?), based on the trade-offs for your use case or sets of use cases.

What all these BTP Cloud and other options have in common is that they are outside of the AB of SAP ERP, but need to integrate with SAP ERP in some way, meaning you get a distributed system as stated above. This integration can take many forms and shapes, like replicating data (in/out), subscribing to ERP events, or calling ERP APIs. Some are loosely coupled (=low cohesion), others are more tightly coupled to your SAP ERP (remember the incompatible ABAP-calls above?). The surface area of integration options can be found at the SAP Business Hub. BTW, SAP calls this solution pattern "side-by-side-extensibility" (SBSE), and in the over-simplified interpretation of "clean core" this was the only option to extend SAP ERP. 

There are times when that surface area is not good enough and the “best” (cheapest, simplest, ..) solution to your problem would be to use code inside the AB. (Again, many multi-tenant SaaS solutions don't allow this at all…) Well, "clean core" allows this custom code inside the AB to a certain extent (pun intended), and the trend of the last 5 years is that more and more is allowed! Yes, more, but not all. The surface area is not every single piece of ERP code (like in "classical" SAP ERP environments), but a limited but growing set of (released, whitelisted) ABAP artifacts like selected ABAP CDS Views, Classes, Functions etc. This surface area is bigger than the one available to SBSE. SAP reduces the upgradability problem, because custom code is now less likely to run into incompatible ABAP (only dependencies to those whitelisted ABAP artifacts). In addition some ABAP syntax is also forbidden (not having to do with ABAP-syntax upgradability issues, but with the power to bypass the whitelist (and access data in other "tenants"/clients). SAP calls this solution pattern "in-app-extensibility" (IAE). Yes, I'm refusing to use the new names ("on-stack developer extensibility" and "key user extensibility"), because I don’t care who does the custom coding (and shouldn’t there be three types of ABAP, where is “classical”?).

As a sidenote, this whole limiting of the surface area is nothing new, SAP has pursued this at least 2 times in my recollection. In the 90s there was the BAPIfication of R/3 with stable remote-enabled function modules (so geared towards custom code outside the AB). Until this very day these BAPIs are heavily used, and are often wrapped inside the AB by newer ABAP-frameworks (especially for side-effects, like create update delete). Less successful (or less known) is the "ABAP Package (Interface) Concept", a fascinating attempt at organizing ABAP code (limiting surface area dependencies via package interfaces), as admirably explained by Tobias Trapp over a decade ago. It was optional, all-or-nothing (AB-wide), needlessly complicated, and (therefore?) hardly used by non-SAP-employees.

 

So with this increasingly broader view of "clean core" you have (almost) all the options for custom code on the table again. SAP calls it "Cloud Extensibility Model" (CEM = IAE + SBSE), and the document describing it is really worth a read. You are not forced to go outside the AB (SBSE) for even the simplest of improvements to your business process and pay the distributed-system-price. Don't ignore SBSE, however, those simple improvements could turn into some separate piece of functionality, which might warrant investment in external platforms outside the AB. Or, more likely, the already existing external platforms you employ, might warrant you to build an SBSE. Or if you don't want to pay the distributed-system-price and find ABAP suitable, build your SBSE-like-custom-app inside the AB (yes inside!), while minimizing dependencies to SAP artifacts. I will repeat myself once again: keep considering the trade-offs in your context.

So CEM nudges you to newer ABAP frameworks (RAP and the like), but conceptually it is custom-code-as-usual. SAP in 2022 defines "clean core" as "an extension methodology where extensions are kept strictly separate from the SAP application. Extensions access SAP business objects only through well defined, upgrade-stable interfaces". Apart from the new and fancy frameworks, I'm not sure how this is so different from how custom code was applied in the past 30 years? You searched for extension points first (user exit, BAdI, enhancement spot) when embedding custom code in SAP standard. For SBSE-like-custom-apps inside the AB, you created custom ABAP with new entities in Z-tables nicely in separate ABAP Packages and accessed only the minimal set of (presumably) stable SAP-produced artifacts (BAPIs, classes, and unfortunately tables (yeah sorry!)), to keep dependencies manageable. The same for wrapping SAP functionality in simplified interfaces for external applications. You rarely if ever modified standard-SAP-artifacts, only if the benefits outweighed all the drawbacks (upgrade issues!) and alternatives. (Remember how difficult it was procedurally to obtain SAP SSCR Keys? Feature was removed in S/4.)

So we now have a whitelist of upgrade-stable SAP ERP artifacts and ABAP-syntax, that's really useful, thanks SAP. I will adhere to that as much as possible, but will suppress it if too restrictive, reverting back to “classical extensibility”, which you can do in a very granular way, thanks again SAP. Naturally, SAP has provided tools to easily isolate this whitelist-violating code.

(With regard to the new and fancy framework tooling like RAP etc, I like simplicity, which I do not yet see, as there is a lot of indirection and code generation (of which I'm suspicious given SAP's poor track record, ie CAF, WebDynpro, ..). So for now I adopt an "explore and experience" stance, until the advantages manifest themselves or not. Anyway, this isn’t relevant for the “clean core” discussion, unless the meaning of “clean core” shifts again…)


I hope this blog has illuminated some perspectives on leveraging SAP ERP, and the role custom code plays. Never stop thinking critically how to automate, optimize and/or standardize your processes to achieve business goals in an economically viable way. Of course, classical IT (especially the I, not just the T) can help big time. SAP has been doing that for more than 50 years, by building such a capable ERP application on top of the powerful ABAP platform. "Keep the core clean" hasn't brought anything new, only a lot of initial confusion and room for misinterpretation. That is useless at the least, and maybe even harmful.


Cheers, Wout