Code Monkey home page Code Monkey logo

sous_chef's Introduction

sous_chef

Description

Installs and configures a Jenkins server for cookbook testing. This cookbook sets up a continuous deployment pipeline for your chef cookbooks. Sous_Chef is an opinionated cookbook designed to simplify the process of testing and publishing your cookbooks to chef.

This cookbook sets up a jenkins server which will execute your specified cookbook testing workflow in addition to machine configuration for ruby environment, gem installation, bundler tasks, git and needed deploy keys.

Notes

This cookbook is not yet ready for the general use-case, as it has been written to the specifics of CommerceHub's environment. The largest assumptions made here are vSphere as hypervisor, and Ubuntu Linux as the client OS. In addition to that we are currently running open source chef server 11.X.

If you would like to extend/adapt for your usage, we encourage you to file issues and welcome Pull Requests.

Requirements

This cookbook depends on several other cookbooks to accomplish the task of configuring a jenkins server to test cookbooks.

  • 'jenkins'
  • 'git'
  • 'build-essential'
  • 'apt'

Platforms

  • Ubuntu 12.04 LTS
  • Ubuntu 14.04 LTS

Contributing

Refer to Contributing for more information about contributing to the sous_chef project.

Usage

The sous_chef cookbook will setup a jenkins server with the end goal of having a continuous deployment pipeline for chef cookbooks. Many of the recipes are designed to only be included in other recipes, these are noted by starting with underscore('_').

To setup just the jenkins server with no cookbook jobs refer to Jenkins Server role file example.

In addition to configuring the jenkins server with everything needed to start cookbook testing, Sous_Chef provides an attribute driven system to create jenkins jobs for cookbooks. This job will represent the deployment pipeline for the chef cookbook. These jobs will be broken into several steps as part of a cookbook testing pipeline. These steps include:

  • bundle install
  • rubocop
  • foodcritic
  • test_kitchen
  • upload_cookbook

This cookbook stresses convention over configuration. There is a default job structure including defaults for many of the configuration options. These defaults are designed to be sane and reasonable, but may be overridden as needed. Keep in mind this cookbook makes assumptions on how the steps should execute and run by default. The default setup for each cookbook job can be found in the default['sous_chef']['default_cookbook'] attribute, and is also described in the Attributes section below. Refer to the Role File Examples for an idea of how this functions.

Refer to the wiki for more information and advanced usage:

Pre-Requisites

SSH Keys for Git Access

When jenkins clones a cookbook it may require ssh access to successfully pull down the remote repository. Sous_Chef will provide a relatively basic way to get your ssh keys setup for a cookbook job. You can configure an array of hashes in node['sous_chef']['jenkins_private_key_credentials'] to manage the private keys on sous_chef. Each hash should look like the example below.

Attributes:

{
  name: '', - The name of your jenkins credential
  id: '', - The ID for the credential
  description: '', - A human readable friendly description describing the credential
  private_key: '', - The private key associated with this credential.
}

The ID field must match regular expression /[a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[89aAbB][a-f0-9]{3}-[a-f0-9]{12}/. An example key taken from the jenkins cookbook readme looks as follows: 'fa3aab48-4edc-446d-b1e2-1d89d86f4458'

Long term plans are to rely on data_bags for the private_key or even the entire credential object but for now setting the private key as an attribute will suffice.

Chef Server Access:

Sous_Chef can upload your cookbook to your chef server after completion of your pipeline. To do this you need an account on your chef server with access to upload cookbooks. Sous_Chef provides a very basic and way to configure your jenkins node to communicate with your chef server. Simply set a few attributes as they pertain to your chef server and sous chef can configure the jenkins user with this information.

Attributes:

node['sous_chef']['chef']['manage_chef_config'] - Have Sous_Chef cookbook manage your chef configuration
node['sous_chef']['chef']['username'] - Username on the chef server
node['sous_chef']['chef']['server_url'] - Chef server URL
node['sous_chef']['chef']['validation_client_name'] -
node['sous_chef']['chef']['chef-validator'] - Your chef-validator pem
node['sous_chef']['chef']['user_pem'] - Your private key for the chef user your created

Long term there are plans to rely on data_bags for the chef-validator and user_pem but for now simply putting the keys as attributes will suffice.

Recipes

  • _base - This recipe includes pre-req and shared requirements for jenkins servers both master and slave.
  • _cookbook_job - The recipe to setup a job for cookbook testing
  • _plugins - The recipe which contains plugin installations and configuration
  • _chef_config - The recipe which will configure a .chef directory inside of the jenkins home directory for chef server access
  • default - The recipe that does nothing. Don't use it.
  • server - The recipe which sets up a jenkins master instance.

Role File Examples

In the below examples any and all combinations of attributes are supported. Each cookbook will be merged with the default cookbook. Feel free to only provide one attribute in a hash if you are only changing that attribute. You can refer to the default['sous_chef']['default_cookbook'] attribute for all possible configurable options.

Setup the jenkins cookbook testing server with all defaults

run_list *%w[
recipe[sous_chef::server]
]

default_attributes({})

Bare Bones: Configure a cookbook to leverage the service with all defaults

default_attributes(
sous_chef: {
  cookbooks: [
    {
      cookbook_name: 'sous_chef',
      cookbook_url: '[email protected]:commercehub-oss/sous_chef.git',
      notification: {
        email: {
          maintainers_email: '[email protected]'
        },
      }
    }
  ]
})

Hipchat Notification: Configure a cookbook to leverage the hipchat notification plugin

default_attributes(
sous_chef: {
  cookbooks: [
    {
      cookbook_name: 'sous_chef',
      cookbook_url: '[email protected]:commercehub-oss/sous_chef.git',
      notification: {
        email: {
          maintainers_email: '[email protected]'
        },
        hipchat: {
          enabled: true,
          hipchat_room: 'Chef'
        }
      }
    }
  ]
})

Triggers: Change how often a job polls SCM

default_attributes(
    sous_chef: {
        cookbooks: [
        {
            cookbook_name: 'sous_chef',
            cookbook_url: '[email protected]:commercehub-oss/sous_chef.git',
            triggers: {
                poll_scm: {
                    schedule: '*/5 * * * *'
                }
            }
        }
        ]
    }
)

Custom Job Definition: Not happy with defaults? Customize the job definition for any given job

default_attributes(
sous_chef: {
  cookbooks: [
    {
      cookbook_name: 'sous_chef',
      cookbook_url: '[email protected]:commercehub-oss/sous_chef.git',
      notification: {
        email: {
          maintainers_email: '[email protected]'
        },
      },
      steps: {
        foodcritic: {
          enabled: true,
          command: 'bundle exec foodcritic . -f correctness',
        }
      }
    }
  ]
})

Attributes

Below is the definition of the default cookbook attribute. This is the base for the job and steps being setup. This allows convention > configuration with minimal configuration.

Default Cookbook

default['sous_chef']['default_cookbook'] =
    {
      cookbook_name: 'cookbook_name',
      cookbook_url: 'cookbook_url',
      notification: {
        email: {
          enabled: true,
          maintainers_email: '[email protected]'
        },
        hipchat: {
          enabled: false,
          hipchat_room: '',
          notifyStarted: false,
          notifySuccess: true,
          notifyAborted: true,
          notifyNotBuilt: false,
          notifyUnstable: true,
          notifyFailure: true,
          notifyBackToNormal: true,
          startJobMessage: '',
          completeJobMessage: ''
        }
      },
      triggers: {
        poll_scm: {
          enabled: true,
          schedule: '*/1 * * * *'
        }
      },
      steps: {
        bundle: {
          enabled: true,
          command: 'bundle install --path vendor/bundle'
        },
        rubocop: {
          enabled: true,
          command: 'bundle exec rubocop'
        },
        foodcritic: {
          enabled: true,
          command: 'bundle exec foodcritic . -f any'
        },
        test_kitchen: {
          enabled: true,
          command: 'bundle exec kitchen test'
        },
        version: {
          enabled: false,
          command: 'thor version:bump patch'
        },
        upload_cookbook: {
          enabled: true,
          command: 'rsync -avzq . ./replace_with_cookbook --exclude replace_with_cookbook --exclude \'vendor\'
          knife cookbook upload replace_with_cookbook --cookbook-path . --freeze
          rm -rf replace_with_cookbook'
        }
      }
    }

Jenkins Configuration

default['sous_chef']['master_executors'] = 4
default['jenkins']['master']['install_method'] = 'package'
default['jenkins']['master']['version'] = nil

Plugins

## Mailer Notifier
default['sous_chef']['plugins']['mailer']['smtp_host'] = 'yourmailserver.example.com'
default['sous_chef']['plugins']['mailer']['smtp_port'] = '25'
default['sous_chef']['plugins']['mailer']['smtp_reply_to_address'] = '[email protected]'
default['sous_chef']['plugins']['mailer']['smtp_admin_address'] = '[email protected]'
default['sous_chef']['plugins']['mailer']['smtp_email_suffix'] = '@example.com'

## Hipchat Notifier
default['sous_chef']['plugins']['hipchat']['enabled'] = false
default['sous_chef']['plugins']['hipchat']['auth_token'] = ''
default['sous_chef']['plugins']['hipchat']['send_as'] = 'Sous Chef'
default['sous_chef']['plugins']['hipchat']['server_url'] = 'yourhipchatserver.example.com'
default['sous_chef']['plugins']['hipchat']['build_server_url'] = "http://#{node['fqdn']}:8080/"
default['sous_chef']['plugins']['hipchat']['default_room'] = 'Chef'

Chef

default['sous_chef']['chef']['manage_chef_config'] = false
default['sous_chef']['chef']['username'] = 'jenkins_cookbook'
default['sous_chef']['chef']['server_url'] = 'https://yourchefserver.example.com'
default['sous_chef']['chef']['validation_client_name'] = 'chef-validator'
default['sous_chef']['chef']['chef-validator'] = ''
default['sous_chef']['chef']['user_pem'] = ''

Private Keys

default['sous_chef']['jenkins_private_key_credentials'] = []

The Hash(s) under the jenkins_private_key_credentials should look like this

{
  name: '', - The name of your jenkins credential
  id: '', - The ID for the credential
  description: '', - A human readable friendly description describing the credential
  private_key: '', - The private key associated with this credential.
}

License and Author

Author:: CommerceHub
Author_Website:: www.commercehub.com
Twitter:: @CommerceHubTech

Copyright 2015, CommerceHub

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and

sous_chef's People

Contributors

gwaldo avatar zarry avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.