 All right, I just looked up Avniya, I think she's in different time zone and I believe for her it will be either very, very late or very, very early, the time for our session. So I wouldn't expect her to be present for Q&A, but for now we'll just start our recorded session and we'll see if she will join us in the end, but it's a big maybe. Let me share the presentation. Hello everyone, I hope you all are doing great. The topic for today's talk is connecting applications with services. I would like to give a brief introduction about myself. My name is Avni Sharma and I am a software engineer at Red Hat. My day-to-day work revolves around OpenShift, Kubernetes and operators. You all can find me on Twitter at my handle, which is 16avniSharma or you can drop me and email as well. So at the very onset of the talk, we should discuss what is the goal of the talk and what would be my takeaway from the talk. So the goal here is pretty straightforward and simple. The goal here is to help you all to bind your applications with services. Simple, isn't it? Well, let's not fall into conclusion too quickly. The goal is to bind those apps and services in cloud-native environments. It can be pretty tricky. So let's discuss about how we can actually make it more user-friendly and easy for users to bind their apps with services. So there would be two important parts of the talk. The first part of the talk, we would be discussing the terminology, what is service binding, the operator that would help us to achieve the service binding and the internals of the operator. Whereas the second part of the talk would be a demo, which would be demonstrating the whole learnings of the talk. Let's discuss the terminology that we would be using in the course of the talk. The first terminology is service. Service can have multiple meanings in various contexts. For the context of the talk, I would consider service to be a system that provides functionality to other systems. For example, PostQuest, Cassandra Databases, or Kafka Streams. The second terminology would be application. An application can be any system that utilizes services. It can be a web application in Node.js or a plain Java application. The third and the most important terminology that would be pretty recurring in the whole talk would be service binding. The act and the process of binding these services and applications is known as service binding. So we at Red Hat have tried to provide a very slim and sleek definitions for what service binding means to us and my team. It means propagation of exposed configuration values or credentials from the services to applications which want to actually interact with those services. So I would be having a PostQuest database and an application, for example, a Node.js application. And I want to connect to my service, which is PostQuest Database. So the propagation of various configuration values that is needed by the app to be able to establish a connection with the service, that would be known as service binding. So here is a more pictorial elaboration of the definition that we just showed. So let us discover or let us rather see how things are being done today. So the first thing that we would do to do or to actually accomplish the connection in today's scenario would be to collect all dependent services configuration values. So how it is today is that various services like Cassandra, MongoDB or any service would announce their configuration values differently. For you, it would be a manual effort to go out there and figure it out how they are announcing their configuration values and then gathering all those. It can be very cumbersome and tiring. Second part after you have actually gathered all the configuration values, you would go ahead and append the applications manifest accordingly exposing the previously collected configuration values. So that would be a manual effort again. Third would be to adjust the application to consume the configuration values. It might happen that the values that have been exposed don't have the same names as the names being referred by the application. In that case, you might even have to make some changes in your application. So as we see the way it is being done currently, it seems that configuration and maintenance can be a tedious and inefficient process. So yeah, while many of you can go crazy, don't be afraid. We have a solution for this problem which is called the service binding operator where binding becomes easier. So the slides would be shared after the talk or maybe the link is just given. You all can go to this link and explore the project which is the service binding operator and it is hosted on GitHub. So what we can achieve with the service binding operator. So there are three major points. First one being that the collection of configuration values from the services that we want to connect to. So those are desired services. So those configuration values are made available in intermediate resources. So we might have an intermediate secret which would be an amalgamation or a pool of all the configuration values that have been collected from the desired services. Second point is that optionally adjust the application's resource to consume these intermediate resources. So the operator will adjust the application in such a way that the intermediate resource that was created by collecting the configuration values that is in some way consumed by the application. So this is all being taken care by the operator. This is something that you would have done manually but now is being taken care by the operator. The third and a very critical point is that whatever changes have been made in the configuration after there has been a connection will also be reflected in the application. So to propagate the changes from the configuration values and credentials which has been exposed by the service to the app all this propagation would be automatically. So you will not have to worry about any change in the configuration value after you have made the or established the connection between the service. So to achieve that there are again two important points. The first one is to make the service bindable. So there are ways where we can advertise that that service is bindable. And the second is to actually create a service binding request or an instance which will bind the application and service together and it is like defining a contract between the desired service and the application which wants to connect to that. So suppose we have a Postgres Analytics app. This is a very pictorial illustration of what we are trying to achieve with the operator. So this Postgres service is a backing service and we have our application which wants to connect to Postgres. And it has some questions to not just asks how do I know what all configuration values have been exported by Postgres and can be consumed by me. The Postgres has an answer. It says let me help you with that by making myself bindable. And then you go ahead and create a service binding request which is also known as SBR. We are happy to go. So as we discussed in the illustration making the service bindable is a key and important point. So to do so and to achieve that we can reference a secret config map or a particular resource field with configuration values or credentials to be exported. So we can actually refer a secret or a config map which might have configuration values and we will show how we would refer that secret and config map in the next slide. Or we can map values from the spec or status part of the backing service custom resource and that can be automatically exported to intermediate manifest. But how do we achieve these two points? So for that we would be using some sort of pattern. So the first can be to expose those configuration values which are in a secret or config map or spec or status. So we want to expose the locations or whether it's in secret config map or as an attribute to annotations. And these annotations would have to be described in the backing service CRD. And the second way is to expose the configuration values or credential locations in cluster service versions or CSV. For those of you who use operator framework which is used in OpenShift can make use of CSVs and it is more for a use case scenario of OLM backed services that is when you're using operator framework. But if you are on vanilla Kubernetes you can go ahead with the first option as well. So as I discussed for a service to tell that it is bindable we can add annotations to it CRD. Let me get the pointer here just to explain how the annotations would work. So for a service binding operator to recognize an annotation we have added the prefix service binding operator dot red hat dot io. So this is basically to scope the annotations to our operator. That is why we've mentioned this. The second part if you see we have mentioned an attribute which is DB name and that is mentioned in the spec part of the service and we want that this attribute is available to my app as an environment variable. So as you can see a lot of is going on in this annotation but I have tried to mark it specifically with using different colors out here. So suppose I have a secret an object or Kubernetes object which is a secret and its reference is DB credentials and the key in that secret is user. This secret name is being exposed by the service in the status. So we mentioned that we want the value of user key from this DB credential secret resource which is in status to be made available to my app as an environment variable. Now coming to the case of password. For password we might want it to be as a volume mount instead of an environment variable. For that we have the convenience of providing it as a volume mount as well. So as you can see I want the password key from an object which is kind secret in my Kubernetes world and the reference for that secret is DB credentials. The key is password and I want its value to be given to the application as a volume mount. Coming to the next part is how to achieve the same exporting of configuration values in an OLM integration way. OLM is operator lifecycle manager under operator framework project and if you're using OpenShift then you would be having OLM and in that as well instead of annotations you can go ahead and describe what you want to export over here in X descriptors. Binding ENV object secret user or password. This is again an illustration to show how a service binding request would look like and the important API endpoints in the service binding request which are two which is mainly application selector and backing service selector. So application selector would refer to the application that wants to connect to a backing service selector. It is not necessary that it is only an operator managed backing service. It can be typically any Kubernetes resource as well as an operator managed backing service. Okay so a lot of information on this slide but I would like to draw your attention to only the important parts which are these rectangles. So on the left over here I have my service binding request and considering the fact that my app is already deployed this is my applications manifest which is of kind deployment and I have made a Node.js application out here. This is just a snippet of the application deployment and over here I have my demo database or CR snippet over here. This is my backing service. So basically the intention of this whole slide is to show how these two resources are being referred in the binding request over here under application selector. We have our Node.js app and in backing service we have our post-quest DB demo. Okay cool so now over here I'm trying to illustrate how there is an API which is known as custom environment variable and it is a very critical API in the project because there might be scenarios when your application is a legacy application and you might not want to change the name of the configuration value and you might not want to you might want to use the value that is being given by the service but not the name that is being exported. So you can actually change the name and you can also make your custom values. So over here if we see this is a string JDBC post-quest and then over here we have a pretty comprehensive go template in which we say that this ID DB from DB status I need connection IP. So connection IP can be as 172.30 not 24.19 and dot I want the DB connection port and it will fetch the DB connection port from the status and the status DB name which is post-quest. So this is a very nice and handy dandy tool in the service binding operator when we create an instance for the service binding. It's pretty great. So we have discussed a lot of functioning of service binding operator and how the services will make or export the configuration values and how apps will consume it but now let's take a quick demo tool to make it more simple to follow and to demystify it. For the demo I would be using an open shift cluster but you all can use any Kubernetes cluster. So over here I'm going to operator hub and installing my post-quest database operator. I will click on install and I will subscribe to this operator in our particular namespace which is service binding demo and I will hit subscribe as we can see the status of the operator it is installing and in some time it install is succeeded we will now go to developer topology view over here we can see the pods and deployments coming up we will now create an application or rather import an app which is a Java application for this demo and I will give the application name as Java app and the resource reference as well as Java app and hit create. So now I can see that my application deployment is up but it is still building so now I will create the database instance and the instance name is db demo there are certain spec values that have been mentioned here like image image name I will hit create and now if I see the status of my instance database instance I can see that certain configuration values have been populated there like connection port connection IP and etc now again I would be going to the topology view and I would see that the post-quest database instance is up and running over here basically I want to connect my Java app to the post-quest database my Java app as you can see is still building so I will go ahead and take a look at the service binding till my Java app build is complete service binding is basically an intent to bind my service with the application you all can see that the API version over here has been mentioned as apps.openshift.io and the kind is service binding request the name of my resource would be binding request in service binding demo namespace under the spec you can see application selector and backing service selector and for each I have provided resource ref group version and resource for backing service selector as well we can see that the group is post-quest operator version v1 alpha 1 kind database and the resource references db demo the custom env var as I had told earlier is a very handy dandy tool in service binding instance over here we can give the custom name for our environment variable and the custom value so over here like we have a string jdbc postgres and the values should be from status db connection ip port etc similarly we can have db user and it can be taken from db config map and the username key so now my java app build is ready but over here you can see that I cannot perform any crud operations because my app is not connected to database so our connection is yet to be established so I will just copy this service binding request and apply it over here on my console so now the operator or reconciliation has come up into action and for this I have assumed that my operator is running locally in the background and as you can see that the connection has been established between the java app and postgres database so now if I try to save a fruit and hit save it would be appended in the list so now we can very clearly infer that a connection has been established by just making our service binding request how cool is that now let us take app take a look at the intermediate secret that was created as part of this process this this is something that user has not created this is something that the operator has created and it has populated the secret with the configuration values from the database over here we can see db user as postgres and our custom variable jdbc url and we can see that the configuration values have been populated as was desired by the go template connection ip connection port and everything has been populated in the service binding request for this second scenario I would be demonstrating how to connect a node just application to two backing services so I have an hcd cluster and a postgres database already installed in the cluster and instances for both the services have already been created beforehand currently we can see that our node just application is loading and booting and a connection has not been established let us go and create a service binding request but over here we have two services for that we would be using backing service electors api and over here we can see that we have a list of services first one being postgres and second one is the hcd so I will go and hit create so now the reconcile has happened in the operator and we are assuming that the operator is running locally but operator is also available on operator hub now so you all can take a look at that as well now we can see under conditions that our operator is ready and the status is true for type ready that means that the connection between our app and the services has been established so let's go ahead and check out the the Browse or the URL and let's try saving some data in our app so by fruits add and we can see that it has been appended in the app that means that our service binding request worked and we were able to in fact establish a connection between the app and the service rather multiple services because in this case we are taking two services now if we go ahead and delete our backing services from the request we should actually be getting a false readiness type and yeah indeed we are getting that and the reason for that is empty backing service selectors if we remove the selectors the status would actually inform us that there is something wrong there is something amiss and so now I will go back and add the list of services that we wish to connect to and hit save and now the reconcile is happening again in the operator and it will look for the services in the background and the status should be true so yeah now it has turned to true so our service binding request actually worked all right that was a pretty cool demo so I would like to urge you all to take a look at the operator and install it and use it from operator hub it is readily available there and if not from the operator hub you can also install it in any vanilla divinators cluster and for that I have pasted the link to the GitHub repository that you all can refer and there is a getting started and kind of onboarding kind of guide which will help you to embrace service binding operator and there are two blog posts as well all these links have been shared on the slides so please take a look at it and thank you all for attending today's talk and I'm ready to take questions and by the time I'm answering questions and discussing it with you all I would urge the rest of the folks to scan this QR code and send me feedback and suggestions thank you all once again for giving your valuable time thanks Avni it was a great occasion and let me just share those coming there and now we are open for questions okay I saw you already answered a couple yeah all right I will not spend too much time waiting for additional questions because it's very early for Avni and once again thank you for a great presentation and I don't think we have anything else coming up today so I'll call it a day for thanks thank you for your participation