 Hi everyone, glad you could join us. My name is Eli, I'm an engineer on the CDK team. And today I wanna show you what it's like to develop a Kubernetes application using CDKs and CDKs Plus. All right, so just some context. This is the construct catalog. It's essentially a Twitter account that tweets every time a new CDK library is published. Now today we wanna add some search capabilities to it. We want users to be able to query to discover those libraries. Okay, so this is my application. It was generated or initialized using the CDK CLI. And you can see there's a main.ts file here, which declares my CDKs chart. This is where my resources will go. Okay, to implement the application, we're gonna use Elasticsearch as the backend. And specifically we're gonna use the Elasticsearch operator slash custom resource. So to that end, I already have the custom resource definition in my Kubernetes cluster. You can see it here. And what I wanna do is import this definition into my application so I can use it in my TypeScript code. Now to do that, I'm gonna use the CDKs import command, which will read the definition, the JSON schema, and generate TypeScript code. All right, so let's do it. So we run kubectl, get CRD, and we take the Elasticsearch CRD, output it as a JSON, and pipe it to CDKs import. Okay, now we have this Elasticsearch.ts file here. You can see it's pretty big. And it contains the entire API spec of the custom resource as TypeScript code. And you can also see that there's this top-level Elasticsearch API object here, or resource. And this is what we'll be using. All right, so let's use it. We're gonna do a new Elasticsearch. You can already see the nice IDE completion. I give it a scope and an ID, and some properties. So we're gonna give it... You can see there are a few optional and a few required ones. You can also see a nice inline documentation. So let's start with the version. We're gonna use 7.7.1. We'll configure one node set with the count of one and the name of default. And we also need a few other configuration properties which I'm just gonna paste in so I don't make any mistakes. Okay, I'm also going to disable SSL for now, just because it makes it easier with the demo. So this is how you do it. And also I'm going to explicitly set my service ports. So I'm going to use the standard, standard Elasticsearch 9200 port. Okay, that's it. That's all I need. Now I can generate my manifest, sorry. I do this by running city-kates-sync. And let's take a quick look. So this is the manifest. No big surprises here, right? This is what we expected. And also it has this metadata name here which was auto-generated by the city-kates. So the city-kates will generate a name for every resource that doesn't have a name configured. And this is gonna be very useful. We'll see why later on. All right, let's apply this to the cluster. Okay, let's take a look at our pods. We have one initializing pod, that makes sense. Let's give it a second. Now let's take a look at our service. We have this HTTP service which we configured with the 9200 port. And you can also see that the service name also has this prefix of the custom resource name, this one. Okay, let's see where our pods are. Have one running pod, it's still not ready. Let's give it a second or two. All right, cool, it's ready now. I'm also going to index some mock data into the cluster just so we'll have something to play with. So I can do this by running cube, cuddle, port forward. And I have this curl command ready here. All right, now let's move on. So the next thing we wanna do is create a small proxy service that's basically going to translate user requests into elastic search queries and return the result to the user. So I already have this code prepared, it's not super interesting. The one thing to note here is that I need to pass these three environment variables to it. And this is, we're gonna have to pass it from the application, from the manifest definitions. All right, so what I wanna do now is create the container. I need to create a container and configure the environment variables and somehow include this query.js file in the container. So to do that, I'm going to use cdkates plus. Now, cdkates plus is a package which is part of the cdkates tool chain and it contains these high level intent based APIs that are based on the low level core Kubernetes objects but they make it a lot more easier and natural to work with. Now let me just show you what I mean. All right, so I'm just gonna import this cdkates plus library as K plus. From cdkates plus. And I'm going to create my container. So I'm gonna do new K plus container. So I need to give it the image. So it's gonna be node 12.18.0-stretch, specific. And the command is going to be node query.js, right? And I'm gonna give it a port and I need to configure the port here as well. So let's just extract this out. It's gonna be query port. And we're gonna use it here and we're going to use it here. Okay, now I need to expose or make this query.ts file available to the container. So I like doing this with config map based volumes and then just mounting the volume onto the container at a specific path. So let's do that. Let's create a config map. So I'm gonna do config map, K plus config map, give it a scope and an ID and take a look at its API. So I see that there's this add file API, which is exactly what I need. So I'm gonna use it. And now I need to create the volume, right? So I'm gonna do K plus dot volume from config map. And now I need to mount this volume to the container. So to do that, I'm going to store the container again in constant and take a look at its API. So I can see that there is a container dot mount API, which accepts a path and a volume. And I'm going to need to configure this path also as the working directory of my container so that this command will work. Now let's extract this out. Okay, I'm gonna use it here and use it here. Deplication averted. All right, now I need to configure the environment variables. So to do that, I'm going to use the end key. And let's take a look at which environment variables do I need. So I need the elastic search username, that's easy. It's going to be like the standard default username that the custom resource creates. So I'm going to do K plus dot end value from value, basically just a way to pass a little string. The next thing is the elastic search endpoint, which is a little more interesting. It's going to be K plus dot end value, but let's stop here for a second. So the endpoint is actually related to the service that we saw before. So let's take a look at it again. This is the HTTP service that I want to hit. So I'm going to have to construct the endpoint using the service name and the service port with the HTTP, of course. So again, I'm gonna do from value, it's literal string, it's just a dynamic one. And here I'm gonna do HTTP. And now I need to have access to this generated name. So to do that, I'm going to store the custom resource, oops, in a constant elastic. And now I can just use this resource dot name and to get the name. And again, this dot name will work for any SDK resource, even if you don't specify a name on your own. All right, so now I just need to append this suffix. And I also need to give it the 9,200 port. And since this is repeating itself also, so let's just extract this. So it's gonna be ES port. And I'm going to use it here. And I'm going to use it here. All right, next up is the password. So the password is the most interesting one because it's actually stored inside a Kubernetes secret and it's created by the custom resource. So if we take a look at the secrets, this is the secret we need. And again, you can see that it's prefixed with this resource name, which we already know how to access. So the first thing we need to do is import this secret into our manifest, so to speak. So to do that, we just use the kplus dot secret from secret name. And again, we already know how to create this name just by doing this. Okay. And now we can use this secret to create environment variable values. So we do kplus and value from secret. Whoops, yep, nope, from secret. We give it the secret and we give it the specific key inside the secret that actually contains the value. And again, this is the documented key. Okay, I think we're ready as far as the container is concerned. The next thing we wanna do is just create the deployment. So we do new kplus deployment. We give it a scope and an ID. I'm gonna go a little faster here and configure, so just one replica and the pod spec is gonna be just my single container. Oops, container. All right, and now I want to expose this deployment as a service, right? So let's take a look at the API that the deployment resource has. Okay, deployment dot. So you can see that there's an expose here which says expose a deployment via a service equivalent to running kubectl expose. This is perfect. This is what I need. So I'm just gonna give it the port to my willing. All right, I think that should work. So let's generate the manifest and see where we're at. So cdk is seen. Let's take a look. All right, so we can see the manifest is much bigger now. Obviously also because of this inline application code here. But we can also see that there is the service here, right? And the deployment here, which is great. And also we can see that these selectors are here even though we didn't really specify them in the application, right? Here we didn't have to think about selectors like anywhere. Normally when you define the YAML, you have to apply labels to the pod and then you have to apply the selectors or use them as the selector for the deployment and the same thing for the service. Now, Cdk plus actually does that for us. It interprets our intent. This is what I mean by like intent-based APIs. It assumes that if the pod spec template is defined in the scope of the deployment here, then it makes sense that the deployment will just automatically select the pods in its template. Now, another thing worth mentioning is that, for example, this target port of the service is also kind of implicitly inferred, right? We didn't have to specify this here when we exposed the deployment because the information is already here. And also, Cdk plus configured this volume in the pod spec for us. We didn't have to configure the volume here in the pod spec because, again, this volume is attached to this container. So it knows that it needs to be part of the pod spec as well. All right, I think we're just about ready to apply this. So let's just do one quick check and see that everything is configured properly. Yeah, all right. So we do kubectl apply. All right, let's take a look at our pods. Yeah, we have one running pod. So now comes the moment of truth. Let's create the port forward and try to hit that endpoint. So we do kubectl port forward using the service name and the 9,000 port that we configured here. And let's hit the endpoint now. Yeah, cool. You can see that this is the Cdk library that we saw before in the catalog, this one, the statics website. And this is what we're after. Obviously, building some nice UIs on top of that. All right, so this is what I wanted to show you. I hope you can see the potential these kinds of APIs have and how they can really reduce the cognitive load for developers and make it a much more friendlier experience. We think it's a cool direction for manifest authors. All right, I'm gonna head it over to Nate right now for a quick recap. And thanks so much. Bye, everyone. Thanks, Ellie. That was a fantastic demo. I really wanna thank you for taking the time with us today to learn a little bit more about how Cdk's can help you accelerate and standardize development on Kubernetes anywhere. We have big things planned for this project. So get involved or follow along on GitHub or at cdkids.io. If you wanna check out and try the demo that Ellie just showed, you have the link right here and that's on our GitHub.