 All right, I think we're going to go ahead and get started. I'd like to thank everyone who's joining. Oh, sorry, I totally dropped off. Sorry, we'll get started again. I'd like to thank everyone for joining us today. Welcome to today's CNCF webinar, Understanding Cloud Native Application Bundles or CNAM. I'm Karen Chu, Community Program Manager at Microsoft and Cloud Native Ambassador. And I'll be moderating today's webinar. We would like to welcome our presenter today, Carolyn Van Slike, Senior Software Engineer at Microsoft. And before we get started, just a few housekeeping items. During the webinar, you're not able to talk as an attendee. And if you have any questions, please use the Q&A box at the bottom of the screen to be next to participants. And feel free to drop any questions you have in there and we'll get to as many as we can at the end. And so because this is an official webinar of the CNCF, everyone is subject to the CNCF Code of Conduct. Please don't add anything to the chatter questions. That would be a violation of that code or code of conduct and basically just be respectful of all your fellow participants and presenters. And with that, I'll hand it over to Carolyn to get started with today's presentation. Hi, everyone. Super excited to be here. Just a little bit about myself. I am Carolyn Van Slike. I work at Microsoft. Pretty adjacent actually to Karen. And I am one of the co-creators of Porter, which is a CNAB or cloud native application bundle tool that lets you work with bundles. And boy, CNAB, what a funny word. What a mouthful. So what is it exactly? Cloud native application bundles. To be honest, me personally, I throw away the first three words and I just call them bundles. And what it is, it's a specification for allowing you to take your cloud native application and package it up into a single file and be able to distribute it and work with it and hand it off to somebody else and be able to say, I made this wonderful application and I want you to install it. In short, it's a cloud installer. If you're anything like me, you heard that and you're like, boy, those were a lot of words that I've heard before, cloud native, distributed applications. But to be honest, it doesn't really make any sense. That's okay. I'm going to break this down into concrete use cases and just kind of explain it without having to go into the spec at all. Before going into that, I want to clarify a few things. One, this isn't actually a Microsoft thing. I don't mean carrying on Microsoft. It seems like this is the Microsoft posse. It's not. It's a specification that was made primarily from Microsoft Docker and Pivotal, but there were also a bunch of other companies like Intel and Hashing Corp, Datadog, and the rest of the community. You don't have to be a big company in order to be involved. And we've all been working on this almost for a year now. So what does bundle solve? You know, ever since Docker kind of came about, we kind of got a handle on going, we have our application, we have our code, we show it inside of a Docker container, and we know how to give it to somebody and go, look, we've deployed our code. But what we're starting to realize as we've operated this in production is that there's kind of this gap between giving someone our apps code and what it really takes to deploy our application in a new environment. And we'd like to be able to do what Docker did for helping, and what containers did essentially for shipping and working with your app's code, dealing with that gap of deploying everything your app needs to be able to put into a new environment. So I say app a lot, and it doesn't really matter what your app is, but let's just kind of step back and make an example application and let's talk about what that gap is. Let's talk about what that pain point is. So when I talk about an app, I want to talk about something that it has some code, but also relies on a little bit of infrastructure. Okay? So we love infrastructure. It's probably going to be a Kubernetes cluster because Kubernetes is cool, but doesn't have to be Kubernetes. Okay? So I'm going to have my app is going to be deployed with Helm. It's going to go on to a cluster, and I'm going to use Terraform to handle all of my infrastructure. So it could be a load balancer, it could be some DNS, and maybe I'm putting some CDM with Cloudflare, maybe I need some SSL certs. It really doesn't matter, but I just want to kind of separate like that. I've got two kinds of concerns here that I need to work with. And then I'm probably gluing it all together with some type of scripting. It doesn't have any bash. This all works with LUNOS too, but just kind of giving an idea of like I have an app, I have all this extra stuff out there, and then I need to smoosh it all together and orchestrate installing this. So let's talk about that gap. Okay. I have a friend, a coworker, someone in IT. I want them to deploy my application. All right. So let's walk through what that takes. Do they clone my repository for the application? Do I have a DevOps repository instead that has all this information inside of it? Well, do they need a specific version of the CLI for Terraform and Helm? Okay. Well, do they need an environment variable that needs to be set specifically with like, maybe access keys, personal tokens? Do they need a configuration file, like a cube config? Doesn't need to be in a special place. Okay. Well, what exactly is the Helm command that I need to run? Oh, and now I need to know Helm. I need to know Terraform. I need to know exactly what to pass. What files, how do I get those environment variables into there? They just passively use. They need to pass in. Well, let's say that I'm super clever and I make a utility Docker container that takes everything I just said and it puts it in the Docker container. I still actually can solve all the problem though because I'm probably going to have credentials. Okay. My identity that I pass maybe to talk to the Google Cloud or AWS or Azure or to DigitalOcean and I need to maybe pass parameters. So I need to be able to mount volumes or files from my local host or pass environment variables that I have set on my laptop that has my GitHub access token or things like that. And I need to get them into my utility Docker container because I really hope we're not like hard putting them into that image. Okay. So there's still problems. Now that friend, did they guess all of that correctly the first time? Let's say that someone's on call at 2am and they're supporting an app that they didn't write. They're the new person on the team. They did a different feature. They just work on the app but they don't do the infrastructure so they don't really know how to use Terraform. Did they get all these calls right the first time? What did they mess it up and they have to kind of read docs and figure it out? Are they still your friend? Oh my gosh. I don't want to over complicate things but this is the gap. This is what I'm talking about. There's this awkward bit between like we were able to put our code inside of a container and we made that part super easy but there's all these other bits that are still kind of awkward and hard and we kind of want, this is the part that CNAB is trying to solve. So I want to replay this. I want to look at this gap but I want to show you what it looks like with a bundle. I know we haven't really talked about what a bundle is. Let's just talk about it from the user experience perspective. So Porter is a CNAB tool and what it's going to do is I'm going to give my friend the name of a bundle. This is a pretty cool bundle. It's called Tron from Deus Labs and I'm going to say, here's the name. It's Deus Labs slash Tron V1 and I'd like you to install it. My friend is like, whoa, I don't know what's in this yet. So I'm going to use Porter and I'm going to say, explain what is this, how I work with it. And it's going, Porter's going to look at it and use the metadata inside that bundle and it's going to go, well, it's called Tron. This is what it is. It's a game of light cycles and discourse. Sounds pretty cool. If you're not familiar, Tron is an old movie from the 80s. That's the running joke. And it's upfront going to tell me these are the credentials you need to install this bundle. I don't need to go hunting for it and find out halfway through that it's installed that I only had half the credentials. So it's going to need a cube config for my cluster and Tron takes one parameter sparkles. So by default sparkles are turned off, but I can tell the bundle that I'd like sparkles turned on. That's pretty exciting. There's a little warning down here at the bottom that this actually isn't implemented in Porter. It will be implemented tomorrow. But yeah. So everything really to see now is kind of in beta. So you'll see like little bumps like this, but cool. So now that I know what the bundle does, and I know that I'm going to need certain credentials in this case, a cube config, how do I make that? So Porter has a command called credentials generate. And I give it the name of my bundle, you know, days, labs, Tron, and it'll walk me through going, okay, you are going to need a cube config. Where do you want to get it from? And I say, okay, I'd like to get it from my home drive dot cube, and it'll save it into a credential inside Porter home called Azure. So I'm all set. It walked me through that. Now I'm ready to do Porter install. I do Porter install. I'd like to call my installation Tron. I give it the name of my bundle. And I say, I'd like to use those credentials we just made called Azure. And I'm a fan of sparkles. So I'd like to flip the sparkle parameters to on. So this is the flip side to that gap. Instead of finding repositories, figuring out environment variables, trying to figure out what credentials are needed, understanding everything like that. So let's look at like what's the difference between those two scenarios. Because this is what CNAP is trying to fix. We have to figure out, did we actually make it better? The bundle told you what it needed to install itself. It told you upfront, I needed a cube config. If it had needed gcloud credentials or AWS credentials or, or GitHub token, it would have told you that too. So you didn't end up in a situation where you got halfway through a script and you had three or five things installed. And then you realized that you didn't have everything you needed. And that's certainly in a weird state where you needed to undo stuff. So that's really nice. In install of the single commander is just Porter install. You didn't have to do, you didn't have to work with Helm. You didn't have to work with Terraform. You didn't have to then work with the bash script. You got to work with just one thing. I got to work with just pulling it down from that Docker registry. You just saw I got to do dash T and then the name of the bundle. And hopefully it was simple enough that I'm still friends with what I just told to do that. It was maybe a little dicey knowing like, Oh, where did I get that cluster from? Unfortunately infrastructure doesn't come on the thin air. See now it doesn't solve that problem. But it did boil down the gap that we're talking about to that single command. And that's what see now is trying to do is make that easier. So that felt like a lot of magic. So let's just like step back and think about what, what was that bundle? What was really happening? So what we put inside that bundle. As we had our application, which was, you know, it was a Docker image, right? That's what we've been talking about this whole time. But it was also everything that was needed to install my application. Okay. So before I talked about like, what version of Helm do I need? That CLI was actually inside the bundle. And Terraform was inside the bundle. My Helm chart was in there. My Terraform files were in there. The bash script that understood the Terraform should be called first. And then maybe it needed to wait for an IP address and then it should run Helm. That was in that bundle as well. So I'm silly. Like I'm going to ask some of the awkward questions for you because I really hate when people like pitch and like, this is not a pitch. Like there's some like rough spots. I want to ask some of these first. Does this replace, say, any of these cool talks I'm talking about, like how, like Terraform is pretty slick. Like it lays down a bunch of stuff. Does it replace it? Not really. As you noticed on the previous slide, Terraform and Helm were still inside my bundle. They were still doing the heavy listing. If we think about the definition for what CNAB is, it's a specification for a packaging format. It's not a specification for a magical do all the things for me format. So it's going to package the, you know, it's going to package Terraform inside or something. It's going to package the Azure CLI or the G Cloud CLI, or it's going to package Chef or Ansible, or whatever it is you're using. It doesn't make that technology go away. What it's going to do is give you a nice way to encompass it and single file, bring all of the tools, the files, the configuration that you're using, and give you a nice way to distribute it and package it. But it doesn't replace that technology. Another awkward question. Is it, why wouldn't I just use that tech all by itself? You're like, I'm using Terraform. I'm using Azure ARM. I'm using whatever. It doesn't really matter what it is. But I'm using it. It works. I don't need CNAB. And like I get that. And to be honest, in some situations you totally don't. Like if you live in a Kubernetes only world, you may not actually need this. But sometimes it depends if you're feeling that pain of the gap that we were talking about. If you are having problems, distributing your extras to other people, if you like, oh, here, here's my artisanal repository. And then trust me, this is the right version. And then like you're having all these other difficulties of giving it to people and having them install it and then trust it. These are things that CNAB can help with. And I'm going to go into, there's a bit more. So it's less that like, again, because it doesn't replace the tech, it's more additive. If you like the other things that CNAB adds on top, then you may want to consider it. If you're totally cool and you've come up with your own in-home things that deal with all the stuff or you don't feel the pain of what CNAB is adding, you don't need it. Some of you may have noticed I said the word bash a lot and you may not like that. Nothing about CNAB says you have to use bash, you have to write scripts. Some of the CNAB tools make that go away and they use other solutions for this. I was just kind of using that as like an example. Other tools like Porter, they kind of make some of the bash go away and you don't use it and use other things like ammo. So like you just pick your poison. I will get to the spec. I'm sorry, I'm kind of starting backwards. I'm going to talk about bundles before we really know what they are. But when would you use a bundle? Sometimes you have a whole bunch of extra stuff that you need to distribute with your application in order to do a deployment to make it useful. You need those Terraform files. You need the Helm chart. You need the Helm CLI. You need a very specific version of it potentially because it's like my server is on this version. I need that. I have a bunch of web assets and you do a list along with it. I need my ARM template, et cetera. When those things are very important, especially when you need to coordinate it across a whole bunch of services that you may have because maybe we're not so good at really separating our microservices and making them independent. This is pretty useful. And you can separate them all out inside your installer or the invocation image. Oftentimes when you're deploying your application, you don't just deploy the code. You also need to either touch infrastructure, verify the state of infrastructure, or run additional custom logic that ensures something about the outside world. So CNAB gives the ability to run a custom script when you're deploying your code to also do that. Maybe I need to make sure something's right in AWS, run something in Terraform, talk to HOME, whatever. It doesn't matter. These are just examples. We have the ability to basically run your own custom logic when you do an install or an upgrade and do whatever it is that's specific to your app's domain. This is pretty cool that I haven't talked about yet, but think about your GAP networks. This is kind of completely 360, actually not 360, 180. Different direction. 90 degrees from what we've been talking about. But in some networks, your prod is completely isolated from what you're working with as a developer. And developer, you're like, hey, back to the internet. I can pull anything I need. And it doesn't matter. And my home chart can just go, I'm going to access this. And it doesn't matter. And I can pull it just in time. Other networks, though, are air gapped. And they don't actually have access to everything they need. And what needs to happen instead is inside your pipeline, you need to pull in all of the assets that are necessary to deploy your application, right that in there. And put it inside of an installable thing like a bundle and go, here is the image I need to deploy. Here are all the images, maybe PNG, things like that. Here's the home chart. I can't pull it from the stable repository. And you have to put all onto, say, a CD, a USB stick, something like that. And somebody needs to physically carry it across an air gap and plug it into a machine onto that network because it doesn't actually have access to the internet or things like that. So bundles have the ability to do that, to bring everything that's necessary to install an application and then carry it around and have the bundle actually work, whether or not it's connected to the internet. I love this one. You can't see the picture. It's a guy packing his luggage with his foot, which is how I travel. When you're working with multiple tech stacks, oftentimes you don't get to just work with Cube CTL or just with Customize or just with the G-Cloud CLI or just with Terraform. You're mix and matching like five or six of them. And when you come onto a team or you're supporting this in ops, you don't really have the luxury of intimately knowing every single one. So it's kind of neat about the bundle interface is that I just need to know Porter install. And I don't need to know that this bundle is using three of the five. And then this bundle is using Chef and then that bundle is using this. It's always just Porter install, Porter uninstall or whatever. And that's pretty slick. One of the other things that is not 100% inside of CNAB yet, but it's something that we're actively developing as part of the spec is the ability to say that what we're installing is unchangeable. So if I install it last week or install it tomorrow or you install it, it's always exactly the same thing. And the way I like to think about this is consider when I'm installing a Docker image and I install it with the latest tag. You know how it can be different. You never know really what you're pulling. If I install with the latest tag last week, I'll get one image and someone could have pushed and I install it today. I may get a different thing. So what the CNAB spec does is it has you reference images by the content digest of the image. So it looks at the entirety of the image and says this is a digest of everything that's in the image instead. And that's how it references an image that it's going to use inside the installer. So when you go to install something that goes, oh, I need to install my SQL 5.7. It's not actually referencing my SQL 5.7. It's my SQL 5.7 at some giant ugly content digest. It's very long. And then the bundle, which has all these references and various images, is signed so that you know that when I download and pull it, that it hasn't been touched and I know where it came from. And it can also have things like, it says it's past user acceptance testing, things like that. The implementation details of how this is all going to play out is still in flux. But these are our goals that we want to be able to say as part of the bundle spec. So speaking of the spec, there's no such thing as just a CNAP spec. Surprise. There's actually a couple of specs. Core, if someone just says CNAP spec, they're probably referencing core. That's the one that's finished and complete and isn't going to change and that all the tools support. But there's a couple more that are still in progress and you all could help shape and provide feedback on. So I'm just going to walk through what's involved in some of these. But to be honest, you don't need to understand anything about them in order to use bundles. So if you're not a spec person, feel free to like, please your eyes and just wait for the demo. I won't judge. So the core specification covers a couple things. One is the bundle file itself. The bundle file says, I'm a bundle. This is my name. This is my description. And of course it's JSON because, you know, you had to pick JSON or YAML. We went JSON. The invocation image itself, that's the installer I've been talking about. And this is where you can put all the various files and things that you want to ship around with your bundle. It has basically it's everything that a tool that wants to support the specification would need to understand and adhere to. So I'm going to skip through here just a little bit, but we hit 1.0 this month and all the tools are some beta, but they all support 1.0 at this point, which is pretty slick. So let's walk through a little bit what this looks like. When I talk about a bundle, it's actually, it's one thing, it's one file. It's one thing you can reference, but it's actually three things in one, three types of things. One, it's your images. It's the things that you're trying to install in the first place. It's your Docker images. And now here's my big lie. I use the word Docker image because that is the easiest thing for us to understand, but not everyone lives in the Docker world. And tech is going to move forward. And Docker may not be the way we solve everything in the future. Okay. So CNAB actually isn't written specifically to Docker whatsoever. So application image could be a virtual machine. Your installable unit, MySQL, for example, could be a virtual machine that has MySQL on it. It could be WebAssembly instead. It could be WASM or something like that as well, or it could be something we come up in the future. It doesn't matter. It needs to be an image, an installable unit, a set of bits, basically. We can ship around in package and we can digest, but it doesn't have to be Docker. Docker is actually just a driver that CNAB supports. Invocation images is the installer. That's where all the logic goes. That's where the helper files, that's where we shove Terraform CLI, the Helm CLI, our charts, things like that. And then the bundle descriptor is everything that says, this is the metadata about the bundle. And when we smoosh all this together and we ship it around, we call that a bundle. So these images, nothing about them changes. They're completely unaware that they are inside of a bundle. They don't need to know. So the invocation image or the installer, this 100% understands that it's part of a bundle and it needs to know. And again, this is where you put the tools that need to know how to install your app. This is where your config goes, your templates, and then the magical script that understands how to perform installation upgrade and uninstall. And then that bundle descriptor, is the manifest that lists out what are all the invocation images, what are the application images, those digest, so that we ensure that when we install it today, tomorrow, three months from now, we're always pulling those same images, understanding what credentials are necessary, what parameters the installer would accept, and what outputs could be generated by the installer. I don't really talk about this much. One example of an output, I would say that my bundle created a Kubernetes cluster. An output would be the KubeConfig. Another specification that is pretty solid, but not 100% at 1.0 yet, is the registry specification. And very short, it lets you push and pull bundles to OCI registries. So instead of having to come up with a new way to distribute them and send them, we don't need to throw them over. I'll put them somewhere. We can distribute them just like we do our Docker images right now. We can put them in OCI registry. So like Docker Hub, Quay, Azure registry, things like that, Docker registry, we can ship them just like we do our application images. The security specification, the implementation inside of it, and how we're going to do it, is still unbaked. But what we want to accomplish, it hasn't changed very much. We want to be able to have immutable images. We want to ensure that the bundles have not been touched. They have not been tampered with. We want to be able to say that we know where that bundle came from. Who wrote it? What's the origin of it? It came from Microsoft, things like that, that it passed certain levels of testing. Next up, we're going to be able to establish trust with the bundle. This is the spec I work on, dependencies, is super early, but we have a working group, which is my yesterday on it. And this lets you say that I'd like to rely on a bundle that I maybe didn't write. Maybe I have a WordPress app, and I'd like to be able to rely on my SQL bundle, and I'd like to get a connection string back from it. It's actually really that simple on some levels. I just like to be able to rely on other bundles and have dependencies. It sounds so easy. And yet we don't want to let that get too complicated. So we'll be very careful about this one. So there's a couple of different tools right now that support the CNAM 1.0 specification. Core. There's Porter, which is what I work on. There's Docker app, which you can get in a couple different ways. We go to their GitHub repository. And there's Duffel. Duffel was written to help prove out the spec as we were writing it. And you can write your own too. Actually, this is pretty cool. Every single one of these tools is actually based on the CNAB Go library. And the CNAB Go library implements the runtime. And this is how we kind of get consistent behavior across everyone without us having to read the spec interpret it and come up with consistent interpretation. A couple of people have written their own in different languages too. Gosh, I've seen some in, I think C sharp rust, Python, et cetera. But I don't know, Cloud Native and Go are kind of, I don't know, we all seem to like each other. So if you want to write your own, you could too. And you'd get pretty far pretty fast with this. I love asking myself awkward questions. So, weird question is, aren't these all the same then? Because they're just written off the same library. Yes and no. The cool thing is if I make a bundle in Porter, I can run it. I can run it. Doffle can run it. Docker app can run it. And vice versa. Okay. But the experience of making a bundle and adding one of these tools is wildly different. They all have a different take on how to make these bundles. Docker app looks a lot like Docker compose. Actually, it's Yaml, and it's very like microservice focused. So, the bundle is really designed to teach you the spec. Because we use it to prove the spec. So when I said like do you like bash scripts? Double. Porter was, and I'll show you in just a second, was a take to kind of be like, I don't want to learn the spec at all. So it looks very different from both of those. So they are interchangeable from the standpoint of the runtime, but they are completely not interchangeable from the like authoring experience. Okay. So, I said I helped make Porter and I'm going to be really evil and show you Porter. It helps you take all your existing assets and scripts and tools and whatever that you have on your pipeline and be able to reuse them as is or close as close as you can and make them into bundles. And make them into bundles that hopefully are robust and kind of fit with the idea of how bundles should work. So for example, one of the worst things I think a bundle can do is I run upgrade and I end up in a state where like half of it's upgraded and I can't really get it to un-upgrade and it's stuck and then I had to go fix it myself just using underlying tools. That would be like a huge failure and I'd be super upset and sad. So Porter uses something called Mixins, which are little adapters that understand how to talk to Helm, Terraform, Bash, the Azure CLI, GCloud, AWS, Cube CTL, I don't know, all bunch, right? And they understand how to add a little bit of reliability and understands how CNAM works to add in things like retries, handling errors and just getting things into the state that it works the way we expect bundles to work. So you don't get stuck in the middle of an upgrade and you can't get it to work. You could rerun upgrade five times and it wouldn't do something silly. And then the other thing that I really like about Porter is it was need for the community to work with. So it was kind of made for people to like remix and do weird stuff too. And you want to make a mixin that like order dominoes. I wish someone would make that. I keep offering, no one's taking me up on that yet. I would love to demo for you now, a real bundle so you can see in action. And this bundle makes... It makes a... Oh, I'm so sorry. Let's take a look at it here. It makes an S3 bucket on digital ocean. And then it creates a Postgres database using Terraform. And then it deploys a Spring Music app using Helm. Okay, so I'm going to kick this off because it takes about five minutes. And then I'm going to walk through all this with Porter and kind of see what this looks like. Okay, so Porter install. We're going to pass in my credentials for digital ocean. And then I'm going to give it two parameters for my buckets. I'm going to call my bucket my database webinar and then I'm going to show you a little bit of what I'm doing. Terribly creative. Segmentation fault. That is the worst error ever. I'm going to show you a little bit about Porter and how my bundle did not work. That's the best demo when stuff doesn't work. So one of the things that Porter does is it lets you see how things happened. So I ran Porter lists and I was able to see that Spring Music here, which I ran 14 seconds ago, and I was able to see that it had failed and let me down in the middle of my live demo. So let's take a look and see what happens. So by the Porter instance show, and I'm going to do Spring Music. I'm going to take a look at it and see. Do, do, do. That it ran. And so this is super janky. Look, it already has an output. So I obsessively ran this demo a couple of times this morning. And I think I re ran over on top of an existing thing. So what I'm going to do is I'm going to try to run this again. But I'm going to pick some unique names here. My unique demo. And we'll give this another shot. Everyone cross your fingers. Oh my goodness. We're going to try one more time. We're going to throw a debug on here. And otherwise you can all silently judge me, or you can judge me in chat and it'd be kind of fun too. All right, let the silent judgment roll. Okay. I apologize. I'm sorry. I'm sorry. I'm sorry. I'm sorry about this. And I promise you all one recorded demo after this. Okay. Let me show you what is in our quarter. Not YAML. And I promise you it totally worked right beforehand. Sorry. Okay. So the way Porter works is instead of having a. Json file and having you write a bash script yourself. What you do instead is you use a YAML file and Porter generates all that for you. So I'm defining a bundle called spring music. And I'm setting my version at four one here. Okay. Now we talked a bit about what's inside of a bundle. And what Porter is going to do is I name. I'd like an invocation image and I'd like to call it. Porter dash Dio. Okay. And I'd like to have a bundle that's eventually called. Porter Dio bundle. Again, it'd be. For that one. All right. And when I run, let's give me at least build. I'm going to keep pushing the limits of my demo, even though. Something is wildly against me. We're built. Well, at least on that. So what it's doing. Is it's building my invocation image and it's building my bundle. But what is it using right here? I'm giving it a starter Docker file to create that invocation image. So let's take a look at that. Inside my Docker file, I needed a couple of things in order to use my bundle. Now, I remember we wanted to install a couple of tools in order to work with it. And we take in a little bit of a look at what my bundle is using. It was using S three CMD. I want to be able to write make buckets. Okay. S three CMD. Let me create buckets using the. AWS S three compatible API. The other present curl so that I can download. Cube CTO. And then what I also do here is I copy everything that's in my current directory. So I'm going to go into the bundle directory that's inside the invocation image. So let's take a look and see what's inside my current directory. I have a charts directory. And a Terraform directory. So charts. I spring music, which is my spring music app. And as my charts. And then I have some Terraform files to deploy my database. Pretty exciting. So that copies everything into. My, my invocation image. And then I'm all set from that standpoint. And it needs my bundle for me. And the next thing it does here is I have, it defines some credentials for me. So I have. A digital ocean token. Digital ocean spaces key and space is secret. That lets me make buckets on digital ocean. It lets me make. Blobs and things like that. I also have a cube config, which is for a Kubernetes cluster on digital ocean, which I have actually just right here inside my current directory. And what credential says is I need to collect all this and pass it into my bundle when I go to run it. I also have parameters here. Which I can correct like my region, my spaces name, my database name, it all has defaults. So I can pass things in and run it like on easy mode, but I can also override them. And my bundle also generates an output. So I can go look at my spring music app when the bundle is done running. So I said that Porter has this concept of mix ends, which are a little, it's executable wrappers that understand how to talk to things like how I'm in Terraform. And exec knows how to like, eventually somewhere you're probably in my script. So exact how it was sent. So let's break it down. Look at what install is doing. I'm going to make a bucket. So I'm going to use S3 CMD. And I'm going to pass a whole bunch of arguments. And so this is the kind of underneath thing that Porter helps you do. Is it helps you pass those credentials. And those parameters. That you were collecting inside your bundle. And inject them into your commands. So right here, we have a little bit of template in magic, those mustache. Templating. And inject them into my command. So here I'm putting in the digital ocean spaces keys. And then later on here in Terraform, when I'm making money database, I'm passing in my credentials, my spaces key, my secret, I'm passing in some parameters here. So I'm able to just kind of seamlessly run exec and have it run the command and then jump into Terraform and do that now with Terraform. I'm doing something kind of cool afterwards, which is I can then collect things from Terraform, like the host, the port, everything that the database, the credentials from the database, and then pass it along next to Helm and go here, Helm. I want to use that and give it to the set statement and go use that when you're making the spring out and inject those credentials in. And so that's how it works. It may be kind of like the next awkward question would be, why don't I just write a fast script that does all this. Just to repeat myself a little bit. Each one of these mix-ins has a little bit of reliability baked in where it can handle errors for you. It'll do like Helm upgrade, install dash or upgrade dash, dash install. It'll look for things like I tried to delete something and it was already gone. So I'm not going to freak out and give you an error. There's just a lot of like robustness baked into these things. So you don't have to try to do that. And the other thing is it's structured. So if you were trying to maybe look at these and parse the metadata and understand what your bundle is doing at a higher level, you can, and you're not parsing a batch script. So that's what that bundle is doing. I apologize that my demo didn't work. If you look in chat, it looks like Ralph posted a video of the exact demo with Jeremy, the other co-creator for Porter. He did a demo of this. This is actually his demo. I'm just stealing it and showing it here. So a couple of writing awkward questions. Is Porter a Microsoft only tool? No, it's not. It is open source. Anyone can contribute. We have a couple of external contributors. And I don't know if I can say this. Like my PM Ralph is on here and he'll pie yell at me. I would absolutely love to eventually get this into the CNC app and then get a whole bunch of other people contributing to Porter because absolutely nothing about it is Microsoft specific. It works with G Cloud, it works with AWS, it works with Azure, it works with DigitalOcean except for the very awkward blow up there. Yeah. Our bundle's ready to use. Every single one of the tools that I listed out there is still in beta. And obviously half of the specs there aren't finished yet. So is it ready to use in production? No, but you should be looking at it. And if you think bundles look interesting to you organization, now would be a good time to think about it because you can provide feedback right now. Now, if you're watching this and you were like, oh my goodness girl, I have feedback. I think you're doing everything wrong. You're doing everything right. You don't know about X, you don't know about Y, but what about this? Don't tell me. You should come to our weekly CNAM meetings. You should come to the Porter office hours, which will be next week. And you should tell the wider group because I will forget. And everyone is going to want to hear your feedback. I think that would be really great. CNAM is not just for big companies, it's for everybody. So please come and share that feedback and let everyone hear about it. Next, I really love to open this up to questions. And here's just some resources to learn more about CNAM or if you're just an important. Awesome. Thanks Carolyn for a great presentation. Yeah. So we're now going to have some time for questions. If you have questions you'd like to ask, please drop them in the Q and A tab at the bottom of your screen and we'll get through it as many as we have time for. So the first question is from, you know, and he asked, can Porter run bundles created by other CNAM tools? Yes, it can. That's the point of the specification is they all support the same runtime. So as long as the bundle was created by a CNAM tool, Porter can run it. And same thing. If Porter makes a bundle, one of the other CNAM tools can run it as well. Cool. Next question, how does CNAM and Porter deal with ad hoc changes? In the case that I install a bundle using Porter, do some ad hoc changes change and reinstall the bundle? So what Porter will do is Porter detects that you've changed the Porter.AML file. It'll rebuild the bundle. Okay. It'll take all your changes and make a new bundle of descriptor and it'll make a new installer, an invocation image. And then it'll run the install again for you. You'll have to do the uninstall and then reinstall, do the install again. If we're talking about upgrade, you don't even need to do an uninstall and a reinstall. And it'll just use the new logic that's inside the installer and the new config files, all of that. You don't need to keep using the same old version of the installer just because that's what you were originally used. You can fix bugs in your installer and then use that against live instances of bundles that have already been installed. Great. Move on to the next question. Is there a way to use one of the tools to conduct blue, green canary deployments? Yes, there is, but they don't have that logic like baked in. That's not like a CNAB logic thing. I would probably point to Docker app because I think, I'm not like familiar with some of these tools, but I think you'd want to combine something like that with maybe one of the existing tools in the CNC app landscape that already support that. But off the top of my head, I'm not like a tecton or something like that. You maybe want to grab one of them and pull that in and use like a combo of an existing tool or like workflow engine that supports blue, green. Does that make sense? Like you'd want to use your bundle inside something that already understands blue, green. Next question. Assuming my app is not distributed as Docker or OCI images, but as proprietary packages, which of these specs and tools will fail? Oh, okay. Well, we need my, can I get them to clarify by packages? Do you mean like maybe Debbie in packages or Ruby gems and things like that? This is a question from Gerald. So Gerald, if you're still on the call, you can clarify the question. I can come back to this later on. Yeah, let's do that. And then I'll go to the next question. Is it possible to keep or show the state of deployed two to three different versions of the same application in one bundle and switch between them? Yes, it is. So inside the invocation image, you can put in whatever you need to. So if you need to pull in multiple file sets, maybe you need to have a v1 v2 and v3. And then maybe install by default, you install v1 and then upgrade. You could select to put down, maybe as a parameter, you pick v2 v3. You could then choose which files you want to install. And then you can install that. And then by installing, you can, you can clean everything up. You can put whatever you need to inside of that invocation image. The invocation image doesn't have to be tied to just one version of your app or only just one app, even. Is there a way to take out outputs from the dependent bundles? Let's say there's a bundle of VPC and another MySQL. Can we grab an output from the first one and reference it in the second to know VPC parameters deploy MySQL to? Yes, that is exactly what dependencies are for. So you define a dependency and you say, this is the dependency I want to use. All bundles can say that they produce outputs. And when you say I have a dependency on, let's say they're depending on VPC, you can say I want to use the outputs from VPC or I want to use the outputs from MySQL and you'll be able to then get it in your bundle and then consume them and use them as parameters. Okay, so Gerald responded with some clarifications. They said clarification packages are jar files in a proprietary format. Which CNAP specs or tools can be used to distribute these? Yeah, so Roddy, he's another person who works on CNAP. You can pull your packages. He clarified in chat actually that you can pull your packages inside your invocation image and then use that to distribute your jar files. You don't have to always have your app be a Docker image or anything like that. So you could put your jar files inside that in your invocation image and then if you need to then drop them into environment, the invocation image basically is a temporary place where you use them to move them around. Next question. Are you working with CNCF SIG app delivery and or the KSIG apps group? A number of us are in CNCF SIG app delivery and hope to be working with them in the future to have CNAP be a part of that and work with them on some of the best practices and maybe have some of our libraries and things like that be involved. So yeah, totally. Not so much Kate specific CNAP is not specific to Kubernetes. I know I use them a lot in my examples, but it would be with CNCF. Sorry, my cuckoo clock is going off. It's a little early. Next question. Where does the Porter YAML collect its secrets from? Oh, okay. Yeah. The Porter YAML says where it wants the secrets to go inside the invocation image. So maybe it wants to put the secrets into an environment variable. But when you run Porter install or upgrade, one of the parameters is credentials. And there was a command before that I gloss over super quickly at the very beginning, which is Porter credentials generate. And that's an interactive command that walks you through and it says, where do I want to get my credentials from? And it'll say, I have my credentials sitting on my laptop at the moment in environment variables. Maybe it's in GitHub access token or Azure service principle, blah, blah, blah. Or maybe it's in my file system. It's in, you know, cube config and my home directory and things like that. It'll walk you through that and you'll give it a name. And that's what you pass in as a parameter to Porter install. And then Porter handles injecting that into your bundle when you run it. So it's kind of like a two step process of you. You collect it and get a name. And then that's what gets passed in the bundles. Okay. Few more questions. I'm going to try and get in. I try to link up the help docs quickly about Terraform, but I didn't, but I don't see any mention of the plan capability, which is super important feature of Terraform. Is there a dry run capability that adds confidence to the changes to be applied? Thanks. I don't know enough about Terraform to answer that question for you. But we could maybe have someone who knows either answer in chat or circle back and answer that for you. If you are on Twitter, we can probably answer that for you in like five or 10 minutes after this. Sorry, I can't answer that though. Okay. Okay. Has Pivotal or Cloud Foundry participated in the CNAP spec discussion? It seems they have an application runtime C far and was wondering if there's any comparability. Pivotal is been involved with the CNAP spec since the beginning, but I'm not familiar with the application. That's C far. So I don't really, I can't answer that. I don't know if Ralph, you're on chat. If you're familiar with that. That's C far and question. All right. I'm going to move on to the next one. Yeah. Can you have a bundle of bundles? Yes, you can. That's the dependency spec. So with the dependency spec, I could make basically a Meta bundle or a bundle of bundles that relies on five or six or 10 or 20 or three bundles that could then rely on other bundles. At the moment, it just goes one level deep. But the plan is for, for more in the future. And then I'm going to cut this off as the last one. Can developers with little experience with Go contribute to Porter? Do you offer guidance and mentorship for them? Definitely. The very last link on the slide, or second to last link on the slide right there, porter.sh slash contributes is a landing page that will walk you through everything you need to know about figuring out how to contribute to Porter. We will help you figure out how to contribute, how to do PRs, all of our good first issues walk you through where to find the code, how to run the tests, how to, you know, every single thing you need to do. And I regularly mentor new Go contributors. So I definitely welcome, please come on. This is very accessible, easy to do. A lot of the new code is at the CLI level, which is one of the best places to start if you're new to Go. Great. Thanks, Carolyn, for a great presentation. That's all the time we have for today. Thanks everyone for joining us. The webinar recording and slides will be online later today. And we look forward to seeing you at a future CNCF webinar. Have a great day, everyone. Thanks.