 So the session is about test-driven development of infrastructure code, and I'm Sridevi. I work as a lead consultant with ThoughtWorks. I have been in software testing for about 10 years now. I was testing different kinds of applications in a couple of domains, worked on building test frameworks for most part of my career, and I also worked on different languages. So that's about me. This is my Twitter handle and my LinkedIn profile. All right. So why are you here? I would like to understand what your expectations are from the session. What are you expecting to learn here? What is TDD? Okay. I'm not sure about the new way, but certainly a way. Yeah. How the infrastructure code can fail with the test fields? I mean, how it fails with how the test passes? Because the cycles are very fast, and the infrastructure to have it create and fail. So it's a slow process, infrastructure is a slow process. Right. I think you need to reconcile how we have this. So how testing can happen against infrastructure code and how fast or how easy it is to test it. Yeah, I think we'll cover that. Okay, anybody? Okay, this is a demonstration. So I'm going to show only Chef. The concepts I'm sure are going to apply for any configuration management framework. But from my experience, Chef has better testing support than Puppet. It actually comes with out-of-the-box testing frameworks which I'm going to use here. Chef is a configuration management framework. I'll talk about it. I have a small Chef 101 basics kind of a slide. All right. So what is test-driven development? I think most of you might have attended today's keynote and the speaker actually spoke in depth about test-driven development. So he compared tests as automated warning signals in a nuclear power plant actually. So when he was talking about that, I thought, okay, that's actually a very nice analogy, right? So how many of us have done TDD before? Okay, got a lot of hands. And anybody wants to take a shot at what TDD is? Want to explain before I show the slide? Yeah, go ahead. Yes, I want you to... No, okay. Anybody wants to take a shot at it? Right, yeah. So I think pretty much it is. Anybody who's a fan of diagrams, we remember TDD, or we know TDD as the red, green, and refactor circuits, right? So TDD is about writing test first, keeping the functionality in focus without any code, and then writing code to satisfy that functionality. And at this point, tests will be passing. And then do some refactoring, because till this point, we have only written code just to meet the test, but we might not have applied any good standards on it. So refactor it to follow standard development practices, and the shapes code up, and then write more tests for the next piece of functionality. So this goes on in cycles, and delivering, you know, building the application. There are two reasons why I personally like TDD. The first one is that it brings functionality in focus. So now the functionality can actually guide the application development. And the second reason is that testing is not happening after the fact. So there is a problem when testing happens after the fact that it can very easily be deep prioritized. Okay, you have some application that is delivering some functionality. Why even bother about writing automated tests for it? As a tester, I have seen this happen in many places. If you are adopting TDD approach, that solves half the problem because you're writing tests ahead of building the application. So there were two parts for the title. Parts of the title, right? TDD and infrastructure code. This is the second part of the title. What is infrastructure code? I would like to understand how many of us have already worked on any infrastructure code frameworks like Puppet or Chef or Ansible. Okay, there are a few hands. So what does infrastructure mean to you? Infrastructure code mean to you? So basically it's a configuration which we need to do to not make server ready. As we talked in the previous session, a golden image which needs to be ready. Okay, yeah, I think that's pretty much it. Do the others want to add anything onto it? I'll repeat the answer. But do you want to add to it? Item potency, okay. Do you want to explain that or? Okay. You do certain steps and you do the same steps the next time you get the same output. Okay, so configuring servers, writing code for servers in an idempotent way. Okay, if there are no additions to it. So infrastructure code is about writing code to build infrastructure, right? And I think we have gone into quite detail in the previous session. I don't want to repeat it. In fact, Z actually stole a lot of my thunder about DevOps, but that's all right, I'll go ahead with the demo. So at this point, I actually want to take a step back and understand that we all understand what DevOps is. I think there were some very good questions about DevOps also, right? Infrastructure code is about writing code to build your infrastructure and it facilitates DevOps culture. All right, and it helps continuous delivery. I just want to state it and then leave it there. If we do not have any further questions or if we want to have some understanding of DevOps, then I would like to go into detail about it. Because in the previous session, I think a lot of it is covered. If some of us have not attended the previous session, then I would like to talk about it. Otherwise, I'll just go on. Here's a part of the process. Yes, but DevOps is about beginning development and eventually seeding together. Some of us might have faced this before when agile was being adopted in organizations where development and testing teams used to work in silos. Earlier prior to agile, right? We were working on, we were reporting to different hierarchies and then there used to be a layer between the dev and testing teams. And with the adoption of agile, we actually came together and started working for the common cause. So DevOps, I feel is a similar revolution, a similar movement that is going to bring the devs and the operations team together. And the way it helps continuous delivery is by reducing the delay in the release management process and the operations process, which is a bottleneck today. To understand infrastructure code, as we have seen, infrastructure code is nothing but writing code for your infrastructure elements. And the infrastructure elements can be of numerous varieties depending on the context that you are in, depending on the kind of application that you are using. I'm going to take a simple example to make things clear. This is an app, all right? And, okay, I forgot to actually ask, how many of us are developers or testers here? Okay, that's about 70% maybe. And how many of us are from the operations team or release management team? Okay, three people, all right? There's a person who raised hand for both the roles. Nice. So we mostly work in this area of the product development, right? We are in the application development. For this application to be useful to anybody, it has to be deployed in environments, has to be configured in different ways. So we need an application server to hold the application, all right? And we need some web server which serves as a front end to it and a DB server which serves as a back end to it. And we need some network components to support this environment. We like maybe a DNS server, firewall, routers, switches, many other stuff. So in this diagram, what do you think are actually infrastructure code? Do you think application is an infrastructure code? All right. So pretty much everything apart from the application itself is infrastructure code here, all right? And is that all? Is that all infrastructure code talks about? Not really. So I wanted to have this slide just to show the extent of infrastructure code. Infrastructure code actually starts from how your servers are configured, how they're created. If you are in the cloud infrastructure, how the servers are brought live to configuring those servers and finally making them work together, the interactions between the servers, how the communication happens in the event of a failure, how the failover mechanism kicks in and so on. So all this comprises of infrastructure code. Coming to what we are up to in this demo, right? I'm going to walk you through building a small piece of this infrastructure code, which pretty much sits in the server configuration part of it. I'm sorry. Which pretty much sits in the server configuration part of it. I'm going to walk you through building a MySQL installation code, which is guided by Tess, all right? Let us imagine that our application has two supported platforms, an Ubuntu flavor and a CentOS flavor, all right? And we are using MySQL as the backend for the application. We have to write code to install MySQL on these two flavors of Linux. So that is what we are going to do in the demo. Do you have any questions or do you want me to repeat the goal of the demo? We are going to build MySQL installer. We are going to write code for MySQL installation, which supports two flavors of Linux, Ubuntu and CentOS, all right? Because that's what the application actually requires. Okay. Anybody has any ideas about how to go about building it? Some of us are new to Chef or Puppet have not used it. So do you want to take a shot at how you can actually do something of that sort? Pardon, I didn't get it. You'll take the help of a scripting language, which does the installation. I think you mentioned shell script. So typically, I think release management teams use shell scripts for the operations. But there are some issues with using shell scripts, because they are usually not meant to be reusable and maintainable modular code. So there are frameworks like Puppet and Puppet Chef Ansible Salt, you might have heard these four names, right? Which facilitate infrastructure, writing infrastructure code in a way that is reusable and maintainable. So they have a DSL that they come with. They have a domain-specific language that they come with that is actually used to build the components. We'll look at that, we'll look at the code so it might make more sense then. But the answers are correct in that typically it is done using shell scripting and you use the underlying operating systems package managers, right? So if you are going about, if you want to install MySQL on CentOS, how would you do that? You would use the yum package manager to install it. While on Ubuntu, you would use something else, apt-get maybe. These are the underlying package managers for the, for the different flavors of Linux. Okay, so we are going to do that anyway. So let us leave it there. How would you go about testing it? Okay, now you have written some code in some way. But how would you test it? So will you, can you actually deploy it? Deploy whatever code you have written on your environments and test them? Not really, right? Because you do not know, you do not know, you're not sure about whether you have built them correctly or not. So coming back to your question. To test them, you need some way of, some mechanism to create different environments, different flavors that you want to test your code on, right? And also you need some way to verify whether the installation happened correctly. When a component gets installed in an operating system, right, on a machine, typically there will be some new servers, services that are added, some new ports that are open, some packages are installed. So you want to verify whether those things happen or not. So you need some way, some framework to actually help you query the operating system, whether particular services are running or not. So we need two things here. One is we need to be able to create some environments where we can test our code. The second is we need some server testing mechanism. We want to be able to SSH into a server where we have run our code and verify whether the particular actions have happened or not, like installation of a package or service starting. Okay, let's get started with the demo. Before that, I'll actually get into Chef basics because I'm going to use Chef here. I'll take a couple of minutes if you have any questions or if you are lost somewhere, because you want that installation to work with different platforms and different versions of those platforms, absolutely. Yes, right, in fact, you could use Chefs, MySQL, which is already there. I think I have to get some part of what it already does. But for the sake of a demo, it's kept as simple as possible. All right, so we look at Chef basics, which are, Chef is a popular configuration automation framework. What it does is it lets you automate different operations tasks and Chef actually works in client server mode, all right? So there is a Chef server which holds all the infrastructure code. And there are these Chef clients, they're called us. There are these nodes in your infrastructure which pull that infrastructure code and run the infrastructure code on them, right? So the server and the clients are actually connected and the server is like a repository of infrastructure code and clients pull this infrastructure code and run whatever they require to run. So there could be a web server in this which just requires HTTP code to run on it and a DB server and so on. There is something called as a workstation to write your infrastructure code. So typically Chef servers might be Unix or Linux boxes and it might be difficult to actually code in those boxes. You need some workstation workspace to write your code and test it and then upload it to the Chef server. So Chef workstation actually takes care of that. It is usually your own machine. You can use your IDs to write your code and test it and upload it. This workstation also can talk to nodes to bootstrap them and to do some preliminary installation on the Chef clients. So there is a very important tool in Chef which does the task of uploading infrastructure code into server. Anybody wants to guess what that could be? It is Chef. What is the most important tool that Chef would require? A knife. So there is something called as a knife which uploads, which actually communicates with the server and it also bootstraps the Chef clients. So these are the basics of Chef components. I don't want to get into more detail about it and I want to talk about how Chef organizes its infrastructure code. So we have been talking about, there is a lot of infrastructure code in the server and it is going to get pulled by the nodes and so on. But how does actually Chef organize its infrastructure code? Is it in classes and objects? How does it actually treat it? There are two important concepts that Chef uses. One is called a recipe and a cookbook, again quite understandably. A recipe is a file that does the basic task in Chef like installing MySQL or configuring MySQL or upgrading MySQL. And there is something called as a cookbook which is a collection of recipes. So you combine all the related recipes for a particular component and then call it a cookbook and upload it into Chef server which is used by the Chef clients. So we're going to do that, we're going to build that. It typically bootstraps the nodes that by that it installs Chef client software on the nodes. So the nodes actually have a piece of Chef architecture which is called as a Chef client that knows how to pull the infrastructure code from the server to the node. So Knife establishes communication between the server and the nodes. All right, we can actually take it offline and explain it to you. Individual silos which can be cross-used. Yeah, so if you are building cookbooks for common components like how I'm doing it, building it for MySQL or some DBs which can be reused across, then they are reusable across the community itself. So there is a Chef supermarket where you can find a lot of cookbooks. So if you want to actually install MySQL for your application, you can download that cookbook and use it right away. I just want to ask is practically are the cookbooks related to each application which is to be installed, has a cookbook because it will have multiple things, MySQL, a front-end, a web service. So is it the practice with this done in many companies? A cookbook is not at an application level. At an application level, you have something called as a different run lists. Run lists are combinations of different cookbooks. Cookbook applies at a component level. So if you are doing a packaging for your application, you'll create a packaging cookbook which will contain code for the application packaging. But for building an entire end-to-end infrastructure, it's not just packaging, right? You have to install your softwares and then configure them and then package them. So you have to create a list of all the cookbooks that you want to be installed on the node. That is called as a run list for each node. What is that answer? Have a cookbook. So for dealing with Tomcat related tasks, you have a Tomcat cookbook and for dealing with the other things that means web server, HTTP tasks, you have a HTTP cookbook. Whereas in that HTTPD, you have got HTTP management, you have got different tasks like installation, configuration. So each of those tasks becomes a recipe. A recipe is like the most basic block in Chef. Yes, you can, yes, you can do that. Yeah, it depends on the level of obstruction that you want to have. Yeah, you can do that. But actually, the Chef, the app server and the... How you want to structure your cookbooks. Generally, it is at an app server level, you have a cookbook and at an app server level, you have a cookbook. But if you are actually using the reusable cookbooks from Chef supermarket, right? Then you can create a cookbook on top of that and then structure it that way. It depends on how you want to break down your infrastructure model. And if that is a reusable component that you're going to use across all your environments, then if that makes sense, that you can organize it that way. All right. So a cookbook can be a combination of other recipes from other cookbooks also. The app server, it could be Javas or Tomcat or anything. Right? Any specific, okay, I have one Tomcat cookbook that I have on Javas that I have on top. It's nothing like that. Yes. So in your application, you want to abstract out, okay, do the app server installation and that actually takes care of installing whichever platform you are using, right? Yeah, so. But you will eventually be reusing some Javas cookbook or the Tomcat cookbook from open-sourced, you know, library, right? So cookbook is the basic block that is actually packaged in Chef. A recipe cannot stand alone. So if you want to upload some code into Chef server, it has to be a cookbook. You can combine cookbooks and then form a nested level and then pick recipes from different cookbooks and then combine them to form a cookbook that makes sense to your application. The list is a sequence of recipes that you actually run for the node. The recipes will be sitting in cookbooks. So I can show you an example, maybe. I try to hide the details just to, or maybe I have it here. So here you can, so this is a command from using Knife where we are configuring a run list for a node and node two is the name of the node, all right? There you can see that I'm creating a list from recipes alone. So this is the recipe. I'm adding to this run list is MySQL install. Run list is a list of recipes. It's not a list of cookbooks. So you can actually, to answer, come back to your question, you can create a run list from different cookbooks and recipes too, instead of having to aggregate them into another cookbook, okay? So I missed your question. So this MySQL is a cookbook. Cookbook is what is managed by a Chef server. It is versioned. It is a collection of recipes. But run list is actually, it's a list at a recipe level because you might have different cookbooks and you might want to collect recipes, different recipes from them. Yes, the recipes installed. So this is, sorry, this is the cookbook name and install is the recipe name. And you can create a run list of different recipes from different cookbooks. Yes, recipes are the basic tasks that you do, like install. That's the reason. Okay. Then it makes it. Okay. Anybody has any questions so far? All right. I'd like to do a very basic workstation. What do you mean by workstations? My machine, developer's machine. Yeah, absolutely. What it applies to, what it develops, and it's awesome. But can you give me an example of the tasks that you want to do? Very basic, but say, I have set of applications which are to be used by a developer as part of this particular application. So every time that on board, as part of onboarding process, a lot of time goes over there for installation and all. I just create one cookbook for them, which they execute and I mean, it is installed in that application. Yeah, absolutely. I think that can be done and that's a very good use of using any configuration automation framework also. Building development environments, using the required softwares, it helps in two ways. One thing is your dev environments are not becoming works of art. Generally dev environments start with some software and then you upgrade it, you do something on that and then they gather dust, right? So which means your code might be actually working against some versions, whereas the actual production environment, something else. But if you create a cookbook which has installers for all the different softwares that is required, then all the dev environments are actually consistent and you can actually use something like Vagrant to create those dev environments. I'll be using Vagrant, I'll be talking about it in a bit. But whether you can create one cookbook, you can certainly create one cookbook, whether it is a good idea or not, that is debatable. You might want to have modularity at different tasks that you are doing, that is you are developing four or five different applications, right? Installing applications. You might want to have a modularity at that level and then combine the different recipes that you want to actually do. Vagrant and Chef are not dev-hoc together. Chef is a confidential communication network and what Vagrant does is it gives you a wrapper around the virtualization platform. So Chef, so Vagrant gives you the machines on which to run Chef code. Yeah, right. So shall I go ahead? So where was I? All right, so we are going to do some test-driven development here, right? So let us look at what test frameworks that Chef has and what are the things that we actually need? So if you remember, we identified two things that we'll actually require for writing tests. One was anybody wants to recollect? Just to reassure me that you have actually listened. Otherwise I'm going to take some names. Krishnan. All right, sorry, sorry, I know him. So we identified two things, right? One is we need a framework that can query the server or the machine on which the installation happened. Let us say we are installing MySQL. We need a way to know whether MySQL service is running after the installation, to know whether a particular port is actually running, is open or not, and some other stuff like that. We can do it manually also, but I'm not a big fan of manual testing. Are there any fans of manual testing? Every time you deploy code, you want to log into the machine and then actually verify that. Nobody, right? All right, so we want some framework that actually does that task for us. And the second thing that we wanted was we needed some environments to actually test our code. Now we cannot use the application's test environments because for the infrastructure code, they're actual production environments, right? The test environments that we have in our application pipeline, in the application stages, they may be test environments for your application code, but not for infrastructure code because you're going to build those test environments with your infrastructure code. So you need some platform or some mechanism to create the different environments which are going to be supported by the infrastructure, right? So Chef actually offers different frameworks to solve that, and we also need, by the way, we also need a third thing that is unit testing. We want to have some basic tests that run very, very quickly. If we change something by mistake, we get to know about it, right? So Chef supports these frameworks out of the box. In fact, the reason why I chose Chef for this demo and not Puppet was that it has got very good integration with the different testing frameworks, all right? So at the unit level, it has got ChefSpec. If you're using Puppet, there is also a good unit testing framework in Puppet, but it does not have good support for the remaining two frameworks, all right? So ChefSpec gives you a way to just, for every Chef statement that you write, you can verify whether that statement is there or not. It does not do any deployment. It's just a static checking of whether the code is exactly the same as it is written. And ServerSpec is what helps you do the service query and the port query, as we talked about. ServerSpec is supposed to work with different configuration automation frameworks, all right? And the environment part that we were talking about is provided by Test Kitchen. Test Kitchen helps you spin different environments, depending on the templates that you provide it. So if you give it some vagrant boxes, it will create instances of those vagrant boxes. It will not touch those boxes as such, but it will take those as templates and then create some environments for you on which you can deploy your code and test it and then make sure that it works. So if you supply it AWS node information, it will create an instance exactly like that of the, that AWS server and it will actually run your code. So that's an interesting thing and a very helpful thing. The way Test Kitchen works is it has different plugins for different virtualization platforms, okay? So I can actually maybe show you. And maybe I'm talking too much without showing the code. Do you want to wait till I actually show the code? So these are the three things that we are going to use. And I think that's pretty much the concepts that I have, the theory that I have, and I'll very quickly jump into the demo. I'll not waste your time by actually, I'm sorry, anybody has any questions? Okay, by installing stuff or the delay in actually checking out the code and so on. So what it is, I have this code checked into GitHub repo and I created different stages as per our, as per how we want to progress, all right? So in the first stage, I'll actually show how Test Kitchen can create the test environments depending on our templates. And then we'll write tests. Remember this is TDD write, we'll write tests and see them fail and then we'll write the code to actually see them pass one after another. We'll just first write code for CentOS and then we'll write code for Ubuntu and then see them pass. And then finally we'll add some unit tests and then we'll deploy it on the actual Chef Clients. So in the first stage, as I was speaking, we wanted to create the test environments themselves, right? We need some place where to deploy our code. So this is a Test Kitchen's configuration file in YAML. Here I'm specifying the different platforms on which I want to run the code. So I want to run them on Ubuntu and CentOS with these versions. These are simply names for the machines. But the actual template is going to come from a Vagrant box, Ubuntu 1204 and CentOS 64. So in my Vagrant environment, I actually have Ubuntu 12.04 and CentOS 64 boxes. Vagrant boxes, how many of us have worked with Vagrant before? Plop hands. So Vagrant is a, as I mentioned before, it's a wrapper on your actual virtualization platform. It helps you to be easily able to work with the underlying platform. So if you are using virtual box as the virtualization software, right? Vagrant gives you easy commands, like Vagrant create, destroy, Vagrant up to be able to talk to it. Otherwise you'll have to use that particular platforms, command and interface to do that. There are some other merits to it. I'm not going to go into detail into that. But in the Test Kitchen environments, I'm actually asking Test Kitchen, hey, I've got two Vagrant boxes. Give me, create me environments based off of them, but do not touch my Vagrant boxes. I might actually use them for some serious stuff. So, okay, this is the stage one. And I have created these two boxes already, so that we don't waste time in creating them. So this is a Test Kitchen command, which is actually telling you that the two boxes are created and it is appending a default name to it. So you know that these are newly created instances actually out of the templates. So there is a default Ubuntu 12.04 and default CN2.64 created by Kitchen for you as Test Environments. I didn't actually run any tests so far. In this stage, I'm actually running the tests and it will fail now. I'm going to show you failing tests. I didn't get your question. I'm not answering this question. You have to write a failing test. Yeah, yeah. Why did you write code before the failing test? So it's a white page because it's already, the Google Server is up, the box is up, and the server is also up. Right. And it's quite great. The servers are up. No infrastructure code is actually deployed on them and we have not even yet written any tests. So this is a point where, okay, let me show you the code. No, the server is where the infrastructure, I know. I think I get your point. We are not using, so what I'm doing now is not actually creating the CentOS server. I'm actually installing MySQL on it. Okay. But that's an interesting thing and it's very complicated to actually, for me to demo it or test it, I believe. All right. So at this point, we have got two environments, two instances, which have nothing on them. No infrastructure code, not even tests. Those are just our test environments. Am I making sense at all? Any sense? Absolutely, it can be. Chef can be used for a range of things. The scope where we are right now is, we have servers that are going to install MySQL on it. All right. In the second stage, or in the next stage, let me not keep numbering them. I'm going to add some tests. So we are adding these tests even before we are writing code. All right. So these are the server tests that are called as or component tests. What we're taking here is whether MySQL service is running or not. And a particular port, the default port of MySQL is listening or not. So when you don't install anything, MySQL, this would not be listening. And this is parameterizable. This is not the best way to do it. But I actually, for the sake of simplicity, I put it in here. Depending on where you are installing it, which is most likely to come from a configuration file, this has to be parameterized. All right. So now we are going to run these tests. So the framework that is used for this is ServerSpec here. And as I told you before, it gives you a way to query the underlying operating system to give you feedback whether things are working, things are installed or not, et cetera. It is based on RSpec. So if any of you have used RSpec before, this syntax should look familiar. It is an RSpec expectation. And this is the DSL of ServerSpec. So it has got a lot of assertions to verify whether things are to be listening or to be running. It reads better. So you know what you're checking. You know that port is listening, port should be listening, service should be running. Yes. Now, when I actually, so this is the second stage I am on. So I'm on the second stage where I have only added the tests. I have not written any code. And let me show you that in the cookbook that I'm actually developing, right? There is no code as of now. There is a recipe. It is an empty recipe. There is an installed recipe here, but it is empty. I have not written anything, but I have got some tests to drive my development. Yes. Kitchen still has that yaml file, right? Kitchen has the same yaml file. Okay, let me run this test now. By the way, if you have noticed, the two tests actually apply to both the platforms. So I'm seeing the tests are failing. And maybe for a change, I'm happy that the tests are actually failing. So the tests that are failing are both the tests. My SQL configured server is listening on port, is failing, and also it has a running service of my SQL. This is also failing. All right, which is quite understandable, right? Because we haven't written the code yet. Now, in the next stage, we are actually going to write some code to get it to pass. So this is stage three, and I have written some code here. So the code that I wrote is applicable just for CentOS platform. And I'm using yaml package manager, obviously, because it is a red hat flavor. And this is a Chef statement. It is in fact coming from another cookbook, from some default cookbooks. So there is an action defined in that cookbook, which actually, which lets you install packages. And then I'm starting my SQL demon. You don't have to. So I'm actually building it incrementally. So I'm writing some code to just get the CentOS stuff work fast, and then I'll add something else to get the Ubuntu up. Was that your question whether we are, we have to write different? Yes, right, because different platforms actually use different package managers, and the process of installation also could be different. We'll say that for Ubuntu, it's not a straightforward usage of the package manager app kit. We actually have to do some preceding for the MySQL admin password and credentials. We have to use a preceding file for that. So it differs on different platforms. And that I think is a challenge, and having configuration automation frameworks like Chef, they actually create an abstraction over different platforms. They're one level above that so that you can use one cookbook to install MySQL on any platform. Provided they're tested well. Okay, so at this stage, what do we expect to happen? We expect to have a partial pass because we have only coded for CentOS. So this is just coded for stage three for CentOS. So let me just see. I'm running tests against CentOS platform alone. So Kitchen actually lets you run against one of the environments. So we had CentOS over to two, right? So here we are running just against CentOS. And it runs fine because the code is actually built and it is deployed on the instance. All right, am I making sense so far? Now let me see whether Ubuntu is going to work or not. This should fail, right? Because we haven't written the code. It fails. First time I think a demo is running as I expected. All right. So let us go to, let us now build the code for, write the code even for Ubuntu. I'm just stage three, stage four, Ubuntu. Good books, recipes, install. So earlier we have written a code for CentOS and now we are saying if platform is Ubuntu then do something else. And you can see that the implementation actually got more complicated, right? We are using a template, a seed file, which is defined here. It requires password information. And I hope, let me try to put it in. I hope you are able to see it. So it requires a seed file. Now these are the implementation details. If you are installing MySQL on that, you do Google, you'll know that this is something that has to be done. And it also requires the password to be specified in a variable, right? That is coming from attributes. I have specified MySQL admin password here. It uses the template and does some magic here. And it doesn't update its package repository. And then finally it does an install. All right. This is the code to perform the installation on Ubuntu. And we have included that. And now at this stage, the test should pass for both, right? So this will actually make, this will actually get the test to pass. So in the TDD we have written test first and then we have written code to satisfy those tests and then we have tests that are green passing, all right? In the next stage, I'm actually going to add some ChefSpec tests around it. So we were talking about a unit testing framework, right? So ChefSpec verifies whether you are using some Chef statements. Like in the earlier, in the recipe, you have seen that we were doing a install action on app package. You saw the action install on app package, right? Let me just show you that. Yes, exactly. There are packages along with the code. I think that was the top of the code. Okay, so here I have come back to the interact code actually. So we are using app package command here and then we are using an action on this, right? So to write ChefSpec tests for it, we have to verify whether the particular usage is there or not. So in the ChefSpec test, what I verify is that whether install app package command is used or not. So the moment I change code in the infra code, this test will actually fail. All right, am I making sense here? If you are not understanding the details, I think that's all right, but the concept is that have some tests, unit tests around that so that whenever you make any change by mistake, your unit tests give you the quickest feedback. All right, so these are my spec tests which run very fast, ChefSpec tests, unit tests. Okay, so that is pretty much about building the cookbook. So we have a cookbook which takes care of installing MySQL on different platforms, all right? The next step would be to actually deploy it on Chef nodes and also see that it works. You may want to run some tests when it is actually deployed. Now as testers, we do not want to really trust that, things will work fine when deployed in production when they are actually tested in local test environments. So you can actually run the same server spec tests on your nodes also just to make sure that services are running, ports are open and so on. I will quickly show how you might want to deploy. This is more like a Chef thing. So stop me if you would not be interested in actually looking at this. A load balancer is again a server, right? And it'll have some configuration, some way to install it, some way to configure it. Yes, right. Depending again on which kind of load balancer you want to use. There is a Chef supermarket where you can actually download already defined cookbooks, already created cookbooks that can actually give you a lot of help if you want to use some web servers and some app servers, things like that. So if Tomcat is your application container, you do not really want to create code for this. I'm just doing this for the sake of an example. You can actually use it ready made, but you should just make sure that they are from authentic source and they're tested well. Sometimes I've seen that the cookbooks did not actually run as expected when I was running it. Yeah. The servers on the node, I mean, what is it? Create, yes, what I'm trying to do now is to install my SQL on the actual nodes. So going back to the slides, right? So we are here, we are in our workstation where we have developed cookbook. Now we have to upload it to server and then actually deploy it on the actual infrastructure. You need to test it. We have written, we have tested the functionality also, right? Not just unit tested, but yeah, you might want to call depending on how you define unit test. It is locally tested, right? So Kitchen was actually creating the environments locally. Now you are going to, now we have to upload the cookbook into Chef server and then the Chef clients will actually pull it and then run it. In the stages that I used because it's a different repo, it actually created new environments that's not necessary. Otherwise I would have to create them. I don't have to create them, but you know, I have to check it out and then show. So that might slow the demo. That's the reason why I'm using it. So for every kitchen, different kitchen yamble file, it's going to create new instances. And if I actually look at it, I don't want to look at my virtual box now. There might be some 10 instances created, right? So we have a lot of instances created because I have so many stages and each stage is creating two instances. This is not necessary. This is just for the demonstration. All right, so now let us try to upload the cookbook into Chef server. This is just going to take, oh five more minutes. I think I'm shooting, overshooting time. We'll try to wrap it up very quickly. So as I told you before, knife is a very important tool in Chef, obviously. And it takes care of communicating with the server, uploading your work into Chef server. Here I'm actually seeing, I have already uploaded it. I'm not uploading it now. So I just want to show you that knife cookbook list is actually going to show you all the cookbooks that are uploaded into the server. Okay, and for my demo, I have used Hosted Chef. Hosted Chef is a Chef server on the cloud that you can use to create some environments, all right? So I have created two environments on Hosted Chef. It gives you up to five nodes forever, I believe, but they keep sending you emails about your feedback, how you're using it. So this is Chef server on the cloud. You can actually use it. I have created two instances on that. One is CentOS and the other is Ubuntu. And these are my actual infrastructure servers on which I'm going to install my SQL. Now, to install it, so to install code on different Chef clients, what they require is, as we have seen in the diagram before, Chef clients are going to pull code from the server. All that there needs to be is a run list defined for the nodes. Every node should know what it has to run, right? So I've defined run list here already. Let me see. So using this command, I have defined a run list for node one and node two to run my SQL install, all right? I hope I'm not confusing you, but just try to understand that there are these run lists defined and when I run Chef client on the nodes, my SQL is going to get installed on them. And these are my nodes here. This is node one. I'm running Chef client here. So it is supposed to run the MySQL cookbook on it and actually install MySQL on it. So it's running Chef code. It'll take maybe a couple of minutes, but before that, this is the end of the demo anyway. I would like to take questions as this is running. If not, this is going to run. I'm sure. I just tried it in the morning. So yeah, so that is all I have, but I'll be available. Those of you who want to stay back for this, please stay back, but those of you who want to actually remind me that I'm overshooting time, have just a couple of slides to wrap it up. Can you try it at home? Yes, you can try it at home. This is not done under any strict surveillance or whatever. You can use, as I told you, hosted Chef to create some nodes and you can take the guidance of the repo that I have. It is pretty much exactly what I have used. So you can do that. And also try with other recipes. I have used a very simple concept to demonstrate, but you can use try to configure more involved infrastructure components. And also tell me how it goes. So this is the repo location and this is where you can reach me. I also have some Chef related blogs on my blog post on my blog if you want to get any help with that. So that is all I have. Okay, it ran. So we were running it on Ubuntu and you can see that the cookbook ran, it actually ran, I installed my SQL on it. I can also verify it using server spec. Not going to do that now. Right. Do I not have, I have shown you the Chef control panel. This is what it is called as. Can you run Chef clients on, you know, from here? I am not really sure. You should be able to do it. But usually the way it happens is you have a set of commands that you define and then that gets, so Chef client periodically keeps pulling pulling out the infrastructure code. And whenever it's run list or modified, it actually updates itself. It is better run as a command line because in a CI CD pipeline, right? You will specify that as a task and it keeps pulling down the code and then running periodically, rather than using here. This means you have to actually manually do it every time. You don't want that. You'll have some jobs, periodical scheduled jobs to do that. Okay. That's all I have. Thank you so much. Thanks for the patience.