 Today we are going to explore the concepts and the implementation behind a universal control plane, a control plane for everything, infrastructure, services, applications. But before we do that, let me do a quick introduction. My name is Viktor, I am a developer advocate at Upbound, we're a company behind the CNCF project Crossplane, which is the implementation of a universal control plane. I am accompanied by two of my colleagues and I will let them introduce themselves. My name is Aaron Eaton, I am the senior site reliability engineer at Upbound Cloud and I am a maintainer on the provider AWS project. Hi everyone, I'm Muafak, I've been working on crossplane for the last two and a half years and one of the maintainers of crossplane and all the providers and I'm a staff software engineering engineer at Upbound. Traditionally, we tend to manage infrastructure and services by defining the desired state and then letting some command line interfaces converge the actual state into that desired state by communicating with the API of a provider of choice. That could be AWS, Azure, Google Cloud, Alibaba or any other cloud provider. What is special about those APIs is that there is always a control plane behind them. A control plane is making sure that resources are created, updated, deleted, that they are scheduled, that they have allocated resources and so on and so forth. However, there are a couple of problems with the tools that we are using today. They do not have an API and they do not have a control plane. And managing infrastructure and services without an API and without a control plane is painful. And we already experienced the benefits of having those tools through deployment of our applications in a Kubernetes cluster. Kubernetes API allows us to communicate with Kubernetes control plane and tell it what is the desired state that we want. When dealing in applications, especially those running in Kubernetes, we moved away from the imperative way of managing them. We are not saying anymore install this, create that, update this, delete that and so on and so forth. We are always defining the desired state and letting the scheduler, the control plane, figure out what should be done. The benefits of Kubernetes API and control plane are obvious and that's why most of us are moving or already moved our workloads to Kubernetes. But that is not enough. We need something more universal. We need a universal API and a universal control plane that will allow us to manage not only applications in a Kubernetes cluster, but everything, services, infrastructure, applications or any other type of resources allocated to one or many clouds. Most of us are moving towards multi-cloud type of systems and we need a universal API and a universal control plane that will manage everything. And the solution cannot be proprietary. It needs to be open source and all major vendors need to contribute to it. And we already have such a solution. It is called crossplane. So today we are going to explore crossplane and see some of the benefits. There is not enough time to see all the benefits but we are going to see some of the benefits that crossplane gives us especially when compared with some other tools that we might be using to manage our infrastructure services and applications. Let's take a look at what crossplane is and how crossplane can use compositions to empower your development teams to self-provision custom resources while maintaining your platform teams control and visibility on what is being deployed and managed. Crossplane is an open source Kubernetes add-on focuses on two main feature areas, custom platform abstractions which we call APIs and crossplane resource model otherwise known as the XRM. Custom platform abstractions enable infrastructure owners to declaratively build an opinionated platform for developers while the crossplane resource model provides a universal API for managing those resources consistently in every environment. Crossplane was launched in December of 2018 by the creators of Rook which is a CNCF graduated project. As it says here we were accepted into Sandbox in June 2020 our first major stable milestone was released in December of 2020 and in September of 2021 we moved to incubation status in the CNCF. Crossplane manages granular resources for both cloud and on-prem infrastructure as represented as CRDs. Controllers which we call providers are written to plug into crossplane with these CRDs and interface with any API-driven system to enable you to provision infrastructure or any API-driven resource through the Kubernetes control plane. What this means is that as a platform operator you would create an RDS resource, submit it to the API server, it would then be watched by the RDS controller which would submit commands to the AWS API to provision RDS instances. We call these providers in the crossplane world. There are already several providers available for major clouds and more are being developed by the community every day. To get a look at what we already have covered you can head over to doc.crds.dev which will give you a complete breakdown of any publicly available crossplane provider. Here we're looking at crossplane provider AWS. You can investigate what resources we cover, what sections of the API and what attributes of that resource we expose. To reach alpha status in a provider resources only need to be able to be created and destroyed. Complete coverage of every field, ability to detect out of sync changes. All of that is a beta feature. If something has been promoted to beta API level within a provider it is fully functional and it should detect any change to a configuration of a currently running resource and bring that resource in line with whatever you've specified in the Kubernetes API. Crossplane allows you to build your own platform API through the use of compositions. What this means is you can take all of those granular resources we were just talking about from any cloud and any vendor even mixing and matching and assemble them into your own composed resource definition. These will be exposed in your Kubernetes control plane and can be leveraged as claims by your development teams. Your Kubernetes clusters may not look like everybody else's Kubernetes cluster. Your organization may have different security or access requirements. You may have certain performance goals which require tweaks to the configuration that are non-standard. You may have unique solutions in how your app is architected that require you to provision your infrastructure in ways that are not the same as everybody else. You may be re-running multiple clouds. You may have GKE clusters which are using EC2 nodes. All of this is the reason we created compositions. You can compose your definition of what is a Kubernetes cluster? What is a storage bucket? What is a database? And make it available for your development teams to access. You can compose these and offer them as a single cluster resource limiting the configuration values to only those that a developer would need to change to suit their purposes. Everything else within the composition would stay within the control of the platform team. This allows you to hide infrastructure complexity and also allows you to add policy guardrails around the infrastructure that your teams need to launch. All of this is happening within the Kubernetes API. This means any tool that you currently use in-house to talk to your Kubernetes clusters can continue to be used when talking to these custom resources that you have created. This is not code. Crossplane resource model allows you to handle all of this in configuration and definition. You do not have to write your own custom code in order to manage these custom resources. Crossplane uses the crossplane resource model in order to give you a consistent API across all of your resources. So the same API that allows you to declare a deployment or a replica set or a service or a pod is also going to allow you to provision a Kubernetes cluster. You get to decide whether that Kubernetes cluster goes into an already existing network or has its own. You get to decide when you provision a bucket if it already comes with an IAM role or service account for access to it. You get to decide what security configuration goes into it and all of that can be built in. You can call for a claim for an instance of one of these resources through the same Kubernetes API that you're using to deploy your services and your workloads. We are extending the Kubernetes resource model in an opinionated way to provide this universal experience. This means that if you have a package that you want to run that if you are using some kind of standardized resources some publicly available configuration package on the crossplane tool it's going to behave exactly the same way as your custom packages. Every object in the Kubernetes resource manager has a consistent behavior. We've enabled you to do cross resource references standardized spec and status. We've enabled connection secrets and credentials. We allow you to set the external name of your resources and we have lifecycle policies for managing them through their different phases of deployment and tear down. Our composition engine also has another unique feature in which you can publish several compositions which respond to the same custom resource type. You can use labels to select these compositions when you create your claim. This means that if you are in an organization where your developers are concerned with whether their clusters are running in a specific cloud or a specific environment you may have use cases where you need to test how your code behaves when it's inside of AWS versus when it's inside GCP versus when it's inside Azure. You can do all of this through the same resource by changing the label of the composition that it's going to leverage. So when we say you can mix and match you can have compositions that work across all clouds. You can have compositions that deploy resources in multiple clouds simultaneously and allows them to interact. Or you can construct cloud specific compositions depending on your use case. So the same cluster resource that you declare can have an AWS variant and a GCP variant. And as you can see launching a Kubernetes cluster on EKS requires a different set of support mechanisms than launching a Kubernetes cluster on GKE. Some of these abstractions are name only a network and VPC are roughly analogous but some node pools and node groups are roughly analogous but some of them are fundamental differences. And at the same time while you're launching an EKS cluster or a GKE cluster and all of the associated infrastructure needed to drive them you can include Helm charts that are standardized across both. You have certain cluster operators, policy agents, enforcement tools that you need to run on every cluster. You can include those in your composition as well. Before we jump into a demo let me give you a brief overview of what I will try to accomplish. I want to have a single API through which I want to manage everything. Some resources might be in Azure, others might be in AWS. I might sprinkle it with Alibaba and so on and so forth. I want to be able to manage infrastructure and to manage services and to manage applications. And I need a single API through which I can do all that. Through which I can declare the desired state that I want. Through which I can query the actual state and so on and so forth. And behind that API there must be a control plane. A control plane capable of figuring out what to do with all those resources. What should go where, how something should be done, where something should be done and so on and so forth. That alone would be highly beneficial but I want to go a step further. I want to be able to create completely new interfaces, new resource definitions that will enable developers to manage infrastructure and services and applications by themselves. So I want operators or SREs and security experts and so on and so forth to be able to implement best practices and implementations of all the resources that we need but expose those to everybody else, to developers in a way that is easy to manage, easy to consume and easy to define. This is about being able to shift left. It is about collaboration between different types of experts all with the goal of enabling people on the left, developers, testers and so on and so forth to manage everything and to have full freedom without being constrained with things that do not matter to them. So let's jump into a demo and see cross-plane in action. We always want to start with the desired state. We want to define what should be the state of some resources and those resources could be anything. It could be a cluster. It could be networking. It could be a database. It could be applications or more often than not, it should be a combination of all those. Let's start with a simple example. Let's say that we want to have a cluster and let it be in Google Cloud. Maybe it could be GKE cluster, for example. A definition could be something like this. Examples, Google, GKE, no XRD. And remember, this is a very simple example. I will show you more complex examples soon. So here we have a cluster and that cluster has some parameters like, hey, it should run in US East and it should be the latest version. And then we have a node pool that should be attached to that cluster and that node pool also has some parameters like, hey, location should be this one and the reference to the cluster is this one. So it should be attached to this cluster. This is the number of nodes I want to have initially and there are some other parameters here. They're not really important for this story. What does matter is that this gives me a declarative way to define my resources. I could do something similar with Terraform, Pulumi, Ansible, and so on and so forth. Soon you will see the things that you cannot do with those tools. For now, what makes this special is that this is a Kubernetes API. These are not definitions in some proprietary format. This is Kubernetes syntax. Those are Kubernetes manifests. And in this case, we are using Kubernetes resources to define infrastructure in Google Cloud. And of course, we can do something like this. CubeCuttle, apply, and then the dash-dash filename and the examples, Google. I forgot what is it, Jiki, XRD, and .yml, right? We can apply those resources in a Kubernetes cluster that already has cross-plane up and running in the same way as we would manage any other resources in a Kubernetes cluster. The major difference in this case is that cross-plane extends the reach of Kubernetes API. Instead of managing only our applications, we are managing things not only inside a Kubernetes cluster, but also outside. And in this case, outside means Google Cloud resources. So I'm going to apply this and voila. Come on. Go, go. There we are. We got two Kubernetes resources created. And from now on, cross-plane will take this as the desired state and make sure that the actual state is converged into that desired state. It will make sure that the cluster and the node pool is not only created in Google Cloud, but that the state is maintained forever, or at least until I change my opinion and change the desired state. So cross-plane is doing automated drift detection and reconciliation. And I will show you an example of that in a second. For now, what I want to focus on is the API. I should be able to query Kubernetes API to find out the status of those resources. And I can say something like, hey, get clusters of type container.gcp.crossplane.io. And I can see, I should be able to see in a second. Yes, there is a cluster. And right now that cluster is being provisioned. Cross-plane is communicating with Google Cloud. It is telling its API what to do. And right now Google is provisioning. It is creating the cluster. But I can go further. I can do things that other tools cannot do because other tools in that area, like infrastructure is called, do not have an API. So I can do things, hey, give me the status of all GCP resources. And I can see what's going on with all the resources related with GCP, with Google Cloud. There is a cluster that is being provisioned right now. And there is a node pool that is not even synchronized. It is not synchronized because for the node pool to be created, the cluster needs to be up and running. And this is an example of an advantage of having a control plane. Cross-plane control plane is trying to figure out what should be done, how it should be done, when it should be done, and so on and so forth. Right now it is waiting for the cluster to be provisioned. And only after that it will go and create the node pool because one depends on the other. If I would need to see the details of a resource, I can do something like I would do for normal Kubernetes applications. I can say, hey, let's describe clusters container.gcp.cross-plane.io. And the resource I want to describe is called a-team-gk-no-xrd. And now I can see all the details about that specific resource, in this case of a Kubernetes cluster of GKE cluster, including the events that are happening right now. Now, this will take a couple of more minutes. I do not want you to wait until Google Cloud creates all the resources, so I will fast forward a few minutes and then we can explore drift detection and reconciliation. We can see here that the cluster was created in Google Cloud. And if I go to that cluster, I can see that it is fully operational. Everything is great and so on and so forth. But let me do something that will show how drift detection works. And that will be yet another thing that infrastructure as code tools cannot do simply because they are not control planes. They're not monitoring the actual state and trying to find the drifts. So I will go to nodes, for example, and I will simulate that something terrible happened to my node pool by deleting that node pool. I'm simulating that the data center went down or something terrible happened with the node pool and so on and so forth. Now, if I go back to the terminal and do Q-Cut will get node pools, I should see that from the cross-plane perspective it is still running. That's because the node pool was not yet fully shut down. And let's see what's going on, node pools. And we can see that the state is stopping. Cross-plane detected that the node pool is being shut down. So it is fully aware at any given moment what is the actual state of the resources. The point here is that cross-plane is making sure that the state is always maintained and I do not need to worry about it. So instead of me freaking out and saying, hey, I do not know what's going to happen, whether node pool will be recreated or not and so on and so forth, I will just go and get myself a coffee and come back 10 minutes later because, hey, I'm calm. I know that cross-plane is going to figure out what to do. So let's see what's going on. Q-Cut will get node pools and it's provisioning. Cross-plane with its drift detection reconciliation figured out that the desired state and the actual state are not in sync, that there is a drift between the two and as soon as it could, it started creating a new node pool so that the state is maintained. But now you might be saying, hey, that's a simple example. I want something more complicated. So let's do that. Let's go into a more complex example and see how we can manage more resources at once and how we can enable everybody, developers, testers, whomever, to manage infrastructure and services and applications and everything else in an easy way without going crazy. So if you want to enable others, we have three options. We can encourage them to open JIRA tickets so that other people can create infrastructure and services and deploy applications and do whatever needs to be done. But that's not the goal. We want to enable others. We don't want others to depend on us. So opening issues and tickets and requesting, hey, you do this for me and do that for me is not an option. The second option would be for everybody to stop what they're doing and dedicate a couple of years of figuring out all the details about how AWS works or Alibaba or whatever we are using. That's not a good idea for obvious reasons. So we need to think of a different solution. And that different solution is to create services that others can consume. And those services should be made to fulfill the needs of our users. And those users, as I said before, could be developers, could be testers, could be whomever. So I'm about to create a completely new custom resource definition or to be more precise, cross-plane resource definition or what we call XRD that will generate a new interface. And it could look something like this. Cross-plane config definition K test. So this is an open API. Here we are open API schema that says, hey, whenever somebody wants to manage a cluster, there should be some properties. And those properties would be in this example, in this scenario, version and node size and minimum number of nodes. And whether they would like to manage their resources through GitOps. And if they do, what should be the repository for the manifests. And then we need the implementations of this schema. And one possible implementation for AWS could be cross-plane config, composition, EKS. So this is an implementation. This contains all the details that are required to run a cluster successfully in AWS. And as you can see, there are many things here because what we do is complex. We need to do a lot of things. Let me scroll to the top. If I ever get to the top to show you what I need. If I want to run a cluster in AWS, where is the top? Where is the top? Oh my God, this is really, really complex. Here we are. So I'm creating a composition, which will be an implementation of the schema that I showed you before. And that one will create a cluster and then it will create a node group. And after that, it will create an IAM role. And after that it will create another role. Actually, it's not before or after that. Cross-plane will figure out what is the order of all those things. I just need to specify what I need and I need many, many, many, many, many, many, many things. An average person who is not expert in AWS would probably need a lot of time to figure this out. And I will create not only AWS resources like route table, but I will also make sure that that cluster is production ready. And what is production ready depends from one scenario to another. And in this hypothetical situation, I will configure Helm to use the credentials of the cluster that is yet to be created. And then I will install Prometheus in that cluster. And then I will, what else will I do? I will install Argo CD in that cluster. Actually, I will not install anything. Cross-plane will make sure that those resources are up and running. And then I will configure Kubernetes provider which will create a namespace called production and it will create an Argo CD project. And then it will create an Argo CD application and so on and so forth. The details are not important right now. What does matter is that I as an SRE or operator or SIS admin can define what infrastructure and services and so on and so forth are and what is required to run something well. But this will be hidden from everybody else. This is an implementation detail because remember, I'm creating a completely new service custom made for my organization. So others, consumers of this service could do something like this, could define something like examples, awseks.yaml and say, hey, I want to create a cluster claim. Cluster claim is the name that I gave to the definition that I showed you before. And I will define some labels and say, hey, I would like to have a cluster in AWS and that cluster should be KS. I as a user could change those labels. I would say, no, I would like Alibaba, for example, or Azure or Google Cloud. That's an implementation detail. It's the job of somebody else to define the implementation of this interface of this cluster claim. And my job as a user is to say what I want and to define a couple of parameters like, hey, I care about node size. I would like my nodes to be small. I do not know what small is. I assume that whomever created the implementation for AWS in this case knows what small is. And I would like to have a minimum of three nodes. So I as a developer, as a user, can write this example and just say, hey, kubectl-name space. I want to do it in my own name space, a team, and I would like to apply something defined in a file that is located in examples, awseks.yaml, and there I go. I created that single resource, or I'm about to, there we go. I created a single resource cluster claim that is easy way for me to define what I want, even though behind that single resource, there are many. And I will show you what those are. If I would now change the role to be an operator, I could say, hey, let me see what Victor created. And that could be kubectl get managed, manage resources, resources managed by crossplane. It takes a couple of seconds until it processes everything. And I can see that behind that single YAML, behind those 20, 30 lines of YAML, I got some policy attachments and some roles and node group and cluster and subnets and security groups and VPCs and Internet Gateway, a route table and so on and so forth. But there's more to it because I will not get only a cluster as you saw before from the implementation, that cluster will have from Meet Use and it will have Argo CD and that Argo CD will be already hooked to Git repository so I can manage my applications just by pushing files to Git. Let me give you an overview of what's going to come in the next month in crossplane so you can follow along everything happening in the roadmap project and I think we're updating that every two weeks with the community meeting that you can also attend. One of the most exciting things for me is Tetherjet and the vast provider coverage that it will get us. Tetherjet is a project, a code generation project that will let anyone to generate a crossplane provider using a telephone provider. You can essentially take one telephone provider and produce code, controller code and CRDs and everything using Tetherjet. With that project we're going to have thousands of CRDs available for you to use and now we have AWS and Azure but you can use any telephone provider you would like for that purpose. It could be your internal telephone provider or any provider like Cloudflare or GitHub or anything you want. So that's one thing. The other things are scale testing and performance improvements that Nick is working on in core crossplane. This will allow us to scale the number of composite and claim resources to or drop like 10,000. Right now we're able to scale to 2,000 or 3,000 I think users are reporting but with these improvements we'll get even higher with less resource usage. And the next thing is plugable secret stores. So there have been lots of users asking for a way to not use Kubernetes secrets for various reasons. One of the other tools that was requested was using Vault as the store for credentials of the cloud resources that crossplane provisions. So that will come with plugable secret stores where you can just choose secret stores you would like and crossplane will publish secrets only to those resources. And the other thing is custom compositions. A lot of crossplane users are happy with composition as is but there are also like advanced use cases or like for example for loops and if and else conditions that they need and they're not right now possible in composition. Since we want to keep composition as a layer as simple as possible we will introduce custom compositions that you can just hook up your own server that can render anything you would like with the programming language that you choose. And after that we have some UX improvements like composition validations. Right now you would have the templates in your compositions but they would get validated only after you create a composite resource or a claim. So with the composition validations we will be able to validate them before they make it to the API server. And observe only resources is another feature that is requested by the community which will allow us which will allow users to make a managed resource only observable meaning we crossplane will not issue an update or deletion or anything for that matter. And that is most useful in cases for example you have a VPC and you would like to use the same VPC in different crossplane environments so having it reconciled in different crossplane environments would might result in a racing condition. So far like you know you can just use the VPC directly or with that feature you can just import it as observe only managed resource and then refer it using cross resource references. And the last one I would like to mention is generic cross resource references. Today as you know the cross resource references work just like how it works in Kubernetes meaning you give name and name space only and then it'll find the resource and produce the value that the source resource needs and then just add it there without you know having to know like you know which field of that target resource you need to get and each in which format. However this does not scale to all all use cases. In some cases the source custom resource does not know about the target reference resource. In those cases we need to have a generic way to tell controller that hey go take that value convert it in that way and like you know put it in this field of that of this source custom resource. So that feature will enable us to do that. And these are like you know the main highlights of the roadmap but please make sure to go ahead and like you know take a look at the roadmap and attend the community meetings and we really highly value user feedback when we decide on like you know which one which one of those should get prioritized in our backlog. This was a very quick overview I did not have time to go into all the details because I think that the session should be 25 or 30 minutes or something like that but if you would like to know more just come to the Slack channel ask your questions you can contact me directly or contact the community as a whole and we will do our best to help you out and give you more information more detail about cross-plane because trust me I only scratch the surface there is much more to cross-plane than what you saw in such a short period of time.