 Hi everyone, Paul Tchaikovsky here. I'm a developer advocate at VMware. I don't want to talk about myself too much. Let's just get right on to the meat of this. So welcome to my session of open source summit. I'm going to be talking about helm. No notice. I don't have any slides. We're actually going to be doing most of this is going to be live demo. And so I'll just have a couple of websites like the helm website where I'll talk about things. So let's kick straight into it. Shall we? So helm is self-described as the package manager for Kubernetes. It claims to be the best way to find share and use software built for Kubernetes. So I thought maybe we'll put that to the test and see what happens. Certainly it is the most popular package manager for Kubernetes. And it is a package manager. It doesn't package your application. It packages the Kubernetes manifests that describe how your application should be deployed. So similar to apt or yum, or I guess even homebrew, you build these helm charts and you package them and then you can share them with other people. So there is a chart, a package. There's a helm chart repository, which is a server where you can share and download helm charts from and then as part of the chart, you have the ability to do templating, right? So if you want to deploy a particular helm chart to different places, you might need to make minor changes to the Kubernetes manifests for that for your application. And so you do that using templating inside of helm. So for some fairly basic stuff, like if I want a load balancer or I don't want a load balancer, you can use variables and templates to make those differences, become more easier for people and keep things fairly seamless. So I think the first thing we should do is make sure helm works, right? So I have the helm client installed and we're going to go ahead and try and install an application. So this is the hub, the helm hub, hub.helm.sh and it contains links to over a thousand ready-to-deploy helm charts. So there is a helm chart community that maintains helm charts and different communities and companies have their own official helm chart repos. Let's say I want to deploy everyone's favourites demo application WordPress. So if we search for WordPress, you can see we have a couple options. Bitnami are a very reputable source of both images and helm charts. So I feel comfortable using theirs and so I click through it gives me instructions on how to install it. We have to add their repository and then we have to run helm install. So pretty simple. I can copy these commands and see what happens. All right, so I have a Kubernetes cluster. It is running in Amazon, but it's not an EKS cluster or anything. It is a Tanzu Kubernetes grid, Kubernetes cluster. I don't want to go into details. We're here at an open source somewhere. So I just want to talk about tools. So we run helm version. You can see we have both a client and server response and they match. All right, so we want to install WordPress. We had those commands. We could copy and paste from above. So this first one, which is adding the Bitnami repo. Once we've added that repo, we can now install the chart. So you can see we're installing it and we're doing a specific version, which is always a good thing. So it's already complete. That was pretty quick. Because what helm is doing is it's effectively grabbing the package. It is rendering templates and then pushing those templates up to Kubernetes. That all happened to relatively quick and it doesn't actually wait for Kubernetes to actually get your app running. I believe I could have done dash dash wait and it would wait, but I didn't do that. So while I'm talking, Kubernetes has been deploying our app and I bet if we go ahead and run these commands. So you can see it's let's go and have a look at what it's done. So here we have it's given it a name. We didn't specify a name. So it's picked a random name. It's showing us deployed. I'm currently set to hello as my default namespace. So it's installing it to there. And here's some resources. So config maps, deployments, volume claims, pod secrets, services, the usual things you would expect in Kubernetes. You can see not only is it deploying WordPress, but it's also deploying a database to use for the back end. Right. So it's pretty comprehensive. And it's got these notes to tell me how to actually access my application so I can watch the status with this. So let's go ahead and run this command and see what we get. So here it is, and I'm guessing it's working. On Amazon, the external IP address, it gives you is actually a host name, a DNS name pointing to the load balancer. So I should be able to access the WordPress that I just deployed. Oh, hang on. I need to break that. And then I can, wow, typing. All right. That looks like it's a website. So we open up this guy and run, copy and paste for the win. Maybe that's what it was giving me all along. I don't know. I'm not very good at computers. So here we go. WordPress is installed. Right. I can't even copy and paste correctly, but I can use Helm to install WordPress. So pretty good. Right. Even for me. So there it is. Now WordPress obviously has an admin dashboard. So we go there. We need to use a password. Helm is smart enough to help us with those things. So if we look back to our notes, which there should be, there we go. Open a browser, log in with the following credentials. So I can copy and paste these two commands. So what are we doing? We're echoing our username and echoing our password. And the password is being collected from a secret. So Helm created a random password and stored it in a Kubernetes secret basis for encoded. So we just had to extract that out. So now we can go and actually test it. So user, password and boom. So we have a WordPress website. All we would really need to do now is create a C name in DNS pointing to this load balancer. And we would have a reasonably solid install of WordPress that we could start using. With very little work on my behalf, which is exactly what we try and do with Helm is get that like first user time to dopamine time right down so that even someone hasn't really used Helm before should be able to at least get an app deployed or create their own Helm chart. So let's do that. So in the spirit of keeping things easy for people, we've tried to make it easy to deploy Helm charts to create Helm charts. So first of all, let's do a Helm LS and let's Helm delete this release here. So we don't want WordPress to stick around, especially because you now have my admin password. So that's going to clean it up. Now let's make sure I'm in the right directory. Yes, I am. All right. So I want to create a Helm chart as a new user. I want it to be simple. So I can run Helm create hello world enter. And that's going to go ahead and create a basic Helm chart for me. So let's have a look what's inside this home chart. So you can see we have a chart.yaml, we've got a set of templates. We even have some tests. And we have values.yaml. So let's explore those things a little bit. So here we have our hello world. So chart.yaml. So this is the metadata about the chart, right? So the chart has a version name description, the version of the app that we're installing. And let me just set that to be that. No, I think that I'll fix it. It's probably wrong. All right. So one thing I like to do is the Helm chart community has a set of best practices that aren't quite fully enveloped in the Helm create command. So let's have a quick look at that. Where are we? Review guidelines, utility versioning, chart metadata, right? So name, home, version, description, maintainers. So we're missing home and maintainers, right? And so home will be like a website for it. So home. Now this lives on GitHub pages. So it'll be github.com.io slash charts. And then maintainers. And this is an array. I think we do name and your GitHub username and email and your email address. So I think this now is complete. And of course, you always want an extra character turn at the end of like a blank new line, the end of your files. I can't tell you the number of times I have created the chart and not put that extra return in there and failed CI. So I always try and remember put that in there. I used to have a plugin to make VS code automatically do it. But I guess that broke our computers. All right. So that is my chart.yaml. Next, we have the values.yaml. And so this is the values that are going to be rendered into my templates if I don't override them. So by default, it's going to install nginx. Now, I don't want to install nginx. And that's for a couple of reasons. First of all, it's not very exciting, not that a Hello World app is very exciting, but it also is an insecure pod, right? So it runs as root inside the pod and it uses port 80. And so if I want to actually deploy it in a secure way, I'm going to have to do a bunch of extra work, or I'm going to have to tell my cluster, be okay with this insecure application. I like to try and be reasonably responsible. So I am using a cluster that has pod security policies, which means nginx will not work, right? And to save us from having to see that failure, let's go ahead and do, let's hope I get it right. Tag, I think it's like really 0.1, but I'll just cheat and say latest, right? And then here's some other things I can set. So I definitely want to set security context, otherwise it will fail my pod security policy, right? So I want to make sure I have no capabilities. I don't want to read only, but I do want to run as non-root and run as user. Ingress is disabled. Resources aren't set. Do we want to go ahead and set? We don't need to for the basic demo. But basically you can see these, there are some default things that helm things you probably want to do. And then for things like this, it's not going to force you, but it is going to provide you hints in the way of comments on how to actually set it. So I think that's what I want here. And the other thing we need to do is modify my deployment because we're not on port 80. So here's my deployment, some interesting stuff here. So you can see here we have the double curly braces. And we're basically using the release name and some other stuff to formulate the various metadata, so names and labels and stuff. And we do that so that if you want to deploy the same application to multiple places, you're going to get different metadata. So you're not going to have any name collisions, right? You can do things like here's our replica count. So if I specify six replicas, it'll render that in. Pretty simple stuff. Here's my actual containers, that security context I just set up. But what I'm looking for is this ports. So we changed the port 8080. So we'll save that off. It's a named port, which means my service is probably good. The other thing I'm going to do is this app does take, it's a hello world app, but it takes a second to load up. And with a liveness probe, if your app isn't listening, liveness probe will assume it's broken and will kill the pod and create a new pod, right? Because of the deployment. I don't want that to happen. So I'm going to comment that out. The other thing I'll show you is notes. So notes let you pass in notes that get rendered out when the home chart is installed, right? So you can give hints about how to access the application. You can see we're doing things like if ingress is enabled, then we'll print out the host name because we know the host name. If not, if it's a node port, we'll just access it with a node port. If not, is how you access it with a cluster IP, with the load balancer, sorry. And then with a cluster IP. So it'll give me different output based on the type of service I ask for. So let's go ahead and install this. I think this is all I need. Let's switch across. We're in the chart. So helm install dash n, we'll give it a name, a hello, name space, hello. Or my name face is defaulted to hello. So I don't need to put the name face in, but just for the sake of completeness, I will. And then it's in the current directory. So I can just do a dot. I think that's all I need for my helm install, right? And that's it. So that's my helm chart created and installed. It only took me a few minutes and a bunch of that was waiting around and talking while I was doing it, right? So pretty good meantime to dopamine. We got a cluster IP. And so it's giving me instructions on accessing export the pod name. And then it's giving me, I can just run this whole block here. And we should get, right? And it's even doing forwarding for me. Let's just put that in the background. And then, oh, there's a failure right there. So the port forward, actually, I need to fix this to be 8080 to 8080 because we changed that port. So quickly in the notes, we can fix that. So fix that to there. 80, check for just 80. Okay, that's fine. And I bet I need to set that in the test as well. Value service port. Oh, no, that's okay. All right. So we can kill, close this off. Oh, and so we use, we changed the port for the deployment, but because it's a named port, we don't need to change anything in the service. The port here is the port that service will expose it as. So now let's come back to our command font and rerun this port forward, stick that in the background, local host 8080. Right. And so there is our response. Now, what do we want to show? Let's do something. Let's modify the help chart. And then see what we have. See what we can do. So let's change this message. And I believe we can do that by setting an environment variable called message. So let's go ahead and set that. So let's go to our values up to the top. Message world. And then in our deployment, in our template, is it end? Ends? I always get this one. No matter what, which one I do, I'll get it wrong. So name, message, value dot values message. Right. So this should set an environment variable with the name message, with the value values message. And that is world. So let's go ahead and update this and see if we did it right. So there's a few things you can do. If I want to double check that I've done stuff right, I can run helmet. You can see it's no failures. I can also do helm template dot. And that will render out the templates to standard out, which is also useful if you want to give someone some pre-rendered manifests is you can set all the values as you think they should be and then pass them on to whoever is actually going to be deploying. But we've done a helm install. So now we want to do a helm upgrade. Name is hello. Now helm upgrade command, you don't need the dash in, but helm upgrade hello dot. And we'll see how that goes. So that has updated it. So let's have a look at our deployment. Hello world. And let's look for N. So there's our environment variables. I guess I got it right for once. Message hello world. And then do a K get all. You'll see we have our second replica set has spun up. Our old replica set has spun down. And we have our new, our new pod spinning up. Our service is still cluster IP. So why don't we do this? Why don't we, well, let's make sure it's working. Port forward. Now we don't want to keep having to look out for our pod name. We can actually do this service slash hello hello world. Let's just do that. Let's try that again. Port forward service hello hello world 8080. Background. Oh, I think I forgot to actually background it properly. HDP localhost. And there it is. Okay. So world. Oh, I forgot to put hello in there. Let's fix that up. So where's our helm upgrade command? All right. So what I'm going to do is I'm going to set some values. So I want to set service type equals load balancer. And then I want to set message to let's actually set something meaningful. Black lives matter. Right. And we will save that. Oh, I got my quotes wrong. Upgrade set message. Okay. So that's done another upgrade deployed, etc. All right. So let's do a helm LS. You can see what's going on. So you can see hello, we're on to revision three. And there we go. All right. So let's do, we don't need that. Port forward anymore. So we go to get service. We now have a load balancer. So we can do a HDP of that. All right. So the load balancer is set up, but it's still actually getting wired up. So we probably need to give it a minute. Is there anything else we need to look at? So you can see I ran that dash dash set. I could have also done dash dash values and dev values.yaml. So if I was doing something Git Opsy and I wanted to have my environment settings outside of my source, I could do this and have a values.yaml in a environment repo and do something like that. Right. But we didn't do that because we're trying to keep it simple. Let's have a look. Are we working yet? Perfect. So hello world is a very unimportant message. Black Lives Matter is a much more important message. So that's the message we are sending out to the world. Anyone who hits that URL while this demo is live will get a worthwhile response. All right. So that's our Helm chart created. Right. So now let's go ahead and actually, well, let's talk about what other things to Helm do. So we do the templating, we've done that, but the sharing part. So we need to package it up and then we need to be able to share it. So let's think about how we can do that. So Helm package will create our package for us. And I think we just do it like Helm package dot Helm package chart path. Yeah. So Helm package dot. So now we have a hello world table. So Helm Helm chart package is assigned table of the directory. So if we do a TZDF, so we just test that you can see that the exact same set of files are there. Right. Now that's packaged. We need to share it. So we need a Helm repository, sorry, Helm chart repository. We saw hub dot Helm dot SH. That was a collection of chart repositories. And so a chart repository is a website that has at its base and index dot YAML file. And that index dot YAML file has a description of the charts that are on that Helm chart repository. Right. So chart name, version, some of the metadata and a link to the actual table that is the Helm chart. So the good thing about that is we can use any static hosting to host that. And GitHub provides a perfect place with GitHub pages. So let's have a quick look at, well, first of all, let's commit this in. So let's make sure we're on a hello world, like my matter branch. And then we will commit this up to my repository. So get status one more down, get status. So there we are there. Give add dot chart's hello world. Oh, I don't know why I did that. I'm so used to doing a dot, but I want to be specific and so whatever. So get status. Right. There's our files, commit dash M, hello world chart. But before I do that, I have had a hello world chart here before. And I don't want to break my CI. So let's just make a quick change. Let's go to my chart dot YAML. And let's just, I think if we just bump the version 1.0, that should keep us out of trouble. I hope. I hope, I hope, I hope. All right. So let's run get add again, get commit, get push origin. All right. So we've pushed our chart up. And it says we can create a pull request by going here. So let's go here. All right. So open a pull request, get pull request. So now I can show you how we're going to end up with our home chart repository. So in, in our repo, we have some GitHub actions. And we have a lint test and a release. So whenever we create a pull request, this lint test will run. And so on pull request, we're going to run lint tests. We're going to run, sorry, we're going to check, check our code out. We're going to run our lint tests. We're going to create a kind cluster. And then we're going to deploy our chart to the cluster and make sure it works. Right. And so that's pretty comprehensive for simple use cases. The actual testing tool is smart enough to just look at the charts because this is built to be used with a monorepo with multiple charts. So it'll look for which charts changed and only test those charts. So if you look at my base here, you can see I have a multiple, multiple charts here. And so it needs to figure out, it only needs to test out the one. And then under release, whenever we push to the main branch, we will run the following tests. Again, we're going to check it out. We're going to configure Git because we're going to push to GitHub pages. We install the helm client. And then we add a dependency and we run chart releaser. And chart releaser is going to do the work of creating the helm package. It's going to upload the package to GitHub releaser. So create a release with GitHub. It'll upload the tar ball. And then it will update the index.yaml file that's sitting in GitHub pages to include that new version. All right. So you can see there, it's done the check. Hello world. Has anyone changed? So it's run the lint test. That's already complete and passed. And now it's going to create the kind cluster and actually install it. Because we don't have all the time in the world, we're going to assume that's going to pass the tests. And so let's come back to our pull request and let's merge it, squash and merge. All right. So we have merged it and let's go ahead and validate that it is working. So again, we'll come back to GitHub actions. You see our release chart is running and this should release reasonably quickly. While it's doing that, let's come to here. We have instructions on installing it. So let's go ahead and run this command and let's get a little bit ahead of ourselves. So first of all, let's change to a different namespace. Helm repo add. So while that's doing, let's have a look at something else. Back to hello. So one thing I didn't mention is that a while back, we bumped from Helm two to Helm three. And one of the reasons we did that was because Helm had a piece called tiller, a server side piece that ran inside of Kubernetes. And it was considered to be insecure or certainly insecure by default. You can secure. It's not easy to secure it. And so most people don't. In the same way, it's not easy to run a secure cluster with pod security policies and everything turned on. So most people don't. So with Helm three, we removed that component. So right now, I think I'm running home too, right? And so we have a plugin. Helm plugin install Helm two to three. It's already installed on here. And that will let us actually migrate our installed charts from Helm two to three. So Helm two to three convert, delete B two releases. Hello. So we'll run this. And this will convert our Helm two releases into Helm three releases. And we do a helm LS now. And we should get blank. So then we'll want to delete our, our old tiller. So cut all, delete dash and move system. I need a sort of tiller dot release, hillar dot deploy. Yes, got it. And there's a service too, but I actually don't install that as part of trying to be a bit more secure. There's a service account that we should probably take out. Let's go ahead and take that out. There's also a roll binding and some other stuff, but you get the idea. You want to clean up tiller. You don't need it there anymore. And then we'll blink helm three to hell. So now we run the helm version and we only get a server version. That's all we should get. Because there's no tiller anymore, but we do helm LS and we can still see the helm chart we had installed using Helm two. So that's a pretty seamless upgrade. We've seen some folks do some Helm two to three upgrades with some fairly extensive chart installs on clusters and it's gone smoothly. So we're pretty happy with the state of that upgrade process. Now with that being done, let's switch to the other namespace and let's check out our, first of all, our chart released correctly. So come back to home charts. We'll look at GitHub pages. And so you can see in GitHub pages, we have index.yaml. We can look there. Hello world. You see hello world version one over one. And then here's version one here. So here's the one we just pushed. And that's why I bumped the version because I knew I used to have one call the same thing. So with that done, we can now, we might need to redo this because we're now on helm three. And so let's go ahead and run the helm repo add. And I think we have to do a helm repo update. Just make sure we've got the latest version of the charts. And then we want to do helm install. Hello two. So we didn't do a dash n. So that's no longer there. But we can still do a namespace. Hello two. And then my home repo is Paul's and then hello world. And this should work. Right. And that has worked. So okay, get all. So there's our app installing. Let's recap. Let's talk about what we have done. We deployed a WordPress helm chart. And that was really easy. Really, really easy. We then created our own help chart. We modified it to deploy our hello world application. And then we did a few iterations of that hello world application. And when we were happy with it, we then created, we push it up to get and we use the helm community provided GitHub actions to test it and then to release it to GitHub pages. So not only did we write a helm chart, but we deployed it. Anyone can now deploy that helm chart that I wrote. And we did it in a way it's not adding any extra real infrastructure or service costs to me. We're using GitHub as like a service provider, almost doing it in a serverless kind of way. If we want to throw some buzzwords around. So thank you so much for watching. Please enjoy the rest of the open source summit. Thank you. Hi. So I just did a quick wardrobe change. You can see I'm representing, I think it was Prague open source summit. If we have any questions, now would be a great time. Okay. Toma asks, can we talk about sub charts? So if you remember what I did at the start with WordPress, I'd also deployed a database. That database was a sub chart. And so you can include any other existing home chart in your chart as a sub chart. And then you can configure it in your values, just like you do in your own home chart. And so that lets you set that dependency to my sequel and have my sequel installed alongside your application. And then you can have a condition on that. So you can say my sequel disabled and use an external service like Amazon's RDS, which would mean in your local dev environment, you might have the MySQL chart deploy MySQL, but then in production, you might be using a more robust cloud provider provided MySQL database. And then we also have umbrella charts and library charts, which are designed to help you deploy lots of charts that are very similar without having to write an entire chart itself. So we have kind of a couple of different abstraction layers to do that. And then I think you had a follow up, if I need to use Minio. So yeah, I think I answered that. So I would add Minio as a chart dependency. And then I would have like, if Minio enabled is true, then include the Minio. Otherwise, don't. And we use that a lot for when you need an object storage in dev, but you obviously have something in production like S3 or Google Cloud object storage. So it's pretty easy to do that. If you look at the Spinnaker Helm chart, which is very comprehensive, you can see where we make decisions about things like subcharts for Minio. If that hasn't answered your question, feel free to ask further. And then Sven asks, what are the benefits of Helm versus Ansible or Terraform? I think the main benefit is that Helm is not only your installation scripts or whatever you like to call it, it's not just like, here's my resource template out, but it also solves the packaging problem and the storing and sharing of those packages. If you are already heavily invested in Ansible or Terraform, it may make sense to continue using those. And then you can also use Helm with them Terraform absolutely has some good Helm providers, and I'm certain Ansible does as well. And that way, you may be using Ansible to generate the values you're passing into Helm. So there's a number of ways to do that. Also, it's often you'll want to have, if you're doing a lot, if you're running microservices, but deploying them like a model if you might need to deploy six or 10 charts at once, and sometimes you would reach for a tool like Ansible to help you coordinate that, or you would reach for a tool like Helm file, which is similar, which allows you to compose multiple charts without having to set a crazy wiring of subcharts and library charts and stuff. Toma, when you saw passwords? So that is a great question. You can store the passwords in your Helm chart values file, encrypt that and put that in Git. You can pass them in as environment variables. And then when you're writing your Helm chart templates, you decide how you want to then store them in Kubernetes. So normally, you would create a Kubernetes secret and render those passwords base64 and coded into a secret. You can also bring secrets out of the picture altogether and simply expect that you already have some sort of secret management system. And that secret management system is going to take care of creating those secrets for you in Kubernetes. And so there's integrations with Vault. I actually got some Vault that would do that for you. So there's a number of ways of doing it depending on where your comfort level is and how you like to do things. Oh, my command prompts then. So I'm using Starship, which is a really comprehensive prompt on top of ZShell bash fish. And it's super useful. I'm a big fan of it. I got turned onto that by Brian Miles. Before that, I was just using regular Omy ZSH. But I find Starship to be pretty fantastic. How are we going? I think. Oh, Tomah, relationship between Helm and Customize. So they kind of come at the problem from a different angle. So Helm solves the templating problem by using Go templates. And that means that you have to care about spaces and indents, etc. in the templating. So when you're, say, embedding a string or if you're doing like a set of values in an array, you have to do some templating tricks to indent them to the right location. And some people don't like that and prefer to reach for something that instead of you having to, like, figure out those templating bits, something that understands more the structure of YAML. And so tools like Customize and YTT solve the problem by doing kind of overlays. So with Customize, you set a bunch of Kubernetes resources manifests. And then you can apply overlays and basically, like the really basic use case, you can provide like the same secret, like namespace type and set a different value and have that as your secret overlay for production. So when you deploy it to production, you would tell it to use that overlay and you would get your production secret in there instead of your development secret. So they come at the problem from a different angle. When you're using Customize, you certainly have to then figure out how you're going to package and ship it. It is integrated with Kubernetes. You can do dash K in kube-cuddle and use Customize. And if you really want to, you can have it up and get. So you can do kube-cuddle, kube-cuddle create dash K, pass it to get repo, and that will work. But I do like the packaging and sharing of the packages that Helm provides. I'm sure we'll see more options for that as the OCI spec is now pretty solid. And we're starting to see good examples in Docker registry tools like Harbor, Quay or Key, however you pronounce it, where you can store your Helm charts as part of like an OCI image. So we're starting to see ways you can store them there. And so I would imagine we'll see similar things for that. Process for getting a chart into the official Helm hub. So we have two chart repos as part of the Helm charts community, stable and incubating. And we're actually in the middle of defrecating those because we don't want the chart maintainers to be a gateway toward a gate for features getting into Helm charts. We're not experts in say MongoDB. So us having to review changes to a MongoDB chart just slows things down. So what we're doing right now is we're getting a lot of folks to sell posts their own Helm charts. And that's why we've spent a lot of time and effort on the GitHub actions to make it really easy to do that. And then so if you want to be on hub.helm.sh, there is a Git repo for that, which I don't remember off my head. And there's a couple of places you do a full request and you add your chart repository in there. So if you followed what I did to create your own chart repository using GitHub pages, there's like a four or five lines of YAML you have to add to a conflict file in the Helm hub repository. And there's also a new CNCF artifact hub that does more than just Helm charts. And that has a more GUI driven way to add your charts to that. But right now both are pretty heavily used. So I would go into the Helm hub first and then also add it into the artifact hub. Okay. I think I have answered everything I see. Oh, how do I know the deployment status during Helm install or upgrade? So you can tell Helm to wait. So you saw when I ran Helm install, it just like finished right away. You can tell it to wait and it will kind of watch Kubernetes and see what's going on. Otherwise, you're kind of dropping down to looking at the actual Kubernetes resources you asked for. So when I do a Helm chart install in CI, I will you almost always use the wait command. And that way, you know, that it will stop and it will wait till it's installed and it will exit zero if it's successful, exit with a failure if it's not. So it gives me a better way to process the exit results of doing a Helm install or Helm upgrade. And I think that is all of the questions and we are right at time. So thank you so much for joining me. I hope this was helpful. Feel free to hit me up on Slack afterwards. And I'm also available on Twitter and all the other social medias. Thank you so much.