Create Destination using mta.yaml

Using the CAP application mta.yaml file, we can create both the CAP application destination and custom destinations during deployment.

To create destinations, we first need to create service instnace of destination service, bind the application to the service and then define the destination details.

Create Instance and Service Binding

This can be achieved by declaring the Destination service as a required dependency in the module definition, as shown below:

mta.yaml
- name: cap-application-destination-service

For Example, under modules requires section -

mta.yaml
_schema-version: 3.3.0
ID: cap-application
version: 1.0.0
description: "A simple CAP project."
parameters:
  enable-parallel-deployments: true
build-parameters:
  before-all:
    - builder: custom
      commands:
        - npm ci
        - npx cds build --production
modules:
  - name: cap-application-srv
    type: nodejs
    path: gen/srv
    parameters:
      instances: 1
      buildpack: nodejs_buildpack
    build-parameters:
      builder: npm-ci
    provides:
      - name: srv-api # required by consumers of CAP services (e.g. approuter)
        properties:
          srv-url: ${default-url}
    requires:
      - name: cap-application-auth
      - name: cap-application-db
      # Declare Destination Service Requirement below
      - name: cap-application-destination-service

We can then define the service details under resources section like below -

mta.yaml
resources:
  # Define Destination Service Resource detials
  - name: cap-application-destination-service
    type: org.cloudfoundry.managed-service
    parameters:
      service: destination
      service-plan: lite
      service-name: cap-application-destination-instance # <-- Service instance name
      config:
        HTML5Runtime_enabled: true

So your mta.yaml will look like -

mta.yaml
_schema-version: 3.3.0
ID: cap-application
version: 1.0.0
description: "A simple CAP project."
parameters:
  enable-parallel-deployments: true
build-parameters:
  before-all:
    - builder: custom
      commands:
        - npm ci
        - npx cds build --production
modules:
  - name: cap-application-srv
    type: nodejs
    path: gen/srv
    parameters:
      instances: 1
      buildpack: nodejs_buildpack
    build-parameters:
      builder: npm-ci
    provides:
      - name: srv-api # required by consumers of CAP services (e.g. approuter)
        properties:
          srv-url: ${default-url}
    requires:
      - name: cap-application-auth
      - name: cap-application-db
      # Declare Destination Service Requirement below
      - name: cap-application-destination-service

  - name: cap-application-db-deployer
    type: hdb
    path: gen/db
    parameters:
      buildpack: nodejs_buildpack
    requires:
      - name: cap-application-db
  
  - name: cap-application
    type: approuter.nodejs
    path: app/router
    parameters:
      keep-existing-routes: true
      disk-quota: 256M
      memory: 256M
    requires:
      - name: srv-api
        group: destinations
        properties:
          name: srv-api # must be used in xs-app.json as well
          url: ~{srv-url}
          forwardAuthToken: true
      - name: cap-application-auth
    provides:
      - name: app-api
        properties:
          app-protocol: ${protocol}
          app-uri: ${default-uri}




resources:
  # Define XSUAA Service Resource details
  - name: cap-application-auth
    type: org.cloudfoundry.managed-service
    parameters:
      service: xsuaa
      service-plan: application
      path: ./xs-security.json
      config:
        xsappname: cap-application-${org}-${space}
        tenant-mode: dedicated
        oauth2-configuration:
          redirect-uris:
            - https://*~{app-api/app-uri}/**
    requires:
      - name: app-api
  
  # Define HDI Container Resource details
  - name: cap-application-db
    type: com.sap.xs.hdi-container
    parameters:
      service: hana
      service-plan: hdi-shared
  
  # Define Destination Service Resource detials
  - name: cap-application-destination-service
    type: org.cloudfoundry.managed-service
    parameters:
      service: destination
      service-plan: lite
      service-name: cap-application-destination-instance # <-- Service instance name
      config:
        HTML5Runtime_enabled: true

Now since service binding has been created, we can proceed to create Custom Destination.

Create Custom Destination

Now to create custom destinations, we can define its details in the resources like -

mta.yaml
  # Define Destination Service Resource detials
  - name: cap-application-destination-service
    type: org.cloudfoundry.managed-service
    parameters:
      service: destination
      service-plan: lite
      service-name: cap-application-destination-instance # <-- Service instance name
      config:
        HTML5Runtime_enabled: true
        # Destination 3 - Custom Destinations
        init_data:
          subaccount:
            destinations:
              # Destination detail
            - Name: cap_application_Testing_Destination_URL
                Type: HTTP
                ProxyType: Internet
                Authentication: NoAuthentication
                URL: https://myurl.com
            existing_destinations_policy: update
        version: 1.0.0

Create CAP Destination using xsuaa credentials

Now to create custom destinations, we can define a separate module which will use the xsuaa service credentials and will create the destination -

mta.yaml
- name: cap-application-cap-destinations-creator-module # Module to create Destination using Destination Service
  type: com.sap.application.content
  requires:
    - name: cap-application-auth
      parameters:
        service-key:
          name: cap-application-cap-auth-key
    - name: srv-api
    - name: cap-application-destination-service
      parameters:
        content-target: true
  parameters:
    content:
      subaccount:
        destinations:
          # Destinations based on the CAP service and XSUAA service are created here.    
          # Destination - 1 
          - Name: cap_application_Testing_Destination #The destination to the CAP service. It is required by your UIs running in SAP Launchpad service to access your service.
            Authentication: OAuth2UserTokenExchange
            TokenServiceInstanceName: cap-application-auth
            TokenServiceKeyName: cap-application-auth-key
            URL: '~{srv-api/srv-url}'
            sap.cloud.service: cap-application.service
            
          # Destination - 2
          - Name: cap_application_Testing_Destination-auth #The destination to your XSUAA service instance. The SAP Launchpad service needs it to convert OAuth tokens for use with your CAP service.
            Authentication: OAuth2UserTokenExchange
            ServiceInstanceName: cap-application-auth
            ServiceKeyName: cap-application-auth-key
            sap.cloud.service: cap-application.service

        existing_destinations_policy: update
  build-parameters:
    no-source: true

So the complete mta.yaml file looks like-

mta.yaml
_schema-version: 3.3.0
ID: cap-application
version: 1.0.0
description: "A simple CAP project."
parameters:
  enable-parallel-deployments: true
build-parameters:
  before-all:
    - builder: custom
      commands:
        - npm ci
        - npx cds build --production


modules:
  - name: cap-application-srv
    type: nodejs
    path: gen/srv
    parameters:
      instances: 1
      buildpack: nodejs_buildpack
    build-parameters:
      builder: npm-ci
    provides:
      - name: srv-api # required by consumers of CAP services (e.g. approuter)
        properties:
          srv-url: ${default-url}
    requires:
      - name: cap-application-auth
      - name: cap-application-db
      # Declare Destination Service Requirement
      - name: cap-application-destination-service

  - name: cap-application-db-deployer
    type: hdb
    path: gen/db
    parameters:
      buildpack: nodejs_buildpack
    requires:
      - name: cap-application-db
  
  - name: cap-application
    type: approuter.nodejs
    path: app/router
    parameters:
      keep-existing-routes: true
      disk-quota: 256M
      memory: 256M
    requires:
      - name: srv-api
        group: destinations
        properties:
          name: srv-api # must be used in xs-app.json as well
          url: ~{srv-url}
          forwardAuthToken: true
      - name: cap-application-auth
    provides:
      - name: app-api
        properties:
          app-protocol: ${protocol}
          app-uri: ${default-uri}

  - name: cap-application-cap-destinations-creator-module # Module to create Destination using Destination Service
    type: com.sap.application.content
    requires:
      - name: cap-application-auth
        parameters:
          service-key:
            name: cap-application-cap-auth-key
      - name: srv-api
      - name: cap-application-destination-service
        parameters:
          content-target: true
    parameters:
      content:
        subaccount:
          destinations:
            # Destinations based on the CAP service and XSUAA service are created here.    
            # Destination - 1 
            - Name: cap_application_Testing_Destination #The destination to the CAP service. It is required by your UIs running in SAP Launchpad service to access your service.
              Authentication: OAuth2UserTokenExchange
              TokenServiceInstanceName: cap-application-auth
              TokenServiceKeyName: cap-application-auth-key
              URL: '~{srv-api/srv-url}'
              sap.cloud.service: cap-application.service
              
            # Destination - 2
            - Name: cap_application_Testing_Destination-auth #The destination to your XSUAA service instance. The SAP Launchpad service needs it to convert OAuth tokens for use with your CAP service.
              Authentication: OAuth2UserTokenExchange
              ServiceInstanceName: cap-application-auth
              ServiceKeyName: cap-application-auth-key
              sap.cloud.service: cap-application.service

          existing_destinations_policy: update
    build-parameters:
      no-source: true




resources:
  # Define XSUAA Service Resource details
  - name: cap-application-auth
    type: org.cloudfoundry.managed-service
    parameters:
      service: xsuaa
      service-plan: application
      path: ./xs-security.json
      config:
        xsappname: cap-application-${org}-${space}
        tenant-mode: dedicated
        oauth2-configuration:
          redirect-uris:
            - https://*~{app-api/app-uri}/**
    requires:
      - name: app-api
  
  # Define HDI Container Resource details
  - name: cap-application-db
    type: com.sap.xs.hdi-container
    parameters:
      service: hana
      service-plan: hdi-shared
  
  # Define Destination Service Resource detials
  - name: cap-application-destination-service
    type: org.cloudfoundry.managed-service
    parameters:
      service: destination
      service-plan: lite
      service-name: cap-application-destination-instance # <-- Service instance name
      config:
        HTML5Runtime_enabled: true
        init_data:
          subaccount:
            destinations:
              # Destination 3 - Custom Destinations
              - Name: cap_application_Testing_Destination_URL
                Type: HTTP
                ProxyType: Internet
                Authentication: NoAuthentication
                URL: https://${org}.${default-domain}
            existing_destinations_policy: update
        version: 1.0.0
Note:

${org} - it gives Subaccout subdomain

${default-domain} - it gives cf org details

Create SBPA Destination

So, as we discussed earlier, to create or use service credentials, we first need to create the service instance, establish a service binding, and then create the required destination using those service credentials.

Describe SBPA Resource details-

We can declare the requirement of SBPA resources under modules resources section like-

mta.yaml
- name: cap-application-sbpa-service

Define SBPA Resource details-

We can define the SBPA service details under resources section like-

mta.yaml
# Define SBPA Service Resource detials
- name: cap-application-sbpa-service
  type: org.cloudfoundry.managed-service
  parameters:
    service: process-automation-service
    service-plan: standard
    service-name: cap-application-sbpa-service-instance

Define SBPA Destination details-

Now we can define the SBPA instance details under destination module section like-

mta.yaml
# Destination Module
- name: cap-application-cap-destinations-creator-module # Module to create Destination using Destination Service
  type: com.sap.application.content
  requires:
    - name: cap-application-auth
      parameters:
        service-key:
          name: cap-application-cap-auth-key
    - name: srv-api
    - name: cap-application-destination-service
      parameters:
        content-target: true
    - name: cap-application-sbpa-service  # <-- Add SBPA resource details as requirement here
      parameters:
        service-key:
          name: cap-application-sbpa-service-key
  parameters:
    content:
      subaccount:
        destinations:
          # Destinations based on the CAP service and XSUAA service are created here.    
          # Destination - 1 
          - Name: cap_application_Testing_Destination #The destination to the CAP service. It is required by your UIs running in SAP Launchpad service to access your service.
            Authentication: OAuth2UserTokenExchange
            TokenServiceInstanceName: cap-application-auth
            TokenServiceKeyName: cap-application-auth-key
            URL: '~{srv-api/srv-url}'
            sap.cloud.service: cap-application.service
            
          # Destination - 2
          - Name: cap_application_Testing_Destination-auth #The destination to your XSUAA service instance. The SAP Launchpad service needs it to convert OAuth tokens for use with your CAP service.
            Authentication: OAuth2UserTokenExchange
            ServiceInstanceName: cap-application-auth
            ServiceKeyName: cap-application-auth-key
            sap.cloud.service: cap-application.service

          # Destination - 3 - SBPA Destination
          - Name: cap_application_Destination-sbpa
            Authentication: OAuth2UserTokenExchange
            ServiceInstanceName: cap-application-sbpa-service-instance  # <-- SBPA Service Instance Name
            ServiceKeyName: cap-application-sbpa-service-key            # <-- SBPA Service Service Key
            sap.cloud.service: cap-application.service

        existing_destinations_policy: update
  build-parameters:
    no-source: true

So the complete mta.yaml will looks like-

mta.yaml
_schema-version: 3.3.0
ID: cap-application
version: 1.0.0
description: "A simple CAP project."
parameters:
  enable-parallel-deployments: true
build-parameters:
  before-all:
    - builder: custom
      commands:
        - npm ci
        - npx cds build --production
modules:
  - name: cap-application-srv
    type: nodejs
    path: gen/srv
    parameters:
      instances: 1
      buildpack: nodejs_buildpack
    build-parameters:
      builder: npm-ci
    provides:
      - name: srv-api # required by consumers of CAP services (e.g. approuter)
        properties:
          srv-url: ${default-url}
    requires:
      - name: cap-application-auth
      - name: cap-application-db
      # Declare Destination Service Requirement below
      - name: cap-application-destination-service
      # Declare SBPA Service Requirement below
      - name: cap-application-sbpa-service


      
  - name: cap-application-db-deployer
    type: hdb
    path: gen/db
    parameters:
      buildpack: nodejs_buildpack
    requires:
      - name: cap-application-db
  
  - name: cap-application
    type: approuter.nodejs
    path: app/router
    parameters:
      keep-existing-routes: true
      disk-quota: 256M
      memory: 256M
    requires:
      - name: srv-api
        group: destinations
        properties:
          name: srv-api # must be used in xs-app.json as well
          url: ~{srv-url}
          forwardAuthToken: true
      - name: cap-application-auth
    provides:
      - name: app-api
        properties:
          app-protocol: ${protocol}
          app-uri: ${default-uri}

  - name: cap-application-cap-destinations-creator-module # Module to create Destination using Destination Service
    type: com.sap.application.content
    requires:
      - name: cap-application-auth
        parameters:
          service-key:
            name: cap-application-cap-auth-key
      - name: srv-api
      - name: cap-application-destination-service
        parameters:
          content-target: true
      - name: cap-application-sbpa-service  # <-- Add SBPA resource details as requirement here
        parameters:
          service-key:
            name: cap-application-sbpa-service-key
    parameters:
      content:
        subaccount:
          destinations:
            # Destinations based on the CAP service and XSUAA service are created here.    
            # Destination - 1 
            - Name: cap_application_Testing_Destination #The destination to the CAP service. It is required by your UIs running in SAP Launchpad service to access your service.
              Authentication: OAuth2UserTokenExchange
              TokenServiceInstanceName: cap-application-auth
              TokenServiceKeyName: cap-application-auth-key
              URL: '~{srv-api/srv-url}'
              sap.cloud.service: cap-application.service
              
            # Destination - 2
            - Name: cap_application_Testing_Destination-auth #The destination to your XSUAA service instance. The SAP Launchpad service needs it to convert OAuth tokens for use with your CAP service.
              Authentication: OAuth2UserTokenExchange
              ServiceInstanceName: cap-application-auth
              ServiceKeyName: cap-application-auth-key
              sap.cloud.service: cap-application.service

            # Destination - 3 - SBPA Destination
            - Name: cap_application_Destination-sbpa
              Authentication: OAuth2UserTokenExchange
              ServiceInstanceName: cap-application-sbpa-service-instance  # <-- SBPA Service Instance Name
              ServiceKeyName: cap-application-sbpa-service-key            # <-- SBPA Service Service Key
              sap.cloud.service: cap-application.service

          existing_destinations_policy: update
    build-parameters:
      no-source: true



resources:
  # Define XSUAA Service Resource details
  - name: cap-application-auth
    type: org.cloudfoundry.managed-service
    parameters:
      service: xsuaa
      service-plan: application
      path: ./xs-security.json
      config:
        xsappname: cap-application-${org}-${space}
        tenant-mode: dedicated
        oauth2-configuration:
          redirect-uris:
            - https://*~{app-api/app-uri}/**
    requires:
      - name: app-api
  
  # Define HDI Container Resource details
  - name: cap-application-db
    type: com.sap.xs.hdi-container
    parameters:
      service: hana
      service-plan: hdi-shared
  
  # Define Destination Service Resource detials
  - name: cap-application-destination-service
    type: org.cloudfoundry.managed-service
    parameters:
      service: destination
      service-plan: lite
      service-name: cap-application-destination-instance # <-- Service instance name
      config:
        HTML5Runtime_enabled: true
        # Destination 3 - Custom Destinations
        init_data:
          subaccount:
            destinations:
              - Name: cap_application_Testing_Destination_URL
                Type: HTTP
                ProxyType: Internet
                Authentication: NoAuthentication
                URL: https://myurl.com
            existing_destinations_policy: update
        version: 1.0.0

  # Define SBPA Service Resource detials
  - name: cap-application-sbpa-service
    type: org.cloudfoundry.managed-service
    parameters:
      service: process-automation-service
      service-plan: standard
      service-name: cap-application-sbpa-service-instance

!!! Its Done !!!