 Kubernetes as universal infrastructure control plane. Kubernetes is generally related to as a piece of software that is pretty much useful for orchestrating and managing containerized applications. However, Kubernetes by its inherent extensibility is useful even to manage infrastructure outside of a Kubernetes cluster. I am Raghuraman Balak Chandra and I am a co-founder at Invisible Cloud where we offer gravity as cell service Kubernetes platform that simplifies the developer experience for Kubernetes while DevOps teams and central teams can use gravity to standardize Kubernetes across the organization. So Kubernetes operators are useful to perform custom automations that are not natively offered by the Kubernetes APIs available out of the box of any Kubernetes cluster. So what we can do is, so if you have, let's say, some kind of a custom automation that we want to run, then we can write our own operators where we define what the spec or the schema looks like through a custom resource definition. And then when the user creates a custom resource, the user provides essentially a desired set of inputs that is required for the custom resource to be created. And then we have a piece of logic that takes those inputs and then performs whatever automation that is required. While you may not have written on operator by yourself, you're very likely to have used a lot of operators. So whenever you install any kind of add-on to a Kubernetes cluster, they essentially are operators written by irrespective vendors. So operators allows us to perform these kinds of custom automations, right? So why not we use these operators to even manage cloud resources? Why should we use a third-party tool to even orchestrate cloud resources, such as a database or an object store and so on and so forth. So we can use Kubernetes to orchestrate cloud resources through these custom operators. And the key benefit is that users can use then the familiar Kubernetes-based models like writing the YAML definitions, like how you would write for a deployment or an increase or a part. And in the same fashion, you can actually even provision cloud resources, right? And then you can manage them using the rich set of tools available within the Kubernetes ecosystem. So in the past, there have been attempts made to achieve this from a Kubernetes cluster itself. So one of the earliest implementations were done on using the Kubernetes service catalog API where you can have an open service broker implementation to provision cloud resources through Kubernetes itself, right? And currently today, all the cloud providers offer their own specific operators. So for example, AWS offers something called ACK, which is AWS own controller for Kubernetes. Azure has something called Azure service operator and GCP has GCP connected. So all of them are custom operators provided by the specific cloud provider where you can use these operators, install them on the cluster and then provision respective cloud services through these operators. One of the other interesting things that is happening in various organizations currently is what is called as the rise of platform teams, right? So many organizations are building internal platform teams where these platform teams are tasked with building abstractions where these abstractions are offered as shared services to developers. And the abstractions actually take care of implementing a lot of these best practices, policies and guardrails, right? So for example, if a developer needs, let's say a database or a queuing service or a messaging service, then the platform team actually builds these kinds of abstraction and offers it to developers where developers simply say, okay, I just need this queue and the service actually takes care of provisioning the actual infrastructure. Developers on the other hand, expect a self-service way of consuming these abstractions where they can simply use a self-service experience to provision infrastructure so that they can actually move fast without being limited by DevOps teams bandwidth and so on and so forth. And the key thing is they don't want to deal with the infrastructure directly where they'll have to be required to provide a lot of configurations and parameters, right? This is exactly where Crossplane comes into the picture, right? So Crossplane is an open source project where it can be used to orchestrate any cloud infrastructure from a Kubernetes cluster, right? So Crossplane exists as what's called as an universal control plane. And using Crossplane platform teams can actually compose various abstractions and offer them to developers. And these abstractions hide away all the complexities of provisioning the infrastructure. And the abstraction can actually also implement all the guardrails and policies and controls that is required by a particular organization. Developers when they want to provision an infrastructure they simply use these abstractions. And the key thing is that they can use the same Kubernetes style declarative way of defining the infrastructure and provision those infrastructure directly. And Crossplane has out of the box support for all the major cloud providers. And you can pretty much provision any cloud service through Crossplane currently. So let's dive a little bit deeper into Crossplane. And at a high level, there are six major building blocks that Crossplane offers. We will dive into each one of them to understand what they are and how we can use them to compose our infrastructure. So before I dive into those concepts, so let's look at a simple use case. So let's say a platform team wants to offer a simple PostgreSQL service or an abstraction where the service takes care of a lot of these configurations and the developers simply specify what is the required storage and in which cloud provider they would want the PostgreSQL instance to be created. And the rest of the configurations, everything will be automatically taken care by this particular PostgreSQL abstraction that the platform team is offering. So with that as the context, so let's look at how we can use Crossplane to offer such an abstraction or a service. So the first concept is providers. So providers as the name suggests are the actual infrastructure providers. So these are the actual Crossplane packages that gets installed on a cluster and it deals with the actual cloud service APIs whenever a particular resource needs to be created. So in this example, you can simply install, for example, a provider AWS which has all the required managed resources which I'll talk about in the next slide. And it can be used to create any resource within the AWS cloud. The next building block is called as managed resource. A managed resource within Crossplane actually represents an external resource such as a cloud service. So it could be an RDS instance or a GCP is Cloud SQL instance any AWS or a GCP or an Azure service, for example. And this is a fundamental core building block that can be used to create corresponding cloud services. So what you see here on the right side is where you can create an RDS instance by specifying various properties and when you apply this YAML, a corresponding RDS instance actually gets created. So while you can directly create a cloud resource through managed resources, most people will not use this directly because most of the time we would want a higher level abstraction that takes care of even composing other required infrastructure as well. And that's where compositions come into picture. And we start composing infrastructure through compositions and the first step to do that is to define something called as a composite resource definition, XRB in short term. So an XRB essentially has the spec or the schema that defines what kind of composite resources exist within the system and it can be used to create various resources downstream, right? So think of XRB is very similar to the Kubernetes custom resource definitions if you have dealt with that before. Or if you're, let's say, coming from the data form world XRB can be thought of similar to variable blocks that you will have in a typical TF module. So here is a simple example for a composite resource definition. So in this case, for our Postgres SQL example, so we are defining a kind called as X Postgres SQL instance and simply we are defining this spec of this composite resource definition. So this is again left to the platform team, right? So they're actually creating a custom definition and this spec can be defined as they are going to define the actual abstraction. So in this case, we are defining a spec which simply expects the storage GB as the parameter from the end user, right? Okay, so now we have a spec, then the next step is to actually create different compositions. So a composition essentially allows us to create various resources in the form of a composition, right? So you compose various resources using a composition and these can be used by cross plane to create the actual underlying resources. So the composition in turn creates the corresponding managed resources such as the RDS instance or a Cloud SQL instance in the respective cloud provider. So as a platform team, what we will be essentially doing is creating different types of compositions. So whatever abstractions we want to offer, we will create different variants of that abstraction through compositions, right? So in our example of trying to offer a Postgres SQL instance, we could have a production Postgres which automatically configures high availability and encryption while a Dev Postgres composition restricts let's say instance types, so let's say small or the medium, right? So like that we can create different flavors of our composition and offer them to developers to actually provision the resources. So a composition can be thought of something similar to a Terraform module or a Helm template that is used to define how a particular resource will get provision. So for our example of trying to offer an abstraction for creating Postgres SQL instance on both AWS and GCP, a platform team essentially creates two compositions but both of them if you see are of kind ex Postgres SQL instance. This is also of ex Postgres SQL instance and the GCP one is also of ex Postgres SQL instance. But where they differ is that in the AWS case, the actual underlying managed resource that is getting created is obtained already as instance, whereas on the GCP side, the managed resource is actually a Cloud SQL instance. Then as part of the composition itself, we can pre-configure a lot of parameters. This is where you start baking in a lot of those best practices and guard rails and so on so forth. So we can do that as part of the composition itself. And then when the user gives the inputs, let's say in this case, we want to accept the storage GB as an input, then we can merge those user inputs to the actual managed resource that is getting created. So in this case, we are saying we are accepting storage GB as a parameter from the user. In a GCP scale is map the parameter to the data disk size GB on the GCP side, while on the AWS side, map that same parameter to the allocated storage on the AWS side. So this is how we create different types of compositions depending upon how we would want to create our abstractions. Now, once the compositions are available, the next step is to actually create those resources that we want. So that's when we create a composite resource. A composite resource represents a set of managed resources that will eventually get created in the underlying cloud service provider. So a composite resource provides the required inputs from the user to the composition. And then the composition kickstarts creation of the managed resources in the underlying cloud provider. So composite resource can be thought of similar to a custom resource in the Kubernetes world or like a TFRs or a Helm avaliage.yaml, right? That's how you would relate to a composite resource. So let's say we switch the persona and we go to a developer persona and we want to create a resource, then essentially we create a composite resource. We're saying that we want an X Postgres SQL instance database and we're saying that, okay, we want 20 GB and the provider is AWS. That's all we are saying. And when we apply this YAML, the respective composition is automatically picked up and the corresponding managed resources are automatically created by cross claim. There's also another concept called as composite resource claim. A composite resource claim is very similar to a composite resource. It actually one-to-one maps to a composite resource and also has the exact same schema like a composite resource, right? The key difference between XRC resource claim and a composite resource is that typically XRC, the composite resource claim is used by developers and DevOps teams and platform teams can use the composite resource to create resources, right? And the other key difference is that the composite resource claims are all namespace scoped. They reside within the namespace that is specified and the composite resources are actually clustered scoped, right? But one-to-one they have a exact same spectrum schema and they relate to each other in a one-to-one fashion. So how does all these things actually get assembled and you put together how does it look like, right? So the first step is the platform team defines the spec through a composite resource definition. And then the platform team can create different compositions which create the actual composite resources. And as a developer, they initiate a composite resource claim to be created by creating a claim which in turn creates a composite resource and the composite resource starts creating all the required managed resources in the underlying provider as defined in the composition defined by the platform teams, right? So that's how this whole thing is going to work. Okay, so with that, let's actually jump into a demo where we will see things in action. So I've got a Kubernetes cluster running on AWS EKS and I've got it connected to my local and you can see that my Qube config is currently connected to that, right? Now the first step to do is that we can start installing cross plane so that can be installed just by using a helm and install the cross plane helm template. And once cross plate is installed, then the first step is to actually install the provider that you would want to enable. So in this case, you can simply say I want to have provider AWS to be installed because we are going to deal with AWS primarily. And I've already got that as well installed on the cluster. So if I just say, okay, get providers. So I've got the provider AWS installed on the cluster, right? Now, so let's say we want to create an SQS abstraction where we want to offer an SQS service where developers can create a Qs on the fly. So what we will first do is we will create a composite resource definition for SQS. And we define, okay, it's a composite SQS and it can be claimed by the developer using the name SQS and we simply define the spec for this particular abstraction that we want to offer. It's a very simple spec where we simply accept name, region and the visibility time out from the end user, right? So that's the first step to define a composite resource definition. Then we define a composition, right? Where we are saying that, okay, that's a composite SQS kind. And in the composition, we are pre-defining the message retention period and we are accepting visibility time out region from the user. And that's actually mapped from the user specified parameter to the actual visibility time out property in the actual underlying managed resource. Similarly, region is also mapped to the region parameter in the managed resource, right? And so that's the composition. And as a user, when I want to use this composition and create a particular SQS queue, I simply say, okay, I want to create a queue. The name is whatever demo SQS and region is us each one and the visibility time out is 30. And I can also say that, okay, once this queue is created, I want the queue connection details to be available in a particular secret because my application needs to be able to connect to the particular queue, right? So that's actually good and install all of this. So let's say we first install the CRD, right? So let's actually apply the CRD ML. That should happen. Yeah, so we have got the composite resource definition created. So the next step is to define the, to install the composition, we'll go ahead and actually install the composition. So typically this activity will be performed by the platform steam and the compositions will be available. And then when it's available for the developer, they simply initiate a claim which actually creates a queue, right? So now that the composition is actually available, we can actually go out and create a particular queue as well. So before that, let's actually switch to SQS console. So we don't have any queue available here. So let's actually go and say SQS claim.yaml to actually initiate creation of a particular SQS queue. So yeah, so there you go. SQS demo is created. See if I actually say go to cube CTL get SQS demo. I should actually see out. So I actually have the SQS demo queue created. So what you see here is, you now start managing SQS itself from Kubernetes, right? So you now have that custom resource created here itself and actually can manage that particular queue from Kubernetes itself without even going to the AWS console or using any other tool, right? So if I switch back to my AWS console, a queue should get created in another few seconds. Maybe yeah, there you go, right? So the queue actually has got created. So as simple as that. So now the power of Transplane now comes into picture where like I mentioned, you can now manage everything from Kubernetes itself. And because it runs in Kubernetes itself, all the aspects of Kubernetes like your reconciliation loop, all those things also apply to even this particular cloud resource, right? So let's take for example, somebody goes and modifies this particular queue where they actually go and change the visibility time mode. Let's say 60 seconds instead of 30 seconds, right? And say go and save, right? So now because the queue was created from Kubernetes through Transplane, it will automatically try to maintain the state as defined in your desired state, right? So the reconciliation loop is always going to keep reconciling and finding out whether there is any change and automatically detect the drift and you know, revert that change. So if I actually go back and refresh this, so it's one minute now. And if you give another a few seconds while the crossplane kicks in and finds out that you know this particular thing has changed, it will actually revert it back. So let me actually see if it happens. I think we just have to, yeah, there you go, right? So the time out, visibility time out has actually come back to 30 seconds as defined in our claim, right? So that is the key difference between crossplane and other infrastructure as code tool, right? Where drifts can be automatically detected and automatically reconciled and you can go back to your desired state as defined in your spec, right? So that was a simple demo. And if you just want to delete this particular queue we can actually again, simply delete it from here itself, right? Entire lifecycle can be managed from Kubernetes itself, right? So that was the simple demo of how you can use a crossplane to provision cloud service like an AWS SQS right out of your Kubernetes cluster. Now the next question is what about part identities, right? So now this queue has got created. How does the application connect to that particular queue because it needs credentials to talk to the particular queue, right? So in terms of AWS IAM roles or whatever, right? Now every pod when it wants to connect to a particular cloud service then it needs to have those fine-grained permissions that are specific to what that particular pod needs to connect to. Let's say there's a pod that connects to SQS it needs only SQS permission. If there is a pod that needs to connect to let's say DynamoDB it needs to have only that particular permission. So this whole thing needs to be again dynamically created whenever the pod comes up and you need to create those respective IAM roles and policies and also create those respective service accounts, right? So if you're operating as a platform then this whole process needs to be again automated, right? So how do we do that? So again, the operators are to the rescue, right? So what we can do is we can actually have our own custom operator to manage the whole pod identity aspect, right? So you can have your own custom operator written where what it does is whenever a pod comes up and it needs to let's say connect to a particular cloud service it identifies which service it needs to connect to it automatically creates those required IAM roles and policies and also creates the required community service accounts attached to the particular pod. And you know, immediately the pod can actually start connecting to that particular queue, right? So hopefully that gives you an idea of how we can automate the entire infrastructure of provisioning cloud services and even provisioning IAM roles everything through operators through a combination of cross-plane and our own custom operators. So in terms of the benefits that cross-plane offers I think the first fundamental benefit is that because we are managing everything through Kubernetes itself now as users we can use the Kubernetes ecosystem and its tools to even manage cloud resources, right? You don't have to use another third party tool to manage cloud resources. The entire state of your cloud resources are available within your Kubernetes clusters itself, right? And that's a big advantage in terms of simplifying the entire infrastructure pipelines. And we also saw in the demo where the reconciliation happens automatically so that any drifts that happens in the infrastructure outside of cross-plane is automatically detected and it maintains a desired state as defined in our definitions, right? This is very, very powerful where any drifts is actually automatically rolled back. So that's pretty much it. So hopefully that was useful. So if you have any follow-up questions so please do reach out to me. Thank you and have a great day.