← Volver a tutoriales

Cloud Transport Management en BTP: transporta una app de DEV a TEST y PRD

Configura cTMS como el STMS de la nube: destinations, nodos, rutas y el release paso a paso de una app MTA, con los errores típicos y cómo resolverlos.

Also available in English →

Si vienes de ABAP, conoces el ritual: liberas la orden de transporte, entra en la cola de calidad, alguien la importa, se prueba y luego pasa a productivo. En SAP BTP ese papel lo cumple Cloud Transport Management (cTMS): modelas los ambientes como nodos, los unes con rutas y cada versión de tu aplicación recorre el camino DEV → TEST → PRD con importaciones controladas.

STMS (ABAP) cTMS
Crear la orden de transporte Subir un archivo (crea la transport request)
Objetos de la orden El archivo .mtar de la aplicación
Liberar la orden Subirla al nodo DEV
Cola de importación de QAS Cola del nodo TEST
Importar en QAS / PRD Import manual en TEST / PRD

Diferencia clave: cada .mtar es un despliegue completo de la aplicación, no un delta. La nueva versión reemplaza a la anterior.

En este tutorial transportamos una app Fiori sencilla empaquetada como MTA (Multi-Target Application).

La arquitectura

Cuenta global
├── Subcuenta "Central Service"   → cTMS (nodos, rutas, destinations)
└── Subcuenta de ejecución        → Cloud Foundry
                                     ├── space DEV
                                     ├── space TEST
                                     └── space PRD
  • cTMS va en una subcuenta propia, separada de los ambientes. Es el patrón que recomienda SAP: así controlas quién puede transportar sin dar acceso a los ambientes.
  • En una cuenta trial los tres ambientes son spaces de una misma subcuenta, porque las subcuentas nuevas no suelen tener memoria disponible. En un landscape real, cada ambiente sería normalmente una subcuenta distinta; el resto del tutorial no cambia.

1. Poner en marcha cTMS

En la subcuenta central:

  1. Entitlements: añade los dos planes de Cloud Transport Management: lite (la interfaz de usuario) y standard (acceso por API). En trial vienen asignados a la subcuenta trial: quítalos de ahí para poder asignarlos a la central.
  2. Suscripción: en el Service Marketplace, crea la suscripción a Cloud Transport Management con el plan lite.
  3. Roles: crea una role collection (por ejemplo, TMS Admin), añádele la plantilla de rol Administrator de la suscripción y asígnate. Para quien solo importa existe la plantilla Import Operator.
  4. Comprueba: abre la aplicación desde Instances and Subscriptions. Debe aparecer la página Overview, vacía.

2. Prepara los ambientes destino

Antes del primer transporte, cada destino debe tener todos los servicios que pide tu mta.yaml. Para la app de este tutorial:

Servicio Plan Para qué
Cloud Foundry Runtime MEMORY Ejecutar el approuter (256 MB por ambiente)
Authorization and Trust Management (xsuaa) application Login de la app
HTML5 Application Repository app-host Guardar el contenido de la app
HTML5 Application Repository app-runtime Servirlo desde el router
Destination Service lite Destinations de la app

Comprueba la memoria real de la org con cf org-quota <quota>: el cockpit puede mostrar el entitlement asignado aunque la org siga con 0 MB.

3. Destinations: a dónde despliega cada nodo

En la subcuenta central, Connectivity → Destinations, crea una por ambiente. Todas apuntan al deploy service de Cloud Foundry:

https://deploy-service.cf.<región>.hana.ondemand.com/slprot/<org>/<space>/slp
Campo Valor
Name TMS_DEV, TMS_TEST, TMS_PRD
Type HTTP
Proxy Type Internet
Authentication BasicAuthentication
User / Password Un usuario técnico con rol Space Developer en el space destino

Tres avisos que ahorran horas:

  • Org y space distinguen mayúsculas. Un dev en vez de DEV produce un error Not Found al importar.
  • «Check Connection» no valida credenciales ni que la org o el space existan: solo que la URL responde. La prueba real es el primer import, o un cf login con el mismo usuario.
  • Revisa que cada destination apunte a su ambiente. Un import puede terminar en Succeeded y haber desplegado en el sitio equivocado: cTMS despliega donde diga la destination.

4. Nodos y rutas

En la aplicación de cTMS, Transport Nodes:

Nodo Allow Upload Forward Mode Content Type Destination
DEV ✅ Pre-Import Multi-Target Application TMS_DEV
TEST ❌ On Success Multi-Target Application TMS_TEST
PRD ❌ On Success Multi-Target Application TMS_PRD

Deja desactivado el import automático en los tres: cada import será manual y controlado.

Y en Transport Routes: DEV_TO_TEST (DEV → TEST) y TEST_TO_PRD (TEST → PRD).

Los modos de reenvío (Forward Mode)

Modo Cuándo pasa la versión al siguiente nodo
Pre-Import Al iniciar el import en el nodo actual (no al subir el archivo)
Post-Import Después del import, termine bien o mal
On Success Solo si el import terminó bien
Manual Cuando alguien lo reenvía desde la cola

Con esta configuración, una versión llega a TEST en cuanto la importas en DEV, y a PRD solo si el import en TEST fue correcto.

5. La aplicación: tres detalles del MTA

Cualquier MTA sirve. Si usas una app Fiori con approuter propio, cuida estos tres puntos.

La versión, en cada release. cTMS identifica cada transporte por su archivo; súbela siempre:

_schema-version: "3.2"
ID: helloworld-mta
version: 0.0.2

Un xsappname distinto por space. Si la misma app vive en varios spaces de una subcuenta, sus instancias XSUAA chocarían. La variable ${space} lo evita:

  - name: helloworld-mta-uaa
    type: org.cloudfoundry.managed-service
    parameters:
      config:
        tenant-mode: dedicated
        xsappname: helloworld-mta-${space}
      path: ./xs-security.json
      service: xsuaa
      service-plan: application

Los redirect-uris en xs-security.json. Sin ellos, XSUAA rechaza el login del router con OpenID provider cannot process the request:

{
  "xsappname": "helloworld-mta",
  "tenant-mode": "dedicated",
  "scopes": [],
  "role-templates": [],
  "oauth2-configuration": {
    "redirect-uris": ["https://*.cfapps.<región>.hana.ondemand.com/**"]
  }
}

oauth2-configuration va dentro del objeto raíz, como una propiedad más.

6. El release, paso a paso

  1. Desarrolla y prueba la app (en SAP Business Application Studio, con la vista previa).

  2. Sube version en mta.yaml.

  3. Genera el archivo desde la carpeta del MTA:

    mbt build
  4. Descarga el .mtar de mta_archives/.

  5. En cTMS: Transport Nodes → DEV → Upload. Elige el .mtar y escribe una descripción útil (versión y requerimiento).

  6. En la cola de DEV, Import Selected: se despliega en DEV y, por Pre-Import, pasa a la cola de TEST.

  7. Valida la app en DEV.

  8. En la cola de TEST, Import Selected. Si termina bien, pasa a la cola de PRD (On Success).

  9. Valida en TEST.

  10. Con la aprobación, Import Selected en la cola de PRD.

Dos acciones de la cola que conviene distinguir: Reset permite volver a importar una versión ya procesada en ese nodo; Remove la saca de la cola para descartarla.

7. Errores típicos

Síntoma Causa Solución
No deja crear el nodo sin destination Un nodo con Content Type (no virtual) la exige Crea la destination antes que el nodo
Subiste a DEV y no aparece en TEST Pre-Import reenvía al importar, no al subir Importa en DEV
Error during client creation: Unauthorized Contraseña incorrecta en la destination Corrígela; usa un usuario técnico
Error during client creation: Not Found Org o space mal escritos en la URL Copia los nombres exactos, con mayúsculas
Service plan application not found Falta el entitlement de XSUAA en el destino Asigna xsuaa – application a esa subcuenta
Router en Stopped, 0 MB disponibles La quota de la org no se sincronizó con los entitlements Revisa cf org-quota; en trial, usa la org de la subcuenta trial, que sí tiene memoria
Login: OpenID provider cannot process the request Falta redirect-uris en xs-security.json Añádelos, sube la versión y vuelve a transportar
Import Succeeded pero la app está en otro ambiente La destination apunta al ambiente equivocado Corrige la URL, haz Reset del transporte y reimporta. Limpia lo que se desplegó por error

En una cuenta trial, Cloud Foundry detiene las apps una vez al día. Si tu app no responde, cf start <app>.

8. Reglas del cambio

La herramienta es la mitad; la otra mitad es el proceso:

  • Nadie importa a productivo fuera de la ruta definida.
  • Quien desarrolla no aprueba ni importa su propio cambio.
  • Cada cambio que llega a PRD tiene requerimiento, pruebas aprobadas y transporte asociado.
  • Las destinations usan usuarios técnicos, nunca personales.

Todo cambio en productivo debería poder responder tres preguntas: quién lo pidió, quién lo probó y quién lo aprobó.

Siguiente paso

El mismo cTMS transporta otros tipos de contenido. Los iFlows de Integration Suite, por ejemplo, viajan por paquete: se activan los transportes en la configuración de Integration Suite, el Content Agent empaqueta el contenido y las destinations de los nodos apuntan al tenant de Cloud Integration destino. Para que un iFlow se adapte a cada ambiente sin tocarlo, empieza por externalizar sus parámetros.