Whatever happens in an Azure and BTP private linky swear, stays in the linky swear!
|This post is part of a series sharing service implementation experience and possible applications. Part 1 serves as introduction into the topic with basic setup. Part 2 explains the configuration for SAP Integration Suite. Part 3 sheds light on the different deplyoment modes given by your SAP architecture.|
With the release of the Beta of BTP Private Link Service exciting times dawned upon us. We finally get a managed solution to securely connect from our Apps running on BTP (deployed on Azure) to any IaaS workload running on Azure without even traversing the internet. The first options that come to mind would be SAP WebDispatcher, ECC, S4, Hana, anyDB, Jenkins, Apache or HPC cluster to name a few.
Before Private Link Service, you would have typically deployed an SAP Cloud Connector (reverse connect tunnel over the public internet) or sophisticated internet-facing setups involving gateway components with web application firewalls to allow inbound. Often this required two separate VMs (primary + shadow instance) or at least additional processing power on the primary application server, web dispatcher or the likes. In addition to that you needed to open outbound ports for the cloud connector to reach the public BTP endpoints to initiate the reverse connect.
If you feel brave enough for the Beta those days are gone 😊
Fig.1 pinkies “swearing”
The first scenario we are going to look at in this series, is the consumption of an OData service living on my S4 system, which is locked up in an Azure private virtual network (VNet). My BTP workloads are provisioned in an Azure-based subaccount in west Europe (Amsterdam) and my S4 is based in north Europe (Dublin). Note: SAP restricts the location of the involved resources to west Europe for the time being.
Fig.2 architecture overview
Let’s look at the moving parts
To get started we need to identify our VM, its location, and the VNet where it is contained.
Fig.3 S/4Hana VM properties
We can see the system has no public IP. Furthermore, my Network Security Group on the mentioned subnet is set to allow inbound from my VNets and my P2S VPN but not from the Internet. This reflects common setups. So, my way in to reach my S4 from BTP will be the private link service.
Next, I deployed a standard load balancer within the same resource group as my S4 and configured it to target my two SAP web dispatchers. They will be addressed round-robin to achieve optimal throughput and address high availability to some extent.
Fig.4 Screenshot of Load balancer configuration
I pointed my health probes against the SSL port, that was configured on backend transaction SMICM. SAP NetWeaver exposes two “pingable” endpoints. You can verify on backend transaction SICF.
- /sap/bc/ping needs authentication and
- /sap/public/ping, which is open to be called by everyone in line of sight of the system
Fig.5 Screenshot of Load balancer health endpoint configuration
The load balancing rule finally ties together everything and establishes the route.
Fig.6 Screenshot of Load balancer rule configuration
Using this rule, I receive https traffic on the standard port 443 and pass it on to the https port my web dispatchers are listening on. Usually that is 443 + SAP instance number.
Now, we are all set to create the Private Link Service on Azure using the VNet info from the VM and the load balancer config.
Fig.7 Screenshot of Private Link Service Deployment settings
On the access security tab, I chose “Role-based access control only” but you can adapt to your needs.
Once the deployment finishes navigate to the Properties pane (under Settings) of the Private Link Service on Azure and retrieve the Resource ID. You will need it to complete the process on the BTP side.
Fig.8 Screenshot of Private Link Service Deployment settings
With that we move over to BTP. Open your subaccount, ensure that you assigned the Private Link service (Beta) on your entitlements and create the service. Use the name az-private-link in case you want to plug & play with my examples. Type a message to ensure you can identify the connection request on the Azure side. This is useful if there are multiple requests on the same service and you need to be able to act on them separately.
Fig.9 Screenshot of Private Link Service deployment on BTP
So far so good. Finally, we need to bind this new BTP private link service to any app to be able to send http calls through that tunnel and see the private IP on the BTP side. Without that first binding it won’t be generated. Re-use my naming to be able to run my Java or CAP project right away.
Going forward, I will reference my Java app using the SAP Cloud SDK, but you could do with any other BTP supported runtime. Harut Ter-Minasyan provided another nice CAP example targeting the Business Partner OData service tested against an S4 CAL deployment (Be aware you might need to change/delete the public IP when using CAL).
But wait, plain http calls on code level? We have destinations to abstract away the configuration and authentication complexity.
So, let’s create the destination service “az-destinations” on our dev space to cater for that. We maintain the connection to our S4 using the private IP we got from “az-private-link”. Eventually you need to bind the destination service to your app too. With my implementations that will happen automatically on deployment, because they are listed as required on the mta.yaml.
Fig.10 Destination config on CF space dev for private link service
The additional properties make it available to SAP Business Application Studio and ensure the sap-client. In my case that is 000.
Ok great, let’s test this!
Fig.11 Screenshot from Java app start page
I open the Java app and follow the link to the Servlet as highlighted above. Aaaand private linky linky link don’t break our swear! …
Let’s check on the application log what happened.
Fig.12 SSL error message from Java app via private link service
Ah ok, fair enough. The SSL handshake checks if the response originates from a responder, that we expect. Since our app on BTP “sees” 10.220.0.4 there is a mismatch on the received server certificate. My S4 sits behind the Azure load balancer and a pool of web dispatchers, which send a certificate, that doesn’t mention 10.220.0.4. Mhm, what now? There are various options to tackle this. Here are a few.
- Override the SSL peer verification process in your code with the private IP of the private link service. Check my BTPAzureProxyServletIgnoreSSL.java class for more details.
- Change the Destination config from https to plain http.
- Add property “TrustAll” to your Destination.
However, for maximum security in such a shared environment as BTP you would want to tackle this end-to-end without unverified trust. We need to be a bit more patient with the beta until all requirements are compiled and a general solution to this can be offered.
I will add “TrustAll” for now.
Consuming OData via the private linky app is a piece of cake now
From here on all implementation topics like app roles, XSUAA, logging, monitoring, staging, scaling etc. stay the same as if you were using any CloudFoundry implementation. For simplicity I exposed the private linky app via another destination and created a Fiori app based on that.
Fig.13 Destination config for consuming app
Fig.14 Fiori app consuming OData via private linky app
The complete feature set of that OData service is available. We only created connectivity using this new beta service after all 😉
Thoughts on production readiness
The connectivity components of the setup are managed by Microsoft or SAP for enterprise-grade apps. The development best-practices by SAP are not touched. You code your apps without any need to know of the private link service.
All your traffic stays on the Microsoft backbone, it is private and you get rid of the additional infrastructure components overhead mentioned at the beginning. No outbound ports need to be opened, which makes life easier for deployments such as HEC for instance. This kind of simplification speeds up roll-out and increases resiliency.
For non-prod scenarios the beta implementation is already well enough advanced. Once the SSL verification is added to the feature-set we are all set for a true Cloud Connector alternative for all your Azure IaaS and BTP deployments.
- SAP docs for SAP BTP Private Link Service for Azure
- Developer Tutorial for Private Links Service
- SAP’s official blog post for the new service
- Microsoft docs for Azure Private Link Service
- SAP Cloud SDK docs
Linky swears are not to be taken lightly. I believe SAP is making good use of the Azure portfolio creating another integration scenario that will become popular going forward. Today we saw the setup process for this new private link service that keeps your BTP traffic private and on the Microsoft backbone, drilled a little in the security configuration with destinations and verified the usual development approach can be applied to the apps routing through the private link service with a standard Fiori app. As they say “trust is good, control is better” 😉
In part two of this series, we will look at applying this approach with SAP Integration Suite. Any other topic you would like to be discussed in that regard? Just reach via GitHub or on the comments section below.
Find the mentioned Java, CAP and Fiori projects on my GitHub repos here.
As always feel free to ask lots of follow-up questions.