 Hi, everyone. How was lunch? Doing OK? Yeah, ready? Is your brain energized? Are we good? Someone told me that Room B here is where all the, there's been a bunch of exciting talks here today here in Room B, so I hope that. I hope that we'll still have some fun here. So this is about delivering heterogeneous architectures. Obviously, we're at the Cloud Foundry Summit, so we're going to talk about how Cloud Foundry makes this possible and even fun. Hopefully, how Cloud Foundry makes it possible and fun without anyone from IT or operations losing their minds when you tell them you want to try out a new programming language, which I'm sure no one here has ever, ever tried before. So I am curious, how many folks here can say with certainty that in your production environment, you are only running one programming language right now? One person, two people, maybe? OK. And then how about two? Two programming language running something important in your production infrastructure? Three, four? AngularJS counts as a programming language, so anyone? Five, 10? There we go. OK. So a handful. Every time you introduce a new environment, you introduce the need to manage that environment and have some understanding about how to do it. And that's where a lot of pain can come in, but I think that's where Cloud Foundry's architecture and specifically the way that build packs work end up saving us from a huge amount of that pain and saving us from a huge amount of what would otherwise be manual labor. It's not just about the pain and the labor of managing those environments, though. It's also about making sure that you have flexibility and freedom. So I'm going to try and show you why Cloud Foundry provides that flexibility and freedom. And we'll see how that plays out. A couple of important things, though, maybe even more important than that. Who's on Twitter? Anybody have the Twitter? It's 2016 now, so maybe if you have the Twitter. You can follow me. If you disagree with things I have to say, that's cool. You should post it on Twitter. I'll retweet it. We'll see how that plays out for you. If you disagree more vehemently, this is my personal email address, and you can email me. If anyone's into writing screeds, this is your opportunity. I make no guarantees about how quickly that screed will make it from my email to Twitter, but you can give it a shout if you want to. I write things on the web at kcwest.com. It's also a place to find other ways to reach me. Maybe if Twitter is too new of a technology for you and email is too old, maybe LinkedIn is somewhere in the middle and you can find me there if you want to. If you're really on the bleeding edge, I suppose you could probably follow me on Instagram or something if you want. What's that? What's my Slack channel? That is private, sir. Yeah, it's slack.cloudfoundry.org. You can totally find me there, actually. And then I work at this company called Pivotal. They allow me to fly around the world and give talks like this. I appreciate that. Hopefully you appreciate that. And because of that, this is my appreciation bullet point for Pivotal. Thank you, Pivotal. So heterogeneous architectures are real. By show of hands, we sort of demonstrated this today. I believe I had one actual hand raised when I said who's running one programming language. Most of the organizations that I talk to, when they only run one or two programming languages or one or two runtime environments, it's because they feel stuck. They got into this rabbit hole with Java and a specific application server or with.net on Windows and then they feel like everything has to be that way because that's the thing we know how to manage. And that makes sense if you have to manage it all yourself. But hopefully you don't. And hopefully you want freedom of choice and you have that opportunity. Also, not everything's done that in Java, right? So who's rocking some Ruby right now? Or some Python? Or some PHP? Or some Perl? There we go. Or some Rust? No, go. Yeah, all right. Et cetera, et cetera. Yeah, so you want freedom of choice. You wanna be able to use the right tool for the right job, right? So how do you do that? How do you do that in an operationally mature way, especially in a production environment where you need some guarantees and you need some consistency? So I think Cloud Foundry has an answer. And even if you're not doing it now, I'm here to tell you that heterogeneous architectures are possible and we'll see how. And because of that, I believe that we are now at an age where middleware lock-in is dead. You don't have to be stuck on a specific environment, specific runtime tied to a specific web application server. You don't have to do that anymore. Right, so if you take nothing else away from this talk, take away the fact that you are free from middleware lock-in if you choose to be and you're here at a conference working with some cool technology that makes this particularly possible, right? So you don't have to be stuck anymore. So thank you, build pecs. So I wanna ask a question. I know I'm here at Cloud Foundry Summit, sometimes I'm surprised. How many people interact with Cloud Foundry actually? Right now, okay? Most everyone. So have you pushed an app? Yeah, cool. Or like 20 apps, you know? That's cool. And then have any of you looked into how the build packs work? So who would say you know how build packs work? Right, so just a handful of folks. So the build pack is sort of your magic secret to how when you push an app it just works. Like Anci made this amazing haiku, this really cool haiku that really resonates that here's my source code, run it in the cloud for me, I do not care how. Well that I do not care how part is a privilege that you only have if you have a really good environment to run your applications in. And the build packs are that secret sauce to I do not care how, right? So if you like that idea and most of us are working with Cloud Foundry so I suspect that you do like that idea, that I do not care how part is really magical because you can go on with life and you can care about only the things that are important to you. So build packs create immutable containers that will run consistent, with consistent operational characteristics. Right, this is super important. Right, in an age where folks are super excited about containers and we are too, the Cloud Foundry ecosystem has been running them for a long time. And build packs help us create these containers. And then when we run them, they have consistent operational characteristics. That's absolutely critical to having a heterogeneous architecture that is easy to manage rather than one that is hard to manage. So how does it work? Let's just sort of break this down. So build packs require input. So to build that immutable container, you need an application. Who here knows what that means? I probably don't have to explain that anymore. I'm using hand-based participation to keep everybody awake. Yeah, okay. So I probably don't have to dig into what an application is right now, right? And then you need a manifest.yaml. So we know what that is, right? Yeah. So here's a basic manifest.yaml. So you've got your killer app, that thing that's gonna make you tons of money. Maybe you have a path, like if you're in the Java ecosystem and you're building jars, maybe you have a consistent path. You're probably gonna provide this on the command line. You can provide it in the manifest if you want to. And then you might specify a build pack. You don't always have to, but sometimes you might. So super basic, probably the most basic manifest that you can make in order to pull your application to Cloud Foundry. But these are the inputs, right? So you've got an application and a manifest.yaml. Those are your inputs to the system. And then what is a build pack? A build pack are three basic steps, right? So if you look at the directory structure of your most basic build pack, this is literally it. Each of these are scripts. They can be written in Bash or Ruby, you know, or other languages, whatever you want. But you've got to compile, a detect, and a release. And that's it. Zero directories, three files. That's a build pack. So if it was a mystery before, this basic structure sort of demystifies it. It's not that much, but we should look into it a little bit further. What happens here? This is not actually the steps. The step is first detect, should I run this application? So build pack wants to make a reasonable assumption that if it's going to try to create a container in order to run an application, it wants to make the decision as easy as possible to say, should I do this or not, right? So should I run this app? And then compile will create a droplet. A droplet is what we call a container. Who knows about this concept of droplets, right? So at least in the sort of native and consistent Cloud Foundry world, a droplet is our container. And then release is the third phase where we'll provide and it's optional to provide it, but we'll provide some basic metadata for running instances of our application. So this could be the default way that we spin up an instance of an application or maybe some environment variables or flags that we're gonna specify for a JVM or some other runtime environment. So these are the three phases to building a container to make it run on Cloud Foundry and the build pack is responsible for making this happen. So we can dig into it even further. Let's take the case of Ruby. We can sort of deconstruct this. This is, I've removed some stuff here in order to make it fit nicely on a slide and I think it fits pretty well. But basically in the Ruby ecosystem, there's a file called a gem file that is used as a best practice to determine the libraries that we wanna install and run for this application. So if one exists, then we have detected that we can run this application using this build pack, right? So this is a Ruby app. If it doesn't, then we say no. And of course in Unix LAN, you exit zero for it's good and you exit one or any other thing for it's bad because that totally makes sense, right? But we've been doing it that way for more than 30 years so we will almost certainly keep doing that. And then we compile. So compile in the abstract is responsible for a couple of things, but primarily it wants to create the root file system. So what is a container, right? Who knows what a container is? Like you definitely know, it's not a cute whale necessarily, although that is a type of a container. So a container is a root file system, an isolated file system wrapped in some metadata that explains to the kernel how it should treat processes that are run within that isolated environment. So we need to make that file system and that's one of the primary responsibilities of the build pack and one of the primary responsibilities of the compile phase. So it starts with a root file system, a very sparse Linux file system typically. And then we put a runtime environment on top of that file system and that runtime environment will be dependent on which build pack we're building. So in the Ruby world, we're going to put a Ruby interpreter and we're going to run gem install to make sure all our libraries are there. In the Java ecosystem, we will make sure there's a JVM and the Python ecosystem, we'll make sure Python exists and if you're trying to deploy a static site, we'll make sure the engine X is there to be able to serve that site. And then you put your app in that file system as well. That's the responsibility of the build pack's compile phase. And then because it wants to actually create a droplet, what the stager environment that interacts with the build pack does is it wraps it in that metadata which is often supplied by metadata.yaml and then whatever sort of defaults you've specified for running application instances in your instance of the platform. And now we have a container, right? And of course in Cloud Foundry, we call that a droplet. So if we were taking this Ruby example, a Ruby app droplet would be your Ruby app with Ruby and the gems that you've specified and CF Linux FS2 as the typical root file system, although that's pluggable and you might do something else. So that's what it is. And I like this because it's a square and a square like gives me this warm fuzzy feeling that it's interoperable with other squares. And that ends up being what you get out of this is that you have this really consistent interface. This is my Ruby app and it is a square and that's fine. But I might not just wanna do Ruby apps, I might wanna do other things. But with this square, we can then release it. So this is the release phase where we might specify some basic default information for how to run this application on Cloud Foundry. So in this case, again, this is a basic bash script that emits YAML this time. So the Cloud Foundry will run this in order to determine the properties that it should apply to this application when it runs. It can also emit nothing. So maybe you don't have any specific ideas, but interestingly, typically, you do have to have the release script there even if it doesn't do a whole lot, which is a minor divergence from Buildpacks' other home, Heroku, which allows you to get away without a release script if you don't want one. Minor technical detail there, but in any case, then you see a push and your app is deployed. So with an app and a manifest and Buildpacks and the stager in Cloud Foundry, then we have droplets. And those droplets are immutable artifacts with consistent operational characteristics. So the way that you manage them, spin them up, spin them down, create them, destroy them, it's all the same regardless of the environment that you're running on, right? Or the, sorry, regardless of the framework or the language that you've chosen to run your applications, which is great. So when you wanna deploy and you wanna run a few instances of your Ruby app, no big deal, you run a few instances, they all tend to operate the same way, they all are the same shape, they're all this box, right? You've crammed whatever you've got into this box, and that's good. And that's sort of the glory of the container model, but what's beautiful about the Buildpack model is you have an incredibly consistent method for building these containers, right? So that's what's great about that. So what if you wanna deploy more apps? Well, you can do that as well. So let's say we have our Ruby app. Well, let's say that it's sort of a back office app. We used Rails and we're able to make some really good CRUD forms to interact with some data and we've sort of built up a little CRM system or something, that's great. Say that we've got Java for an API, we're using, you know, I like Spring Boot and I like all the goodies that I get out of that. I like the JVM because it keeps my app pretty fast and so I'll use Java for my API and then, you know, I'm gonna write my UI in Angular because everyone else is writing it in Angular even though I like Emblem or Ember.js rather better, but I can't find any Ember.js developers and so I've got these apps, right? So what do you do there? Well, if we remember that build packs create immutable containers that will run with consistent operational characteristics, then build packs to the rescue. This is, by the way, usually when you present this opportunity or this situation to your IT operations team and you don't have something like Cloud Foundry, this is when people really start setting their hair on fire because they figured out how to build the golden images for, you know, their Ruby app and they know how to run those and manage those but now you're asking them to build two completely new environments that they're not really that familiar with and they're not really sure how they're gonna operate or what their characteristics are gonna be whenever you're running your application. That's the old world and the new world with Cloud Foundry and with build packs is that you don't have to worry about that much, that very much anymore because the build packs will take care of a consistent environment and Cloud Foundry provides the promises of resiliency as the platform itself, so that's not bad. So what now though? Well, just deploy. So let's say we've already got our Ruby app. We have a few instances of that. They all look the same on the outside, they all have similar characteristics, they have similar interfaces, similar inputs, so then we can just spin up our Java apps and our Angular apps without really having to worry about it and how do we do that? We'll see a push and the build packs go through the process that we identified earlier of detect, compile and release in order to make sure that we have a consistent environment to run an application regardless of the language or the framework that is written to support. So that's good news. I feel good about that. Does that feel good to you, like this consistency and reliability? Ring a bell for things we want? Yeah, I see some nods. Some people are like, I don't want that. I like exciting infrastructure. Dynamic infrastructure. Yeah, the words exciting and infrastructure should never be in the same sentence in a positive way. Just heads up. I like consistency. So build packs that are supported by the open source community and supported as the open source distribution of Cloud Foundry, Java, Ruby, Node, Go, Python, PHP, Static, Sites and raw binaries. As long as you build an application that's meant to run in the cloud and it's in one of these languages that's supported out of the box, the beautiful thing is that this is open source. There are about 40 more build packs for runtimes and environments that aren't on this list. Many of the vendors that are here today who provide their own versions or implementations on top of the core Cloud Foundry have their own. That's grade two. So looking at this list, though, just of what's supported by the open source community from security patches that are happening constantly and upgrades to the latest versions, like, does this satisfy needs of anybody in this room? Like, is this good? Like, for production today? So everybody running, is anyone running any of these application environments in production today? Yeah, okay. And then, you know, if you're only running one of them, maybe you want to run some more. Maybe you want to try out Go. Like, you go talk to our super excited Go friend over here in the front row and you're like, wow, we got to try some Go. Well, how do you do that? Well, build packs are your answer. You can start to have creativity. So, you know, if you're using command line to interact with a Cloud Foundry instance, you can type CF build packs and see what build packs are installed by default on your instance of Cloud Foundry. I got this from PCF Dev, which is a lightweight sort of Cloud Foundry in a box that you can use for local development and local testing. This is what you get out of the box. They have priorities. The priorities are important because if you don't specify a build pack explicitly, then it will go through the detect phase for each of these build packs in order. And it will start with Java and move down the stack. So, if you build an application and you just deploy it, each of these build packs will attempt to detect whether or not it should be responsible for building, or for running this site, or this application. You can also, you have fine grain operator control over whether or not they're enabled for use or whether or not they're locked. And of course, they are versioned and get released that way. And so as an operator, you can control and manage which build packs are part of your default system, which is great. You can also specify, as a developer, if you have the capability, you can specify build packs that aren't listed here. So I mentioned Rust earlier. I'm sort of playing around with Rust. I'm not a Rust expert, but if I want Rust to work on Cloud Foundry, like how do I make that happen, right? That's the beauty of the open source. There's an open source build pack for Rust. You can see that it's not listed here, but in my engineering organization, I at least want the folks to be able to try new solutions and new technologies independent from what is supported in production. And then if a good tool or a good piece of software comes along, I want to be able to enable it in production as well. And again, the build packs are what let you have fine grain control of that. So what about multiple apps from one repo? So if you've got a heterogeneous architecture, but maybe they're sort of all in one repository or you might use sub modules in order to collect a collection of software in order to make a larger distribution, the nice thing is that you can do that too. This is where the manifests really kick in and help you out. So we're used to using manifests to specify one application, but I don't know if you would know that you can specify multiple applications. So if you've got a Java app, but all of your static assets are under resources, which is a very typical pattern, maybe you'll deploy resources as a static site for your UI right here. And you can specify things like instances and a bunch of other stuff. You could specify Java by targeting a specific jar that you've built, and maybe you've got your Ruby app in there as well or you've got it provided by a sub module. But what's nice is that you can have one manifest. And if you want to deploy all of these applications, which is similar in a way to the way that Docker Compose works in the Docker ecosystem, you can just type CF push and it'll deploy all those apps. If you only want to arrive one, like say you made some color changes to the UI, so you can type CF push UI and it'll only deploy that one, despite the fact that you have multiple applications specified in your manifest. But it's kind of nice to be able to have a master manifest for your architecture, for your particular project, or your particular application. That's kind of cool. And then you just CF push. Not too bad. So what about custom build packs though? So I mentioned Rust. Well, let's say I've got this Rust application. This is a very basic Rust app that's using the iron framework, which provides restful APIs. So it allows you to build, it emits a small web server and lets you build restful APIs. So one of the things you can see here that's happening is that when we get a new request, we will inspect the environment variable CF instance index to see which application instance this is. And then it'll wrap that up in a JSON payload and emit that as a JSON object. That's pretty cool. It'll bind to the port that is specified on the environment. So this is a 12 factor Rust app, which is cool. But Rust very much like go requires you to recompile it. And then you've got this portable binary. So what would it look like to try and make this run on Cloud Foundry? And this is significant because you may have very specific environments for your applications, but you still wanna try and run them on Cloud Foundry. And if it is a 12 factor app or a cloud native app, you should be able to do that. So here's a 12 factor Rust app, not typically supported on Cloud Foundry. So let's build a build pack. Let's detect whether or not this is a Rust app. Rust uses cargo the way that Ruby uses gem file. So this is how we specify underlying dependencies. So if we have a cargo file, then it's a Rust app, if not, it's not and we'll pass. And then we need to compile. Well, we'll get multi-rust, which is a way to easily get a Rust compiler, similar to things like RBE and V or other tools that allow you to switch between versions of underlying VMs. We'll compile our application once we have Rust, and then we'll cache some artifacts out of that so that future compiles are a little faster. That's helpful. So that's our compile phase. This will lay down Rust on the lightweight root file system provided to us by the Stager environment. And then it'll compile our app and put our app in that container as well. And now we have a root file system for application. For release, I'm gonna specify that the default way to run an application in Rust is cargo run, which is true, thankfully. That's very helpful to my case, that that's true. So that way, whenever I try to run this application, I don't have to specify a run command. It'll just assume cargo run. But if I wanted to specify a run command in my manifest, I could override that. And here's a basic manifest. So I've got an application name and I've put this build pack on GitHub. It's actually, I had to fork it from the Heroku build pack, but this is legit. And I'm just gonna specify my build pack from there. And Cloud Foundry, when it tries to sage my application, will go to GitHub, get this build pack, and then use this build pack to build this container. And then I'll have a Rust container. So that was super simple to detect, compile, and release an application. This is my manifest I showed you the app before. And that's that. And I deploy it with CF push. And then I've got Rust running on Cloud Foundry. So that's pretty cool. And the open source community is really neat. So I come from an old school Perl background, so I like to deploy Perl apps to Cloud Foundry from time to time. It really freaks people out. But I come from old school enough that I remember the first meeting at OSCON in 2001, I think, where they were like, hey, you know what would be good for the Perl community to make Perl 6. And then they finally released it last year in December. So there's a programming language called Perl 6. It only took 15 years, no big deal. And I can run Perl 6 on Cloud Foundry too, because there's a build pack for that. And there's a web application framework. And that's pretty neat too, right? And those are future-leaning languages, but the fact that Rust is gaining massive popularity, it has huge backing for Mozilla, and I can run it on Cloud Foundry means I can at least explore its viability for my business problems, right? So this is really what build packs allow and what Cloud Foundry allows and why I think heterogeneous architectures, because they are real, Cloud Foundry is the place to run them. So you get the freedom to be creative. You get the freedom to use the right tech. And you get the freedom to do the right thing. Freedom, free, free. So there are some references. It's always good to read the source code to the build packs. You should know the software you're running, but it's really fascinating to see how this is done, especially in an incredibly reliable way. So what I showed you of the Ruby build pack was a very stripped-down version, but if you go check it out, it's quite serious. It's always good to read up on what you can and cannot do with Manifest. Most of that you can do with command-line utilities as well, but it's super important to know it's there. And of course, the documentation on build packs will steer you in the right direction. If you find yourself in the circumstance where you need to build a custom one, which is AOK. So that's my Twitter handle again, Casey West, and we can be friends. That's what that top line is about. We can be friends on the internet. We can also be friends in real life. That's what the beer emoji is for. We can drink those beers if you want. I mean, not literally those beers, because they're emoji. So you're kind of silly for suggesting that, but we can definitely hang out, and that would be fine with me. We have one minute for questions. Maybe I'll take one question here and then more in the hall. But thank you for your time. I hope that this was good. Thanks.