Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save ptesny/fd74164a2d8b30f4e38dc9f7a08310dc to your computer and use it in GitHub Desktop.
Save ptesny/fd74164a2d8b30f4e38dc9f7a08310dc to your computer and use it in GitHub Desktop.
Configure Custom SAP IAS tenant with SAP BTP Kyma runtime environment

Configure Custom SAP IAS tenant with SAP BTP Kyma runtime environment

This is a companion gist to Configure Custom SAP IAS tenant with SAP BTP Kyma runtime environment | SAP Blogs.

This brief is to showcase how to get this done using a SAP BTP trial account.

Albeit, the entire procedure is well documented in SAP Help portal, namely under Configure a Custom Identity Provider for Kyma, the missing piece of the puzzle is the configuration of the identity provider application.

Any OIDC provider can be used as a custom OIDC provider with a kyma cluster. However, SAP BTP platform makes it both simple and affordable with the Always Free SAP Cloud Identity Authentication services.

From experience, this is is the most error-prone part of the procedure.
In order to alleviate the pain and burden of creating a SAP IAS service provider application I have prepared automation scripts that can be used entirely programmatically from a kyma environment itself.

Let's see how.

Table of Contents
  1. prepare subaccount for kyma runtime with a custom IAS tenant
    1. add relevant service plans to your subaccount entitlements.
    2. enable Kyma runtime environment.
  2. establish BTP subaccount trust with a custom SAP IAS tenant.
    1. subscribe to a Cloud Identity service from the service marketplace.
    2. create subscription to a Cloud Identity service.
    3. Establish BTP Trust.
  3. Kyma Environment.
    1. default kubeconfig for the provisioned kyma cluster.
    2. Deploying custom-idp service provider application.
    3. Update the kyma cluster setting to use the Custom IAS tenant..
  4. Accessing Kyma Dashboard

1. prepare subaccount for kyma runtime with a custom IAS tenant

1.1 add relevant service plans to your subaccount entitlements

Entitlements


Kyma Runtime


Cloud Identity


1.2. enable Kyma runtime environment

Enable Kyma Environment

in three simple steps...

image image

{
    "modules": {
        "default": true
    },
    "oidc": {
        "clientID": "",
        "groupsClaim": "",
        "issuerURL": "",
        "signingAlgs": [],
        "usernameClaim": "",
        "usernamePrefix": ""
    },
    "administrators": []
}

with a kyma cluster now being created...

The cluster creation may take some time. in the meantime we can setup the trust between a Custom IAS tenant and this BTP subaccount.

2. establish BTP subaccount trust with a custom SAP IAS tenant

All one needs to do is go to the subaccount security settings and hit the Establish Trust button there.

If there are no tenants available (as shown below) that means one needs first to subscribe to a SAP IAS tenant in this very BTP subaccount.

2.1. subscribe to a Cloud Identity service from the service marketplace

2.2. Create a Cloud Identity tenant subscription, as shown below

image

2.3. Establish subaccount trust with the SAP IAS tenant

In the aftermath, a custom SAP IAS tenant is ready for action.

3. Kyma Environment

In the meantime our kyma environment has been provisioned


In order to access the kyma cluster please use the above `Console URL: Link to dashboard`.

That should open a kyma dashboard from where you can download the OIDC-based kubeconfig key.

Alternatively, the OIDC-based kubeconfig key can be downloaded to disk.

3.1. default kubeconfig for the provisioned kyma cluster

As this is an OIDC-based kubeconfig it means it is named user-based.

apiVersion: v1
kind: Config
current-context: garden-kyma--fee3078-external
clusters:
  - name: garden-kyma--fee3078-external
    cluster:
      certificate-authority-data: >-
        LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUQ1akNDQWs2Z0F3SUJBZ0lRV29UNXRGL1pQbTVuN1NiRE5kQ0FYREFOQmdrcWhraUc5dzBCQVFzRkFEQU4KTLb2ZRWApxcEVyS2FCWDEzaFhRdWhyUXFIQmZ4QmNEQUh0WXJOZmJvZSsvVklsUDMvTTczRDFnakNaY3NvWQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
      server: https://api.fee3078.kyma.ondemand.com
contexts:
  - name: garden-kyma--fee3078-external
    context:
      cluster: garden-kyma--fee3078-external
      user: garden-kyma--fee3078-external
users:
  - name: garden-kyma--fee3078-external
    user:
      exec:
        apiVersion: client.authentication.k8s.io/v1beta1
        args:
          - get-token
          - '--oidc-issuer-url=https://kyma.accounts.ondemand.com'
          - '--oidc-client-id=12b13a26-d993-4d0c-aa08-5f5852bbdff6'
          - '--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

Good to know:

  • What is a bit counter-intuitive is that initially only the users listed as administrators can access the cluster.
  • Furthermore, only users who have been already registered with the default SAP ID service can be designated as administrators!
  • Last but not least, for the sake of simplicity, please make sure you provide the list of administrators during the kyma cluster provisioning
  • One can amend the list of cluster administrators at any time and/or add/remove/update additional cluster users from within the kyma cluster itself.

3.2. Deploying custom-idp service provider application

The automation is implemented as a helm chart. A helm chart is a collection of so-called manifest templates.
I prepared a couple of automation targets which can be run from a terminal window.

make

Usage:
  make <target>
  help             Display this help.
  skr-easy-deploy  skr-easy-deploy
  skr-easy-undeploy  skr-easy-undeploy
  skr-easy-template  skr-easy-template

For instance, one can run skr-easy-template apply the values against the helm chart template, namely:
make skr-easy-template > skr-easy.yaml

Alternatively, one can run the skr-easy-deploy against the cluster, as follows:

make KUBECONFIG=~/.kube/kubeconfig-fee3078.yaml skr-easy-deploy

kubectl create ns skr-easy --kubeconfig ~/.kube/kubeconfig-fee3078.yaml --dry-run=client -o yaml | kubectl apply --kubeconfig ~/.kube/kubeconfig-fee3078.yaml -f -
namespace/skr-easy created
kubectl label namespace skr-easy istio-injection=enabled --kubeconfig ~/.kube/kubeconfig-fee3078.yaml
namespace/skr-easy labeled
helm upgrade -n skr-easy -i custom-idp helm/custom-idp \
	   --set namespace=skr-easy \
	   --set clusterDomain=fee3078.kyma.ondemand.com \
	   --set services.ias.name=fee3078 \
	   --install --kubeconfig ~/.kube/kubeconfig-fee3078.yaml

Release "custom-idp" does not exist. Installing it now.
NAME: custom-idp

This will result in creating of the SAP IAS service instance and binding (in a dedicated namespace).
The SAP IAS service instance is a placeholder for a custom SAP IAS service provider application that can be subsequently used to gain access to a kyma cluster.

SAP IAS Service Instance


SAP IAS Service binding


SAP IAS Service binding secret


Good to know:

  • You can look up the SAP IAS service provider application clientid and the issuer url from the binding secret
  • Those who cannot install all the required kubernetes tools on their devices will find a script template which can be run from a kyma dashboard of the cluster.

3.3. Update the kyma cluster setting to use the Custom IAS tenant

Goto instances/subscriptions/environments


View parameters


{
  "modules": {
    "default": true
  },
  "oidc": {
    "clientID": "",
    "issuerURL": "",
    "groupsClaim": "groups",
    "signingAlgs": [
       "RS256"
     ],
    "usernameClaim": "sub",
    "usernamePrefix": "-"
  },
  "administrators": [
    "email1@domain.com",
    "email2@domain.com",
    "email3@domain.com"
  ],
  "name": "quovadis"
}
{
  "modules": {
    "default": true
  },
  "oidc": {
    "clientID": "********************",
    "groupsClaim": "groups",
    "issuerURL": "https://***.trial-accounts.ondemand.com",
    "signingAlgs": [
       "RS256"
     ],
    "usernameClaim": "sub",
    "usernamePrefix": "-"
  },
  "administrators": [
    "email1@domain.com",
    "email2@domain.com",
    "email3@domain.com"
  ],
  "name": "quovadis"
}

and then update the kyma cluster environment instance with the following OIDC and administrators subsections:

{
  "oidc": {
    "clientID": "************************",
    "groupsClaim": "groups",
    "issuerURL": "https://***.trial-accounts.ondemand.com",
    "signingAlgs": [
       "RS256"
     ],
    "usernameClaim": "sub",
    "usernamePrefix": "-"
  },
  "administrators": [
    "email1@domain.com",
    "email2@domain.com",
    "email3@domain.com"
  ]
}

Instance update with new OIDC+administrators settings

4. accessing kyma dashboard

Next, go to kyma dashboard and you will be offered to login with the Custom IAS tenant.
If you do not have your user account yet you can register your user account with the Custom IAS by following a self-registration routine, namely:

image image image image

Troubleshooting

  • If in need to revert to default OIDC settings, please follow this procedure:

  • When running any of the make target one may encounter the following error:

43699 loader.go:222] Config not found: ~/.kube/kubeconfig--garden-kyma--fee3078-external.yaml

just make sure to copy your ~/.kube/kubeconfig--garden-kyma--fee3078-external.yaml into ~/.kube/config

Appendix

custom-oidc-kubeconfig

apiVersion: v1
kind: Config
current-context: garden-kyma--fee3078-external
clusters:
  - name: garden-kyma--fee3078-external
    cluster:
      certificate-authority-data: >-
        LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUQ1akNDQWs2Z0F3SUJBZ0lRV29UNXRGL1pQbTVuN1NiRE5kQ0FYREFOQmdrcWhraUc5dzBCQVFzRkFEQU4KTLb2ZRWApxcEVyS2FCWDEzaFhRdWhyUXFIQmZ4QmNEQUh0WXJOZmJvZSsvVklsUDMvTTczRDFnakNaY3NvWQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
      server: https://api.fee3078.kyma.ondemand.com
contexts:
  - name: garden-kyma--fee3078-external
    context:
      cluster: garden-kyma--fee3078-external
      user: garden-kyma--fee3078-external
users:
  - name: garden-kyma--fee3078-external
    user:
      exec:
        apiVersion: client.authentication.k8s.io/v1beta1
        args:
          - get-token
          - '--oidc-issuer-url=https://***.trial-accounts.ondemand.com'
          - '--oidc-client-id=************************'
          - '--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
{
"name": "quovadis",
"display-name": "quovadis",
"user-access": "public",
"oauth2-configuration": {
"grant-types": [
"authorization_code",
"authorization_code_pkce_s256"
],
"token-policy": {
"token-validity": 3600,
"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"
}
}
{
"modules": {
"list": [
{
"name": "api-gateway",
"channel": "regular"
},
{
"name": "istio",
"channel": "regular"
},
{
"name": "btp-operator",
"channel": "regular"
},
{
"name": "serverless",
"channel": "regular"
},
{
"name": "connectivity-proxy",
"channel": "regular"
}
]
},
"administrators": [
"email1@domain.com",
"email2@domain.com",
"email3@domain.com"
],
"oidc": {
"clientID": "",
"groupsClaim": "groups",
"issuerURL": "",
"signingAlgs": [
"RS256"
],
"usernameClaim": "sub",
"usernamePrefix": "-"
},
"name": "quovadis-trial"
}
# Source: skr-easy/templates/binding-ias.yaml
apiVersion: services.cloud.sap.com/v1
kind: ServiceBinding
metadata:
name: skr-ias-binding
labels:
app.kubernetes.io/name: skr-ias-binding
spec:
serviceInstanceName: '<serviceInstanceName>' ##fee3078
externalName: '<externalName>' ##fee3078
secretName: skr-ias-binding-secret
parameters:
credential-type: "NONE"
parametersFrom: []
---
# Source: skr-easy/templates/service-ias.yaml
apiVersion: services.cloud.sap.com/v1
kind: ServiceInstance
metadata:
name: '<name>' ##'fee3078'
labels:
app.kubernetes.io/name: '<label>' ##'fee3078'
spec:
externalName: '<externalName>' ##fee3078
serviceOfferingName: identity
servicePlanName: application
parameters:
name: '<name>' ##'fee3078' ### name of the application created in IAS or the service instance id
display-name: '<display-name>' ##'shoot-name-fee3078' ### display-name of the application created in IAS
home-url : '<home-url >' ## 'https://$BTP_SUBDOMAIN.fee3078.kyma.ondemand.com'
user-access: public ## allows for self-registration
oauth2-configuration:
grant-types:
- authorization_code
- authorization_code_pkce_s256
token-policy:
token-validity: 3600
refresh-parallel: 3
access-token-format: default
public-client: true ## if set to true, enables PKCE flow for the application, where the client does not need to provide a credential.
redirect-uris:
- 'https://dashboard.kyma.cloud.sap'
- 'http://localhost:8000'
subject-name-identifier: ## https://help.sap.com/docs/identity-authentication/identity-authentication/configure-subject-name-identifier-sent-to-application?locale=en-US
attribute: mail ##userUuid
fallback-attribute: none ##uid
default-attributes: ## https://help.sap.com/docs/identity-authentication/identity-authentication/configure-default-attributes-sent-to-application?locale=en-US
assertion-attributes: ## https://help.sap.com/docs/identity-authentication/identity-authentication/configure-user-attributes-sent-to-application?locale=en-US
email: mail
groups: companyGroups
first_name: firstName
last_name: lastName
login_name: loginName
mail: mail
scope: companyGroups
user_uuid: userUuid
locale: language

skr-ias-application-master

Let's assume one needs to provision a kyma cluster with a custom SAP IAS application from the very onset.

In this case the SAP IAS service provider application must be created before the kyma environment is enabled.
It is fairly easy to get it done using a shared SAP IAS service instance with application plan from the BTP subaccount level.

ias-application-master

copy and paste the ias application json payload content into the wizard, as depicted below and create a sap ias application service instance.

ias-application-master-binding

Next step is to create a service binding with the following json payload:

 {
    "credential-type": "NONE"
 }

The binding will contain both the clientid and the issuer url. These values can be used with the kyma cluster provisioning wizard.
For instance:

btp get services/binding --name ias-local-binding | jq '.credentials | { clientid,  url }' > idp.json

where idp.json contians these two attributes required for kyma environment provisioning, namely:

{
    "clientid": "f61*************",
    "url": "https://***.trial-accounts.ondemand.com",

}

Automation scripts

The BTP cocopit GUI is very useful to learn and rehearse.
Eventually, all these operations can be scripted with the help of SAP BTP cli and jq.

Let's see how...

set the automation target

A given subaccount in a BTP global account is the automation target.

btp login --url "https://cli.btp.cloud.sap" --subdomain '<subdomain>' --user 'user1@acme.com' --password '<password>'
Connecting to CLI server at https://cli.btp.cloud.sap...

Authentication successful

bootstrap-custom-idp

.PHONY: bootstrap-custom-idp
bootstrap-custom-idp: ## bootstrap custom idp for the subaccount
	btp subscribe accounts/subaccount --to-app sap-identity-services-onboarding --plan default
	btp list security/available-idp | jq '.[] | .host'
	btp create security/trust --name quovadis-kyma --idp $$(btp list security/available-idp | jq -r '.[] as $idp | $idp.host')
	btp create services/instance  --offering-name identity --plan-name application --name ias-local --parameters quovadis-ias-master.json
	btp create services/binding --name ias-local-binding --instance-name ias-local  --parameters quovadis-ias-binding.json
	btp get services/binding --name ias-local-binding | jq '.credentials | { clientid,  url }' > idp.json

bootstrap-kymaruntime

.PHONY: bootstrap-kymaruntime
bootstrap-kymaruntime: ## bootstrap kymaruntime
	btp get services/binding --name ias-local-binding | jq '.credentials | { clientid,  url }' > idp.json
	jq 'input as  $$idp  | .oidc |= . + { clientID: $$idp.clientid , issuerURL: $$idp.url  }' quovadis-trial-template.json idp.json > kyma-config.json
	
	btp create accounts/environment-instance --display-name quovadis-trial --environment kyma --service kymaruntime --plan trial --parameters kyma-config.json

download-kubeconfig

btp list accounts/environment-instance | jq '.environmentInstances[] | select(.serviceName == "kymaruntime") | .labels | fromjson'
{
  "APIServerURL": "https://api.f24d684.kyma.ondemand.com",
  "KubeconfigURL": "https://kyma-env-broker.cp.kyma.cloud.sap/kubeconfig/D22B4D75-927C-4092-9C5E-13169A962B28",
  "Name": "quovadis-trial",
  "Trial account expiration details": "Your cluster expires in 12 days."
}

btp list accounts/environment-instance | jq '.environmentInstances[] | select(.serviceName == "kymaruntime") | .labels | fromjson | {KubeconfigURL}' 
{
  "KubeconfigURL": "https://kyma-env-broker.cp.kyma.cloud.sap/kubeconfig/D22B4D75-927C-4092-9C5E-13169A962B28"
}

btp list accounts/environment-instance | jq '.environmentInstances[] | select(.serviceName == "kymaruntime") | .labels | fromjson | .KubeconfigURL'
"https://kyma-env-broker.cp.kyma.cloud.sap/kubeconfig/D22B4D75-927C-4092-9C5E-13169A962B28"

btp list accounts/environment-instance | jq -r '.environmentInstances[] | select(.serviceName == "kymaruntime") | .labels | fromjson | .KubeconfigURL '
https://kyma-env-broker.cp.kyma.cloud.sap/kubeconfig/D22B4D75-927C-4092-9C5E-13169A962B28
.PHONY: download-kubeconfig
download-kubeconfig: ## download-kubeconfig
	curl -o kubeconfig.yaml $$(btp list accounts/environment-instance | jq -r '.environmentInstances[] | select(.serviceName == "kymaruntime") | .labels | fromjson | .KubeconfigURL '  )

bootstrap-hana-cloud

  • target definition
.PHONY: bootstrap-hana-cloud
bootstrap-hana-cloud: ## bootstrap hana cloud on your kyma cluster
	kubectl create ns $(NAMESPACE) --kubeconfig $(KUBECONFIG) --dry-run=client -o yaml | kubectl apply --kubeconfig $(KUBECONFIG) -f -
	kubectl label namespace $(NAMESPACE) istio-injection=enabled --kubeconfig $(KUBECONFIG)
	kubectl apply -n $(NAMESPACE) -f  hc-trial-kyma.yaml --kubeconfig $(KUBECONFIG)
  • target execution
make bootstrap-hana-cloud
kubectl create ns quovadis-btp-trial --kubeconfig kubeconfig.yaml --dry-run=client -o yaml | kubectl apply --kubeconfig kubeconfig.yaml -f -
namespace/quovadis-btp-trial configured
kubectl label namespace quovadis-btp-trial istio-injection=enabled --kubeconfig kubeconfig.yaml
namespace/quovadis-btp-trial not labeled
kubectl apply -n quovadis-btp-trial -f  hc-trial-kyma.yaml --kubeconfig kubeconfig.yaml
serviceinstance.services.cloud.sap.com/hc-trial created
servicebinding.services.cloud.sap.com/hc-dbadmin-binding created
servicebinding.services.cloud.sap.com/hc-trial-binding-x509 created
servicebinding.services.cloud.sap.com/hc-trial-binding created

Additional resources

btp login \
 --url "https://cli.btp.cloud.sap" \
 --subdomain "..." \
 --user '$USERNAME' \
 --password '$PASSWORD'
 
btp assign security/role-collection "MyRole” \
 --to-user "$USERNAME" \
 --create-user-if-missing \
 --subaccount "$SUBACCOUNT"

where $SUBACCOUNT, $USERNAME, $PASSWORD are environment variables passed to the scripts from the Environment tab.

Here you can find more additional information about the BTP cli:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment