Cover image for Customizing Chef

Book Description

Take advantage of Chef’s highly customizable design to tackle specific automation issues that you can’t solve by simply using Chef’s tools, resources, and services out of the box. With this practical guide, you’ll examine the internal structure of this configuration management technology and learn where, how, and why to add custom code.

Table of Contents

  1. Dedication
  2. Foreword
  3. Preface
    1. Who This Book Is For
    2. How This Book Is Organized
    3. Conventions Used in This Book
    4. Using Code Examples
    5. Safari® Books Online
    6. How to Contact Us
    7. Acknowledgments
  4. I. Chef and Ruby 101
    1. 1. Introduction
      1. What Is Configuration Management?
      2. So Why Chef?
      3. Think Critically
      4. Meet AwesomeInc
      5. Criteria for Customization
        1. How Do We Find Out When Our Chef Runs Are Failing, and Why?
        2. How Do We Simplify Our Recipes to Reduce the Amount of Replicated Code?
        3. How Do We Stop Our Developers and Ops Staff from Treading All over Each Other’s Changes?
      6. State of the Customization Nation
        1. Chef Supermarket
        2. Development Tooling
        3. Workflow Tooling
        4. Knife Plugins
        5. Handlers
        6. Recipes and Resources
      7. Chef Installation Types and Limitations
        1. chef-solo
        2. Open Source Chef
        3. Local Mode
        4. Private Enterprise Chef
        5. Hosted Enterprise Chef
      8. Prerequisites
        1. Knife
        2. Nodes and Clients
        3. Cookbooks, Attributes, Roles, Environments, and Data Bags
        4. Chef Search
        5. Ruby
      9. Assumptions
    2. 2. Just Enough Ruby to Customize Chef
      1. Ruby Is Object-Oriented
      2. Ruby Is Dynamically Typed
      3. Classes
        1. Getter and Setter Methods
      4. Variable Scoping
        1. Local Variables
        2. Class Instance Variables
      5. Inheritance
      6. Modules
        1. Modules as Namespaces
        2. Modules as Mixins
      7. Using Other Classes and Modules
        1. Local Classes
        2. RubyGems
        3. Built-in Classes
      8. When Things Go Wrong
        1. Exceptions
        2. Handling Exceptions
        3. Defining Custom Exception Types
      9. Tying It All Together
        1. File Operations
        2. HTTP Requests
      10. Summary
    3. 3. Chef Internals
      1. Chef Architecture
        1. Chef Client Tools
        2. Chef Server
      2. Anatomy of a Chef Run
        1. Get Configuration Data
          1. Ohai
        2. Authenticate/Register
        3. Load and Build Node Object
        4. Synchronize Cookbooks
        5. SetUp RunContext
        6. Load Cookbook Data
        7. Converge Node
        8. Finalize
      3. Dry-Run and Why-Run
        1. The Problem with Dry-Run
        2. Why-Run Mode
        3. Usefulness of Why-Run
      4. Using the Source
        1. Getting the Chef Source Code
        2. Chef Source Structure
      5. Tracing a chef-client Run
        1. Execute the chef-client Command
        2. Run the Real chef-client Script
        3. The Chef::Application::Client Class
        4. The Chef::Application::Client run_chef_client Method
        5. The Chef::Client Class
        6. The Chef::Client Class do_run Method
      6. Summary
  5. II. Customizing Chef Runs
    1. 4. Extending Ohai
      1. Introduction
        1. Ohai Attribute Collection
        2. The Ohai Source Code
      2. Ohai Example 1: Plugin Skeleton
      3. Testing and Running Ohai Plugins
        1. Testing Using irb
        2. Running Using Chef
      4. Ohai Example 2: Adding More to the Plugin
        1. The Mash Object
        2. Multiple collect_data Methods
        3. Running example2.rb
      5. Ohai Example 3: Multilevel Plugins
      6. Summary
    2. 5. Creating Handlers
      1. Preparing a Test Environment
        1. Create the Test chef-client Configuration
        2. Create a Test Cookbook
        3. Verify That the Test Environment Works Correctly
      2. Introduction to Handlers
      3. The Run Status Object
        1. Run Status Methods
        2. Run Information Methods
        3. Run Object Methods
      4. Handler Example 1: Start Handler
      5. Handler Example 2: Report Handler
      6. Handler Example 3: Exception Handler
      7. Handlers: Summary and Further Reading
    3. 6. Extending Chef Run Events
      1. Introduction to the Event Dispatcher
      2. Event Dispatcher Initialization
      3. Publish Overview
      4. Subscribe Overview
      5. Creating Formatters
        1. Formatter Example 1: Skeleton Formatter
        2. Formatter Example 2: Slightly Less Skeletal
        3. Formatter Example 3: Custom Event Methods
        4. Setting the Default Formatter
        5. Formatters: Summary and Further Reading
      6. Creating Custom Subscribers
        1. Subscriber Example 1: Skeleton Subscriber
        2. Subscriber Example 2: Registration with Start Handlers
        3. Subscriber Example 3: Custom Event Methods
        4. Custom Subscribers: Summary
      7. Revisiting AwesomeInc—Which Customization?
      8. Summary
  6. III. Customizing Recipes
    1. 7. Definitions and Libraries
      1. Cookbook Structure Revisited
      2. Creating a Test Environment
      3. Definitions
        1. What Is a Definition?
        2. Definition Example 1: Skeleton
        3. Adding Parameters
        4. Definition Example 2: Using Parameters
        5. Adding Resources
        6. Definition Example 3: Using Resources
      4. Libraries
        1. What Is a Library?
        2. Library Example 1: Modules and Mixins
        3. Library Example 2: Methods in a Custom Namespace
        4. Library Example 3: Extending Core Chef Classes
        5. Summary and Further Reading
    2. 8. Lightweight Resources and Providers
      1. Introduction to Resources and Providers
        1. Automatically Choosing Providers
        2. Resources and Providers—Lightweight Versus Heavyweight
      2. Introduction to LWRPs
      3. LWRP Example 1: Getting Started with LWRPs
        1. Example 1: Creating a Resource
        2. Example 1: Creating a Provider
        3. Example 1: Using Our LWRP in a Recipe
      4. The LWRP Domain-Specific Language
        1. Resource DSL
        2. Provider DSL
      5. LWRP Example 2: Extending the Provider
      6. Provider Internals
        1. Desired Resource State
        2. Current Resource State
        3. Identifying and Executing Changes
          1. Keep it simple, keep it relevant
          2. Pick your state object sensibly
          3. Remember the criteria
        4. Informing Chef About Updates
      7. LWRP Example 3: Native Provider
        1. Example 3: Preparing the Resource and Provider
        2. Example 3: The load_current_resource Method
        3. Example 3: Coding the Actions
      8. Summary and Further Reading
    3. 9. Heavyweight Resources and Providers
      1. Introduction to HWRPs
        1. Why Write HWRPs?
        2. HWRPs in Cookbooks
      2. HWRP Example 1: Getting Started with HWRPs
        1. Example 1: Creating a Resource
        2. Example 1: Creating a Provider
        3. Example 1: Using Our HWRP in a Recipe
        4. Example 1: Extending the Provider
      3. Advanced HWRP Tricks
        1. Mixing HWRPs and LWRPs
        2. Overriding Automatic Provider Resolution
        3. Implementing Multi-Provider Resources
      4. HWRP Example 2: Extending the package Resource
        1. Example 2: Creating a Provider
        2. Example 2: Using Our Provider in a Recipe
        3. Example 2: Tapping into Chef’s Provider Mapping
      5. Summary and Further Reading
  7. IV. Other Customizations
    1. 10. Customizing Knife
      1. The Knife Source Code
      2. Introduction to Knife Plugins
      3. Anatomy of a Knife Command
        1. Step 1: Validate and Parse Options
        2. Step 2: Load Plugins
        3. Step 3: Get Subcommand Class
        4. Step 4: Load Dependencies
        5. Step 5: Create Subcommand Object
        6. Step 6: Run Plugin
      4. Creating a Test Environment
        1. Prerequisites and Preparation
        2. Verifying That the Test Environment Works Correctly
      5. Knife Example 1: Wrapping an Existing Plugin
      6. Presenting Presenters!
        1. Chef::Knife::Core::GenericPresenter
        2. Chef::Knife::Core::NodePresenter
      7. The UI Class
        1. User Interaction Methods
        2. Message Output Methods
        3. Other Output Methods
        4. Object Editing Methods
        5. HighLine Methods
      8. Knife Example 2: Search Plugin
      9. Working with Chef Objects
        1. Loading Objects: Searching
        2. Loading Objects: Direct Loading
        3. Editing and Saving Objects Noninteractively
        4. Editing and Saving Objects Interactively
        5. Creating and Updating Objects from Files
      10. Knife Example 3: Tying It All Together
      11. Revisiting AwesomeInc—Plugin Best Practices
      12. Summary and Further Reading
    2. 11. The Chef API
      1. Introduction to the Chef API
        1. So Why Use the Chef API?
        2. Authenticating to the Chef API
      2. Creating a Test Environment
      3. API Example 1: Authenticating and Making a GET Request
      4. The Chef::Rest Class
      5. API Example 2: Combining Multiple API Requests
      6. Error Handling
      7. Secrets of the Chef API
        1. The /_status Endpoint
        2. Partial Search
      8. Summary and Further Reading
    3. 12. Contributing Your Customizations
      1. Documentation
      2. Supporting Your Code
      3. Managing Contributions
      4. Testing Your Software
        1. Ruby and Infrastructure Testing Tools
        2. Continuous Integration Tools
        3. Chef-Specific Tooling
        4. Further Reading
      5. Versioning Your Software
        1. Semantic Versioning
      6. Licensing and Copyright
        1. Copyright
        2. Licensing Your Code
      7. Distributing Your Customizations
        1. Sharing the Source Code
        2. Community Cookbooks
        3. RubyGems
        4. Distribution via Cookbook
      8. Summary
    4. A. Chef API Endpoints and Verbs
  8. Index
  9. Colophon
  10. Copyright