Lesson 4 of 5
Configuration per environment
10 min
Listen to this lesson
If the same archive goes to development, test and production, something must still differ between them: the S/4HANA system it talks to, the memory and number of instances, the service plans, the URLs users open. The rule is simple to say: code and descriptors are the same everywhere; configuration lives with the environment. This lesson shows where each kind of configuration belongs on SAP BTP.
Destinations: the pairing that matters most
The fleet order status app calls a released OData API in SAP S/4HANA. It does not know the URL. It asks the destination service for a destination by name, say CMC_S4HANA, and each subaccount defines that destination differently: CMD in cmc-ext-dev, CMQ client 100 in cmc-ext-test, CMP in cmc-ext-prod. The archive is identical; the destination name is the contract. That also means a wrong destination is a stage problem, not a code problem, and it is the first thing to check when one stage fails.
Extension descriptors
An MTA extension descriptor is a YAML file with the extension .mtaext that complements the deployment descriptor with environment-specific data such as scaling and credentials, so the same archive can be deployed with different configurations without changing it. It declares the same schema version as the deployment descriptor, an ID of its own, and extends with the ID of the MTA (or of another extension descriptor) it builds on. Several descriptors can be chained; each has higher priority than the one it extends.
| Rule | What SAP's documentation says | Example for Contoso |
|---|---|---|
| Simple values | Overwritten directly | memory: 1GB in the archive becomes 2GB in prod.mtaext |
| Maps (objects) | Merged in depth | A service config map keeps keys not mentioned in the extension |
| Lists (arrays) | Replaced completely | Repeat every list element you want to keep |
| What you cannot do | Add modules or resources, change types, add new requires/provides, alter read-only parameters | A production-only module must be in the archive, not in prod.mtaext |
Parameters and properties are overwritable and optional by default in schema version 3; metadata can mark a value as required or non-overwritable. Contoso uses that for a property the app must never run without: the descriptor marks it required, so a deployment with a missing value fails at validation instead of at 08:00 on a Monday.
Getting the right descriptor to the right place
There are two routes for the extension descriptor, and teams should pick one per target. For deployments done by the pipeline, the Acceptance and Release stages have an MTA Extension Descriptors field that takes a path to a file in the repository. For deployments done by SAP Cloud Transport Management, you upload the .mtaext into the import queue of each Cloud Foundry node, which needs the TransportOperator authorization. SAP's documentation is explicit on two points: descriptors are not forwarded to target nodes, so each queue needs its own; and a version binding controls which MTA versions the descriptor applies to. The default asterisk means all versions; a specific version wins over the asterisk when both exist.
| Item | cmc-ext-dev | cmc-ext-test | cmc-ext-prod |
|---|---|---|---|
| Destination CMC_S4HANA | CMD | CMQ client 100 | CMP |
| Instances / memory | 1 / 512MB | 1 / 1GB | 2 / 1GB |
| Extension descriptor | dev.mtaext in repository (pipeline) | test.mtaext in CMC_TEST queue | prod.mtaext in CMC_PROD queue |
| Role collections | Developers | Testers, key users | Fleet service agents; admins by approved access |
Contoso's configuration matrix for the fleet order status app (illustrative values).
- Does the value differ between stages?No → keep it in mta.yaml · Yes → continue
- Is it a connection to another system?Yes → destination in each subaccount · No → continue
- Is it a secret?Yes → destination, service binding or credential store; never Git · No → continue
- Is it a deployment parameter or runtime property?Yes → extension descriptor for that target
What would you do?
After the first production import of version 1.5.0, the app runs with one instance and 512MB, although prod.mtaext asks for two instances and 1GB. The same descriptor worked for 1.4.0. What is the most likely cause?
- Same archive everywhere; configuration lives with the environment.
- Destinations pair each subaccount with its S/4HANA system; the destination name is the contract.
- Extension descriptors overwrite simple values, merge maps, replace lists, and cannot add modules or resources.
- In SAP Cloud Transport Management, upload descriptors per import queue; they are not forwarded; version binding decides which versions they apply to.
- Secrets live in destinations, bindings or the credential store, never in Git.
Check your understanding · not graded
Lesson check
1. What does an MTA extension descriptor let you do?
2. How are lists (arrays) handled when an extension descriptor overrides them?
3. You uploaded an extension descriptor in the CMC_TEST queue. What happens in CMC_PROD?
4. Where should the URL of the S/4HANA system that the app calls be kept?