Build Cookbooks and The Service Delivery Canvas
Webber, Christopher
So you have Chef Delivery, now what? This talk is a practical introduction to build cookbooks and how to figure out what should run in each stage. Have you ever found yourself wondering: "What is a build cookbook?" "Where should I put performance tests?" "How does this work with Docker?" If you have, this talk is for you. Come join us as we plan out a few projects in Delivery. We will start by using the Service Delivery Canvas, a tool for thinking about where things go in the pipeline, to layout our project. From there, we will take what we learned from the canvas and walk through building out a few applications, including examples from Chef's own infrastructure. We will also demonstrate multiple language runtimes and methodologies. Come be part of delivering all the things!
 All right, so has everybody started to wake up from the lunch coma or are we just going to kind of like take a nap? Because I'm going to try and have enough energy to keep us going, but I totally understand if you just like, you know, over because, like, yeah, lunch was wonderful. All right, so we'll start with a little bit of where did it go? Oh, that's wonderful. We'll just use the button. Or maybe we won't. There we go. All right, so let's talk a little bit about who I am or who am I? I'm the person that was behind. How many people were at ChefConf last year? So if you watch the video on stage, they delivered delivery using delivery on stage at ChefConf. I was the person in the back super heavily stressed because they were doing that live in on stage and I was responsible for writing the build cookbook that made all of that happen. To the point of there was actually a little Sinatra app written off to the side that gave us the ability to like cut over fastly to a pre-prepped thing just in case because we're all ops people, right? Like you got to have a backup plan. But that was legit. We actually did deliver delivery on stage at ChefConf using delivery now automate workflow. I'm the author of about 20 or so build cookbooks and that number just keeps increasing because my team keeps shipping software. The important part to really take in is I'm not standing up here as a developer of automate. In fact, I'm customer really patient zero. I'm going to be the person that goes to the delivery team and is like, guys, can we fix this thing because it kind of hurts. The delivery team, I'm going to use that word. The workflow team has been super responsive in the number of opportunities we've had to dock food our own stuff and actually fix things before they got out to customers. It's just been fantastic. With that said, I'm the engineering manager for the CIA team that has nothing to do with intelligence. We have everything to do with our corporate infrastructure and applications, which when we get into some of the stuff later, you'll understand why I say it doesn't have to do with intelligence. So what are we going to cover today? We're going to cover the prerequisites and assumptions, some concepts, vocabulary, prerequisites, and these are kind of the things I think are prerequisites. The mechanics of how all of this works, the actual service delivery canvas, yes, it's actually a thing. Some examples using that canvas. Then I'm going to show you some actual code that runs actual things at Chef. So starting with prerequisites and assumptions because we always have to make assumptions. I'm going to assume you're doing the DevOps and really all of my code assumes you're doing the DevOps. Now as we all know, that's kind of a loaded term. What does it actually mean to do the DevOps? I'm going to use some very specific things that I expect of you. I think that the workflow that I'm going to present to you really does require. The app dev teams and the ops teams are able to use Git. It's workflow. We're opinionated. One of the things we're opinionated is you can use any one of the version control systems as long as they are Git. Very specifically deliveries, Git hubs or Bitbuckets because those are the ones we support today. But the team has to be able to use Git. If you can't use Git, this just isn't going to work because the system kind of depends on it. Each group is willing to see the work the other is doing. This is super, super important because I'm going to ask you to take your ops infrastructure code that relates to the application that's being deployed and the application code and put them in the same repo. You've got to work with the rest of your organization. You've got to work with your app teams. You've got to work with your ops teams. It is all about being as a single team because how many people have had that thing where it's like, okay, oh my God, we have to coordinate this change across the cookbook and the app at the same time because otherwise everything is going to go wrong and how often does that work well? Instead, I can make a code change and a cookbook change and they get deployed as the same change set because they really are the same change set. Both groups have to care about production. I usually start, but I'm going to do it right now. How many people in the room identify as sys admins, operations engineers, that sort of thing? How many people are enrolled? How many people identify as developers? That, right? Totally. Do I have any QA folks in the house? DBAs? I've got to give it up for my DBAs because that's a hard job. You have to be in a place where everybody is talking and you all have to care about the end result because I'm going to say some super blasphemous things in a few minutes and it will really make sense why we all have to care about the service and production. In fact, I'm going to go so far as to say the only thing that matters is the service in production. The source code for the application, and I touched on this a second ago, but the application, the cookbook that deploys the application and the cookbook for building the application all need to live in the same repo in harmony because it's just the only same way to operate in my not-so-humble opinion. I should probably also mention these are my views of how my team functions. That doesn't necessarily mean they are the views of how Chef thinks you should function because there's a completely different thing between what my team does and what we say is the right thing to do. But I'm totally going to tell you this is totally the right thing to do. We all have to start from a place of an API. I want you to deliver the entire service. How many people think the service is some application code? I sure don't. It doesn't look like anybody else. I just got blank stares. Like, what are you talking about, dude? Because, right, it's like a load balancer. There's probably some storage involved. Hey, we probably got to have compute instances. I actually have services that I run that don't have compute. It's kind of cool. There might be some CDN involved. You have to be in a place where the majority of your stuff is API accessible. It doesn't all have to be. But for everything that's not in the pipeline, the more opportunity you have for things to go horribly wrong. So the more you do it in the pipeline as part of the pipeline makes a huge difference. So for me, what the minimum thing has to be is that we can provision new compute, whether that's VMs, instances, you know, pick your flavor, right? Open stack, VMware, AWS, Azure, Google, you can provision a thing. Most of us don't just like stand up an instance and point stuff at it. There's usually some sort of load balancer stuff. You really should be able to spin or make the load balancer change necessary to spin up that cluster of servers. And also, how many people have API access to change their DNS? That makes me sad. So how many people are in the cloud right now? How about people on prem data centers? Okay. I've got suggestions. I should totally, yeah, we'll talk about that later. Okay. So we're going to talk concepts, vocabulary, you know, words I'm going to use. We are delivering a service, a thing that you hit. What we are not delivering is a packaged binary that someone else downloads and does something with. That's another talk for another day. It is not something, frankly, I care much about. My team delivers services, right? We deliver the corporate website. We deliver the thing that makes the jobs actually show up on the website. Those are the things my team is responsible for. When I say the word artifact, what does that mean to people? Is there anybody that, like, how many people have heard the use of the word artifact? Okay. Is there anybody that thinks I'm crazy by saying the simplest artifact we can ship in the world is a tar ball? Anybody have a problem with that? So a tar ball, a cookbook, it is a packaged artifact. We care about the versioned, promotable thing. Which means we really do want to do continuous integration and delivery. I'm just going to say it now, if you are not merging to master, it's not continuous integration. You can run all your tests all day long on Jenkins. If that code isn't on master, it isn't continuously integrated. And delivery actually means it's in production somewhere. Crazy thought. Even if it's in production in QA. Because I don't know about the rest of you, but my acceptance environment, totally production environment, just production for someone else. It goes back to that point. We are talking about services and not code. Your code is no longer holy developers. I don't care that there's something broken on master. Well, I do. But if it gets to master, that's not the end of the world. Because the thing I care about is the artifact. Is that artifact something I can deploy? And if it's not, we need to throw up a big flag that says that artifact, it would be broke. Don't do anything with that. And we need to get to a point where every pull request or change request is shipable. We need to ship the thing. The goal is to get to as many small changes that go all the way out to production as we can. Because as we all know, the smaller the change, the easier it is to debug, right? If I go and deploy six months worth of changes, I just deployed six months worth of changes. And I don't know about you, but that scares me, the crap out, like holy God. A couple of useful tools. We're going to talk a little bit about delivery truck. How many delivery users do I have in the room right now? You already have it installed somewhere. Okay, cool. So, you've probably seen delivery truck, right? It is at the heart of our cookbook workflow. Essentially you can take this cookbook, use its recipes, and it will handle moving cookbooks through the pipeline for you. Little do people know it also has some facilities for moving your versions of the application that you're using through the pipeline. And that's probably also a good point. When I talk about moving a version, that doesn't mean we deploy the thing. That just means the version pinning, just so that we're super clear on that concept. And then there's delivery sugar, which is a neat cookbook that has a whole bunch of helper methods that are sugar on top of delivery, right? So there's, for example, one where you use it to go talk to the delivery's chef server to pull versions and do some stuff. Those live in delivery sugar. So let's talk about mechanics. The display is weird. Okay, so we're going to talk about phases and stages. So I'm going to walk through this real fast, just so that everybody has it. We have stages with phases inside of them. This is our verify build acceptance union rehearsal and delivery. In Lint, we run things to Lint our code. And I just want to be clear. Everything before acceptance is pre-artifact. So we're talking in terms of this is about the code. So we're linting the code. We're syntax checking the code. We are unit testing the code. That doesn't mean we're standing up to service and running tests against it, because that's bad. We're going to be as fast as possible, and functional tests come later. We do it again in build. So when that approve bit hits, we just merge to master. Let me say that again. When we hit the approve button, we have merged to master. There are two places where there are human gates. That is for a reason. We're not going to get into it now. But anytime you sit and think to yourself, oh, my God, we need to approve that one more time, don't. There are reasons why. And I'd love to talk some more about it, but why there are only two human gates. So when we get back into build, we've now merged to master. As anybody that's ever used any sort of version control system, you know that on occasion, you merge things. And the thing you got out at the other end is not what you thought you were going to get. So we rerun Lint syntax unit, because it's entirely possible that the code that came out the other end wasn't what you thought it was. Security. This is code security. It is not instance security or service security. It is code security. We'll give examples of that a little bit later. Quality. That's kind of a loaded term. And I think we understand that it needs to be there, but we don't have super great examples in many cases of what the right thing to do is there, depending on your language of choice. Publish. This is where you actually do the build. You build the thing. You build the artifact. In my case, tar balls, because I like tar balls. Or in the case of my cookbooks, I do a knife cookbook upload, because we upload cookbooks. We'll talk a little bit about this. Each stage is made up of phases. I think I did that right. I'm totally going to screw that up at some point today, because the words. You can skip phases, but not stages. If you're running, I legitimately have projects that are just HTML files. There's not even, you just make some changes. And we seriously skip unit, Linton syntax, because there's nothing to unit, Linton syntax. It's just go put some files on S3 and stand up some fastly config. Each phase is a collection of two independent chef runs. You run your default.rb in your build cookbook as a recipe, so your default recipe. That is going to be your setup recipe. You're going to handle, and I'll show examples of this, AWS creds. You might want to install some Ruby, because I love Ruby. If you're a PHP shop or Java shop, you're going to do that in that recipe. Then the second run is done as the debil the user, and it executes the phase name, recipe. So if we're in unit, it's going to run the unit recipe. If we're in Lint, it's going to run the Lint recipe. How am I doing on time? She probably moved slightly faster. So version promotion. So what we do essentially is we create a data bag item with the version and artifact information. So if I have version 1.5, where the heck do I get version 1.5? If it's a cookbook, we totally know just to go to the chef's server, right? That's easy. But if it's an application, do you have any artifact users in the house? Nexus? S3? Totally an S3 user. You've got to know where to go find the artifact that you actually want deployed. So what we're going to do is we're going to go take that information. So I always store a checksum because we want to verify that the thing we're supposed to be deploying is the thing that we're deploying. The location of said artifact. So usually it's an S3 URL. And any other metadata that's associated with that that's important because you may need it. I tend to drop the entire delivery environment in just so that I know how the state of the world when it was built. I'm just going to point it out here because we all kind of hit this. Secrets management is kind of an interesting use case or interesting situation in delivery right now. I'm sorry, in workflow right now. It's getting better, but it's not perfect. But for me, the way I handle this is my builders have the encrypted data bag secret on the build nodes. And I use that to encrypt my secrets and put them up in the cloud, or I'm sorry, into the chef's server. And then my actual nodes have the encrypted data bag secret as well and use that. My hope is that over the next year that I'll get a little bit better. We're going to do breaking apart of the app. And I'm just glossing over this because you can have an entire session on just breaking apart applications and understanding what it looks like. But the couple of questions you want to ask yourself are all the pieces related to the application. So you occasionally see applications where it's really three applications and one. We'll break that apart. Maybe there are shared pieces of the application. So we talked about being in an actual on-prem data center. You probably don't spin up a new load balancer for every single application. And if you do, I want to work for your company because you probably have lots and lots of money to have a F5 or net scaler for every single one of your applications. That'd be cool, though. That and it's probably not API accessible if you have to go over and rack something every time. That would be crazy. Is the database shared? I've worked in environments where the database is a shared thing and the applications that go talk to the database, like the database is itself an application. In other cases, we spin in MySQL instance or Postgres instance or Postgres cluster for every single application. It really depends on what you're doing. When we talk about dependencies, you need to understand them. If there are things that you can do something about, they're what we'll call operational concern. I'm sorry, you can't do anything about them. They're operational concerns. So if it's the VMware cluster, that's totally dependency. But you're not going to test whether or not the VMware cluster is up and running. Because if the VMware cluster is not up and running, we probably have a different problem than we shouldn't be having this conversation right now. Is it a build time or run time dependency? We're going to talk explicitly about run time dependencies as we move forward. What I mean by that is, does the service use it while it's running? So like libc, that's a bad example because it's like a service dependency. Anyway, when we talk about things, does this API talk to this other API? Well, if it does, it's probably a run time dependency. You should actually actively test code paths that verify that dependency that you've declared. If you can't test it, there's no reason to declare it. So important, we're emerging after verify. We're going to build for master. We're going to move artifacts, not code, through acceptance, union, rehearsal, and delivered. All right. So first we're going to talk about the service delivery canvas. We're going to start with the artifacts. And this will all make sense in a second when I show you this thing I call the service delivery canvas. It's a canvas, which means it is nonlinear. We all like to think about starting at the beginning and getting to the end. The reality, especially, it's a pipeline, right? Like you start at the beginning of the pipeline, you go through it, and you eventually end. Well, the canvas is not meant to work that way. The canvas is really, it's a document, it's an opportunity to think nonlinearly about your problem set. Identify the operational concerns as you go. I touched on these a little bit ago, but as you're building out your applications, understand what are operational concerns versus what are dependencies. So an operational concern might be the F5 device, because yeah, that's an operational concern. I am only concerned about the VIP for this thing. Maybe the operational concern is that, frankly, we don't actually ever launch features as part of the pipeline. Launching features is an operational concern because we tick on feature flags. That's an awesome way to roll, by the way. Identify the dependencies as you go. Once again, we're looking for runtime dependencies. We really want to be in a place where we can actually test the thing that we're depending on because we're responsible for doing that. There was a talk given by Jess Mink earlier in, or yesterday, as a matter of fact, that gives a little bit more detail around the dependency graph model inside of delivery. But think about this magic for just a second. You have six services. You tell the services what they depend on. Every time I deploy my application, the things that I told workflow that I depended on, they run their tests, too. So all of a sudden, we now have the ability to actually do things like microservices safely. So this is the canvas. Really simple. And this is the PowerPoint version, because it looks pretty. But this is the actual legit thing. Like I was in Palm Springs last week working through my talk, and I pulled this from my backpack and sat and wrote down with a pen and worked through piece by piece what an actual application would look like. And this is actually available at cweber.net delivery underscore canvas.pdf. Huge shout out to Mark Harrison, who actually made this look nice and omnigraphal, because I'm a manager and tend to use PowerPoint for things that shouldn't use PowerPoint for. So the original one was done in PowerPoint. He made it look really, really pretty in omnigraphal. And I may even be able to post the omnigraphal file. So let's talk about a Ruby app. Let's get into this. So really simple, right? We've got some DNS, a load balancer, and some instances. The stupid simple application. We've got Sinatra. There's no database. And just because we all like to have that mental model, it's run at Unicorn and Nginx. Cool. So we're going to start by figuring out what we're going to publish. Because once again, I told you at the end of the day what we care about is the artifact, what we care about is the service. I don't care about unit testing code at this point, because frankly, I care about the service. So what's going to get the service deployed? So let's start by like, let's build it. Let's take it, create a tar ball, create a cookbook. We want to get to that point where we are able to actually go see, did this even come up, right? And sometimes it's a proof of concept. We just need to get it into the pipeline and get it running. The other thing, right, is if you turn on Linting too early, you're going to spend all your time trying to figure out why RuboCop is blowing up instead of like shipping code. And sometimes that's good. And sometimes that's bad. But it really depends on what you're doing. So once again, we're provisioning EC2 instances, an elastic load balancer. We all kind of know how that works, right? I've got, I use Chef provisioning. You may use Terraform. It's all cool. Just pick the thing that makes the most sense to you. In the deploy phase. And once again, we're walking through this as we go, right? So we're going to go run the Chef on the nodes to install and or upgrade the app, right? So in this place, we're going to do things like, hey, there was a cookbook change. So now we're going to change the engineX config. Or hey, like our application actually changed. So we will do a Chef run, which will cause Unicorn to get bounced, that sort of thing. And then Smoke. This is the simplest. You have to remember Smoke should be super brain dead simple. You just want to check, did it work? So did I get a 200 at a particular path? In my case, I use a lot of SAML-based applications. So the first thing I ask is, did I get a 302? Does it redirect? Because I need to auth. And that's a huge awesome Smoke test, right? If I get a 200 on a page that should be sending me to go get authenticated, I want to know that and blow up like that. And then Functional. Like Selenium, if it's an API, maybe you're pulling down some JSON and making sense of the JSON. Like it all is about what makes sense to you. From there, I dive in and it's Ruby, right? So we're going to write some mini-test. It's a cookbook, right? Chef spec. We'll run some Winting. So RuboCop Food Critic. RuboCop works for both our Ruby code and for our cookbook code. Food Critic. How many people are familiar with RuboCop and Food Critic? That is awesome. I love to see that. So here's the thing, right? Like, if cookstyle is your thing, you should totally do that. My team actually just rolls straight RuboCop because we write a ton of Ruby code outside of like ChefLand. Ruby-C. I've got some great stories about this in a few minutes here. But we're just going to check to see, hey, is the syntax right? Like, we want to catch this as soon as possible. And then finally, in the security phase, we're actually just going to make sure that, is Ruby, we're going to make sure that there are no open CBEs against the gems that are in our bundle. If you are running Ruby stuff and in production, you should totally be using Bundler audit because it will tell you, hey, by the way, that sample gem you're using, there's totally an open CBE against it. You should fix that. So let's use a more complex example. This looks a little bit more like our normal applications, right? There's some DNS. There's three layers of caching because, of course, you have to have three layers of caching. We've got the load balancer. We've got the CDN. We've got Redis, Postgres. So what might that look like? As you can tell, not a whole lot changed. But we can look across and go, oh, wow, we're provisioning a lot more things. We should think about that. The canvas gives you the opportunity to, at a glance, get a feel for what you should be doing in your phases before you even write your code. Because we want to get to a place where, before we sit down and go write build cookbooks, we have an idea of what should go where. And I talked a little bit about this a few minutes ago. You work in a real data center. You may not have the ability to do the thing in the cloud. So maybe you're deploying a PHP application. My suggestion, this is totally not paid for, but Infoblox, you can actually hit it with an API. In fact, I think they now have a REST API. Back in my day, it was all Perl. So you wrote some Perl to do the thing. But you can use Infoblox to spin up your DNS and handle IP address like assignment, that sort of thing. Load balancers, you're probably going to talk about a VIP instead of the actual load balancers we discussed earlier. Stand up some PHP instances, some MySQL instances, and some Mcache. And then as VMware instances. And then we need some NFS. So why not do it with Icelon, right? That's API accessible. The key for me is we all have to understand I don't have to have AWS. I don't have to have Google to get this today, to get to this point. The ultimate goal is that when you hit approve and you hit acceptance, the entire thing comes up on its own. When you hit deliver, the application comes into being. You shouldn't have to spend your time going, oh, it's a production deploy. So run through the checklist. Did we do the thing? Did we do the thing as we're deploying it? Like really, what we want to do is actually know because we ran through the checklist in the code to verify that the code is compliant and does the right things instead of whether or not we hit the checklist. And as you standardize your code bases, you get to a point where you stop caring about that because it's encapsulated in the code. This is what that looks like, right? Same general ideas. We've got a lot more operational concerns because the other size I probably should just put AWS because, yeah. But we now care about our F5 cluster and all that stuff. So I'm sure y'all would like to see some code. So we're going to look at some code. This is just so that we have a starting point. This is Chef Web Purchase, an application, a CR of wonderful naming scheme. It's a simple Sinatra app that handles purchases for one-off services. So if you'd like one of our solutions architects to spend a day with you remotely to talk about all things Chef, whether it's to give you advice on how to build cookbooks, cultural questions that you can buy up to three non-contiguous days online on the Internet. In fact, if you go to that website right now, you can totally push those buttons in and hit the credit card button and enter your credit card and I'll get email that says you bought something. So this is a service. We all have things where we accept money and whatnot. So this, as we started, is our Canvas, right? This is how the application gets built. We're going to do unit testing. We've got some lint, some syntax. I didn't fill these all in at the first go around, right? When I first deployed this, we totally didn't have lint enabled. In fact, there's actually a commit on the repo that says make C Webber not a liar because I turned on a bunch of these things to make sure that I wasn't lying when I gave this talk. So let's actually go look at some code. And I just want to point out, like I'm skipping functional right now. I don't, the amount of work it takes to do functional testing with things like Salesforce and Avalara and Stripe, like it's just not worth it for something that I don't know if it's going to make any money at all yet. So at this point, we're just going to skip functional testing. And if it breaks, my bad, it's totally an experiment right now. We'd love to see it successful. Like if you all want to go spend $2,000 to have a day of Solutions Team, I would love you all right now because that would be awesome. So this is my entire default RB recipe. It used to be super longer because back in the day, we didn't have things like Slack integration. We didn't have GitHub integration. Like those were things. It's now gotten really simple. You do a default for delivery truck, which just basically sets up the environment. We have AWS Pre-rex. So for those of you that know about interacting with AWS, you know that you have to have creds on the box. You know that you have to have the actual AWS CLI if that's how you're going to interact with it. There are a lot of little things you need to be useful, so we have a recipe that does that. We also install Ruby the same way that we install Ruby on the actual node because crazy thought, if I can install Ruby the same way in two places, which seems like a miracle sometimes, it's probably going to be more effective, right? So my unit recipe, and I've got to hustle, we're going to do the delivery truck unit test. So that's just going to run unit testing against our cookbook, right? We want to actually care about what the cookbook does. We're going to install our dependencies from Bundler. It's an application that uses.env, so I'm going to have to link my.env file in place because that's kind of useful. And then we've got a little helper method here to run rig test. Same idea, right? We linked the cookbook. We install our Bundler dependencies. We run Rubikop-d, which is to say, I don't like to have to go figure out what in God's name Rubikop was complaining about. Check for syntax. And I mentioned earlier that whole idea of Ruby-c. I initially did that with a find, only to find out that find always returns zero because it found things instead of the thing that was inside broke. Once again, install my dependencies. And Bundler on it, check the bundle. We've standardized, and I'm happy to show anybody the code inside of this, but we are now at a point that I don't think about how a cluster gets stood up. It's what, three, four lines there. That stands up the size number of EC2 instances, and ELB terminates SSL and sets the run list as appropriate. And this goes out to those nodes and tells them to do a chef run. I told you, I'm just checking the status code. That path slash architect days is what matters to me. Did it return 200? A couple of useful things to know about. There is a cookbooks directory. If you stick a cookbook in there, delivery truck will just work. It's beautiful. The config.json is where your actual configuration code goes. You want to read up on it online, but it gives you the ability to do things like skip phases and specify the search for the build nodes. And then I'm going to say this to tongue in cheek.delivery slash build cookbook is kind of the standard. It totally isn't, because there isn't actually a standard. But where my team normally puts our build cookbooks is in.delivery slash build cookbook, so we're not polluting the main part of the namespace. And finally, a couple of just real brief thoughts. Take advantage of custom resources. They will make your life better. Helper methods are awesome, so you can drop things that you use throughout the cookbook all over the place in the library's directory, and it makes your life better. And finally, put shared things in shared cookbooks. So you saw that CIA infra, CIA delivery. That's where those come from. So with three minutes left, that's my talk. What can I answer for you? So the question is, if I'm only going to do something in a certain phase, should I switch on it? So if I'm in unit Linton syntax, I probably don't need Terraform. The answer really becomes it depends on what your coding standards allow for. It also depends on what you want to do. So at this point, build nodes are shared. And the first time it runs, it basically warms the cache. It just makes sure it is there. With Terraform is a great example. If I don't have to install this root, I'm not going to. So I'm just going to put it in as the build user. And that's really what I use as the dint differentiator. I don't tend to add the switches because it adds complexity to my default recipes. But that's me personally. The question is, where can I go to find out more about delivery truck and delivery sugar? So there is info in the docs. So if you search in the docs for delivery truck and delivery sugar, additionally, the cookbooks are up on GitHub. I don't remember. Are they in the Chef cookbooks org or the ops cookbooks org? Chef cookbooks? Awesome. I'll sling here. So yeah, GitHub. Not going to lie, I'm of the belief that the best thing you can do when you run into problems is go read the source code. So I totally go read lots of source code. So with that said, am I at zero minutes? Awesome. Thank you very much. I will be down at the Chef booth if you have any questions after this talk. Thank you very much.
 All right, so has everybody started to wake up from the lunch coma or are we just going  to kind of like take a nap?  Because I'm going to try and have enough energy to keep us going, but I totally understand  if you just like, you know, over because, like, yeah, lunch was wonderful.  All right, so we'll start with a little bit of where did it go?  Oh, that's wonderful.  We'll just use the button.  Or maybe we won't.  There we go.  All right, so let's talk a little bit about who I am or who am I?  I'm the person that was behind.  How many people were at ChefConf last year?  So if you watch the video on stage, they delivered delivery using delivery on stage at ChefConf.  I was the person in the back super heavily stressed because they were doing that live  in on stage and I was responsible for writing the build cookbook that made all of that happen.  To the point of there was actually a little Sinatra app written off to the side that gave  us the ability to like cut over fastly to a pre-prepped thing just in case because we're  all ops people, right?  Like you got to have a backup plan.  But that was legit.  We actually did deliver delivery on stage at ChefConf using delivery now automate workflow.  I'm the author of about 20 or so build cookbooks and that number just keeps increasing because  my team keeps shipping software.  The important part to really take in is I'm not standing up here as a developer of automate.  In fact, I'm customer really patient zero.  I'm going to be the person that goes to the delivery team and is like, guys, can we fix  this thing because it kind of hurts.  The delivery team, I'm going to use that word.  The workflow team has been super responsive in the number of opportunities we've had to  dock food our own stuff and actually fix things before they got out to customers.  It's just been fantastic.  With that said, I'm the engineering manager for the CIA team that has nothing to do with  intelligence.  We have everything to do with our corporate infrastructure and applications, which when  we get into some of the stuff later, you'll understand why I say it doesn't have to do  with intelligence.  So what are we going to cover today?  We're going to cover the prerequisites and assumptions, some concepts, vocabulary, prerequisites,  and these are kind of the things I think are prerequisites.  The mechanics of how all of this works, the actual service delivery canvas, yes, it's  actually a thing.  Some examples using that canvas.  Then I'm going to show you some actual code that runs actual things at Chef.  So starting with prerequisites and assumptions because we always have to make assumptions.  I'm going to assume you're doing the DevOps and really all of my code assumes you're  doing the DevOps.  Now as we all know, that's kind of a loaded term.  What does it actually mean to do the DevOps?  I'm going to use some very specific things that I expect of you.  I think that the workflow that I'm going to present to you really does require.  The app dev teams and the ops teams are able to use Git.  It's workflow.  We're opinionated.  One of the things we're opinionated is you can use any one of the version control systems  as long as they are Git.  Very specifically deliveries, Git hubs or Bitbuckets because those are the ones we support today.  But the team has to be able to use Git.  If you can't use Git, this just isn't going to work because the system kind of depends  on it.  Each group is willing to see the work the other is doing.  This is super, super important because I'm going to ask you to take your ops infrastructure  code that relates to the application that's being deployed and the application code and  put them in the same repo.  You've got to work with the rest of your organization.  You've got to work with your app teams.  You've got to work with your ops teams.  It is all about being as a single team because how many people have had that thing where  it's like, okay, oh my God, we have to coordinate this change across the cookbook and the app  at the same time because otherwise everything is going to go wrong and how often does that  work well?  Instead, I can make a code change and a cookbook change and they get deployed as the same change  set because they really are the same change set.  Both groups have to care about production.  I usually start, but I'm going to do it right now.  How many people in the room identify as sys admins, operations engineers, that sort of  thing?  How many people are enrolled?  How many people identify as developers?  That, right?  Totally.  Do I have any QA folks in the house?  DBAs?  I've got to give it up for my DBAs because that's a hard job.  You have to be in a place where everybody is talking and you all have to care about the  end result because I'm going to say some super blasphemous things in a few minutes and it  will really make sense why we all have to care about the service and production.  In fact, I'm going to go so far as to say the only thing that matters is the service  in production.  The source code for the application, and I touched on this a second ago, but the application,  the cookbook that deploys the application and the cookbook for building the application  all need to live in the same repo in harmony because it's just the only same way to operate  in my not-so-humble opinion.  I should probably also mention these are my views of how my team functions.  That doesn't necessarily mean they are the views of how Chef thinks you should function  because there's a completely different thing between what my team does and what we say  is the right thing to do.  But I'm totally going to tell you this is totally the right thing to do.  We all have to start from a place of an API.  I want you to deliver the entire service.  How many people think the service is some application code?  I sure don't.  It doesn't look like anybody else.  I just got blank stares.  Like, what are you talking about, dude?  Because, right, it's like a load balancer.  There's probably some storage involved.  Hey, we probably got to have compute instances.  I actually have services that I run that don't have compute.  It's kind of cool.  There might be some CDN involved.  You have to be in a place where the majority of your stuff is API accessible.  It doesn't all have to be.  But for everything that's not in the pipeline, the more opportunity you have for things to  go horribly wrong.  So the more you do it in the pipeline as part of the pipeline makes a huge difference.  So for me, what the minimum thing has to be is that we can provision new compute, whether  that's VMs, instances, you know, pick your flavor, right?  Open stack, VMware, AWS, Azure, Google, you can provision a thing.  Most of us don't just like stand up an instance and point stuff at it.  There's usually some sort of load balancer stuff.  You really should be able to spin or make the load balancer change necessary to spin  up that cluster of servers.  And also, how many people have API access to change their DNS?  That makes me sad.  So how many people are in the cloud right now?  How about people on prem data centers?  Okay.  I've got suggestions.  I should totally, yeah, we'll talk about that later.  Okay.  So we're going to talk concepts, vocabulary, you know, words I'm going to use.  We are delivering a service, a thing that you hit.  What we are not delivering is a packaged binary that someone else downloads and does something  with.  That's another talk for another day.  It is not something, frankly, I care much about.  My team delivers services, right?  We deliver the corporate website.  We deliver the thing that makes the jobs actually show up on the website.  Those are the things my team is responsible for.  When I say the word artifact, what does that mean to people?  Is there anybody that, like, how many people have heard the use of the word artifact?  Okay.  Is there anybody that thinks I'm crazy by saying the simplest artifact we can ship in  the world is a tar ball?  Anybody have a problem with that?  So a tar ball, a cookbook, it is a packaged artifact.  We care about the versioned, promotable thing.  Which means we really do want to do continuous integration and delivery.  I'm just going to say it now, if you are not merging to master, it's not continuous integration.  You can run all your tests all day long on Jenkins.  If that code isn't on master, it isn't continuously integrated.  And delivery actually means it's in production somewhere.  Crazy thought.  Even if it's in production in QA.  Because I don't know about the rest of you, but my acceptance environment, totally production  environment, just production for someone else.  It goes back to that point.  We are talking about services and not code.  Your code is no longer holy developers.  I don't care that there's something broken on master.  Well, I do.  But if it gets to master, that's not the end of the world.  Because the thing I care about is the artifact.  Is that artifact something I can deploy?  And if it's not, we need to throw up a big flag that says that artifact, it would be  broke.  Don't do anything with that.  And we need to get to a point where every pull request or change request is shipable.  We need to ship the thing.  The goal is to get to as many small changes that go all the way out to production as we  can.  Because as we all know, the smaller the change, the easier it is to debug, right?  If I go and deploy six months worth of changes, I just deployed six months worth of changes.  And I don't know about you, but that scares me, the crap out, like holy God.  A couple of useful tools.  We're going to talk a little bit about delivery truck.  How many delivery users do I have in the room right now?  You already have it installed somewhere.  Okay, cool.  So, you've probably seen delivery truck, right?  It is at the heart of our cookbook workflow.  Essentially you can take this cookbook, use its recipes, and it will handle moving cookbooks  through the pipeline for you.  Little do people know it also has some facilities for moving your versions of the application  that you're using through the pipeline.  And that's probably also a good point.  When I talk about moving a version, that doesn't mean we deploy the thing.  That just means the version pinning, just so that we're super clear on that concept.  And then there's delivery sugar, which is a neat cookbook that has a whole bunch of  helper methods that are sugar on top of delivery, right?  So there's, for example, one where you use it to go talk to the delivery's chef server  to pull versions and do some stuff.  Those live in delivery sugar.  So let's talk about mechanics.  The display is weird.  Okay, so we're going to talk about phases and stages.  So I'm going to walk through this real fast, just so that everybody has it.  We have stages with phases inside of them.  This is our verify build acceptance union rehearsal and delivery.  In Lint, we run things to Lint our code.  And I just want to be clear.  Everything before acceptance is pre-artifact.  So we're talking in terms of this is about the code.  So we're linting the code.  We're syntax checking the code.  We are unit testing the code.  That doesn't mean we're standing up to service and running tests against it, because that's  bad.  We're going to be as fast as possible, and functional tests come later.  We do it again in build.  So when that approve bit hits, we just merge to master.  Let me say that again.  When we hit the approve button, we have merged to master.  There are two places where there are human gates.  That is for a reason.  We're not going to get into it now.  But anytime you sit and think to yourself, oh, my God, we need to approve that one more  time, don't.  There are reasons why.  And I'd love to talk some more about it, but why there are only two human gates.  So when we get back into build, we've now merged to master.  As anybody that's ever used any sort of version control system, you know that on occasion,  you merge things.  And the thing you got out at the other end is not what you thought you were going to get.  So we rerun Lint syntax unit, because it's entirely possible that the code that came  out the other end wasn't what you thought it was.  Security.  This is code security.  It is not instance security or service security.  It is code security.  We'll give examples of that a little bit later.  Quality.  That's kind of a loaded term.  And I think we understand that it needs to be there, but we don't have super great examples  in many cases of what the right thing to do is there, depending on your language of choice.  Publish.  This is where you actually do the build.  You build the thing.  You build the artifact.  In my case, tar balls, because I like tar balls.  Or in the case of my cookbooks, I do a knife cookbook upload, because we upload cookbooks.  We'll talk a little bit about this.  Each stage is made up of phases.  I think I did that right.  I'm totally going to screw that up at some point today, because the words.  You can skip phases, but not stages.  If you're running, I legitimately have projects that are just HTML files.  There's not even, you just make some changes.  And we seriously skip unit, Linton syntax, because there's nothing to unit, Linton syntax.  It's just go put some files on S3 and stand up some fastly config.  Each phase is a collection of two independent chef runs.  You run your default.rb in your build cookbook as a recipe, so your default recipe.  That is going to be your setup recipe.  You're going to handle, and I'll show examples of this, AWS creds.  You might want to install some Ruby, because I love Ruby.  If you're a PHP shop or Java shop, you're going to do that in that recipe.  Then the second run is done as the debil the user, and it executes the phase name, recipe.  So if we're in unit, it's going to run the unit recipe.  If we're in Lint, it's going to run the Lint recipe.  How am I doing on time?  She probably moved slightly faster.  So version promotion.  So what we do essentially is we create a data bag item with the version and artifact information.  So if I have version 1.5, where the heck do I get version 1.5?  If it's a cookbook, we totally know just to go to the chef's server, right?  That's easy.  But if it's an application, do you have any artifact users in the house?  Nexus?  S3?  Totally an S3 user.  You've got to know where to go find the artifact that you actually want deployed.  So what we're going to do is we're going to go take that information.  So I always store a checksum because we want to verify that the thing we're supposed to  be deploying is the thing that we're deploying.  The location of said artifact.  So usually it's an S3 URL.  And any other metadata that's associated with that that's important because you may need  it.  I tend to drop the entire delivery environment in just so that I know how the state of the  world when it was built.  I'm just going to point it out here because we all kind of hit this.  Secrets management is kind of an interesting use case or interesting situation in delivery  right now.  I'm sorry, in workflow right now.  It's getting better, but it's not perfect.  But for me, the way I handle this is my builders have the encrypted data bag secret on the build  nodes.  And I use that to encrypt my secrets and put them up in the cloud, or I'm sorry, into  the chef's server.  And then my actual nodes have the encrypted data bag secret as well and use that.  My hope is that over the next year that I'll get a little bit better.  We're going to do breaking apart of the app.  And I'm just glossing over this because you can have an entire session on just breaking  apart applications and understanding what it looks like.  But the couple of questions you want to ask yourself are all the pieces related to the  application.  So you occasionally see applications where it's really three applications and one.  We'll break that apart.  Maybe there are shared pieces of the application.  So we talked about being in an actual on-prem data center.  You probably don't spin up a new load balancer for every single application.  And if you do, I want to work for your company because you probably have lots and lots of  money to have a F5 or net scaler for every single one of your applications.  That'd be cool, though.  That and it's probably not API accessible if you have to go over and rack something  every time.  That would be crazy.  Is the database shared?  I've worked in environments where the database is a shared thing and the applications that  go talk to the database, like the database is itself an application.  In other cases, we spin in MySQL instance or Postgres instance or Postgres cluster for  every single application.  It really depends on what you're doing.  When we talk about dependencies, you need to understand them.  If there are things that you can do something about, they're what we'll call operational  concern.  I'm sorry, you can't do anything about them.  They're operational concerns.  So if it's the VMware cluster, that's totally dependency.  But you're not going to test whether or not the VMware cluster is up and running.  Because if the VMware cluster is not up and running, we probably have a different problem  than we shouldn't be having this conversation right now.  Is it a build time or run time dependency?  We're going to talk explicitly about run time dependencies as we move forward.  What I mean by that is, does the service use it while it's running?  So like libc, that's a bad example because it's like a service dependency.  Anyway, when we talk about things, does this API talk to this other API?  Well, if it does, it's probably a run time dependency.  You should actually actively test code paths that verify that dependency that you've declared.  If you can't test it, there's no reason to declare it.  So important, we're emerging after verify.  We're going to build for master.  We're going to move artifacts, not code, through acceptance, union, rehearsal, and delivered.  All right.  So first we're going to talk about the service delivery canvas.  We're going to start with the artifacts.  And this will all make sense in a second when I show you this thing I call the service  delivery canvas.  It's a canvas, which means it is nonlinear.  We all like to think about starting at the beginning and getting to the end.  The reality, especially, it's a pipeline, right?  Like you start at the beginning of the pipeline, you go through it, and you eventually end.  Well, the canvas is not meant to work that way.  The canvas is really, it's a document, it's an opportunity to think nonlinearly about  your problem set.  Identify the operational concerns as you go.  I touched on these a little bit ago, but as you're building out your applications, understand  what are operational concerns versus what are dependencies.  So an operational concern might be the F5 device, because yeah, that's an operational  concern.  I am only concerned about the VIP for this thing.  Maybe the operational concern is that, frankly, we don't actually ever launch features as  part of the pipeline.  Launching features is an operational concern because we tick on feature flags.  That's an awesome way to roll, by the way.  Identify the dependencies as you go.  Once again, we're looking for runtime dependencies.  We really want to be in a place where we can actually test the thing that we're depending  on because we're responsible for doing that.  There was a talk given by Jess Mink earlier in, or yesterday, as a matter of fact, that  gives a little bit more detail around the dependency graph model inside of delivery.  But think about this magic for just a second.  You have six services.  You tell the services what they depend on.  Every time I deploy my application, the things that I told workflow that I depended on, they  run their tests, too.  So all of a sudden, we now have the ability to actually do things like microservices safely.  So this is the canvas.  Really simple.  And this is the PowerPoint version, because it looks pretty.  But this is the actual legit thing.  Like I was in Palm Springs last week working through my talk, and I pulled this from my  backpack and sat and wrote down with a pen and worked through piece by piece what an  actual application would look like.  And this is actually available at cweber.net delivery underscore canvas.pdf.  Huge shout out to Mark Harrison, who actually made this look nice and omnigraphal, because  I'm a manager and tend to use PowerPoint for things that shouldn't use PowerPoint for.  So the original one was done in PowerPoint.  He made it look really, really pretty in omnigraphal.  And I may even be able to post the omnigraphal file.  So let's talk about a Ruby app.  Let's get into this.  So really simple, right?  We've got some DNS, a load balancer, and some instances.  The stupid simple application.  We've got Sinatra.  There's no database.  And just because we all like to have that mental model, it's run at Unicorn and Nginx.  Cool.  So we're going to start by figuring out what we're going to publish.  Because once again, I told you at the end of the day what we care about is the artifact,  what we care about is the service.  I don't care about unit testing code at this point, because frankly, I care about the service.  So what's going to get the service deployed?  So let's start by like, let's build it.  Let's take it, create a tar ball, create a cookbook.  We want to get to that point where we are able to actually go see, did this even come  up, right?  And sometimes it's a proof of concept.  We just need to get it into the pipeline and get it running.  The other thing, right, is if you turn on Linting too early, you're going to spend all  your time trying to figure out why RuboCop is blowing up instead of like shipping code.  And sometimes that's good.  And sometimes that's bad.  But it really depends on what you're doing.  So once again, we're provisioning EC2 instances, an elastic load balancer.  We all kind of know how that works, right?  I've got, I use Chef provisioning.  You may use Terraform.  It's all cool.  Just pick the thing that makes the most sense to you.  In the deploy phase.  And once again, we're walking through this as we go, right?  So we're going to go run the Chef on the nodes to install and or upgrade the app, right?  So in this place, we're going to do things like, hey, there was a cookbook change.  So now we're going to change the engineX config.  Or hey, like our application actually changed.  So we will do a Chef run, which will cause Unicorn to get bounced, that sort of thing.  And then Smoke.  This is the simplest.  You have to remember Smoke should be super brain dead simple.  You just want to check, did it work?  So did I get a 200 at a particular path?  In my case, I use a lot of SAML-based applications.  So the first thing I ask is, did I get a 302?  Does it redirect?  Because I need to auth.  And that's a huge awesome Smoke test, right?  If I get a 200 on a page that should be sending me to go get authenticated, I want to know  that and blow up like that.  And then Functional.  Like Selenium, if it's an API, maybe you're pulling down some JSON and making sense of  the JSON.  Like it all is about what makes sense to you.  From there, I dive in and it's Ruby, right?  So we're going to write some mini-test.  It's a cookbook, right?  Chef spec.  We'll run some Winting.  So RuboCop Food Critic.  RuboCop works for both our Ruby code and for our cookbook code.  Food Critic.  How many people are familiar with RuboCop and Food Critic?  That is awesome.  I love to see that.  So here's the thing, right?  Like, if cookstyle is your thing, you should totally do that.  My team actually just rolls straight RuboCop because we write a ton of Ruby code outside  of like ChefLand.  Ruby-C.  I've got some great stories about this in a few minutes here.  But we're just going to check to see, hey, is the syntax right?  Like, we want to catch this as soon as possible.  And then finally, in the security phase, we're actually just going to make sure that, is  Ruby, we're going to make sure that there are no open CBEs against the gems that are  in our bundle.  If you are running Ruby stuff and in production, you should totally be using Bundler audit  because it will tell you, hey, by the way, that sample gem you're using, there's totally  an open CBE against it.  You should fix that.  So let's use a more complex example.  This looks a little bit more like our normal applications, right?  There's some DNS.  There's three layers of caching because, of course, you have to have three layers of caching.  We've got the load balancer.  We've got the CDN.  We've got Redis, Postgres.  So what might that look like?  As you can tell, not a whole lot changed.  But we can look across and go, oh, wow, we're provisioning a lot more things.  We should think about that.  The canvas gives you the opportunity to, at a glance, get a feel for what you should  be doing in your phases before you even write your code.  Because we want to get to a place where, before we sit down and go write build cookbooks,  we have an idea of what should go where.  And I talked a little bit about this a few minutes ago.  You work in a real data center.  You may not have the ability to do the thing in the cloud.  So maybe you're deploying a PHP application.  My suggestion, this is totally not paid for, but Infoblox, you can actually hit it with  an API.  In fact, I think they now have a REST API.  Back in my day, it was all Perl.  So you wrote some Perl to do the thing.  But you can use Infoblox to spin up your DNS and handle IP address like assignment, that  sort of thing.  Load balancers, you're probably going to talk about a VIP instead of the actual load balancers  we discussed earlier.  Stand up some PHP instances, some MySQL instances, and some Mcache.  And then as VMware instances.  And then we need some NFS.  So why not do it with Icelon, right?  That's API accessible.  The key for me is we all have to understand I don't have to have AWS.  I don't have to have Google to get this today, to get to this point.  The ultimate goal is that when you hit approve and you hit acceptance, the entire thing comes  up on its own.  When you hit deliver, the application comes into being.  You shouldn't have to spend your time going, oh, it's a production deploy.  So run through the checklist.  Did we do the thing?  Did we do the thing as we're deploying it?  Like really, what we want to do is actually know because we ran through the checklist  in the code to verify that the code is compliant and does the right things instead of whether  or not we hit the checklist.  And as you standardize your code bases, you get to a point where you stop caring about  that because it's encapsulated in the code.  This is what that looks like, right?  Same general ideas.  We've got a lot more operational concerns because the other size I probably should just  put AWS because, yeah.  But we now care about our F5 cluster and all that stuff.  So I'm sure y'all would like to see some code.  So we're going to look at some code.  This is just so that we have a starting point.  This is Chef Web Purchase, an application, a CR of wonderful naming scheme.  It's a simple Sinatra app that handles purchases for one-off services.  So if you'd like one of our solutions architects to spend a day with you remotely to talk about  all things Chef, whether it's to give you advice on how to build cookbooks, cultural  questions that you can buy up to three non-contiguous days online on the Internet.  In fact, if you go to that website right now, you can totally push those buttons in and  hit the credit card button and enter your credit card and I'll get email that says you  bought something.  So this is a service.  We all have things where we accept money and whatnot.  So this, as we started, is our Canvas, right?  This is how the application gets built.  We're going to do unit testing.  We've got some lint, some syntax.  I didn't fill these all in at the first go around, right?  When I first deployed this, we totally didn't have lint enabled.  In fact, there's actually a commit on the repo that says make C Webber not a liar because  I turned on a bunch of these things to make sure that I wasn't lying when I gave this  talk.  So let's actually go look at some code.  And I just want to point out, like I'm skipping functional right now.  I don't, the amount of work it takes to do functional testing with things like Salesforce  and Avalara and Stripe, like it's just not worth it for something that I don't know if  it's going to make any money at all yet.  So at this point, we're just going to skip functional testing.  And if it breaks, my bad, it's totally an experiment right now.  We'd love to see it successful.  Like if you all want to go spend $2,000 to have a day of Solutions Team, I would love  you all right now because that would be awesome.  So this is my entire default RB recipe.  It used to be super longer because back in the day, we didn't have things like Slack  integration.  We didn't have GitHub integration.  Like those were things.  It's now gotten really simple.  You do a default for delivery truck, which just basically sets up the environment.  We have AWS Pre-rex.  So for those of you that know about interacting with AWS, you know that you have to have creds  on the box.  You know that you have to have the actual AWS CLI if that's how you're going to interact  with it.  There are a lot of little things you need to be useful, so we have a recipe that does  that.  We also install Ruby the same way that we install Ruby on the actual node because crazy thought,  if I can install Ruby the same way in two places, which seems like a miracle sometimes,  it's probably going to be more effective, right?  So my unit recipe, and I've got to hustle, we're going to do the delivery truck unit  test.  So that's just going to run unit testing against our cookbook, right?  We want to actually care about what the cookbook does.  We're going to install our dependencies from Bundler.  It's an application that uses.env, so I'm going to have to link my.env file in place  because that's kind of useful.  And then we've got a little helper method here to run rig test.  Same idea, right?  We linked the cookbook.  We install our Bundler dependencies.  We run Rubikop-d, which is to say, I don't like to have to go figure out what in God's  name Rubikop was complaining about.  Check for syntax.  And I mentioned earlier that whole idea of Ruby-c.  I initially did that with a find, only to find out that find always returns zero because  it found things instead of the thing that was inside broke.  Once again, install my dependencies.  And Bundler on it, check the bundle.  We've standardized, and I'm happy to show anybody the code inside of this, but we are  now at a point that I don't think about how a cluster gets stood up.  It's what, three, four lines there.  That stands up the size number of EC2 instances, and ELB terminates SSL and sets the run list  as appropriate.  And this goes out to those nodes and tells them to do a chef run.  I told you, I'm just checking the status code.  That path slash architect days is what matters to me.  Did it return 200?  A couple of useful things to know about.  There is a cookbooks directory.  If you stick a cookbook in there, delivery truck will just work.  It's beautiful.  The config.json is where your actual configuration code goes.  You want to read up on it online, but it gives you the ability to do things like skip phases  and specify the search for the build nodes.  And then I'm going to say this to tongue in cheek.delivery slash build cookbook is kind  of the standard.  It totally isn't, because there isn't actually a standard.  But where my team normally puts our build cookbooks is in.delivery slash build cookbook, so we're  not polluting the main part of the namespace.  And finally, a couple of just real brief thoughts.  Take advantage of custom resources.  They will make your life better.  Helper methods are awesome, so you can drop things that you use throughout the cookbook  all over the place in the library's directory, and it makes your life better.  And finally, put shared things in shared cookbooks.  So you saw that CIA infra, CIA delivery.  That's where those come from.  So with three minutes left, that's my talk.  What can I answer for you?  So the question is, if I'm only going to do something in a certain phase, should I switch  on it?  So if I'm in unit Linton syntax, I probably don't need Terraform.  The answer really becomes it depends on what your coding standards allow for.  It also depends on what you want to do.  So at this point, build nodes are shared.  And the first time it runs, it basically warms the cache.  It just makes sure it is there.  With Terraform is a great example.  If I don't have to install this root, I'm not going to.  So I'm just going to put it in as the build user.  And that's really what I use as the dint differentiator.  I don't tend to add the switches because it adds complexity to my default recipes.  But that's me personally.  The question is, where can I go to find out more about delivery truck and delivery sugar?  So there is info in the docs.  So if you search in the docs for delivery truck and delivery sugar, additionally, the  cookbooks are up on GitHub.  I don't remember.  Are they in the Chef cookbooks org or the ops cookbooks org?  Chef cookbooks?  Awesome.  I'll sling here.  So yeah, GitHub.  Not going to lie, I'm of the belief that the best thing you can do when you run into problems  is go read the source code.  So I totally go read lots of source code.  So with that said, am I at zero minutes?  Awesome.  Thank you very much.  I will be down at the Chef booth if you have any questions after this talk.  Thank you very much.
Build_Cookbooks_and_The_Service_Delivery_Canvas_0_131.png Build_Cookbooks_and_The_Service_Delivery_Canvas_132_779.png Build_Cookbooks_and_The_Service_Delivery_Canvas_780_4475.png Build_Cookbooks_and_The_Service_Delivery_Canvas_4476_12359.png Build_Cookbooks_and_The_Service_Delivery_Canvas_12360_12551.png Build_Cookbooks_and_The_Service_Delivery_Canvas_12552_18491.png Build_Cookbooks_and_The_Service_Delivery_Canvas_18492_18587.png Build_Cookbooks_and_The_Service_Delivery_Canvas_18588_30875.png Build_Cookbooks_and_The_Service_Delivery_Canvas_30876_30959.png Build_Cookbooks_and_The_Service_Delivery_Canvas_30960_33875.png Build_Cookbooks_and_The_Service_Delivery_Canvas_33876_41927.png Build_Cookbooks_and_The_Service_Delivery_Canvas_41928_47243.png Build_Cookbooks_and_The_Service_Delivery_Canvas_47244_49019.png Build_Cookbooks_and_The_Service_Delivery_Canvas_49020_55235.png Build_Cookbooks_and_The_Service_Delivery_Canvas_55236_55295.png Build_Cookbooks_and_The_Service_Delivery_Canvas_55296_55415.png Build_Cookbooks_and_The_Service_Delivery_Canvas_55416_55463.png Build_Cookbooks_and_The_Service_Delivery_Canvas_55464_55511.png Build_Cookbooks_and_The_Service_Delivery_Canvas_55512_55559.png Build_Cookbooks_and_The_Service_Delivery_Canvas_55560_55619.png Build_Cookbooks_and_The_Service_Delivery_Canvas_55620_55691.png Build_Cookbooks_and_The_Service_Delivery_Canvas_55692_55883.png Build_Cookbooks_and_The_Service_Delivery_Canvas_55884_55931.png Build_Cookbooks_and_The_Service_Delivery_Canvas_55932_56267.png Build_Cookbooks_and_The_Service_Delivery_Canvas_56268_56387.png Build_Cookbooks_and_The_Service_Delivery_Canvas_56388_56435.png Build_Cookbooks_and_The_Service_Delivery_Canvas_56436_56519.png Build_Cookbooks_and_The_Service_Delivery_Canvas_56520_56663.png Build_Cookbooks_and_The_Service_Delivery_Canvas_56664_56711.png Build_Cookbooks_and_The_Service_Delivery_Canvas_56712_56759.png Build_Cookbooks_and_The_Service_Delivery_Canvas_56760_56807.png Build_Cookbooks_and_The_Service_Delivery_Canvas_56808_56855.png Build_Cookbooks_and_The_Service_Delivery_Canvas_56856_56903.png Build_Cookbooks_and_The_Service_Delivery_Canvas_56904_56975.png Build_Cookbooks_and_The_Service_Delivery_Canvas_56976_57035.png Build_Cookbooks_and_The_Service_Delivery_Canvas_57036_57083.png Build_Cookbooks_and_The_Service_Delivery_Canvas_57084_57131.png Build_Cookbooks_and_The_Service_Delivery_Canvas_57132_57203.png Build_Cookbooks_and_The_Service_Delivery_Canvas_57204_57323.png Build_Cookbooks_and_The_Service_Delivery_Canvas_57324_57467.png Build_Cookbooks_and_The_Service_Delivery_Canvas_57468_57515.png Build_Cookbooks_and_The_Service_Delivery_Canvas_57516_57563.png Build_Cookbooks_and_The_Service_Delivery_Canvas_57564_57647.png Build_Cookbooks_and_The_Service_Delivery_Canvas_57648_57695.png Build_Cookbooks_and_The_Service_Delivery_Canvas_57696_57755.png Build_Cookbooks_and_The_Service_Delivery_Canvas_57756_57766.png
All right, so has everybody started to wake up from the lunch coma or are we just going to kind of like take a nap? Because I'm going to try and have enough energy to keep us going, but I totally understand if you just like, you know, over because, like, yeah, lunch was wonderful. All right, so we'll start with a little bit of where did it go? Oh, that's wonderful. We'll just use the button. Or maybe we won't. There we go. All right, so let's talk a little bit about who I am or who am I? I'm the person that was behind. How many people were at ChefConf last year? So if you watch the video on stage, they delivered delivery using delivery on stage at ChefConf. I was the person in the back super heavily stressed because they were doing that live in on stage and I was responsible for writing the build cookbook that made all of that happen. To the point of there was actually a little Sinatra app written off to the side that gave us the ability to like cut over fastly to a pre-prepped thing just in case because we're all ops people, right? Like you got to have a backup plan. But that was legit. We actually did deliver delivery on stage at ChefConf using delivery now automate workflow. I'm the author of about 20 or so build cookbooks and that number just keeps increasing because my team keeps shipping software. The important part to really take in is I'm not standing up here as a developer of automate. In fact, I'm customer really patient zero. I'm going to be the person that goes to the delivery team and is like, guys, can we fix this thing because it kind of hurts. The delivery team, I'm going to use that word. The workflow team has been super responsive in the number of opportunities we've had to dock food our own stuff and actually fix things before they got out to customers. It's just been fantastic. With that said, I'm the engineering manager for the CIA team that has nothing to do with intelligence. We have everything to do with our corporate infrastructure and applications, which when we get into some of the stuff later, you'll understand why I say it doesn't have to do with intelligence. So what are we going to cover today? We're going to cover the prerequisites and assumptions, some concepts, vocabulary, prerequisites, and these are kind of the things I think are prerequisites. The mechanics of how all of this works, the actual service delivery canvas, yes, it's actually a thing. Some examples using that canvas. Then I'm going to show you some actual code that runs actual things at Chef. So starting with prerequisites and assumptions because we always have to make assumptions. I'm going to assume you're doing the DevOps and really all of my code assumes you're doing the DevOps. Now as we all know, that's kind of a loaded term. What does it actually mean to do the DevOps? I'm going to use some very specific things that I expect of you. I think that the workflow that I'm going to present to you really does require. The app dev teams and the ops teams are able to use Git. It's workflow. We're opinionated. One of the things we're opinionated is you can use any one of the version control systems as long as they are Git. Very specifically deliveries, Git hubs or Bitbuckets because those are the ones we support today. But the team has to be able to use Git. If you can't use Git, this just isn't going to work because the system kind of depends on it. Each group is willing to see the work the other is doing. This is super, super important because I'm going to ask you to take your ops infrastructure code that relates to the application that's being deployed and the application code and put them in the same repo. You've got to work with the rest of your organization. You've got to work with your app teams. You've got to work with your ops teams. It is all about being as a single team because how many people have had that thing where it's like, okay, oh my God, we have to coordinate this change across the cookbook and the app at the same time because otherwise everything is going to go wrong and how often does that work well? Instead, I can make a code change and a cookbook change and they get deployed as the same change set because they really are the same change set. Both groups have to care about production. I usually start, but I'm going to do it right now. How many people in the room identify as sys admins, operations engineers, that sort of thing? How many people are enrolled? How many people identify as developers? That, right? Totally. Do I have any QA folks in the house? DBAs? I've got to give it up for my DBAs because that's a hard job. You have to be in a place where everybody is talking and you all have to care about the end result because I'm going to say some super blasphemous things in a few minutes and it will really make sense why we all have to care about the service and production. In fact, I'm going to go so far as to say the only thing that matters is the service in production. The source code for the application, and I touched on this a second ago, but the application, the cookbook that deploys the application and the cookbook for building the application all need to live in the same repo in harmony because it's just the only same way to operate in my not-so-humble opinion. I should probably also mention these are my views of how my team functions. That doesn't necessarily mean they are the views of how Chef thinks you should function because there's a completely different thing between what my team does and what we say is the right thing to do. But I'm totally going to tell you this is totally the right thing to do. We all have to start from a place of an API. I want you to deliver the entire service. How many people think the service is some application code? I sure don't. It doesn't look like anybody else. I just got blank stares. Like, what are you talking about, dude? Because, right, it's like a load balancer. There's probably some storage involved. Hey, we probably got to have compute instances. I actually have services that I run that don't have compute. It's kind of cool. There might be some CDN involved. You have to be in a place where the majority of your stuff is API accessible. It doesn't all have to be. But for everything that's not in the pipeline, the more opportunity you have for things to go horribly wrong. So the more you do it in the pipeline as part of the pipeline makes a huge difference. So for me, what the minimum thing has to be is that we can provision new compute, whether that's VMs, instances, you know, pick your flavor, right? Open stack, VMware, AWS, Azure, Google, you can provision a thing. Most of us don't just like stand up an instance and point stuff at it. There's usually some sort of load balancer stuff. You really should be able to spin or make the load balancer change necessary to spin up that cluster of servers. And also, how many people have API access to change their DNS? That makes me sad. So how many people are in the cloud right now? How about people on prem data centers? Okay. I've got suggestions. I should totally, yeah, we'll talk about that later. Okay. So we're going to talk concepts, vocabulary, you know, words I'm going to use. We are delivering a service, a thing that you hit. What we are not delivering is a packaged binary that someone else downloads and does something with. That's another talk for another day. It is not something, frankly, I care much about. My team delivers services, right? We deliver the corporate website. We deliver the thing that makes the jobs actually show up on the website. Those are the things my team is responsible for. When I say the word artifact, what does that mean to people? Is there anybody that, like, how many people have heard the use of the word artifact? Okay. Is there anybody that thinks I'm crazy by saying the simplest artifact we can ship in the world is a tar ball? Anybody have a problem with that? So a tar ball, a cookbook, it is a packaged artifact. We care about the versioned, promotable thing. Which means we really do want to do continuous integration and delivery. I'm just going to say it now, if you are not merging to master, it's not continuous integration. You can run all your tests all day long on Jenkins. If that code isn't on master, it isn't continuously integrated. And delivery actually means it's in production somewhere. Crazy thought. Even if it's in production in QA. Because I don't know about the rest of you, but my acceptance environment, totally production environment, just production for someone else. It goes back to that point. We are talking about services and not code. Your code is no longer holy developers. I don't care that there's something broken on master. Well, I do. But if it gets to master, that's not the end of the world. Because the thing I care about is the artifact. Is that artifact something I can deploy? And if it's not, we need to throw up a big flag that says that artifact, it would be broke. Don't do anything with that. And we need to get to a point where every pull request or change request is shipable. We need to ship the thing. The goal is to get to as many small changes that go all the way out to production as we can. Because as we all know, the smaller the change, the easier it is to debug, right? If I go and deploy six months worth of changes, I just deployed six months worth of changes. And I don't know about you, but that scares me, the crap out, like holy God. A couple of useful tools. We're going to talk a little bit about delivery truck. How many delivery users do I have in the room right now? You already have it installed somewhere. Okay, cool. So, you've probably seen delivery truck, right? It is at the heart of our cookbook workflow. Essentially you can take this cookbook, use its recipes, and it will handle moving cookbooks through the pipeline for you. Little do people know it also has some facilities for moving your versions of the application that you're using through the pipeline. And that's probably also a good point. When I talk about moving a version, that doesn't mean we deploy the thing. That just means the version pinning, just so that we're super clear on that concept. And then there's delivery sugar, which is a neat cookbook that has a whole bunch of helper methods that are sugar on top of delivery, right? So there's, for example, one where you use it to go talk to the delivery's chef server to pull versions and do some stuff. Those live in delivery sugar. So let's talk about mechanics. The display is weird. Okay, so we're going to talk about phases and stages. So I'm going to walk through this real fast, just so that everybody has it. We have stages with phases inside of them. This is our verify build acceptance union rehearsal and delivery. In Lint, we run things to Lint our code. And I just want to be clear. Everything before acceptance is pre-artifact. So we're talking in terms of this is about the code. So we're linting the code. We're syntax checking the code. We are unit testing the code. That doesn't mean we're standing up to service and running tests against it, because that's bad. We're going to be as fast as possible, and functional tests come later. We do it again in build. So when that approve bit hits, we just merge to master. Let me say that again. When we hit the approve button, we have merged to master. There are two places where there are human gates. That is for a reason. We're not going to get into it now. But anytime you sit and think to yourself, oh, my God, we need to approve that one more time, don't. There are reasons why. And I'd love to talk some more about it, but why there are only two human gates. So when we get back into build, we've now merged to master. As anybody that's ever used any sort of version control system, you know that on occasion, you merge things. And the thing you got out at the other end is not what you thought you were going to get. So we rerun Lint syntax unit, because it's entirely possible that the code that came out the other end wasn't what you thought it was. Security. This is code security. It is not instance security or service security. It is code security. We'll give examples of that a little bit later. Quality. That's kind of a loaded term. And I think we understand that it needs to be there, but we don't have super great examples in many cases of what the right thing to do is there, depending on your language of choice. Publish. This is where you actually do the build. You build the thing. You build the artifact. In my case, tar balls, because I like tar balls. Or in the case of my cookbooks, I do a knife cookbook upload, because we upload cookbooks. We'll talk a little bit about this. Each stage is made up of phases. I think I did that right. I'm totally going to screw that up at some point today, because the words. You can skip phases, but not stages. If you're running, I legitimately have projects that are just HTML files. There's not even, you just make some changes. And we seriously skip unit, Linton syntax, because there's nothing to unit, Linton syntax. It's just go put some files on S3 and stand up some fastly config. Each phase is a collection of two independent chef runs. You run your default.rb in your build cookbook as a recipe, so your default recipe. That is going to be your setup recipe. You're going to handle, and I'll show examples of this, AWS creds. You might want to install some Ruby, because I love Ruby. If you're a PHP shop or Java shop, you're going to do that in that recipe. Then the second run is done as the debil the user, and it executes the phase name, recipe. So if we're in unit, it's going to run the unit recipe. If we're in Lint, it's going to run the Lint recipe. How am I doing on time? She probably moved slightly faster. So version promotion. So what we do essentially is we create a data bag item with the version and artifact information. So if I have version 1.5, where the heck do I get version 1.5? If it's a cookbook, we totally know just to go to the chef's server, right? That's easy. But if it's an application, do you have any artifact users in the house? Nexus? S3? Totally an S3 user. You've got to know where to go find the artifact that you actually want deployed. So what we're going to do is we're going to go take that information. So I always store a checksum because we want to verify that the thing we're supposed to be deploying is the thing that we're deploying. The location of said artifact. So usually it's an S3 URL. And any other metadata that's associated with that that's important because you may need it. I tend to drop the entire delivery environment in just so that I know how the state of the world when it was built. I'm just going to point it out here because we all kind of hit this. Secrets management is kind of an interesting use case or interesting situation in delivery right now. I'm sorry, in workflow right now. It's getting better, but it's not perfect. But for me, the way I handle this is my builders have the encrypted data bag secret on the build nodes. And I use that to encrypt my secrets and put them up in the cloud, or I'm sorry, into the chef's server. And then my actual nodes have the encrypted data bag secret as well and use that. My hope is that over the next year that I'll get a little bit better. We're going to do breaking apart of the app. And I'm just glossing over this because you can have an entire session on just breaking apart applications and understanding what it looks like. But the couple of questions you want to ask yourself are all the pieces related to the application. So you occasionally see applications where it's really three applications and one. We'll break that apart. Maybe there are shared pieces of the application. So we talked about being in an actual on-prem data center. You probably don't spin up a new load balancer for every single application. And if you do, I want to work for your company because you probably have lots and lots of money to have a F5 or net scaler for every single one of your applications. That'd be cool, though. That and it's probably not API accessible if you have to go over and rack something every time. That would be crazy. Is the database shared? I've worked in environments where the database is a shared thing and the applications that go talk to the database, like the database is itself an application. In other cases, we spin in MySQL instance or Postgres instance or Postgres cluster for every single application. It really depends on what you're doing. When we talk about dependencies, you need to understand them. If there are things that you can do something about, they're what we'll call operational concern. I'm sorry, you can't do anything about them. They're operational concerns. So if it's the VMware cluster, that's totally dependency. But you're not going to test whether or not the VMware cluster is up and running. Because if the VMware cluster is not up and running, we probably have a different problem than we shouldn't be having this conversation right now. Is it a build time or run time dependency? We're going to talk explicitly about run time dependencies as we move forward. What I mean by that is, does the service use it while it's running? So like libc, that's a bad example because it's like a service dependency. Anyway, when we talk about things, does this API talk to this other API? Well, if it does, it's probably a run time dependency. You should actually actively test code paths that verify that dependency that you've declared. If you can't test it, there's no reason to declare it. So important, we're emerging after verify. We're going to build for master. We're going to move artifacts, not code, through acceptance, union, rehearsal, and delivered. All right. So first we're going to talk about the service delivery canvas. We're going to start with the artifacts. And this will all make sense in a second when I show you this thing I call the service delivery canvas. It's a canvas, which means it is nonlinear. We all like to think about starting at the beginning and getting to the end. The reality, especially, it's a pipeline, right? Like you start at the beginning of the pipeline, you go through it, and you eventually end. Well, the canvas is not meant to work that way. The canvas is really, it's a document, it's an opportunity to think nonlinearly about your problem set. Identify the operational concerns as you go. I touched on these a little bit ago, but as you're building out your applications, understand what are operational concerns versus what are dependencies. So an operational concern might be the F5 device, because yeah, that's an operational concern. I am only concerned about the VIP for this thing. Maybe the operational concern is that, frankly, we don't actually ever launch features as part of the pipeline. Launching features is an operational concern because we tick on feature flags. That's an awesome way to roll, by the way. Identify the dependencies as you go. Once again, we're looking for runtime dependencies. We really want to be in a place where we can actually test the thing that we're depending on because we're responsible for doing that. There was a talk given by Jess Mink earlier in, or yesterday, as a matter of fact, that gives a little bit more detail around the dependency graph model inside of delivery. But think about this magic for just a second. You have six services. You tell the services what they depend on. Every time I deploy my application, the things that I told workflow that I depended on, they run their tests, too. So all of a sudden, we now have the ability to actually do things like microservices safely. So this is the canvas. Really simple. And this is the PowerPoint version, because it looks pretty. But this is the actual legit thing. Like I was in Palm Springs last week working through my talk, and I pulled this from my backpack and sat and wrote down with a pen and worked through piece by piece what an actual application would look like. And this is actually available at cweber.net delivery underscore canvas.pdf. Huge shout out to Mark Harrison, who actually made this look nice and omnigraphal, because I'm a manager and tend to use PowerPoint for things that shouldn't use PowerPoint for. So the original one was done in PowerPoint. He made it look really, really pretty in omnigraphal. And I may even be able to post the omnigraphal file. So let's talk about a Ruby app. Let's get into this. So really simple, right? We've got some DNS, a load balancer, and some instances. The stupid simple application. We've got Sinatra. There's no database. And just because we all like to have that mental model, it's run at Unicorn and Nginx. Cool. So we're going to start by figuring out what we're going to publish. Because once again, I told you at the end of the day what we care about is the artifact, what we care about is the service. I don't care about unit testing code at this point, because frankly, I care about the service. So what's going to get the service deployed? So let's start by like, let's build it. Let's take it, create a tar ball, create a cookbook. We want to get to that point where we are able to actually go see, did this even come up, right? And sometimes it's a proof of concept. We just need to get it into the pipeline and get it running. The other thing, right, is if you turn on Linting too early, you're going to spend all your time trying to figure out why RuboCop is blowing up instead of like shipping code. And sometimes that's good. And sometimes that's bad. But it really depends on what you're doing. So once again, we're provisioning EC2 instances, an elastic load balancer. We all kind of know how that works, right? I've got, I use Chef provisioning. You may use Terraform. It's all cool. Just pick the thing that makes the most sense to you. In the deploy phase. And once again, we're walking through this as we go, right? So we're going to go run the Chef on the nodes to install and or upgrade the app, right? So in this place, we're going to do things like, hey, there was a cookbook change. So now we're going to change the engineX config. Or hey, like our application actually changed. So we will do a Chef run, which will cause Unicorn to get bounced, that sort of thing. And then Smoke. This is the simplest. You have to remember Smoke should be super brain dead simple. You just want to check, did it work? So did I get a 200 at a particular path? In my case, I use a lot of SAML-based applications. So the first thing I ask is, did I get a 302? Does it redirect? Because I need to auth. And that's a huge awesome Smoke test, right? If I get a 200 on a page that should be sending me to go get authenticated, I want to know that and blow up like that. And then Functional. Like Selenium, if it's an API, maybe you're pulling down some JSON and making sense of the JSON. Like it all is about what makes sense to you. From there, I dive in and it's Ruby, right? So we're going to write some mini-test. It's a cookbook, right? Chef spec. We'll run some Winting. So RuboCop Food Critic. RuboCop works for both our Ruby code and for our cookbook code. Food Critic. How many people are familiar with RuboCop and Food Critic? That is awesome. I love to see that. So here's the thing, right? Like, if cookstyle is your thing, you should totally do that. My team actually just rolls straight RuboCop because we write a ton of Ruby code outside of like ChefLand. Ruby-C. I've got some great stories about this in a few minutes here. But we're just going to check to see, hey, is the syntax right? Like, we want to catch this as soon as possible. And then finally, in the security phase, we're actually just going to make sure that, is Ruby, we're going to make sure that there are no open CBEs against the gems that are in our bundle. If you are running Ruby stuff and in production, you should totally be using Bundler audit because it will tell you, hey, by the way, that sample gem you're using, there's totally an open CBE against it. You should fix that. So let's use a more complex example. This looks a little bit more like our normal applications, right? There's some DNS. There's three layers of caching because, of course, you have to have three layers of caching. We've got the load balancer. We've got the CDN. We've got Redis, Postgres. So what might that look like? As you can tell, not a whole lot changed. But we can look across and go, oh, wow, we're provisioning a lot more things. We should think about that. The canvas gives you the opportunity to, at a glance, get a feel for what you should be doing in your phases before you even write your code. Because we want to get to a place where, before we sit down and go write build cookbooks, we have an idea of what should go where. And I talked a little bit about this a few minutes ago. You work in a real data center. You may not have the ability to do the thing in the cloud. So maybe you're deploying a PHP application. My suggestion, this is totally not paid for, but Infoblox, you can actually hit it with an API. In fact, I think they now have a REST API. Back in my day, it was all Perl. So you wrote some Perl to do the thing. But you can use Infoblox to spin up your DNS and handle IP address like assignment, that sort of thing. Load balancers, you're probably going to talk about a VIP instead of the actual load balancers we discussed earlier. Stand up some PHP instances, some MySQL instances, and some Mcache. And then as VMware instances. And then we need some NFS. So why not do it with Icelon, right? That's API accessible. The key for me is we all have to understand I don't have to have AWS. I don't have to have Google to get this today, to get to this point. The ultimate goal is that when you hit approve and you hit acceptance, the entire thing comes up on its own. When you hit deliver, the application comes into being. You shouldn't have to spend your time going, oh, it's a production deploy. So run through the checklist. Did we do the thing? Did we do the thing as we're deploying it? Like really, what we want to do is actually know because we ran through the checklist in the code to verify that the code is compliant and does the right things instead of whether or not we hit the checklist. And as you standardize your code bases, you get to a point where you stop caring about that because it's encapsulated in the code. This is what that looks like, right? Same general ideas. We've got a lot more operational concerns because the other size I probably should just put AWS because, yeah. But we now care about our F5 cluster and all that stuff. So I'm sure y'all would like to see some code. So we're going to look at some code. This is just so that we have a starting point. This is Chef Web Purchase, an application, a CR of wonderful naming scheme. It's a simple Sinatra app that handles purchases for one-off services. So if you'd like one of our solutions architects to spend a day with you remotely to talk about all things Chef, whether it's to give you advice on how to build cookbooks, cultural questions that you can buy up to three non-contiguous days online on the Internet. In fact, if you go to that website right now, you can totally push those buttons in and hit the credit card button and enter your credit card and I'll get email that says you bought something. So this is a service. We all have things where we accept money and whatnot. So this, as we started, is our Canvas, right? This is how the application gets built. We're going to do unit testing. We've got some lint, some syntax. I didn't fill these all in at the first go around, right? When I first deployed this, we totally didn't have lint enabled. In fact, there's actually a commit on the repo that says make C Webber not a liar because I turned on a bunch of these things to make sure that I wasn't lying when I gave this talk. So let's actually go look at some code. And I just want to point out, like I'm skipping functional right now. I don't, the amount of work it takes to do functional testing with things like Salesforce and Avalara and Stripe, like it's just not worth it for something that I don't know if it's going to make any money at all yet. So at this point, we're just going to skip functional testing. And if it breaks, my bad, it's totally an experiment right now. We'd love to see it successful. Like if you all want to go spend $2,000 to have a day of Solutions Team, I would love you all right now because that would be awesome. So this is my entire default RB recipe. It used to be super longer because back in the day, we didn't have things like Slack integration. We didn't have GitHub integration. Like those were things. It's now gotten really simple. You do a default for delivery truck, which just basically sets up the environment. We have AWS Pre-rex. So for those of you that know about interacting with AWS, you know that you have to have creds on the box. You know that you have to have the actual AWS CLI if that's how you're going to interact with it. There are a lot of little things you need to be useful, so we have a recipe that does that. We also install Ruby the same way that we install Ruby on the actual node because crazy thought, if I can install Ruby the same way in two places, which seems like a miracle sometimes, it's probably going to be more effective, right? So my unit recipe, and I've got to hustle, we're going to do the delivery truck unit test. So that's just going to run unit testing against our cookbook, right? We want to actually care about what the cookbook does. We're going to install our dependencies from Bundler. It's an application that uses.env, so I'm going to have to link my.env file in place because that's kind of useful. And then we've got a little helper method here to run rig test. Same idea, right? We linked the cookbook. We install our Bundler dependencies. We run Rubikop-d, which is to say, I don't like to have to go figure out what in God's name Rubikop was complaining about. Check for syntax. And I mentioned earlier that whole idea of Ruby-c. I initially did that with a find, only to find out that find always returns zero because it found things instead of the thing that was inside broke. Once again, install my dependencies. And Bundler on it, check the bundle. We've standardized, and I'm happy to show anybody the code inside of this, but we are now at a point that I don't think about how a cluster gets stood up. It's what, three, four lines there. That stands up the size number of EC2 instances, and ELB terminates SSL and sets the run list as appropriate. And this goes out to those nodes and tells them to do a chef run. I told you, I'm just checking the status code. That path slash architect days is what matters to me. Did it return 200? A couple of useful things to know about. There is a cookbooks directory. If you stick a cookbook in there, delivery truck will just work. It's beautiful. The config.json is where your actual configuration code goes. You want to read up on it online, but it gives you the ability to do things like skip phases and specify the search for the build nodes. And then I'm going to say this to tongue in cheek.delivery slash build cookbook is kind of the standard. It totally isn't, because there isn't actually a standard. But where my team normally puts our build cookbooks is in.delivery slash build cookbook, so we're not polluting the main part of the namespace. And finally, a couple of just real brief thoughts. Take advantage of custom resources. They will make your life better. Helper methods are awesome, so you can drop things that you use throughout the cookbook all over the place in the library's directory, and it makes your life better. And finally, put shared things in shared cookbooks. So you saw that CIA infra, CIA delivery. That's where those come from. So with three minutes left, that's my talk. What can I answer for you? So the question is, if I'm only going to do something in a certain phase, should I switch on it? So if I'm in unit Linton syntax, I probably don't need Terraform. The answer really becomes it depends on what your coding standards allow for. It also depends on what you want to do. So at this point, build nodes are shared. And the first time it runs, it basically warms the cache. It just makes sure it is there. With Terraform is a great example. If I don't have to install this root, I'm not going to. So I'm just going to put it in as the build user. And that's really what I use as the dint differentiator. I don't tend to add the switches because it adds complexity to my default recipes. But that's me personally. The question is, where can I go to find out more about delivery truck and delivery sugar? So there is info in the docs. So if you search in the docs for delivery truck and delivery sugar, additionally, the cookbooks are up on GitHub. I don't remember. Are they in the Chef cookbooks org or the ops cookbooks org? Chef cookbooks? Awesome. I'll sling here. So yeah, GitHub. Not going to lie, I'm of the belief that the best thing you can do when you run into problems is go read the source code. So I totally go read lots of source code. So with that said, am I at zero minutes? Awesome. Thank you very much. I will be down at the Chef booth if you have any questions after this talk. Thank you very much.
our corporate infrastructure and applications, to go wrong and how often does that work well? blasphemous things in a few minutes and it will the right thing to do. We all have to start from you do it in the pipeline as part of the pipeline you hit. What we are not delivering is a packaged moving cookbooks through the pipeline for you. yourself are all the pieces related to the as you're building out your applications, the canvas. Really simple. And this is the let's start by like, let's build it. Let's take hey, there was a cookbook change. So now we're in production, you should totally be using idea of what should go where. And I talked a remotely to talk about all things Chef, whether this, as we started, is our Canvas, right? This I don't like to have to go figure out what in