 I'm actually the CTO. I don't want to take my boss's job. So, small clarification there. But yeah, so I'm super excited to be here. Thank you so much for listening to me for being here. I want to tell you a little bit about development with Ansible and VMs. This is based largely off of what we do at my company, Choose. And so I want to kind of go through how we've set things up and why we think it's pretty great. So, let's take a look at what we're going to learn today. We're gonna start by trying to understand what is a better dev environment? What are we actually looking for? What's our wish list? In terms of what makes a really great dev environment? We're going to look at some environment tools. How do we create the right environment for our code to live and run in? Then we're gonna talk about config tools and how we set up that environment to run the code that we wanted to to have all the packages we needed to. And then we'll wrap up and kind of check in on what we learned today. So I hope you can learn something that you can put into practice tomorrow with this. We've found Ansible and developing in VMs to be really, really great for us. So I hope you agree. So let's start with what is a better dev environment? What are we really looking for on that in building that dev environment and running our code? So what's our wish list? We start with an environment that's standardized. If we have a known baseline, that means there are no surprises. So we wanna start there. And we want it to be repeatable. So if the standard environment is repeatable, this gives us a lot of power. We can spin up a new dev environment. If we do something crazy to it and we don't like what we've done, like we installed an extra package by hand and we don't wanna deal with that, you can toss it away and recreate it from scratch because it's standardized, it's repeatable. You can build two of them and run them side by side. If someone steals your laptop, you can just get a new laptop and with a few commands be up and running again with your full dev environment just as you left it. So those two things together can be really powerful but there's more, we want it to be isolated. So this means we have complete control over what packages are running in that environment. Let's say that you want Django 1.5 for a slightly older project that you're running and then you wanna run Django 1.7 RC, whatever we're on today for a personal passion project in a different environment. With these isolated environments, you can run one in one, the other in the other but more than that, we also wanna be able to isolate system packages. So let's say that one of your projects needs Postgres 8 series, 8.4 and the other one needs 9.3. So you're able to accomplish that as well if it's really, truly fully isolated and that's what we're looking for here. We want our dev environment to be as like production as absolutely humanly possible. Anyone who's dealt with a production only bug knows the pain that that causes. The best way to avoid that is you make sure that your dev environment is as absolutely picture perfect close to your production environment as possible and I'm a little bit fanatical about that myself. So that means, what do we need? We need total control over how our code's running. That means we need to control what OS it's running in. We need to control what system packages are available, what users are set up on that box, everything. So that's on our wish list. Even though you're running in a production like environment, you wanna use your tools, right? If for you to be productive, maybe you're a Mac person, you use Sublime, maybe you like to run Ubuntu or Debian and Vim or Emacs, whatever it is, whatever your tool set is, you should be able to use that so that you can be fully productive while still running your code in the most production like environment possible, right? So that's on our wish list. And finally, if we have all of this, we also want it to be shareable, right? So we have a new person join the team, they're gonna be working on the code too. They should benefit from all of this as well. So we wanna be able to just hand them something and go off to the races. So that's our wish list, how are we going to do it? So let's talk a little bit about environment tools. So these are the tools that are going to kind of set up that baseline environment. You've probably all heard of PIP. PIP is for installing Python packages. I'm not really gonna go into it cause that's not really the point of the talk but we're gonna use it and you should all keep using it. It's pretty great. PIP leads us to virtualMV which you've also probably heard of if you've been in the Python world for a little while. VirtualMV isolates Python versions and Python packages for those versions. So this is what can allow you to run Python 2.7 in one environment and Python 3.3 in a different environment to run Django 1.5 in one place and 1.7 in another place. And that is really helpful and that is really great but I would argue it doesn't go far enough and that's where these VMs really come into play. So let's talk about what a VM is. If you're not familiar with it, a VM stands for a virtual machine and basically it's a little tiny computer running inside the computer. So it's all, you know, it's virtualizing an entire computer running inside your computer. I have one running right now on my computer. And so what this does for you is in that computer inside the computer you can isolate everything, right? You can set it up to be its own OS, right? So we run our production environment is Ubuntu-like and so our VM when I'm developing is Ubuntu but if you can see the top of my MacBook, you know, I'm running my stuff on Mac. So it doesn't have to match. You get to set it up, set up the VM with your own, whatever OS you need, whatever system level packages you need, all of that kind of stuff. And this is how you isolate the entire box. So like I said, you get your Python packages isolated, you get your system packages isolated and get it as close to production as possible. Now if you've never used a VM you might be wondering how the hell does this work? So a little bit about that, you know, why am I able to run this other box and then still kind of seamlessly use my Mac system to edit things? It sets up really easy networking between them so that I can open up a web browser and open up whatever's running on the guest on the little machine inside the machine and it mirrors folders. So you're able to say, this is my project folder. I want it exactly mirrored between my machine and the machine within the machine and any changes made in one place are reflected instantly in the other back and forth which is how when you're using your editor on your OS those changes happen literally simultaneously on the little tiny VM and if you're running Django there, Django sees those changes, reloads, it all happens automatically, it's very seamless, it's really fun. So that's VMs. Let me talk you through a little bit kind of what our setup is. There are a number of different ways to do this. I'm gonna walk you through what we do. We use two tools here. One's called VirtualBox and the other is Vagrant. They're both free and open source and really wonderful and allow you to virtualize pretty much anything. VirtualBox is the thing that actually runs the virtual computer, the virtual machine and Vagrant provides some really nice command line interfaces to working with VirtualBox. So I'll show you a little bit what that looks like. So at a super basic level, this is how you would set up your kind of baby's first VM machine. You would download those two packages I showed you and get them installed. You can type Vagrant in it and here we're specifying a precise 64 version of Ubuntu. Vagrant actually hosts a bunch of these kind of basic boxes. If you have a disk image that you wanna use yourself you can do that too of course but they have a bunch of kind of standard ones and it makes it really easy to get up and running with them. You type Vagrant up and it installs the machine, gets it booted up, sets up all the networking, all the basic stuff and you have a running computer. And then that last one, Vagrant SSH allows you to SSH into that box and you have full access to it right from there. So it's really that simple, it's three lines. But of course that's just the kind of basic starting point. So let me walk you through a little bit how we've got our VM set up. And I'll walk you through this line by line in a second. You don't have to kind of stare at the whole thing here. But this really is, I mean I made a couple of changes for TV magic but basically this is all that we really have at choose to configure our virtual machine. And this file it's called a Vagrant file. It's what you use to tell Vagrant kind of your configuration for that box. And this I recommend that you generally want to check into version control so that you can have one standardized thing, you can version it, you can share it with your team. So let me walk you through this. So we start with ConvigVM box equals that one that you saw in the previous step. This is how you would specify in kind of a more canonical way and share it with your team points to the right box if you don't have this installed. Like if a teammate just pulled down the code and is using Vagrant it will know where to go and get that box and it'll install it for you. So that makes that really easy. Then we set up some networking, a host name and then a private network with a static IP 10.0.100 in this case and that means that you can access that virtual machine at that IP address. And Vagrant does all that setup for you. So all that kind of networking, headache-y stuff all handled for you. This last bit down here is Ansible. So we'll get into this a little bit more in a few minutes but basically you tell it which provisioner to use. You can use any of a number of them. In this case we're using Ansible to set up the box and you point it to a playbook which is kind of Ansible terms for kind of the entry point for your Ansible configuration. So like I said, we'll talk more about this but this is how in your Vagrant file you basically tell it how to set up this machine. It's really that simple. That really is pretty much all we have. So let's talk a little bit about the config tools. So this is where we talk about configuration management and what is configuration management? If you've never used any of these tools before basically what you're doing is you're defining how the system gets set up from top to bottom. So Vagrant and the VM set up kind of gets you bootstrapped with that OS. You're running a box now and configuration management is that last piece where you're saying, okay, from that OS what do we need set up? We need Postgres. We need this version of Python. We need these users on the box. We need all of that kind of stuff. This is the tool that you're gonna use to do it. This is a big key for me. You write this all in code or Gamal or some sort of a language like that. This is really important because it means it's documented and it's versioned. If it's not clear to you and your teammates how to set up a new box to run a dev environment and everyone's running slightly different stuff you have no guarantee that a bug is reproducible. You have no guarantee that your teammate can help you out. You have no guarantee that even you could reproduce it under different circumstances. But if everything's documented everyone knows exactly what's going on. It's versioned so as you make changes to the code you have new dependencies. Those are all captured there in the history. It's a really beautiful thing. And like I said, it's also shareable so now your teammates can all get in on this. You can share it really easily. So let's talk about all of these tools in this ecosystem. Typically these are all different and sort of competing configuration management options. Chef and Puppet have been around a while. They're both written in Ruby. Ansible and Saltstack are both written in Python. Ansible's kind of the new kid on the block. And Bash just please don't. It's better than nothing I guess but there are way better options and it's not that hard to get started on them. Bash scripting is gonna be a beast to maintain. So I can't recommend that. I'm not gonna go in to all of the reasons why we're using Ansible right now. That's kind of outside the scope of this talk. Will be my comp out for that. But if you wanna talk about that after the talk or whatever you can come find me. What I will say is Ansible has been very good to us. It's written in Python so if you ever need to dig into the internals for something that's very easy to do. I've just, I've tried all of them and Ansible is my choice. So we'll leave it at that for now. But you all kind of came knowing knowing that you were gonna hear about Ansible. So let's get in and go through kind of a basic example of what an Ansible setup would look like. So don't worry about reading this, you're not supposed to be able to yet. But this is the entirety of our Python setup using Ansible. So we split our system into multiple different things, right? We have one of these files for Postgres. We have one for Redis. We have one for Supervisor. You know all of these different kind of baseline things that we want set up. We have a different file for an Ansible. And you kind of organize things that way. I wanna walk you through our Python one both cause this is kind of a Python-y sort of place. And because it's I think a really great example of how kind of simple and straightforward this can be but also very powerful. So let's start looking at this. At a baseline, all Ansible is is a series of steps that you want it to do that really like there's a lot of complication built around it but really at the end of the day Ansible is just a series of steps that you've put into a YAML file. And these names, these are just kind of human readable definitions of what you're doing step by step. So these were all in that file that you saw a moment ago. I'm going to go through these one by one. But at a high level, what are we trying to do? We're going to install some basic system level packages. We're going to get PIP and virtualM kind of bootstrapped on the system, get those up to the right versions. We're going to install everything in our requirements.txt file. And then for a little touch of luxury, we're going to add a couple of lines to our bashrc file that when we SSH into the box using Vigrant that these will activate the virtualM and CD into the project directory so that we're all kind of ready to go in the right place every time that we SSH into the box. So let's look at these one by one. So for installing the system packages, let's take a look at this. It starts with this line APT package equals crazy curly stuff and state installed. So Ansible the way it works is it has all of these kind of understandings of what different system level options are. So in this case, it knows what APT is. It's a package manager and it knows how to interact with it. So you have this really nice shorthand for saying, here's the package I want and I want it installed. Just go do that Ansible. And it does that in a way that is item potent. If you've hung out with configuration management stuff a while, you've probably heard the word item potent is just a fancy word for saying it'll do the thing once and then if it tries to do it again but knows that it's already been done, it won't do the work twice. So as with this, it'll make sure that the packages are installed but if you go through and run the configuration again, it won't reinstall them or anything silly like that. APT already does that of course, but lots of the other Ansible tools will handle that item potency for you. So what are these double curly braces? This is a really interesting thing and really powerful tool with Ansible if you look at this next line with items. So basically what you're doing is you're giving it a list in this case, Python, Python dev, Python pip, Rebex amount and XLST and you're saying I want to do that action, that APT thing with each of these items. And what it's doing is it's actually rendering that line as a little mini template, the APT line. And it looks a lot like Django's templating language because it acts a lot like Django's templating language. Technically it's actually using JINJA under the hood, but if you know Django's template language you'll feel right at home. So basically it's taking each of those items from one by one, plopping them in and doing the APT install for each. And then we pseudo the command because that's what you gotta do. So that is how we're installing some standard system model packages with Ansible, pretty straightforward. Step two, we're going to bootstrap pip and virtualMF. As you can see, in the same way that Ansible understands what APT is, Ansible also built in understands what pip is and how to interact with pip. You'll notice we installed the pip package in our last step. So there's already kind of the system package that APT installed its version of pip. But we also, pip can update itself and we wanna be working with the latest version of pip and we want a version of virtualM installed. And we can use pip to do both of those things to kind of get a baseline setup on our system. Again, so here we've got two options. We're saying name equals curly bases again. And we're saying version equals curly bases again. So this is using with items but in a slightly more advanced format. So here we're defining dictionaries instead of just a straight list. So here we have a list of dictionaries. There's tons of power under the hood in terms of how with items works. There are lots of crazy things you can do. This obviously makes it pretty clean to encapsulate pegging a certain package and a certain version and having it handle all of that. So once you've done this, we know that we have the version of pip that we expect to have, the version of virtualM that we expect to have. And we're on to the next step, which is to install our requirements.txt. So you can see we're using pip again but this time in a slightly different way. The same way that you know you can install with a requirements file or you can install a straight up package using pip. Ansible understands those two functions as well. So in this case, if we use pip and specify a requirements file and a virtualM that we want to use, it knows how to do that. It does all the heavy lifting for us. Depending on how many packages you had off, obviously this step might take a little while but it knows how to do that. It handles everything for you. So that step's pretty straightforward. The last step, as I said, a little bit of luxury, a little nice to have. We're going to add a couple of lines to our bashRc file and we're gonna use this new tool. Ansible also has a lot of different ways of working with files on the system as you might expect. This one's called lineInFile which does pretty much what it sounds like. It makes sure that this line is in this file. So we're going to give it a destination and say we're talking about this bashRc file and once again we're using this curly brace item thing and we're gonna tell it, make sure that these lines are in the file. And the items that we're doing, we're going to activate the virtual environment, like I said, and we're going to change directories into our project directory. So every time we vagrant SSH into this box, these things happen automatically from the bashRc file. And like I said, the item potency applies here again. LineInFile knows how to search through that file and make sure that it's not duplicating those lines. So it's not adding those every time you configure. It makes sure they're there. If they're not, it adds them pretty straightforward. So that's really all that is. And I hope you agree. I think that that is really simple, really readable and also pretty powerful, right? To have that now documented in code, to have that shareable with the rest of the team, I think is a really, really powerful thing. And again, so we do this with Postgres, we do this with Flattice, we do this with Solar, Supervisor and a bunch of other things to get our whole system up and running. So let's talk, let's go back and see what we've learned. I wanna first show you kind of how magical I feel like this is. And especially, I'm building a new developer into your team, working together with them. It's really important, at least to me, to make sure that they can get up and running fast. They can feel ownership of the code on day one. And this makes that really possible. So let's walk through just a day in the life, the first day of someone joining our team. They install VirtualBox and Vagrant, that takes a few minutes, but no big deal. You get cloned out of repository, no big deal. And you type Vagrant up. And that's glossed over a little bit, sure, but that is really, really, really close to all you have to do. And you do wait a while on this step. That step, the Vagrant up, it's doing a lot of stuff and it does take a while. But it really is about as simple as that. And you're up and running with a totally working version of Choose. It does everything you want. Like it literally is running. You can open it up in a browser. You can make changes to the code and see it immediately represented in your browser. Full working environment, it's pretty great. So let's go back to our dev wish list and see if we've hit all of our points. We want it to be standardized. So we've standardized our setup with code. We've written it all down in code so it's all standardized across all of our team. It's repeatable. You just type Vagrant up and you've got a new box. It's isolated at the OS level, at the system package level, at the Python level. At every level, it's a totally isolated environment that we have complete control of. It is as close to production as we can possibly make it. But it still lets you use your tools as you're working, your editor, your OS. And you can share with your team and get them up to speed in almost no time. So I think this is pretty good. I hope you agree. Again, I'm Jeff. I really appreciate you taking the time to listen to all this. I have to pimp Choose real quick because they paid for me to be here. This is my company. We do lunches. So if you have lunches at your office and you want them to be better, we can help you do that, get in touch. But yeah, that's it. Thank you so much.