CHAPTER 10

image

Lightweight Resource Providers

This chapter discusses lightweight resource providers (LWRPs). They are a way to enhance the functionality of chef to provide new integrations which are not provided for out-of-box in chef.

Lightweight Resource Providers

A resource is something that defines the action that needs to be taken and a provider is something that executes that action.

To implement the functionality of a resource and provider in a recipe which is not an inbuilt resource provider, you can create your own LWRPs. You can use custom Ruby codes and inbuilt chef resources to create an LWRP.

LWRPs help in achieving the core objective of chef which is idempotence. One can achieve this state using scripts or recipes by leveraging “if”-type constructs to choose when to run the script; however, this process becomes fairly complex to manage.

LWRPs help us in achieving idempotence for complex and scalable infrastructure to provide reliable configuration management.

LWRPs are loaded from files that are saved in the following cookbook subdirectories:

Directory

Description

providers/

The subdirectory in which lightweight providers are located.

resources/

The subdirectory in which lightweight resources are located.

The name of the cookbook and the name of the files in the resources/ and providers/ subdirectories determine the naming patterns of LWRPs.

For example, if a cookbook named example was downloaded to the chef repository, it would be located under /cookbooks/example/. If that cookbook contained two resources and two providers, the following files would be part of the resources/ directory:

Files

Resource Name

Generated Class

default.rb

Example

Chef::Resource::Example

custom.rb

Custom

Chef::Resource::ExampleCustom

And the following files would be part of the providers/ directory:

Files

Provider Name

Generated Class

default.rb

Example

Chef::Provider::Example

custom.rb

Custom

Chef::Provider::ExampleCustom

Chef-Maintained LWRPs

Chef maintains a number of LWRPs. We will discuss some of the important LWRPs maintained by the Opscode community. These are available in cookbooks. If we need to use them, we need to download the cookbook from the community, upload the cookbook to our chef server, and then use them in our custom recipes.

Cookbook

Description

apt

This cookbook is used to configure APT (Advanced Packaging Tool) for managing APT preferences and repositories.

aws

AWS refers to Amazon Web Services. This cookbook can be used to manage the resources that are running in AWS cloud.

chef_handler

This cookbook is used for exception handling. It distributes and enables the exception and report handlers.

cron

Cron is used to schedule something in Unix. This cookbook is used to install cron and start its service.

daemontools

Daemontools are used to manage Unix services. This cookbook is used to install and configure daemontools.

firewall

This cookbook is used to maintain the firewall rules.

homebrew

Homebrew is a package manager for Mac OS. This cookbook helps us to install and configure Homebrew.

iis

This is a Windows-based cookbook and can be used to install and configure IIS (Internet Information Services) server.

lvm

This cookbook is used to install the LVM2 package and then manage LVM.

nginx

This cookbook is used to install and configure Nginx from source code or package and then set up configuration handling.

php

This cookbook can be used to install and configure PHP and custom modules for PHP.

postfix

This cookbook can be used to install and configure Postfix.

powershell

This cookbook is used to install the Powershell module on Windows servers.

rabbitmq

This cookbook will install the RabbitMQ-server.

squid

This cookbook is used to install and configure Squid as a caching proxy server.

sudo

This cookbook is used install sudo and then configure the/etc/sudoers file.

windows

This cookbook can be used for the built-in Windows commands.

yum

This cookbook is used for the yum configuration file.

Creating an LWRP

This section will demonstrate how to create an LWRP. We will create an LWRP to download Wordpress setup, extract it to the desired location, and then delete the downloaded file.

  1. The first step is to create a cookbook in which we will create the resource and provider. Create a cookbook named wp_setup using the knife.  We execute the following command from a workstation:
    knife cookbook create wp_setup
  2. The command creates the files and directories that are required for developing a cookbook (see Figure 10-1). The cookbook will be created in the local chef repository.

    9781430262954_Fig10-01.jpg

    Figure 10-1. Directory structure

  3. The resource directory is where we create our resource. Create a default.rb file in the resource directory. In the default.rb, write the following code:
    actions :extract, :remove
    attribute :wp_url, :kind_of=> String, default: "https://wordpress.org/latest.tar.gz"
    attribute :wp_path, :kind_of=> String, default: "/var/www"

    In this code sample, we are defining the following:

    • Actions: this defines the actions that need to be taken in this particular resource. In this case, we are defining two actions: extract and remove.
    • Attribute: here we define the attributes that will be passed to the resource. In this example, we are passing an attribute called wp_url, which is kind_of string and is a default parameter. The value of this parameter is the download location of the Wordpress web site tar file.

    A default attribute is specified in the resource file so that if an attribute is not specified in the recipe or attribute file, chef client will take the default value from the resource file.

  4. The next step after defining the resource is to map the actions that we have defined to actual execution code which is defined in the provider.

    When the chef client identifies a custom resource, it will look for the related actions method in the provider.

    Create a default.rb file under the folder named providers of wp_setup cookbook.

    In this file, we define the actions to be performed.

    Create methods for the custom actions specified in the resource file.

    def whyrun_supported?
      true
    end

    We use the whyrun method if we want chef client to tell the changes that would be applied to the node without actually applying them when it is run in whyrun mode. Its value can be true or false. For this example, we will set this value to true. To run the chef client in whyrun mode, run Chef-client –W.

    Now we need to define the code that will be executed on calling of actions that we defined in the resources. First we will define the extract action. We will use Ruby and inbuilt chef resources to define the complete set of actions.

    In this method we are using the File.exists? method to check if there is an existing Wordpress folder to achieve idempotency.

    Chef::Log class is used to log entries in the log file.

    A new_resource.updated_by_last_action method notifies the LWRP if the node has successfully updated. True or false is passed as an argument to this method to notify the execution of LWRP.

    The converge_by is a wrapper method used when the chef client runs in whyrun mode and displays a message about that block of code.

    if ::File.exists?("#{new_resource.wp_path}/wordpress")

       Chef::Log.info "#{ @new_resource } already exists - nothing to do."
       new_resource.updated_by_last_action(false)
     
    else
     
    converge_by("Downloading wordpress file") do

    The remote_file is an inbuilt chef resource that downloads the file from a certain URL (uniform resource locator) to the node.

    remote_file "#{new_resource.wp_path}/wordpress.tar.gz" do

       source "#{new_resource.wp_url}"
       action :create
     
    end

    Bash is also an inbuilt chef resource that is used to run bash scripts. We are using the bash resource to extract the downloaded Wordpress file.

    bash "extracting wordpress" do
        code <<-EOH
        cd /var/www
        mkdir wordpress
        tar -xvf wordpres.tar.gz wordpress
        EOH
     
    end

    The following snippet shows the whole code clubbed together:

    action :extract do
     
     if ::File.exists?("#{new_resource.wp_path}/wordpress")

       Chef::Log.info "#{ @new_resource } already exists - nothing to do."
       new_resource.updated_by_last_action(false)
     
    else
     
    converge_by("Downloading wordpress file") do
     
    remote_file "#{new_resource.wp_path}/wordpress.tar.gz" do

       source "#{new_resource.wp_url}"
       action :create
     
    end
     
    bash "extracting wordpress" do

       code <<-EOH
       cd /var/www
       mkdir wordpress
       tar -xvf wordpres.tar.gz wordpress
       EOH

       end

      end

      new_resource.updated_by_last_action(true)

      end
     
    end

    Action: remove: This method contains the inbuilt file resource which will delete the Wordpress installation file.

    Chef::Log class is used to log entries in the log file.

    The new_resource.updated_by_last_action method notifies the LWRP if the node has successfully updated. True or false is passed as argument to this method to notify the execution of LWRP.

    converge_by is a wrapper method used when chef client runs in whyrun mode and displays a message about that block of code.

    File is an inbuilt chef resource that has an action delete, which will delete any file.

    action :remove do
     
     unless ::File.exists?("#{new_resource.wp_path}/wordpress.tar.gz")

      Chef::Log.info "#{ @new_resource } file deleted - nothing to do."
      new_resource.updated_by_last_action(false)

     else

     converge_by("removing the compressed wordpress file") do

      file "#{new_resource.wp_path}/wordpress.tar.gz" do
      action :delete

      end

      directory "/root/chefdemo" do

       action :create

      end

     end

     new_resource.updated_by_last_action(true)

     end

    end
  5. You can use the resource name in the recipe once the resource and provider are in place. Since we created the resource and provider in default.rb files, the resource name will be the cookbook’s name. If the resource and provider have a name other than default.rb, that name has to be appended to the cookbook name while using it in the recipe.
    syntax: cookbookname_resourcename
    wp_setup "extracting wordpress" do
    wp_path node[:wordpress][:path]
    wp_url node[:wordpress][:url]
    action :extract
    end
     
    wp_setup "deleting the installation file" do
    wp_path node[:wordpress][:path]
    action :remove
    end
  6. The attributes wp_path and wp_url are passed using the attribute file.
    default[:wordpress][:url] = "https://wordpress.org/latest.tar.gz"
    default[:wordpress][:path] = "/var/www"
  7. Upload the cookbook to chef server using knife (see Figure 10-2). Knife commands are executed from a workstation.
    knife cookbook upload wp_setup

    9781430262954_Fig10-02.jpg

    Figure 10-2. Uploading the cookbook

  8. Run the chef client on the node (see Figure 10-3).

    9781430262954_Fig10-03.jpg

    Figure 10-3. Running chef client

  9. Confirm the chef client run (see Figure 10-4) by browsing the Wordpress directory under the /var/www folder.

9781430262954_Fig10-04.jpg

Figure 10-4. Verifying installation

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset