Writing a Cookbook and Upload to Chef Server

Introduction


Chef is a configuration management arrangement designed to allow you to automate and control vast numbers of computers in an automated, reliable, and scalable manner.

In previous tutorials, nosotros take looked at some mutual Chef terminology and discussed how to install a Chef server, workstation, and nodes (with Chef 12 or Chef xi). In this guide, we will use these guides as a jumping off point to brainstorm talking almost how to automate your environment.

In this commodity, we volition discuss the basics of creating a Chef cookbook. Cookbooks are the configuration units that allow us to configure and perform specific tasks inside Chef on our remote nodes. We build cookbooks so tell Chef which nodes we want to run the steps outlined in the cookbook.

In this guide, we volition presume that you are starting with the iii machines that we ended the last lesson with. You should have a server, a workstation, and at to the lowest degree ane node to push configuration changes to.

Basic Cookbook Concepts


Cookbooks serve as the primal unit of configuration and policy details that Chef uses to bring a node into a specific state. This just ways that Chef uses cookbooks to perform work and make sure things are as they should be on the node.

Cookbooks are commonly used to handle one specific service, awarding, or functionality. For instance, a cookbook can be created to use NTP to set and sync the node'south time with a specific server. It may install and configure a database application. Cookbooks are basically packages for infrastructure choices.

Cookbooks are created on the workstation and then uploaded to a Chef server. From there, recipes and policies described within the cookbook can be assigned to nodes every bit office of the node's "run-listing". A run-list is a sequential list of recipes and roles that are run on a node by chef-client in club to bring the node into compliance with the policy you set up for it.

In this way, the configuration details that you write in your cookbook are applied to the nodes yous desire to adhere to the scenario described in the cookbook.

Cookbooks are organized in a directory structure that is completely self-independent. There are many different directories and files that are used for different purposes. Let's go over some of the more important ones now.

Recipes


A recipe is the chief workhorse of the cookbook. A cookbook can contain more than one recipe, or depend on outside recipes. Recipes are used to declare the state of dissimilar resources.

Chef resources draw a office of the organisation and its desired country. For instance, a resources could say "the packet 10 should be installed". Another resource may say "the x service should be running".

A recipe is a list related resources that tell Chef how the system should look if it implements the recipe. When Chef runs the recipe, it checks each resource for compliance to the declared country. If the system matches, it moves on to the next resource, otherwise, information technology attempts to move the resource into the given state.

Resources can be of many dissimilar types. You can acquire nearly the different resources types here. Some common ones are:

  • packet: Used to manage packages on a node
  • service: Used to manage services on a node
  • user: Manage users on the node
  • grouping: Manage groups
  • template: Manage files with embedded cherry-red templates
  • cookbook_file: Transfer files from the files subdirectory in the cookbook to a location on the node
  • file: Manage contents of a file on node
  • directory: Manage directories on node
  • execute: Execute a command on the node
  • cron: Edit an existing cron file on the node

Attributes


Attributes in Chef are basically settings. Retrieve of them every bit elementary key-value pairs for anything you might want to utilize in your cookbook.

There are several different kinds of attributes that can be practical, each with a different level of precedence over the last settings that a node operates under. At the cookbook level, nosotros generally define the default attributes of the service or system we are configuring. These can be overridden later by more specific values for a specific node.

When creating a cookbook, nosotros can gear up attributes for our service in the attributes subdirectory of our cookbook. We can and so reference these values in other parts of our cookbook.

Files


The files subdirectory within the cookbook contains whatsoever static files that we volition exist placing on the nodes that use the cookbook.

For instance, whatsoever simple configuration files that nosotros are not likely to modify can exist placed, in their entirety, in the files subdirectory. A recipe can and so declare a resource that moves the files from that directory into their concluding location on the node.

Templates


Templates are similar to files, but they are not static. Template files terminate with the .erb extension, significant that they incorporate embedded Ruby.

These are mainly used to substitute attribute values into the file to create the final file version that volition exist placed on the node.

For case, if we accept an aspect that defines the default port for a service, the template file can phone call to insert the aspect at the bespeak in the file where the port is alleged. Using this technique, y'all can easily create configuration files, while keeping the actual variables that you wish to alter elsewhere.

Metadata.rb


The metadata.rb file is used, non surprisingly, to manage the metadata nearly a bundle. This includes things like the proper name of the bundle, a clarification, etc.

It as well includes things like dependency information, where you can specify which cookbooks this cookbook needs to operate. This will let the Chef server to build the run-list for the nodes correctly and ensure that all of the pieces are transfered correctly.

Create a Simple Cookbook


To demonstrate some of the work flow involved in working with cookbooks, we will create a cookbook of our own. This will be a very simple cookbook that installs and configures the Nginx web server on our node.

To brainstorm, nosotros need to go to our ~/chef-repo directory on our workstation:

          cd ~/chef-repo                  

Once there, we can create a cookbook by using pocketknife. Every bit we mentioned in previous guides, knife is a tool used to configure nigh interactions with the Chef system. We can use it to perform work on our workstation and likewise to connect with the Chef server or individual nodes.

The full general syntax for creating a cookbook is:

<pre> pocketknife cookbook create <bridge class="highlight">cookbook_name</span> </pre>

Since our cookbook will deal with installing and configuring Nginx, we will name our cookbook accordingly:

          pocketknife cookbook create nginx                  

          ** Creating cookbook nginx ** Creating README for cookbook: nginx ** Creating CHANGELOG for cookbook: nginx ** Creating metadata for cookbook: nginx                  

What knife does here is builds a uncomplicated structure within our cookbooks directory for our new cookbook. We can come across our cookbook construction by navigating into the cookbooks directory, and into the directory with the cookbook proper noun.

          cd cookbooks/nginx ls                  

          attributes  CHANGELOG.md  definitions  files  libraries  metadata.rb  providers  README.doctor  recipes  resources	templates                  

As you tin run into, this has created a binder and file structure that we tin can use to build our cookbook. Permit'south brainstorm with the biggest chunk of the configuration, the recipe.

Create a Simple Recipe


If we go into the recipes subdirectory, we can run into that there is already a file called default.rb inside:

          cd recipes ls                  

          default.rb                  

This is the recipe that will be run if you reference the "nginx" recipe. This is where nosotros volition be adding our code.

Open the file with your text editor:

          nano default.rb                  

          # # Cookbook Name:: nginx # Recipe:: default # # Copyright 2014, YOUR_COMPANY_NAME # # All rights reserved - Practise Not Redistribute #                  

The only thing that is in this file currently is a annotate header.

We tin begin by planning the things that need to happen for our Nginx web server to go upwardly and running the way that we want it to. We do this past configuring "resources". Resources do not draw how to do something; they simply depict what a part of the system should look like when it is complete.

Get-go of all, we obviously need to brand sure the software is installed. We can do this by creating a "parcel" resource first.

          bundle 'nginx' do   action :install terminate                  

This little piece of code defines a package resource for Nginx. The first line begins with the blazon of resource (package) and the proper noun of the resource ('nginx'). The rest is a group of actions and parameters that declare what we desire to happen with the resource.

In this resources, we run across activity :install. This line tells Chef that the resource we are describing should be installed. The node that runs this recipe will bank check that Nginx is installed. If it is, it volition check that off the listing of things to do. If non, it will install the program using the methods available on the customer system and then check it off.

After we install the service, we probably desire to suit its current state on the node. By default, Ubuntu does not start Nginx after installation, then we will desire to change that:

          service 'nginx' do   activeness [ :enable, :start ] end                  

Here, we see a resource of the "service" type. This declares that for the Nginx service component (the function that allows us to manage the server with init or upstart), we want to start the service correct at present, and also enable it to kickoff automatically when the automobile is restarted.

The concluding resource nosotros will be declaring is the actual file that we will be serving. Since this is simply a simple file that we will non be modifying, we can merely declare the location where nosotros desire the file and tell it where in the cookbook to get the file:

          cookbook_file "/usr/share/nginx/world wide web/index.html" practise   source "index.html"   mode "0644" end                  

We utilize the "cookbook_file" resource blazon to tell Chef that this file is available within the cookbook itself and can exist transfered equally-is to the location. In our case, we are transferring a file into Nginx's certificate root.

In our case, we specify the file name that nosotros are trying to create in the showtime line. In the "source" line, we tell it the name of the file to look for within the cookbook. Chef looks for this file within the "files/default" subdirectory in the cookbook.

The "mode" line sets the permissions on the file we are creating. In this instance, we are allowing the root user read and write permissions and anybody else read permissions.

Save and close this file when you lot are finished.

Creating the Index file


As y'all saw higher up, we divers a "cookbook_file" resource which should motion a file called "alphabetize.html" into the document root on the node. We need to create this file.

We should put this file in the "files/default" subdirectory of our cookbook. Go at that place now by typing:

          cd ~/chef-repo/cookbooks/nginx/files/default                  

Inside this directory, we will create the file we referenced:

          nano alphabetize.html                  

This file volition merely be a really simple HTML document meant to demonstrate that our resources take operated the fashion we wanted them to.

Paste this into the file:

          <html>   <head>     <title>Hello there</title>   </head>   <body>     <h1>This is a exam</h1>     <p>Please work!</p>   </torso> </html>                  

Save and close the file when you are finished.

Create a Helper Cookbook


Before we go any further, let's preemptively solve a small-scale trouble. When our node tries to run the cookbook that nosotros've created equally it is at present, chances are, it volition fail.

That is because it will endeavor to install Nginx from the Ubuntu repositories, and the package database on our node is most likely out-of-date. Usually, nosotros run "sudo apt-get update" prior to running packet commands.

To address this issue, nosotros can create a simple cookbook whose only purpose is to ensure that the package database is updated.

Nosotros can practise this using the same knife syntax we used before. Let's phone call this cookbook "apt":

          knife cookbook create apt                  

This volition create the same kind of directory construction that we had when we outset started with our Nginx cookbook.

Allow's cut direct to the hunt and edit the default recipe for our new cookbook.

          nano ~/chef-repo/cookbooks/apt/recipes/default.rb                  

In this file, we will declare an "execute" resource. This is but a way of defining a command that we want to run on the node.

Our resource looks like this:

          execute "apt-go update" practise   command "apt-get update" end                  

The first line gives a proper name for our resource. In our case, we are calling the resource this for simplicity'due south sake. If the "command" aspect is divers (as we take done), then this is the actual command that is executed.

Since these are exactly the same, it does not matter in the slightest.

Save and close the file.

At present that we have our new cookbook, in that location are a number of ways that we tin can make sure that we execute this before our Nginx cookbook. We could add it to the node's run-list before the Nginx cookbook, simply we can also tie it into the Nginx cookbook itself.

This is probably the better pick considering nosotros volition non accept to recollect to add the "apt" cookbook before the "nginx" cookbook on every node we want to configure for Nginx.

We demand to conform a few things in the Nginx cookbook to make this happen. Kickoff, let's open up the Nginx recipe file again:

          nano ~/chef-repo/cookbooks/nginx/recipes/default.rb                  

At the summit of this cookbook, earlier the other resource that we have defined, nosotros tin can read in the "apt" default recipe past typing:

<pre> <bridge class="highlight">include_recipe "apt"</span>

package 'nginx' exercise action :install cease

service 'nginx' practise action [ :enable, :start ] finish

cookbook_file "/usr/share/nginx/www/index.html" practice source "index.html" mode "0644" finish </pre>

Salvage and shut the file.

The other file that we need to edit is the metadata.rb file. This file is checked when the Chef server sends the run-listing to the node, to come across which other recipes should be added to the run-listing.

Open the file now:

          nano ~/chef-repo/cookbooks/nginx/metadata.rb                  

At the bottom of the file, yous tin add this line:

<pre> name 'nginx' maintainer 'YOUR_COMPANY_NAME' maintainer_email 'YOUR_EMAIL' license 'All rights reserved' description 'Installs/Configures nginx' long_description IO.read(File.join(File.dirname(FILE), 'README.doctor')) version '0.1.0'

<bridge class="highlight">depends "apt"</span> </pre>

With that finished, our Nginx cookbook now relies on our apt cookbook to take care of the package database update.

Add the Cookbook to your Node


Now that our basic cookbooks are consummate, we tin can upload them to our chef server.

We can practice that individually past typing:

          pocketknife cookbook upload apt pocketknife cookbook upload nginx                  

Or, nosotros can upload everything past typing:

          knife cookbook upload -a                  

Either way, our recipes will be uploaded to the Chef server.

Now, we can change the run-listing of our nodes. Nosotros tin can do this hands past typing:

<pre> knife node edit <span class="highlight">name_of_node</span> </pre>

If you demand to find the name of your available nodes, you lot tin type:

          knife node list                  

          client1                  

For our purposes, when we type this, we go a file that looks like this:

          knife node edit client1                  

          {   "name": "client1",   "chef_environment": "_default",   "normal": {     "tags": [      ]   },   "run_list": [    ] }                  

You lot may demand to set your EDITOR ecology variable before this works. You tin do this by typing:

<pre> consign EDITOR=<span class="highlight">name_of_editor</span> </pre>

Equally you can see, this is a unproblematic JSON certificate that describes some aspects of our node. We can see a "run_list" assortment, which is currently empty.

Nosotros tin can add our Nginx cookbook to that array using the format:

<pre> "recipe[<span grade="highlight">name_of_recipe</span>]" </pre>

When nosotros are finished, our file should look like this:

          {   "name": "client1",   "chef_environment": "_default",   "normal": {     "tags": [      ]   },   "run_list": [     "recipe[nginx]"   ] }                  

Save and shut the file to implement the new settings.

Now, we can SSH into our node and run the Chef customer software. This will cause the client to check into the Chef server. Once it does this, it volition run into the new run-list that has been assigned information technology.

SSH into your node and then run this:

          sudo chef-customer                  

          Starting Chef Client, version 11.8.2 resolving cookbooks for run list: ["nginx"] Synchronizing Cookbooks:   - apt   - nginx Compiling Cookbooks... Converging 4 resources Recipe: apt::default   * execute[apt-get update] action run     - execute apt-get update  Recipe: nginx::default   * package[nginx] activity install (up to date)   * service[nginx] activeness enable     - enable service service[nginx]    * service[nginx] activity commencement (up to date)   * cookbook_file[/usr/share/nginx/www/index.html] action create (up to date) Chef Client finished, 2 resource updated                  

Every bit you can see, our apt cookbook was sent over and run too, fifty-fifty though it wasn't in the run-list nosotros created. That is considering Chef intelligently resolved dependencies and modified the actual run-list before executing it on the node.

Note: There are various methods of ensuring that one cookbook or recipe is run before another. Adding a dependency is only one choice, and other methods may be preferred.

We can verify that this works by going to our node'due south IP address or domain proper noun:

<pre> http://<span form="highlight">node_domain_or_IP</span> </pre>

You should meet something that looks like this:

Chef node Nginx

Congratulations, yous have configured your first node using Chef cookbooks!

Conclusion


Although this was a very uncomplicated example that probably didn't save you much fourth dimension over configuring your server manually, hopefully you lot tin can begin to run into the possibilities of this method of building infrastructure.

Not only does information technology let for rapid deployment and configuration of dissimilar kinds of servers, information technology ensures that yous know the exact configuration of all of your machines. This lets yous validate and test your infrastructure, and also gives you the framework yous demand to chop-chop redeploy your infrastructure on a whim.

<div course="writer">Past Justin Ellingwood</div>

maynardsundis1937.blogspot.com

Source: https://www.digitalocean.com/community/tutorials/how-to-create-simple-chef-cookbooks-to-manage-infrastructure-on-ubuntu

0 Response to "Writing a Cookbook and Upload to Chef Server"

Postar um comentário

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel