DEV Community

Cover image for SAP BTP Kyma blueprints
Quovadis
Quovadis

Posted on

SAP BTP Kyma blueprints

SAP BTP Kyma headless kubeconfig with SAP Cloud Identity Services and kyma runtime environment bindings.


Table of Contents

kubeconfig with the authorization-code authentication flow.

This is the default kubeconfig option with kyma clusters and requires named user(s) be defined with the global SAP ID tenant and have RBAC cluster-admin role binding(s) defined for these SAP ID users as well.

oidc kubeconfig
apiVersion: v1
kind: Config
current-context: garden-kyma--<shoot>-external
clusters:
- name: garden-kyma--<shoot>-external
  cluster:
    certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUQ1akNDQWs2Z0F3SUJBZ0lRYzRZRXZHOTZLdzRS0tLS0tCg==
    server: https://api.<shoot>.kyma.ondemand.com
contexts:
- name: garden-kyma--<shoot>-external
  context:
    cluster: garden-kyma--<shoot>-external
    user: garden-kyma--<shoot>-external
users:
- name: garden-kyma--<shoot>-external
  user:
    exec:
      apiVersion: client.authentication.k8s.io/v1beta1
      args:
      - get-token
      - "--oidc-issuer-url=https://<tenant-name>.accounts.ondemand.com"
      - "--oidc-client-id=6fcadde1-2660-466a-8d30-***"
      - "--oidc-extra-scope=email"
      - "--oidc-extra-scope=openid"
      command: kubectl-oidc_login
      installHint: |
        kubelogin plugin is required to proceed with authentication
        # Homebrew (macOS and Linux)
        brew install int128/kubelogin/kubelogin

        # Krew (macOS, Linux, Windows and ARM)
        kubectl krew install oidc-login

        # Chocolatey (Windows)
        choco install kubelogin
Enter fullscreen mode Exit fullscreen mode

However, such an oidc user based kubeconfig is not suitable for use in headless and/or unmanned environments, for instance, in the remote development pipelines, github action workflows, etc.


kubeconfig with the password grant type authentication flow.

A custom SAP Cloud Identity Service tenant with a public client OIDC application are required to achieve this goal.

The SAP IAS application automation details can be found in the following blog post, namely: Configure Custom SAP IAS tenant with SAP BTP Kyma runtime environment.

kyma custom identity application
resource "btp_subaccount_entitlement" "identity_application" {
  subaccount_id = data.btp_subaccount.context.id
  service_name  = "identity"
  plan_name     = "application"
}

data "btp_subaccount_service_plan" "identity_application" {
  depends_on     = [btp_subaccount_entitlement.identity_application]

  subaccount_id = data.btp_subaccount.context.id
  offering_name = "identity"
  name          = "application"
}

resource "btp_subaccount_service_instance" "identity_application" {
  depends_on     = [btp_subaccount_trust_configuration.custom_idp]

  subaccount_id  = data.btp_subaccount.context.id
  name           = "ias-local"
  serviceplan_id = data.btp_subaccount_service_plan.identity_application.id

  parameters = jsonencode({
    user-access = "public"
    oauth2-configuration = {
      grant-types = [
        "authorization_code",
        "authorization_code_pkce_s256",
        "password",
        "refresh_token"
      ],
      token-policy = {
        token-validity              = 3600,
        refresh-validity            = 15552000,
        refresh-usage-after-renewal = "off",
        refresh-parallel            = 3,
        access-token-format         = "default"
      },
      public-client = true,
      redirect-uris = [
        "https://dashboard.kyma.cloud.sap",
        "http://localhost:8000"
      ]
    },
    subject-name-identifier = {
      attribute          = "mail",
      fallback-attribute = "none"
    },
    default-attributes = null,
    assertion-attributes = {
      email      = "mail",
      groups     = "companyGroups",
      first_name = "firstName",
      last_name  = "lastName",
      login_name = "loginName",
      mail       = "mail",
      scope      = "companyGroups",
      user_uuid  = "userUuid",
      locale     = "language"
    },
    name         = "${var.BTP_KYMA_NAME}-${var.BTP_KYMA_PLAN}-${data.btp_subaccount.context.id}",
    display-name = "${var.BTP_KYMA_NAME}-${var.BTP_KYMA_PLAN}"
  })
}
Enter fullscreen mode Exit fullscreen mode

Last but not least, fetching a short lived kubeconfig user token requires a technical user's name and password with a public OIDC client of a custom SAP Cloud Identity Services tenant.

user token headless kubeconfig

The technical user and password should be kept in a secured vault.

---
apiVersion: v1
kind: Config
current-context: garden-kyma--<shoot>-external
clusters:
- name: garden-kyma--<shoot>-external
  cluster:
    certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUQ1akNDQWs2Z0F3SUJBZ0lRYzRZRXZHOTZLdzRS0tLS0tCg==
    server: https://api.<shoot>.kyma.ondemand.com
contexts:
- name: garden-kyma--<shoot>-external
  context:
    cluster: garden-kyma--<shoot>-external
    user: garden-kyma--<shoot>-external
users:
- name: garden-kyma--<shoot>-external
  user:
    exec:
      apiVersion: "client.authentication.k8s.io/v1"
      interactiveMode: "Never"
      command: "bash"
      args:
        - "-c"
        - |
          set -e -o pipefail

          ISSUER=$(btp get services/binding --name ias-local-binding | jq  -r '.credentials | { clientid, url: (.url+ "/oauth2/token")  }' )
          echo ::debug:: ISSUER content: "$(echo "$ISSUER" )" >&2

          IDTOKEN=$(curl -X POST  $(echo $ISSUER | jq -r '. | .url'  ) \
          -H 'Content-Type: application/x-www-form-urlencoded' \
          -d 'grant_type=password' \
          -d 'username='"$QUOVADIS_USERNAME" \
          -d 'password='"$QUOVADIS_PASSWORD" \
          -d 'client_id='$(echo $ISSUER | jq -r '. | .clientid' ) \
          -d 'scope=groups, email' \
          | jq -r '. | .id_token ' ) 

          # Print decoded token information for debugging purposes
          echo ::debug:: JWT content: "$(echo "$IDTOKEN" | jq -c -R 'split(".") | .[1] | @base64d | fromjson')" >&2

          cat << EOF
          {
            "apiVersion": "client.authentication.k8s.io/v1",
            "kind": "ExecCredential",
            "status": {
              "token": "$IDTOKEN"
            }
          }
          EOF
Enter fullscreen mode Exit fullscreen mode


kubeconfig with kymaruntime environment service bindings

This mechanism allows to acquire a short-lived, service account token based kubeconfig during the provisioning of a kymaruntime environment.

An instance of a cis-local plan Cloud Management service must be provisioned as well for this to work.

The kymaruntime kubeconfig is returned from the SAP Provisioning Service environment bindings API, as follows:

kymaruntime kubeconfig
---
apiVersion: v1
kind: Config
current-context: garden-kyma--<shoot>-external
clusters:
- name: garden-kyma--<shoot>-external
  cluster:
    certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUQ1ekNDQWsrZ0F3SUJBZ0lSQU42Q0VSVElGSUNBVEUtLS0tLQo=
    server: https://api.<shoot>.kyma.ondemand.com
contexts:
- name: garden-kyma--<shoot>-external
  context:
    cluster: garden-kyma--<shoot>-external
    user: garden-kyma--<shoot>-external
users:
- name: garden-kyma--<shoot>-external
  user:
    token: eyJhbGciOiJSUzI1NiIsImtpZCI6IjFxQW56bFp2SnlVNmRwdDBYMnhhbVJLOXV3UjNqOgkyKI-xVJ_LUWqAkm3ek1m4eC8DqMO0WAm4xP-dpwOKho-Uu9-Ls7Y
Enter fullscreen mode Exit fullscreen mode

References

Top comments (0)