 Thanks for coming to my talk. My name is Peter Tran. And I'm going to talk about delivering an application to multiple clouds using Flux and Carvel. Today, we'll talk about the challenges of creating a multi-cloud deployment. I'm going to go over the tools that I'm going to be using to solve that through an example with a live demo. And then I'm going to close off with some options for alternative tools. Who here has received an invitation to go to a wedding in the last year? All right, a few of you. And for those of you who have had your hands up, who still got like a physical, old-fashioned invite? OK, so live went well. So the three kind of milestones we're looking at to kind of invite people to a wedding are, one, your addresses. You want the physical address where people reside, whether it's being your town, your country, or around the world. You also want consistent information. Ideally, things like your venue and location and time don't change unless, of course, you're planning to get married in spring, summer of 2020. The last thing we're looking at is customizing your invitation. Perhaps you have a really good friend who's already married. You might put their name and their partner's name on the invite. Or you have an old friend who might give them a plus one. So a little bit of tweaking per invitation. The reason I draw this analogy is because it's similar to the experience of trying to deploy something on multiple clouds. The first thing, one of the things you need, is a tool that's flexible enough to send off to different environments. So you're different cloud providers, for example. The second thing you're looking for is a consistent application. You don't want an old version running on this place and a new version running over there. You kind of want that confidence of consistency. And the last thing is the customization. Perhaps in your east coast region, traffic is a bit low, so you want to scale down the replica sets to minimize cost. Or if you're having a leader follower model, you might want to scale up and down the replicas or change things like host names. Today I'm going to go over the two tools that I've been using to solve this problem. The problem or the goal of having different destinations that I'm using Flex, and for the consistency and the customizations, I'm using Carbell. By the end of this talk, I'm going to walk you through how I'm putting these two applications, or this one application, onto the cloud. It's my invitation to my wedding that was six years ago. I'm inviting my friend, Abril and Ryan. One lives in Vancouver and one lives in Toronto. So this multi-cloud journey, I broke it out into two parts, two stages. Stage one, we'll take a goal application and build a Carbell package. Stage two, we'll take that Carbell package, pass it into Flex, and Flex does a really great job of sending it off to the two clusters, one in Toronto and one in Vancouver. Before I dive into these two stages for this multi-cloud journey, I wanted to do a sidebar of what I'm calling the Carbell corner, which I'm going to explain all the different tools and interesting pieces that make this journey possible. I want to talk about the package, and the two things that power the package, CAP controller and YTT. The first thing I want to talk about is the image package bundles. So image package bundle is a container and the resource yaml that uses that container, things like your deployment, service, and ingress. And the concept is called image package bundle under Carbell. KBuild is a CLI tool that does quite a few things, but for the purposes of this talk, it compiles the container and the resource yaml into that image package bundle. One thing I forgot to mention was the image package bundle is an OCI image, so you can treat it like an image, put it into registry, there's an open API schema, and the last thing, or second-last thing, is the Carbell package, which is a wrapper around the image package bundle, and I apologize. This is the one that has an open API schema that makes it easy to query. Packages also have versions, and it's another feature of the Carbell Suite. Cap controller is the Carbell controller that makes all of these CRs I just mentioned possible. It's responsible for resolving things like the image package, bundle, the package itself, into the running apps. When it does this, it uses a tool called YTT. YTT kind of looks like a templating language, but it's actually a very powerful programming language. You have if, else's, for loops, and variables, of course, and when Cap controller resolving your Carbell packages, it takes your templatized resource yamls and compiles them into populated resource yamls before applying it to your cluster. So going back to our journey for taking our applications to the multiple clouds, stage one and stage two. Stage one has a little bit more steps involved. We start off with the Golang app. We're gonna use code to build the container. We're gonna write our resource yaml. We're gonna use that kbuild tool from Carbell to create the image package bundle and then wrap it up into a Carbell package. So this is the application I'm using. I wanted to highlight these two lines. It's very basic. I'm gonna grab an environment variable and I'm gonna invite that person to my wedding. If you're invited, I'm gonna use code to build the container. Code is really handy for building go apps. Next, I'm gonna work on my resource yamls for this invitation. Here's an example of like, here's your deployment, your service, your ingress, all these things that you wanna bundle with your container. Highlighted here, I have these two lines and that syntax there is ytt. Over here on the right, I have a variable called guestname and on the left, I have a variable for hostname. And these are just gonna stay as templates in my Carbell package and they're gonna be rendered later on. So that achieves one of our goals, which is to create the customization per our application. The next step is using kbuild, the other Carbell tool to just create the image package bundle. It's actually a command line kbuild-f and because the image package bundle is an OCI compliant image, I'm gonna publish it using image package CLI to push it to my registry. The last step in stage one is to take the image package bundle, wrap it up in this thing called the Carbell package. The Carbell package contains things like versions and the crux of it is this line highlighted here, which is the image package bundle itself sitting on my registry. So that was stage one, we took our goal application, built a container, wrote our resource yambles that will leverage that container, wrapped it up, wrapped it up again into a Carbell package. And now we have that consistent packaging that is versioned that can be easily ported to different places. Moving on to stage two, we have our Carbell package, we're gonna pass it into Flux and Flux will handle pushing it to our two different clusters. One thing I oversimplified earlier was the Carbell package is useless on its own. It's kind of like a Java class. You need to create something called a package install to create an instance of that class or in this case, an instance of that application. And it looks something like this. On the right here, I have this package install. I'm referencing, I don't have the name here, but referencing a specific package name and its version. And if you recall in the previous slide, I created these variables using the YTT syntax. This is where you kind of populate it with your customizations. So right here, I'm inviting Ryan to my wedding. He's based out of Vancouver. And on the left, I'm inviting Abril, who's based out of Toronto. So we're taking our Carbell package, pass it into Flux, we're creating a customization to ask Flux to create an instance of these applications. And it's in the handle of pushing it to the Toronto and Vancouver cluster. For those of you who are not familiar with customization or with Flux, Flux is able to take your application code and put it onto clusters by specifying something called customization, which I've highlighted two lines here, which means a path of where your GitOps repo, your code is lying. So I have a cluster slash Toronto directory. And it also takes an acute config. And the acute config is a really nice universal, kind of like access point. You can swap it out with acute configs from any cloud. It doesn't have to be from the same cloud provider as long as it's valid. And in this example here, I'm passing Flux my Toronto acute config so it can access the Toronto cluster. And anything in that Toronto directory will be published there. And I'm gonna repeat the same thing for Vancouver. So that gives us the last kind of goal we're looking for. We have the customizations of our application. We have the consistency of it. And now we have the flexibility to push it wherever. And that leads us to the end of stage two where we have our writing apps on the different clusters. So let's go into a live demo. So in my get off three pull here, let's start with Toronto. I have my package install. It has a reference to, here we go. It has a reference here in line 11 to that package I already created before this presentation. I have a version number. I apologize for how weird that is. And I have a reference to a secret, secrets below here. And this is where I'm specifying the kind of variables I created in my YTT templateing all the way back when I was building my image package bundle. The three things I have customized here is a replica, a host name for this application and my friend. So, let's unwrite our ravine to the wedding. I'm sure she'll come. She's not too busy these days. All right, let's push it up. All right, so I committed my package install and the secrets file that kind of populated the variables and I pushed it up to my get ops repo. Before this talk, I've set up those customizations I mentioned earlier. And in that customization, I have a pointer to a secret that contained my Toronto cube config. And in a moment, I should see, so this over here is my Toronto cluster. I should see the package install created in my default environment. Oh yeah, oh, here it is, just a second. Wait, no, this is my Toronto cluster. Yeah, okay, here we go. So this is the package install. Ignore the funny string name. That was part of my setup. This package install reference that package I mentioned earlier is gonna have some pods writing. Should be one in my default environment. Here it is. And let's go to Toronto and great. Aval is gonna get my invitation out of my Toronto cluster. And I can do the same thing for, earlier I prepared another package install that is equivalent to the one we just saw. So I invited Ryan to the wedding and he's a really cool guy, so he's definitely gonna come out. And what's happening under the hood here is my package install is being picked up by Flux. Flux sees that we need to resolve everything in this directory, in that Vancouver directory, including the package install and the secret. The package that it's gonna be using, I created earlier and I already uploaded it. And shortly we'll see the package install spin up and the pod underneath show up. I think I set it to 30 seconds, so it shouldn't take longer than that. There we go. Awesome, let's see if our pods are up and running. Awesome, my one pod is up in the Vancouver cluster. Let's go to invite.vancouver. No healthy upstream. That's too bad. I don't really like Ryan that much anyways. Let's give back to the presentation. So today we went over how we took a goal-length application, packaged it up into a Carvel package, passed it into Flux and Flux handed it off to my favorite friend, not the other one. Before we end off, I wanna talk about alternative tools. So today I did talk about Flux and Carvel. To create that flexible destinations, you can use many other tools. Argo CD is one, I see it's very popular here today. And you could use Helm to achieve the consistency and the customizations. And one thing I actually discovered or realized during this week was you could use Flux for this whole experience because customization controller has these variables that you can use. Anyways, you might be wondering, so why did you use this like Carvel stuff? There's two kind of scenarios where I think Carvel has a bit of an advantage. The first one is that YTT tool I mentioned. It's a full programming tool. It's like a templating language and a programming language all at one. And if you're working with some really unwieldy stacks of YAML, I found Helm charts obviously work really great, but a little bit hard to work with in terms of navigating when there's mistakes made or collecting all the images you're using. So YTT, though a bit of a learning curve can be very powerful in making your YAML management a lot easier and friendlier. The second scenario where I think you might wanna consider Carvel is for edge or air gap environments. If you recall the image package bundle, that's kind of the heart of the Carvel package, it's an OCI compliant image. And if you wanted to move your application from one registry to a more secure registry where you're gonna cut off the internet afterwards, there's a really handy command called image package copy, which actually does a reverse, sorry, inverse, no. Recursive copy of your image, it looks into all the resources that image is next to, and all those resources, if they use more images, it goes and copies that over as well. And if those images happen to be a image package bundle again, it recursively goes and scoops up everything and moves it over to your new cluster. So that was actually a really handy scenario where I think Carvel packages are really convenient. So that brings me to the end of my talk. If you have any questions, you can reach out to me at petertrann at vmware.com. And I think we have, I'm taking good time, lots of time for questions. So do you have any questions in the room? In order to orchestrate to the Toronto, where were you running Flux to orchestrate to Toronto and Vancouver? Yeah, for the sake of this demo, I did have it installed on a staging environment that I use all the time, and then I had some fresh environments for my running application. And I guess kind of the question stems from like, what is best practice? I think it's convenient to have it on one of the existing clusters, but I haven't seen any good data points for having it like a brain that pushes to the running clusters, clusters running your application, or like co-locating them for some reason. But that's a really good question. Any other questions? I have a thousand questions, but I'm just going to ask Juan, maybe the other two, the other 99 nine outside. So I've seen a collection of tools, and it might make sense in some cases to have a collection of tools, but why not have a single tool and add then support to Flux for that single tool that does everything? Because in the end, you used customize for the whole thing to glue Flux and your packets. Do you really need to customize or maybe you could have native support for all this into Flux or into Carvel and have a better coordination between the two? So it was your question, did I really need customize or Flux for this area? If I'm already using customize, then I will use customize for everything. Why use customize and Carvel if I always need customize? That's a good question. So I guess there's a bit of a trade-off. If you want everything in one ecosystem, sticking to one set of tools, I think makes it simpler for your everyday life and your team. And if you are going to introduce another tool, you'll have to weigh those trade-offs of maybe edge deployments are really important to you and that recursive copy is something that's interesting. Maybe it's worth introducing yet another tool, but it may not be for everyone. So I think it'll be a case-by-case basis if it's worth introducing. Good question. Are there any other questions? All right, thank you everybody.