Skip to Content

Create and Configure the Approuter Application for a Multitenant Application

Use the tenant-aware approuter application in SAP BTP, Kyma runtime.
You will learn
  • What is SAP Application Router
  • How to create and configure Application Router
  • How to configure Destination for Application Router in Kyma Runtime
  • How to describe Kubernetes objects for Application Router
TiaXu1122Tia XuJuly 7, 2022
Created by
TiaXu1122
April 4, 2022
Contributors
TiaXu1122

Prerequisites

  • Step 1

    Each multitenant application has to deploy its own SAP Application Router (also knows as Approuter), and the application router handles requests of all tenants to the application. The application router is able to determine the tenant identifier out of the URL and then forwards the authentication request to the tenant User Account and Authentication (UAA) service and the related identity zone.

    When a consumer accesses the application, their consumer tenant calls the multitenant application via the application router with their tenant-specific URL. The application router then derives the tenant from the URL and calls the tenant-aware XSUAA (containing the user account and authentication service), which is responsible for the authentication of the business user. The XSUAA reads the tenant and gets the customer-specific identity provider (IdP) from the tenant-specific identity zone. Then, the XSUAA delegates the authentication to the configured IdP, and creates a JSON Web Token (JWT) that contains the tenant, the current user, and the authorization scopes of the user. The JWT is then sent back to the application router, and from there to the application.

  • Step 2
    1. Create a folder kyma-multitenant-approuter in the root directory.

      Shell / Bash
      Copy
      mkdir kyma-multitenant-approuter
      cd kyma-multitenant-approuter
      

    2. In the folder kyma-multitenant-approuter, create a file package.json with the following content:

      JSON
      Copy
      {
      "name": "kyma_multitenant_approuter",
      "dependencies": {
          "@sap/xsenv": "^3",
          "@sap/approuter": "^8"
      },
      "scripts": {
          "start": "node node_modules/@sap/approuter/approuter.js"
      }
      }
      
  • Step 3

    Then you should configure the routes in the security descriptor file xs-app.json of the application router so that application requests can be forwarded to the multitenant application destination.

    In the folder kyma-multitenant-approuter, create a file xs-app.json with the following content:

    JSON
    Copy
    {
        "authenticationMethod": "none",
        "routes": [{
            "source": "/",
            "target": "/",
            "destination": "dest_kyma_multitenant_node"
        }]
    }
    
  • Step 4

    The destinations configuration can be provided by the destinations environment variable or by destination service.

    In order to provide destinations environment variable to the approuter application, you should create a ConfigMap object for the approuter’s reference.

    Create a new deployment YAML file named k8s-deployment-approuter.yaml for the approuter app with the following content:

    YAML
    Copy
    ---
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: destinations-config
    data:
      destinations: |
        [
          {"name":"dest_kyma_multitenant_node","url":"https://<subaccount-subdomain>-node.<cluster-domain>","forwardAuthToken" : true}
        ]
    

    There are two alternatives to define the destination URL:

    1. Use external service URL provided by Kyma APIRule (JWT enabled): "url":"https://<subaccount-subdomain>-node.<clusterdomain>

    2. Use internal service URL of cluster: "url":"http://<service-name>.<namespace>.svc.cluster.local:<service-port>

  • Step 5

    Define the deployment object by adding the following code snippets in the file k8s-deployment-approuter.yaml:

    YAML
    Copy
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      creationTimestamp: null
      labels:
        app: kyma-multitenant-approuter-multitenancy
        release: multitenancy
      name: kyma-multitenant-approuter-multitenancy
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: kyma-multitenant-approuter-multitenancy
          release: multitenancy
      strategy: {}
      template:
        metadata:
          creationTimestamp: null
          labels:
            app: kyma-multitenant-approuter-multitenancy
            release: multitenancy
        spec:
          automountServiceAccountToken: false
          imagePullSecrets:
            - name: registry-secret   # replace with your own registry secret for Docker Hub
          containers:
          - env:
            - name: destinations      # refer to the ConfigMap for destinations you created before
              valueFrom:
                configMapKeyRef:
                  name: destinations-config
                  key: destinations
            - name: PORT
              value: "8080"
            - name: TMPDIR
              value: /tmp
            image: <docker-hub-account>/multitenant-approuter:v1   # replace with your Docker Hub account name
            livenessProbe:
              exec:
                command:
                - nc
                - -z
                - localhost
                - "8080"
              failureThreshold: 1
              initialDelaySeconds: 60
              periodSeconds: 30
              successThreshold: 1
              timeoutSeconds: 60
            name: kyma-multitenant-approuter-multitenancy
            ports:
            - containerPort: 8080
            readinessProbe:
              exec:
                command:
                - nc
                - -z
                - localhost
                - "8080"
              failureThreshold: 1
              initialDelaySeconds: 60
              periodSeconds: 30
              successThreshold: 1
              timeoutSeconds: 60
            resources:
              limits:
                ephemeral-storage: 256M
                memory: 256M
              requests:
                cpu: 100m
                ephemeral-storage: 256M
                memory: 256M
            securityContext:
              allowPrivilegeEscalation: false
              capabilities:
                drop:
                - ALL
              privileged: false
              readOnlyRootFilesystem: false
            volumeMounts:
            - mountPath: /tmp
              name: tmp
          securityContext:
            runAsNonRoot: true
          volumes:
          - emptyDir: {}
            name: tmp
    status: {}
    
  • Step 6

    Now you can create a Service and APIRule to make the approuter application accessible to the internet.

    Add a Service and an APIRule for the approuter application in the k8s-deployment-approuter.yaml file:

    YAML
    Copy
    ---
    apiVersion: v1
    kind: Service
    metadata:
      creationTimestamp: null
      labels:
        app: kyma-multitenant-approuter-multitenancy
        release: multitenancy
      name: kyma-multitenant-approuter-multitenancy
    spec:
      type: ClusterIP
      ports:
      - port: 8080
        protocol: TCP
        targetPort: 8080
      selector:
        app: kyma-multitenant-approuter-multitenancy
        release: multitenancy
    ---
    apiVersion: gateway.kyma-project.io/v1alpha1
    kind: APIRule
    metadata:
      creationTimestamp: null
      labels:
        app: kyma-multitenant-approuter-multitenancy
        release: multitenancy
      name: kyma-multitenant-approuter-multitenancy
    spec:
      gateway: kyma-gateway.kyma-system.svc.cluster.local
      rules:
      - accessStrategies:
        - handler: allow
        methods:
        - GET
        - POST
        - PUT
        - PATCH
        - DELETE
        - HEAD
        path: /.*
      service:  
        host: <subaccount-subdomain>-approuter.<cluster-domain>
        name: kyma-multitenant-approuter-multitenancy
        port: 8080
    

    Replace the placeholder with your subaccount subdomain and cluster domain. Note that the host name of the approuter application must start with your subaccount subdomain so that the application can be redirected to the right authenticator.

    What would SAP Application Router do?

Back to top