 Hello, everyone. Welcome to this talk on Yamal Yo Cloud, Managing Cloud Resources from Kubernetes. To kick off things, let us introduce ourselves. Megan, you want to go first? Yeah. Hi, everyone. My name is Megan O'Keefe. I'm a Developer Relations Engineer at Google Cloud. And yeah, I've been working with Kubernetes and Cloud stuff for the last five years or so. So I'm really excited to be here. Thank you very much. Yeah, I'm Shabir Abdul-Samad. I'm a Developer Relations Engineer as well at Google Cloud. I've been working on Kubernetes and Cloud for the last three to four years. So looking forward to this talk. Let's get started. So to start off, let me brief on what's on the deck. We are going to discuss about what is the Kubernetes resource model just to give a brief introduction. Why we would want to manage cloud resources using Kubernetes. And then finally, go over some of the ways in which we can manage cloud host resources using Kubernetes. So to start the discussion, we would like to speak about two main areas, the API server in Kubernetes and the declarative model that Kubernetes has. So most of the introduction in the next slide can be something that you are already familiar with. So all of Kubernetes components centers around the API server. It's what the control plane uses as the source of truth for external tools, clients, and other internal components. So it's how the nodes know what containers they need to run. It's how any outside actor like a CI-CD system interacts with the cluster. And the API server exposes an HTTP API that the user, external clients, and also the internal components in the control plane can connect to. So through this, we can query and manipulate any of the resources that is understood by the cluster. And some examples of these Kubernetes API clients are the KubeControl CLI tool, client libraries like ClientGo or in any other languages, and also the Kubernetes dashboard. It could be on a standalone Kubernetes deployment or one of the managed Kubernetes provider dashboards. So the second thing we want to cover before we get to KRM is the declarative model adopted by the API server of Kubernetes. So instead of telling how to achieve what you want, what the declarative model says is what you want. And how Kubernetes knows how to get to that part is using the concept of controllers. So every resource or an object in Kubernetes has a controller attached to it. And controllers are trying to continuously drive from the observed state to the desired state, like how you see in this example in the diagram here. So now the next question is, how do we tell the API server what you want? What is your desired state? How do you tell it? For this, we follow the Kubernetes resource model, or KRM, to define the resource or the object we want. So the KRM is a data model or the schema following which the intended state of Kubernetes resources are expressed. And it has three main parts. The first part is the metadata part which explains the object itself. It could have things like the name, name spaces, labels, or even annotations. And then we have the desired state spec explaining what is the state you want the object to be. This has all the information about the resource itself, if it's a container, the things about what's the image to use, what ports to be exposed, and so on. And finally, you have the status field which is maintained, which maintains the current state of the object as is, which is used by the controllers in the reconciliation process. So the status field is only updated and added to the definition on the server side. The clients and the users only specify the metadata and the desired state in a KRM based YAML. So what's cool about this is that as long as we can define resources using this model and have controllers to manage them, we can extend the API server to support all different kinds of entities. New resources that extend the capabilities of the vanilla Kubernetes that follows the KRM are called custom resource definitions. And controllers that introduce capabilities more than just managing the lifecycle of a resource, that is that they manage entire application stacks are called operators. So we have highlighted some of the examples of popping open source operators in the slide here. So whilst that covers what KRM is and gives a general idea, now we would like to see why would we want to manage cloud resources using this model. So with different cloud providers, there are many ways to interact with the cloud APIs. And these tools, and each of these providers have their own tools. And each of these tools also differ from cloud provider to cloud provider as well. And in addition to that, if you operate Kubernetes as well, it could be cloud-based or self-managed, you have an additional API to take care of. And this also comes with a CLI and tools and its own client libraries. So usually an organization running Kubernetes would not only use Kubernetes, but also would need to provision cloud resources like databases, serverless functionalities, DNS, networks, and so on. So this results in having to deal with different ways of interacting with your resources. And this has downsized satisfaction setup. So different APIs with different formats require the expertise to manage it. You also need to deal with the difference in paradigm between internal and declarative. That means the process pipeline would change. And also cloud providers access management, which is commonly known as identity and access management, is different from Kubernetes, from how Kubernetes manages access to its resources, which uses its role-based access control system. And on top of all of this, you run on multiple clouds. If you run on multiple clouds, the variation amongst these increases further. So the question we would like to ask is whether we can consolidate management of all of these via a powerful declarative style introduced by the Kubernetes resource model, the KRM. This wouldn't have to replace your current tooling setup for the cloud, but it could allow for consistency around data format, lifecycle methods, have Git as your source of truth, and also enable a central way of managing authentication. Also, this could give you the power of KRM, including the ability to transform and customize your cloud resources as static files, allowing for self-service for your developers and also a more consistent platform layer. So what would it look like is what you see here in the diagram that's been presented. Like we see on the right side here, the data model is decoupled and defined as KRM. With the tools having to only operate and worry about dealing with KRM rather than keeping up with how the API is changing. So in an ideal scenario, how would it look like? You can treat your cloud resources as a cloud, as KRM-based YAML stored inside Git repositories, and you can integrate your cloud resources into a change approval and validation process. This is of course a very simplified view that we are showing here. You can have multiple repositories and clusters. The important takeaway that we are trying to show here is that you can manage both Kubernetes and cloud resources from the same cluster. And that's what we are going to show today with the demos that are going to follow. All right, so now that we've covered what the Kubernetes resource model is and why you might want to manage your hosted resources with it, we're going to walk through a couple of demos of how exactly you can make this happen. There's a general workflow that would apply to most cloud providers, which is, one, figure out how you're going to manage your hosted resources. We're going to cover both first-party tools as well as third-party open-source tools. Second, you actually have to write your KRM or YAML resources representing those hosted cloud infrastructure. And then you have to figure out where to put the YAML files. So in Git or figure out the workflow of actually getting those files onto one or more clusters. And then finally, we're going to cover how to set up guardrails and some authentication items to make it more secure to be managing your cloud resources inside of Kubernetes. There's a few considerations to worry about there. So to cover step one, choosing your tools, there are different first-party cloud controllers that you can choose, depending on which clouds you are operating in. AWS, Google Cloud and Azure are examples of cloud providers that do offer controllers for Kubernetes. All of them have similarities in that they operate inside the cluster and they interact with the cloud APIs, but there are a few nuances and differences. So we're going to actually cover two. One is going to be the AWS controller for Kubernetes, and then we're going to cover the Google Cloud Config connector. So let's talk about an example workflow using AWS first. So the AWS controllers for Kubernetes, ACK for short, is an open source project led by AWS that is a set of controllers for Kubernetes designed to manage AWS resources. It's open source and each controller is separate. So there's an EC2 controller and S3 controller. And we're going to be showing a demo of the S3 controller running inside an AWS EKS cluster. So this is hosted Kubernetes running inside of AWS. So the way that the AWS controller for Kubernetes S3 edition works is that you install it onto the cluster. We're going to use Helm, which is what the documentation recommends us to do. You have to give ACK permission to create AWS resources from inside the cluster. So that includes connecting the AWS IAM setup to a Kubernetes deployment. And then we have to create the S3 YAML. And then finally, we are going to show an app that's actually using the S3 bucket. So the way that the ACK S3 controller works is we install it using Helm. There's a Helm chart that's been provided by the project and it's running just as a pod inside of our cluster. So here I am with access into my EKS cluster. And you can see we have this name space called ACK system. We can view the pod in it. And you can see that a few days ago, we installed this controller and it's running in our cluster. And we've given it IAM permissions to create and update and destroy S3 buckets specifically. So we gave it pretty specific permissions. And what I can show here, actually is that here's our S3 management console in AWS. We've created a few buckets as we've sort of tested out the demo. And what I'm gonna show is creating a KRM style YAML that represents the custom resource for ACK S3. And we're gonna create a new bucket using this controller and we're gonna watch it be created from inside of our cluster. And we're gonna see it hopefully show up in the S3 dashboard. So what I just did is I created a new bucket name and I'm going to kubectl apply F that YAML file. Note that in production, you wouldn't probably want to kubectl apply. You'd wanna use CICD or deployment automation for this. But we can see our S3 bucket was created. And then we can go ahead into the S3 management console, refresh the page. And hopefully we should see that new symbol test for bucket called this show up in our dashboard like so. So that's just a very simple example of creating an S3 bucket using KRM. And what we've also done is deployed that little in-store ads application. And that's already running using a different bucket. And so what I can actually show is redeploying this app pointing to the newly created symbol test for bucket. So I'm gonna go ahead and do that. And the way I can do that is by setting this environment variable and for my actual application to symbol test for and then redeploying the app.yaml. And this is just a deployment. And I can get pods. Let's see that seven seconds ago, a new ad deployment was, sorry, a new ad pod was created. And then we can go ahead and this is our application running. And we can see that, yeah, the ads are being successfully written to S3 and then gotten out of the S3 bucket. And here's that HTML page that we just showed on the browser. So that's kind of an example of one cloud provider and like a little miniature workflow. Obviously this is a very small application, but you can imagine that you could use ACK to create lots of different resources and especially ones that are tightly coupled to your applications to have all of that KRM together to apply it in the same way, provides a nice kind of unification, which is nice. Okay, let's run through another cloud provider. So now we're gonna switch over to Google Cloud. Google Cloud offers a similar service to ACK. It's called config connector. There's a few differences. Unlike ACK, config connector is a product. It's not the code for it is not open source in the way ACK is. And it also operates as one controller that can manage lots of Google Cloud resources all at once rather than separate controllers for each resource type. Other than that, these are very, very similar tools that both operate inside of your cluster as a controller. Right, so the general workflow is pretty similar. I'm gonna show a similar setup, a hosted Kubernetes cluster in Google Cloud that has permissions to create resources and I'm gonna show creating a cloud-hosted resource and then deploying an app alongside. So this cluster, again, it's running in Google Cloud. We can see it here. It's called symbol shops. This is a Google Cloud project. And I've pre-installed config connector before this. So the controller itself is actually running in this namespace CNRM system. CNRM is an old name of config connector. It stands for cloud native resource management but it just means config connector. We can see the controllers running right here. So that should be all ready to be able to deploy resources on our behalf. Should be noted that like AWS, you do have to set up IM. And so in this case, we configure config connector with a service account that has the necessary roles it needs to create resources in our project. And then, similar to the S3 example, we can define a hosted Google Cloud resource as KRM. So in this case, we have a instance of memory store called Redis Cart. It has specific spec fields to memory store which you can find in the config connector documentation. And you can see once we've applied it which I've done right before this, the instance is created and we can actually see in the Google Cloud console over here on the right, managed by CNRM True. What that basically says is, this resource was created from inside of the GKE cluster using config connector. The last thing I'm gonna go ahead and walk through is thinking about how to keep all of this secure. So in the case of config connector, the default instructions actually have you install config connector with massive sweeping permissions on your Google Cloud project. Basically, it's a project owner. It can delete resources. It can update resources. And if you imagine a large production system, that could be risky. Once a KRM resource lands in the cluster, it gets created, config connector will create it. So you want basically to set up some guardrails and some policies that happened before that point. So what I mean by that is, how is that KRM getting into a production system? Are there change approvals in Git? Are there validations there? Then once a resource is on its way into the cluster, how do you make sure that the person or actor deploying it is valid and allowed? And how do you make sure that the resource is set up in a secure way? And Kubernetes can actually handle both of these things, which is cool. The question of who can create what kind of resource is actually something that's pretty much already covered by Kubernetes world-based access control, our back for short. And you may have used this for things like, this application team only has admin permissions in like this specific namespace and it helps you manage multi-tenant environments. So that's already covered, but then there's a question of, okay, what about this resource right here? What if we want to actually look inside of the spec for a specific resource type and set guardrails on what is allowed for that resource? And this is really powerful because with regular imperative formats, this can be really difficult. There's I am for like, this user can create a reticence instance, but within that reticence instance, what is allowed? And I'm gonna cover a project in Cloud Native Computing Foundation that is gonna help us with this. And that's called Open Policy Agent. Open Policy Agent is a open source project with different parts to it. One of them is called Gatekeeper. And Gatekeeper is a Kubernetes admission controller that runs at the base or at the gate of the Kubernetes API server. So it looks at things as they try to come into the cluster and you can set custom policies that are very specific for certain resource types that allow your cluster to basically accept or reject or audit what is coming in and is it in compliance? And as you can imagine, this could have a lot of really helpful impacts on your organization, especially if you have multiple Kubernetes clusters, it can be hard to determine kind of what's going into the cluster and what resources are allowed and which are not. And it could also help accelerate development as well because again, it's adding an automation layer so that yes, at the gate of the cluster, the policies are checked, but you can also run these checks in your CI CD in kind of a standalone mode that says, oh, this person's trying to merge in this resource. We know it's not allowed. And this allows the developer to kind of have a nice fast feedback loop and avoid surprises. Right, so Gatekeeper has a little bit of a learning curve but once you get started with it, it looks really similar for different resource types. So the way it works is you define a sort of an abstract policy. This is called a constraint template that it's some programming code, specifically the rego language, which I'll show in a moment, that basically is the logic of the policy but the actual parameters of that policy, the concrete stuff happens in a separate resource. So this allows you to reuse templates and I'll explain what I mean by that in a sec. And then you apply them to the cluster. These policies are defined as KRM just like everything else, which is awesome. And then we'll see Gatekeeper be able to enforce that policy on inbound cloud resources. Okay, so let's go ahead and do that. So what I'm gonna show here is a example of a policy that's all about the required version of our Redis instance. So you'll see here in for our instance that we are using Redis v5. Imagine that our organization has a policy that says you have to be on that version of Redis for whatever reason. We can use the rego language, which is a policy language. It's a bit different than a general purpose language. You can see the syntax is a little different but basically we're looking inside of the resource and saying is the Redis version what it needs to be? And you can see this is not a hard coded version. It's a parameter that we will define. And then a message that will tell the developer or the CI CD tool, what went wrong? Why was the resource blocked from entry into the cluster? And you can see, you know, we're gonna define the concrete parameter. Here it is, Redis v5. Let's try it out. The first we're going to apply the template. And this tells Gatekeeper about a new policy type. Then we're gonna create the concrete policies that says, okay, now we're gonna require v5. And now what I'm gonna do is try to apply a Redis instance that's Redis v6. And this is perfectly valid for a config connector. This is a real Redis version that would otherwise be created. But if I try to apply it to the cluster, you can see here, we get the message from Gatekeeper that says, as we defined in our policy, Redis version parameter is not allowed. Must use version parameter. And yeah, this resource was not allowed into the cluster. Then again, if we were to apply another Redis v5 instance, this would be allowed in. Just a very simple example of how Gatekeeper and Open Policy Agent can be used not only for regular Kubernetes resources, but also for cloud-hosted resources as defined as KRM. So really powerful. And again, like the possibilities are pretty much endless here. So with that, I'm gonna quickly pass it off back to Shabir. The one thing I do wanna mention you may have noticed, I just covered two cloud providers, kind of quick in succession. And sure, you might just be operating in one cloud provider at a time. And using one of these tools separately could work really well for your organization. But imagine that you actually are working with multiple cloud providers at once. And this could be the case for many different reasons. What this would mean is that you'd have to be working with two first-party tools at the same time, which could be complex. So Shabir's gonna walk through a way that could help us mitigate some of that complexity. So what we saw with the demonstrations that Megan showed was that we, like how we can use provider-specific tools like Config Connector and AWS Controllers for Kubernetes and then how that enables us to manage cloud hostess resources. So still there's still a main problem here, which is that these are still two different tools that evolve independently. And what we would ideally want is to reduce this to just one thing we have to worry about. So that is the problem that CNCF's cross-plane project is trying to address and we will look at it briefly here. So cross-plane is an open-source Kubernetes add-on that can be simply installed into any of your Kubernetes clusters. And then you have to activate controllers and various different cloud providers that they support and you want to work with. So they have wide variety of supports for many of the public clouds out there. And with that cross-plane installed inside your cluster, this cluster becomes the only control plane for everything that you're managing in your infrastructure. It could be your Kubernetes resources. It could be the cloud resources running in your primary cloud provider. If you're running on another cloud provider, then you can use the same control plane to manage resources in that cloud provider. And also it can extend to resources in your on-prem environments. So a key functionality of cross-plane on top of this is also allowing you to assemble multiple cloud resources into a single time definition and to provide that abstraction. But for the purpose of this talk, we will stick to just the basic deployment example we're using cross-plane. And in terms of composition, we will provide you useful links at the end of the talk. And also finally cross-plane provides you support for you to set policies just like open policy agent on your resources. And you can do gatekeeping work on top of it. So how cross-plane works is basically by extending the Kubernetes API, by introducing new custom resource definitions with its own controller. What I have showed here at the bottom is a very small diagram that explains the concepts of creating and managing cloud resources using cross-plane. The resource claim that you see in blue is the main key definition that the user would submit to the API server. Then you have the resource class, which is the Kubernetes object that defines how to serve the claim, which has all the information related to a specific cloud resource type. The resource that you see in orange is the representation of an instance of the cloud resource that actually is going to serve the resource claim. And finally cross-plane also allows you to pool resources together and serve resource claims from this pool of resources. So let's look at a demo. For the purpose of the demo, we will not go through setting up the entire setup. We have already set it up in a Kubernetes cluster, as you see in the diagram here. We have a GKE cluster running in Google Cloud, and we have an EKS cluster running in AWS, just like how Megan showed, and we have cross-plane installed in our GKE cluster. And this cross-plane installation has been given all the information it needs to be able to connect to and create and manage cloud resources in Google Cloud and AWS. So let's have a quick look at this. So what you're seeing on screen is the Kubernetes cluster that I have created. It's called cross-plane cluster. And this is the object browser for the cluster. If you see here, you can see that it has, we have, it has a bunch of new object types, which are namespaced under cross-plane.io. So these are all done by installing cross-plane into your cluster. And I'm going to show you what I have installed by going through some of the items in the CLI. So you can see that I have made the cross-plane installation using Helm. So you can see that Helm chart installation up here. And also we can list all the cross-plane specific resources in the namespace that I've created for this specific purpose. Let's see what it shows. As you can see here, there are four deployments and two of them are specific to two providers. One is for AWS, one is for GCP. Cross-plane also installs an RBEC manager to manage access control. And you have the main deployment that manages all of cross-plane's control activity. We can also quickly list the list of providers that has been installed. You can see already that the deployments, the two deployments were AWS and GCP, but let's look at the provider definitions. So you can see here I have a configuration for AWS. There's a configuration for GCP as well. And I'm going to also have a quick peek into one of these configurations to highlight the key components inside this configuration. So if you see here, this configuration is of kind provider config that says it's a cross-plane provider config. And at the bottom you can see that it has associated to it, a secret reference to a secret inside our cluster. So this secret is mainly the AWS secret that we would usually use with the AWS CLI. Similarly, the GCP config has the GCloud service account, JSON that we would use using GCloud as a secret here. I'm going to show you the two cloud resources that we have created, which is an S3 bucket and a Redis instance through the cloud memory store manage hosted service. So you can see that there is a bucket called symbol ads bucket. That's the S3 bucket. And also you can see symbol mem store, which is a Redis instance that is managed by GCP. So if you go back to our console, you can see the instance being already created. And we can see whether the same is created. So if you see here symbols ads bucket is the bucket that we created. We can make sure that the system is running as expected by just going through the external IP. So it's in the cluster that we are looking at at the moment. So you can see that it's running as expected and you can see that the cart is also working as expected. So as you come to the end, you know, let us wrap up to this presentation. But we saw today is that there are a lot of ways that you can manage your cloud infrastructure in alongside your Kubernetes deployment as well. However, Kubernetes resource model can act as a single data model to consolidate all of them and all your infrastructure in a single place using the declarative model that the Kubernetes API server demands. And different cloud providers has also provided their own solutions to be able to do cloud resource management using a KRM based model. However, crossplane comes as a single control plane to support multiple cloud providers from single cluster. And it also comes with an added benefit of being able to abstract composite resources together. So with that, we come to the conclusion of our demo. Here are a list of resources that we used in the site and some of the things that we could not go into detail because of the time constraints, please go through them. In addition to that, everything that we showed in the demo has been put up in a Git repository that is publicly available for anyone to try it out. Please try it out and report any issues, modifications that you all wanna see. And also these slides are accessible at the link that you see on screen. Thank you very much.