Conf42 JavaScript 2022 - Online

Stop being a YAML engineer, be a software engineer with CDK8s

Video size:

Abstract

Do you want to become an infrastructure wizard overnight? Then this talk is for you.

With most tools for Infrastructure as Code, we describe our infrastructure in a declarative configuration language. But there is another way: We can use a general-purpose programming language like TypeScript, Java or C#.

This talk gives an overview of this alternative approach to IaC and answers some of the most burning questions: Can we finally get rid of tons and tons of YAML and JSON files? What are the pros and cons of coding instead of configuring? What tools can we use, what are their differences? And most importantly, do they help us to build infrastructure like a boss without 30 years of experience?

Summary

  • Instead of being a YAML engineer, you can be a software engineer by writing real code with the help of the cloud development kit for Kubernetes called cdks. You can use Python, JavaScript, typeScript, Java and go. Use cdks everywhere, so it's not something that only works in the cloud.
  • You need the CDKs CLI, and there are multiple ways to install that CLi. There's a built in command that helps you to scaffold an application skeleton. You can also reference custom resource definitions. The next step is actually coding what you want to deploy.
  • Using typescript, cdks can create standard Kubernetes manifests in Yaml. You can then give them to Kubectl apply and it will deploy that stuff in your cluster. Now you could publish this as a code package.
  • CDKs plus is an extension to the basic cdkates library. It exposes a number of high level handcrafted APIs that make it even easier to create and wire up multiple Kubernetes objects. By using code, we can make the code more readable and clearer.
  • CDks just creates vanilla Kubernetes manifests. You can mix and match existing tools. There are multiple ways to interact with the community. CDK day is a community event where you can learn all about the whole CDKs ecosystem.
  • Using programming languages to define your Kubernetes deployments. Let me know what experience you had with that when you tried it out. You can reach me on Twitter and you can find me on LinkedIn. Thanks a lot and have a great day.

Transcript

This transcript was autogenerated. To make changes, submit a PR.
Jamaica real time feedback into the behavior of your distributed systems and observing changes, questions, errors in real time allows you to not only experiment with confidence, but respond instantly to get things working again. Code hi everyone, my name is Robert. I'm a senior solutions architect AWS, and today I want to show you an alternative way to manage your Kubernetes manifests. And that is, instead of being a YAML engineer, you can be a software engineer by writing real code with the help of the cloud development kit for Kubernetes called cdks. So what is the cdks? Let's jump into it. The CDK for Kubernetes, it's an open source software development framework where you can use multiple general purpose languages and the ones that are supported you can see at the bottom. And with those you will model your Kubernetes resources as reusable components with real code. And for that you can use Python, JavaScript, typeScript, Java and go now the benefit you gain here is of course that now that you're not writing YAmL or config files anymore, but instead real code, you can use familiar programming languages and techniques. One of the things you gain, of course, is that you can use software engineering best practices like do not repeat yourself and you can refactor stuff. And it also makes it easier for you to share things, because now your Kubernetes manifests are actually a package of your favorite language. It's not anymore just a bunch of YAML files, but it could be a Python package or a typescript module. Finally, you can use cdks everywhere, so it's not something that only works in the cloud. In the end, cdks is a kind of config generator, so it will put out some standard Kubernetes YAMl for your deployments, but you don't have to write it yourself. That's something that SDK does for you. And then you can take those YAML files and insert them into any existing process. You have to actually deploy your Kubernetes manifests. Now when talking about YAmL, you know it's a configuration language. And I know some engineers who swear that Yaml stands for yelling at my laptop. And there are some good reasons now to use something else instead of Yaml to configure or to define your deployments. And we will look at some of the reasons why it's hard to engineer in Yaml. So let's have a look. Let's engineer some yaml to get back into the experience of how it feels to be in Yaml. Engineer for this example, we're doing something very simple, which is just an HTTP echo server. So we want to go to our Kubernetes cluster and deploy a simple container that just echoes back what we sent to it. And we also want to expose that container to the world through an ingress. So just really standard stuff. So what do we have to do here? Well, first of all, we have to define a deployment, right? So that's the basic object that we know from Kubernetes that helps us to create something that is a highly available container application. And with that we have to define a lot of values, for example, labels, ports and so on. Now this only makes running the container on Kubernetes possible, nothing else. So what we also need is we need to define a service and the service makes it so that these containers actually have a single common ip address within the cluster where you can reach all of them. And the service is already kind of load balancing between those containers. So if one of them crashes, we can still reach the service. If we deployed multiple containers of that now it's still not available in the world, we still have to create an ingress for that. And the ingress in the end is pointing to the service saying okay, now I actually want to expose that. And we want to expose this under a HTTP path called hello. And these are the three ingredients we need for our little application. Now if we look at the various things we did here, we immediately spot that there's a lot of repetition going on, right? So a lot of the time when you're working with Kubernetes, you need to take care of labels and you have to make sure that the labels are the same between different objects because they reference each other through those labels. So here we can see that we have quite a lot of repetition with this app echo label because the deployment needs it to actually find the containers and the service needs it as well to find the containers. Besides that, we also have some repetition of values like the port. So we defined a port initially for the application in the deployment, but then we also have to tell the service that we need the same port so that it is actually reaching the application that is running in the container. And again we have another mentioning of the same port or a similar port where you need to tell the ingress that yes, this is the port number where actually the service is listening so that it then can forward the request to the container. So we already see that we have a lot of repetition here, this is definitely not dry. And the question is, is there a better way to do it. Finally, we also see that we have to do one of the hardest things in software engineering or any kind of engineering, which is naming things. So we have to think about the name for the service here. And again, we have to repeat the same name exactly for the ingress so that the ingress is actually pointing to that specific service. In total, we got 45 lines of Yaml here, and this is something we had to write on our own. So to sum it up, the downsides of Yaml are, well, it's a static configuration language. You don't have a lot of tools to do things like conditionals, variables and tools. It promotes a lot of copy paste. That's what we saw in our example. So that makes it very error prone and difficult to change. It's also hard to customize and share. So there's no native method to actually put in variables or inputs to change the template. And there's no Yaml package manager. So you need to find your own way to actually share those manifests, maybe in your company or publicly. In addition, as we've seen, it's not just about Yaml, it's also about Kubernetes having a lot of dials and knobs. So these manifests actually carry a fairly high cognitive load because you have to make so many settings for the properties and make sure that they match exactly, so that actually the whole thing works. Now how can CDKs help you there? The motivation of CDKs is that as we just saw, authoring Kubernetes manifests can be a rather complicated tasks. And CDKs makes this easier. And this is really what cdks wants to do at the core, making, creating those manifests, authoring those manifests simpler and more robust for you. And what does it leverage to do that? Well, it leverages general purpose languages, and by using general purpose languages you can actually employ best practices of software engineering. Now what are the benefits of general purpose programming languages in comparison to something like Yaml? Well, of course they're dynamic. So you have multiple ways to do control flows. You can iterate over stuff, you can apply things like do not repeat yourself because you can pull but common values that you reuse. You can refactor your code to take, but repetitive code that you use multiple times. And typically you also have a standard package manager. So you can have your Kubernetes manifests distributed as a Python package or as a node module. That's possible. And finally, because now we're actually using programming languages, we can build abstractions so we can remove some of that cognitive load that we saw, some of that repetition which is needed for kubernetes to work, but is actually not really important for you in your day to day work because they are just best practices and standard ways of wiring things up that you do not want to think about. Now let's jump into how you can actually work with cdks. First of all, you need the CDKs CLI, and there are multiple ways to install that CLi, but one of the easiest ones is just to do NPM install minus G and referencing the CDK's minus CLI. You also find other ways to do it, like with Brew, and you can read all about it on the project website, which is Cdkates IO. Now once you did that, the next step is to actually initialize your project. So there's a built in command that helps you to scaffold an application skeleton in the language of your choice. So if for example, you're like me, you would go with cdks in a typescript app. And that would give you the skeleton of a typescript app where you can define your manifests in typescript. And this is what you get when you execute that command. After that you need to import API objects. So this is an important step because as you know, Kubernetes has a lot of versions and each of those versions has different API objects. Some of them graduate between being beta to being stable. And you need to let your project know against which Kubernetes version you are actually working. That's not something that is specific to cdks. That's a challenge you basically have with any tool. And with the fact that Kubernetes gets new updates like every 3 hours, it feels like. So this is something you have to deal with anyway. The way you do this is you're using the import command so you can do CDK's import and then reference the version of Kubernetes that you want to work against. A very cool trick here is as you see, that you can also reference custom resource definitions. So another way to use CDKs is to not only work with the standard objects of kubernetes, but also if you have any operators that expose any custom resources to your cluster, which you certainly have, you can give CDKs the YAml file of those definitions and then CDKs will create classes out of that, and those classes will help you to actually instantiate those custom resources as well in your code. The next step you have to do after that is actually coding what you want to deploy. So this is where you're using the various classes that ckates gives you to create the manifests or the configurations you want to have in your cluster. And in a minute we will jump into how that feels like when you're actually using general purpose programming languages to define your Kubernetes objects. So getting started here, for me it's visual studio code, but it would work in basically any ide that you like. When I start writing my deployment, I can see that now for each of those Kubernetes objects, like the deployment object, I also have a corresponding class provided by cdks. And here it's the Kube deployment. And this is a one to one representation of the deployment specification from the standard Kubernetes API. But the benefit I get here already, as you can see, is as I'm writing the configuration for that deployment, I get a lot of autocompletion hints from my idE, and that's possible out of the box obviously, because now your Kubernetes API is just a code library. So your ide will look at that library and tell you what kind of properties are there. And if I go further and start writing out those properties, I can also see inline documentation here. So instead of going to another website and reading on the properties, I can read about what those properties are doing right in my ide. So that is already a pretty big boost to my productivity. Now let's see how the echo server actually looks like with cdks. And we're using typescript here because I'm a typescript guy. So the first thing is that we are writing that deployment class. We are configuring, instantiating that deployment class. And you see here, it looks rather similar to what we did before with yaml, but now it's in code. And again we need a deployment. Of course we need the service. We have seen that before as well because the service will then load balance between the containers of my deployment. And finally we need the ingress as well. So far no surprises, but we already benefit because we have written code and for writing all these properties we would have gotten autocompletion and also inline documentation. Now where we see some direct benefits is with that point of being dry. So instead of repeating the port number multiple times, we can now pull it out into a variable and then basically reference it anywhere in our application. And also for the labels that we had to repeat before now we can also just define them once and then basically have them here defined or repeated automatically differences anywhere we need them. So that already makes it easier. And we have removed a lot of repetition from before. Another thing that's cool is that there's already some built in convenience even into those basic classes that we have here. So here we can see that we actually don't have to think about the naming like we had to think about before when we were defining YAml on our own. So here we're just instantiating the service. And to reference the service in the ingress, we just have a handy property here service name which we can use for that name. And we don't have to think about how this is actually created. Cdks will do that for me. It will make sure that it's a unique name, so there's no collision. And I just have one less thing to think about when I'm making that configuration. Now that we've written our Kubernetes manifest in a programming language, the next thing we can do is actually synthesize it. And for that cdks has a command called Synth. And what this command will do is it will take that code, run it and create standard vanilla Kubernetes manifests in Yaml out of that. So the way this then looks like is that in the disk folder of your project you will find those manifests as YAML files. And to make it super easy, you can just take those YAMl files, give them to Kubectl apply and it will deploy that stuff in your cluster. At that point there's no dependency anymore on cdks. You just have a vanilla YAMl file, you can take it answers, you can check and lint it with standard tools you have for Kubernetes manifest files. There's nothing special about these files anymore. It doesn't matter that CDK's created. And of course if you have any other tools or processes where you basically drop in your YAMl files, you can reuse all those processes. So if you have some git ops process where the YAML file is taken and applied to your Kubernetes cluster with a kind of control loop to continuously make sure that this is the Yaml file that is applied, you can do all of that because CDK is not involved here anymore, you just have a standard Kubernetes manifest. Now once you did that, you might have the idea that what you build is pretty cool and it's actually something that could be reusable for the whole world or maybe just for your team or for your company. So you could publish this as a code package. And of course that depends on which language you chose. So for example for typescript you might have an internal or external node package manager registry. And you could now create a package out of what you just did, publish that package and make it available for others to use. So that's a great way to actually make your work reusable and share it with others so that they can benefit as well. And this is just some pseudo code, fake code. But you could imagine that you created a library called my team constructs and you would share this for example internally through your package registry. And then somebody else could use your echo server deployment that you have just built and they could just instantiate that and have this standard echo server maybe for debugging. Now we saw some benefits already by using a programming language, but we can go even further. So let me introduce you to Cdkates plus, which is an extension to the basic cdkates library. To explain what cdks does. We have to talk about construct levels. So constructs are what we are calling those classes. You have seen that you instantiate and that represent the real deployment objects or the real API objects. And we think about levels when talking about constructs. And the level defines the sophistication of those constructs. So basically how much they do for you or how smart they are. At the lowest level, level zero, we have the common functionality of the Kubernetes API objects. So this is a very bare bones representation of the normal API objects of Kubernetes. If we go one level up, we have those classes that we already use like Kube deployment, Kube service, Kube ingress. Those are automatically generated. They already give you some convenience, like the name generation I mentioned. But mostly they are still representing the base API from kubernetes. Now where it gets really interesting, and this is where cdkates plus comes into play, is with a level two. So cdks plus exposes a number of high level handcrafted APIs that make it even easier to create and wire up multiple Kubernetes objects that you need to actually get can application running. So to give you a real example of how that looks like, let's take the same Echo server we built with CDKs before and now build it with CDKS plus. What we can see here is that the whole example became much more concise. We are still defining the port. Of course we have to, that's up to our application. We create a deployment again, but this time it's a k plus. So a cdks plus deployment. So it's a different class, it's the high level variant of the deployment. And here we can already see that we have to define a lot less properties to make the deployment work. So actually we mostly just have to define the minimum needed information about the container we want to run in our deployment, which might be the image and the arguments, and the port that is exposed and nothing else. And then to actually expose it via an ingress, there's a nice helper function called expose via ingress. And there we just pass the path we want to use for that, and the type we want to use for that ingress, which is prefix in that case, meaning everything after hello is basically passed to the container. Now we see here that, for example, we do not have to create a service object, and we do not have to create the ingress object on our own. This is basically all done by this smart deployment object, by calling expose via ingress. So this is why this code is much more concise than what we did before. Actually, we have just 13 lines of code here. And before we had something like 45 lines of code. So already by a factor of three, we reduced the amount of code we had to write. And because we have less code and questions that speak to us, it's actually easier for us to declare our intent and to write code for humans and not machines. So if I look at that, it's much more clearer for me what the person, and that might be me. If I look at that maybe a year later, it's much more clear for me as a person what actually was the intent of that code and what that deployment should do. And if we stick to that for just a minute, I think this is a nice segue to clean code, where you can say that if you've read the book, or if you know that there's this clean code book from Robert C. Martin and other authors, where they basically say, well, ideally we want to write clean code and can important property of clean code is actually that it can be easily understood by everyone on the team. I find it's a really interesting aspect that we can try to achieve here with CDKs or CDKs plus. So by now having the ability to change the way we write our deployments, by using code, we can make the code more readable and write it in a way that it clarifies what we actually want to achieve, so that it's easy to understand by other team members and to really drive home. What I meant here is if we again look at that example of CDKS plus and what it does, we can see that now it's much easier to tell a story, right, because we created a deployment, and then we call deployment expose via ingress. So the story is much clearer. I want to create a deployment and I want to expose it via ingress. Now, what's actually happening in the background? Let's look a little bit at what cdkates is doing for us here. So taking that code, CDKates is creating the Kubernetes Yaml manifest. And what it of course does, it creates the deployment. In the deployment it has to reference that port value that we set. Then it also has to create labels so that those labels point to the ports and the deployment actually knows what ports belong to that deployment. And cdks does that for you. You don't see any labels here, right? This is happening in the background. So it's taking all that cognitive load of thinking about a label and making sure that you copy paste the right label between multiple objects. And then we have to create the ingress. Or we would have, but in this case cdks is also doing that for us, right? We don't see that here anywhere. And again this ingress has to reference a port. Typically it can be the same port and then you also have to create that service. Except again we don't have to do that. You don't see the service here anywhere. This nice helper function is doing that for you in the background. And here again you have to think about naming the ingress must reference the name of the service. This is all done for you behind the covers. Again the service has to reference the same port or another port potentially. And again the service needs labels because also the service uses labels to actually figure out which ports shall being to the service and shall get requests that are coming in. And there you see that this whole graph is already getting a little bit complicated for such a simple application. But you don't have to think about that. You wrote your story in CDK's plus and under the hood. CDK's created and wired all those resources for you and took care of boring technical details that you just have to get right, but actually do not really give you something new or cool. It just has to be done and you can stick to your much more concise story of what you wanted to achieve. Summing up here are some reasons why I think you should code your infrastructure. So what are you gaining by using cdks or similar frameworks? Well, instead of using YamL or some other configuration language, you are using a familiar programming language of your choice. And that could be Javascript, typescript, Python, Java or even Golang. That's up to you. With that you get great ide and tool support, because now your deployments are just code, there's nothing special about them. And all the cool features that you have in your ide for refactoring, autocompletion, inline documentation just work out of the box. Going further, we just saw that with cdks plus you also get powerful abstractions to have a more concise configuration and also have the ability to tell a story that's much clearer to your teammates. And of course all of that is wrapped in the opportunity to use software engineering best practices and exercising clean code. Now, are there reasons to not code your infrastructure to not use cdks? Well, yes, of course. So if you are feeling very comfortable with your current tools and your workflows, of course you don't have to change. The cool thing about cdks is that of course you can mix and match. You saw that cdks in the end just creates vanilla Kubernetes manifests. So you could have mixed workflows where you actually can use, for example, your existing tools, but also create part of the application with cdks and then just merge those YAML files together, deploy them together. If you don't like coding, that might also be a reason, and I think it's a fair reason because code means abstraction, and abstractions are nice when they work and you really hate them when they do not work. But that's kind of part of the course for using programming languages. So either you like it and you know how to deal with it, or you don't like it, and then of course you can stick to writing YamL or some other configuration language. Finally, if you are an author of an helm chart and you're wondering, can I use this to actually author the helm chart? So create the guts, the internals of the helm chart. This is not supported. You can deploy Helm charts, so you can interact with helm charts as an end user in your cluster, but you cannot author the helm charts. Finally, I want to leave you here with some resources on how you can get started with cdks if you want to. So for example, a good place to start is of course the project website cdks IO. There you find the documentation and also some instructions on how to install the stuff. A very cool resource is also the constructs hub that you can find under constructs dev. And this is basically a place where you can search for community created constructs. So basically libraries from other people where they already packaged up some cool constructs and classes that do certain things for you. So for example, you could find maybe something like the Echo server we just built there as a premade package and then you could import it to your own project and use it. And do not repeat the same work that other people did. Also, there are multiple ways to interact with the community. So CDks is a CNCF sandbox project and you can read all about that on the CNCF website. We also have a slack under CDK dev. And finally, there's also the CDK day, which is a community event. So that's not basically managed by AWS, but really from the open source community where you can learn all about the whole CDKs ecosystem. So CDks is not the only tool in the CDK ecosystem. There are cloud development kits for AWS and for terraform and some other cool tools that help you to actually build cloud infrastructure with real code. And on the CDK day the community is celebrating these advancements and you can learn about all the cool stuff you can do in that space. So with that, I hope you really liked the idea of using programming languages to define your Kubernetes deployments. Let me know if this is something that's interesting for you. Let me know what experience you had with that when you tried it out. You can reach me on Twitter and you can find me on LinkedIn and I would be super thrilled to learn about your experience there. Thanks a lot and have a great day.
...

Robert Hoffman

Senior Solutions Architect @ Amazon Web Services

Robert Hoffman's LinkedIn account Robert Hoffman's twitter account



Awesome tech events for

Priority access to all content

Video hallway track

Community chat

Exclusive promotions and giveaways