SAP private linky swear with Azure – extending BTP apps with microservices in Azure Kubernetes Service via SAP Private Link
This post is part 9 of a series sharing service implementation experience and possible applications of SAP Private Link Service on Azure.
Find the table of contents and my curated news regarding series updates here.
Find the associated GitHub repos here.
Continuing with the implementation journey of SAP Private Link Service (PLS) for Azure we will have a closer look at connecting to your micro-services hosted on Azure Kubernetes Service (AKS). Why is this interesting? For example, a Scandinavian customer I recently spoke with, connects their SAP Commerce Cloud privately with their non-btp business extensions using this new BTP service.
Fig. 1 Architecture overview of example use case with SAP Commerce Cloud extensions hosted on Azure Kubernetes Service
This post focuses on the AKS setup and builds upon part 1 and part 2 of the series. Part 1 covers the standard Azure load balancer setup and scope, whereas part 2 sheds light on the connectivity from SAP Integration Suite. Integrators put things together, you know 🤠.
#Kudos to Dennis Menge who got me up to speed with K8s and Azure Private Link in one Friday afternoon. A skilled, humble, and fun to work with human being. Best combination in an engineer.
#Kudos to Matthias Winzeler and Gowrisankar M for the meaningful collaboration. Co-development at its best.
Be aware that the private link setup is done through YAML files instead of the Azure portal UI.
Fig. 2 Illustration of pinkies connecting your AKS-hosted microservice via SAP BTP
You didn’t know AKS with PLS worked from day one? Here you go…
Azure Kubernetes Service was not listed on the series yet, because it is a standard scenario for the Azure Private Link Service. But since some of the configurations are beefier than a couple of clicks on the portal, it seemed worth spending a post on it.
Wait, not available through the portal??? 😱
Yes, we must do what Kubernetes demands! And that is command line usage! 🧙♂️No, really. Since Azure Kubernetes Service will govern your Azure Private Link and configurations, you need to use the famous “kubectl”. But don’t worry you will still be able to verify the PLS creation from the Portal. There is a shy🙈 resource group with prefix ”MC_” that gets created. More on that further down.
To hit the code 👊🏽 without any further reading, jump to the GitHub repos.
In case you are following along:
- Start by spinning up an Azure Kubernetes Service instance.
The two resource groups that were created. One that you individually named that contains your AKS service instance. And second generated one prefixed with “MC_” that contains the virtual network and VM scale set etc. This second one will also contain your Private Link and load balancer once we progress with the setup.
- Clone the GitHub repos into your environment.
- Deploy the deployment.yml from the app folder using kubectl command
kubectl apply -f deployment.yaml
It uses a standard NGINX image from the Microsoft Container Registry, mounts the working directory and echoes a simple JSON on each request on port 80.
You may install kubectl locally or use the Azure CLI from the portal, which has kubectl pre-installed.
Hurray 🥳, we have a running micro-service that cannot be called by anyone. Continue with the service YAML, so it can see the light of day…
Fig. 3 Screenshot of deployed container with hello-btp app on AKS pod
- Verify the annotations on the YAML if you are not happy with defaults. Default inbound port is configured as 8888. This is the port that is needed on the BTP Destination.
In my example I am hitting http port 80 on the NGINX web server. Read more about the security settings here.
apiVersion: v1 kind: Service metadata: name: hello-btp-service annotations: service.beta.kubernetes.io/azure-load-balancer-internal: "true" # Use an internal LB with PLS service.beta.kubernetes.io/azure-pls-create: "true" service.beta.kubernetes.io/azure-pls-name: hello-btp-pls service.beta.kubernetes.io/azure-pls-ip-configuration-subnet: aks-subnet service.beta.kubernetes.io/azure-pls-proxy-protocol: "false" service.beta.kubernetes.io/azure-pls-visibility: "*" spec: type: LoadBalancer selector: app: hello-btp ports: - name: hello-btp-port protocol: TCP port: 8888 targetPort: 80
The annotations instruct AKS to create an Azure Private Link Service with name hello-btp-pls 🙋🏾♀️, connect it to the specified subnet via a load balancer listening on port 8888.
Find the AKS virtual network on the shy 🙈 managed resource group prefixed with “MC_” on the Azure portal to learn about your networking setup.
Fig. 4 Screenshot of AKS managed resource group with VNet
Enhance your Azure Private Link deployment with additional annotations if desired. For instance, “service.beta.kubernetes.io/azure-pls-auto-approval” allows auto approving of connection requests from specified Azure Subscription IDs.
- Deploy the service.yml from the app folder using
kubectl apply -f service.yaml
At this point you will see your new Private Link Service and associated load balancer governed by AKS. This is different to the setup described in part 1 of the series, where you were in control to govern the services. You brave human being forfeited that right now to AKS ❤️🔥.
Fig. 5 Screenshot of AKS managed PLS and load balancer
All steps beyond that are identical to the standard example described by the SAP documentation or part 1 of the blog series. Of you go 🏃🏿♀️ to complete the setup on BTP to see the message from your microservice hosted on AKS.
⏩ ⏳ 🧠
… A simple test from our beloved Java app hosted on CloudFoundry on BTP gets you a nice hello message from the AKS hosted workload:
Fig. 6 Screenshot from Java app on BTP calling micro-service on AKS
Nice, isn’t it?
If you want to expose multiple services at once using an Ingress controller, check out the examples for NGINX Ingress controller in the GitHub Repo and familiarize yourself with the different options.
Comments from the “ground”
Below I put two quotes from the engament with the customer mentioned at the beginning. Looking forward to yours 😊
“Only real challenge we have had after getting the iFlows configured with the CF approuter, has been the tight network-rules (NSGs) at the Azure VMs. The Azure Private Link troubleshooting guide was very helpful for the admins!“
“We require IP allow-listing on the CF approuter side to restrict traffic to SAP Cloud Integration. This blog and this doc entry were helpful to progress on the setup.”
Thoughts on production readiness
SAP Private Link is generally available and therefore completely ready for prime time (quoting Gowrisankar M from the SAP engineering team 😊).
Azure Kubernetes Service is an enterprise ready managed service for Kubernetes powering global SaaS applications. Doesn’t get more productive than that 😉
The additional hop with the CF approuter on SAP Cloud Integration is not at all ideal, since it is Internet-facing and giving access to your private tunnel. Make sure it is locked down properly! The approach is technically supported by SAP and described in-depth here. Make conscious decisions based on your security guidelines.
My blog series adds details to SAP’s standard docs to get you up and running smoother.
Not too bad, huh? You saw today how to connect to your AKS hosted workloads nicely and most of all private over the Azure backbone with your BTP apps. The process differs slightly from the setup known so far, because AKS manages the lifecycle of the Private Link Service. With some YAML here and there, you got that sorted in no time too 😊
Any comments regarding your AKS journey with SAP Private Link @Developers and @Architects?
The next part of the blog series discusses web application firwall with Azure App Gateway.
Find the related GitHub repos here.
Find your way back to the aggregator blog post here.
As always feel free to ask lots of follow-up questions.
I assume that in the example given, SAP BTP is being used as the integration layer / middleware because the mentioned Scandinavian customer has chosen to adopt the SAP strategy of using SAP Integration Suite as a hub for integrating with SAP products. Otherwise, I imagine it would have been possible to achieve the end-to-end integration entirely on Azure by using a product like Azure Logic Apps instead of SAP Integration Suite. What do you think?
yes indeed. It boils down to customer choice and architecture desires. The same pattern could have been achieved with Azure Integration Services without and the additional hops throught the CF Approuter etc. Like with any integration pattern out there by the way.
For anyone looking to dig deeper have a look at my comparison: Port your legacy SAP middleware flows to cloud-native PaaS solutions | SAP Blogs.