Rapid Chef Development with Berkshelf, Test-Kitchen and Foodcritic

Preview:

DESCRIPTION

An introduction to Chef Cookbook development tools: * Berkshelf * Test-Kitchen * Foodcritic

Citation preview

CLOUD SAVVY

BROWN BAG:Rapid Chef

Development

Hart Hoover@hhoover

CLOUD SAVVY 2

CLOUD SAVVY 3

ENTERPRISE

CLOUD SAVVY 4

CHEF SOLO

CLOUD SAVVY 5OPEN SOURCE CHEF

CLOUD SAVVY

TOOLS!

6

CLOUD SAVVY

TOOLS!

6

• Git/GitHub

CLOUD SAVVY

TOOLS!

6

• Git/GitHub

• Berkshelf

CLOUD SAVVY

TOOLS!

6

• Git/GitHub

• Berkshelf

• Vagrant

CLOUD SAVVY

TOOLS!

6

• Git/GitHub

• Berkshelf

• Vagrant

• Vagrant Plugins

CLOUD SAVVY

TOOLS!

6

• Git/GitHub

• Berkshelf

• Vagrant

• Vagrant Plugins

• Test Kitchen

CLOUD SAVVY

TOOLS!

6

• Git/GitHub

• Berkshelf

• Vagrant

• Vagrant Plugins

• Test Kitchen

• Foodcritic

CLOUD SAVVY 7

CLOUD SAVVY 8

CLOUD SAVVY 8

CLOUD SAVVY 8

CLOUD SAVVY 8

• A CLI Tool

• A Source Code Management Tool

• A Package Manager

• Replaces parts of knife

• Specifically cookbook management

CLOUD SAVVY 8

• A CLI Tool

• A Source Code Management Tool

• A Package Manager

• Replaces parts of knife

• Specifically cookbook management

THE BERKSHELF WAY IS BETTER

CLOUD SAVVY 9

CLOUD SAVVY 10

CLOUD SAVVY 11

Why Vagrant?

• Repeatable• Customizable• “It works on my machine.”

Developers

CLOUD SAVVY 12

Why Vagrant?

• Disposable Machines• Test your provisioning• Local → Production

Operations

CLOUD SAVVY 13

Why Vagrant?

=

CLOUD SAVVY 14

TEST KITCHEN

Convergence Integration Testing

for Chef

CLOUD SAVVY 14

TEST KITCHEN

Convergence Integration Testing

for Chef

Does my cookbook work?

CLOUD SAVVY 14

TEST KITCHEN

Convergence Integration Testing

for Chef

Does my cookbook work?

NO

CLOUD SAVVY 15

FoodCritic

Lint testing!

Makes it easy to flagknown issues

Better Cookbooks!

CLOUD SAVVY

ChefWorkFlowS

CLOUD SAVVY

OLD CHEF DEV WORKFLOW

17

CLOUD SAVVY

OLD CHEF DEV WORKFLOW

17

EditCookbook

CLOUD SAVVY

OLD CHEF DEV WORKFLOW

17

EditCookbook

UploadCookbook

CLOUD SAVVY

OLD CHEF DEV WORKFLOW

17

EditCookbook

ProvisionMachine

UploadCookbook

CLOUD SAVVY

OLD CHEF DEV WORKFLOW

17

EditCookbook

ProvisionMachine

BootstrapMachine

UploadCookbook

CLOUD SAVVY

OLD CHEF DEV WORKFLOW

17

EditCookbook

ProvisionMachine

BootstrapMachine

UploadCookbook

RunChef Client

CLOUD SAVVY

OLD CHEF DEV WORKFLOW

17

EditCookbook

ProvisionMachine

BootstrapMachine

SSH & Validate

UploadCookbook

RunChef Client

CLOUD SAVVY

OLD CHEF DEV WORKFLOW

17

EditCookbook

ProvisionMachine

BootstrapMachine

SSH & Validate

UploadCookbook

RunChef Client

CLOUD SAVVY

NEW CHEF DEV WORKFLOW

18

EditCookbook

VagrantUp

TestKitchen

CLOUD SAVVY

Our Workflow

19

Berkshelf VagrantUp

TestKitchen GitHub Production Monitoring

CLOUD SAVVY

Our Workflow

19

Berkshelf VagrantUp

TestKitchen GitHub Production Monitoring

CLOUD SAVVY

Our Workflow

19

{DEV

Berkshelf VagrantUp

TestKitchen GitHub Production Monitoring

CLOUD SAVVY

Our Workflow

19

{DEV OPS{Berkshelf Vagrant

UpTest

Kitchen GitHub Production Monitoring

CLOUD SAVVY

DevelopmentWalkthroughPrerequisites

CLOUD SAVVY

What You need• VirtualBox • Vagrant• Opscode’s 12.04 Vagrant Box• Ruby (1.9.3 or higher!)

• Berkshelf• Test Kitchen• Foodcritic

21

CLOUD SAVVY

Virtualbox

22

https://www.virtualbox.org/wiki/Downloads

CLOUD SAVVY

Vagrant

23

http://downloads.vagrantup.com

CLOUD SAVVY

OPSCODE’S VAGRANT BOX

24

$  vagrant  box  add  \opscode-­‐ubuntu-­‐12.04  \http://tinyurl.com/chef1204  

CLOUD SAVVY

CREATE A PROJECT

25

$  mkdir  -­‐p  ~/projects/chefnovaclient

$  cd  ~/projects/chefnovaclient

CLOUD SAVVY

Berkshelf

26

$  gem  install  berkshelf

CLOUD SAVVY

Test Kitchen

27

$  gem  install  test-­‐kitchen  -­‐-­‐pre

CLOUD SAVVY

FoodCritic

28

$  gem  install  foodcritic

CLOUD SAVVY 29

CLOUD SAVVY

DevelopmentWalkthrough

rackspace-novaclient&

supernova

CLOUD SAVVY

GET STARTED

31

$  berks  init

$  cd  ~/projects/chefnovaclient

CLOUD SAVVY 32

$  berks  initberks  init            create    Berksfile            create    Thorfile            create    .gitignore                  run    git  init  from  "."            create    Gemfile            create    .kitchen.yml            append    Thorfile            create    test/integration/default            append    .gitignore            append    .gitignore            append    Gemfile            append    GemfileYou  must  run  `bundle  install'  to  fetch  any  new  gems.            create    VagrantfileSuccessfully  initialized

CLOUD SAVVY 33

$  berks  initberks  init            create    Berksfile            create    Thorfile            create    .gitignore                  run    git  init  from  "."            create    Gemfile            create    .kitchen.yml            append    Thorfile            create    test/integration/default            append    .gitignore            append    .gitignore            append    Gemfile            append    GemfileYou  must  run  `bundle  install'  to  fetch  any  new  gems.            create    VagrantfileSuccessfully  initialized

CLOUD SAVVY 34

$  berks  initberks  init            create    Berksfile            create    Thorfile            create    .gitignore                  run    git  init  from  "."            create    Gemfile            create    .kitchen.yml            append    Thorfile            create    test/integration/default            append    .gitignore            append    .gitignore            append    Gemfile            append    GemfileYou  must  run  `bundle  install'  to  fetch  any  new  gems.            create    VagrantfileSuccessfully  initialized

CLOUD SAVVY 35

$  berks  initberks  init            create    Berksfile            create    Thorfile            create    .gitignore                  run    git  init  from  "."            create    Gemfile            create    .kitchen.yml            append    Thorfile            create    test/integration/default            append    .gitignore            append    .gitignore            append    Gemfile            append    GemfileYou  must  run  `bundle  install'  to  fetch  any  new  gems.            create    VagrantfileSuccessfully  initialized

CLOUD SAVVY 36

$  berks  initberks  init            create    Berksfile            create    Thorfile            create    .gitignore                  run    git  init  from  "."            create    Gemfile            create    .kitchen.yml            append    Thorfile            create    test/integration/default            append    .gitignore            append    .gitignore            append    Gemfile            append    GemfileYou  must  run  `bundle  install'  to  fetch  any  new  gems.            create    VagrantfileSuccessfully  initialized

CLOUD SAVVY 37

$  berks  initberks  init            create    Berksfile            create    Thorfile            create    .gitignore                  run    git  init  from  "."            create    Gemfile            create    .kitchen.yml            append    Thorfile            create    test/integration/default            append    .gitignore            append    .gitignore            append    Gemfile            append    GemfileYou  must  run  `bundle  install'  to  fetch  any  new  gems.            create    VagrantfileSuccessfully  initialized

CLOUD SAVVY 38

$  berks  initberks  init            create    Berksfile            create    Thorfile            create    .gitignore                  run    git  init  from  "."            create    Gemfile            create    .kitchen.yml            append    Thorfile            create    test/integration/default            append    .gitignore            append    .gitignore            append    Gemfile            append    GemfileYou  must  run  `bundle  install'  to  fetch  any  new  gems.            create    VagrantfileSuccessfully  initialized

CLOUD SAVVY 39

CLOUD SAVVY

INSTALL Kitchen-Vagrant

40

$  gem  install  kitchen-­‐vagrant

CLOUD SAVVY

SET UP TEST KITCHEN

41

Goodbye10.04!

CLOUD SAVVY

RUN Test KitchEN

42

Good Luck!

$  kitchen  verify

CLOUD SAVVY 43

CLOUD SAVVY

WHAT FAILED?

44

FATAL:  No  cookbook  found

CLOUD SAVVY

What are our requirements?

45

CLOUD SAVVY

What are our requirements?

45

Python

pippackage manager

make

setuptools

CLOUD SAVVY

COPY/PasTE

46

http://tinyurl.com/chefpart2

CLOUD SAVVY

BERKSFILE: DependencIES!

47

site  :opscode

cookbook  'apt'cookbook  'build-­‐essential'cookbook  'python'

CLOUD SAVVY

RUN Test KitchEN

48

Good Luck!

$  kitchen  converge

CLOUD SAVVY 49

Congrats!

You installed something...

CLOUD SAVVY 49

Congrats!

You installed something...

but not what we need.

CLOUD SAVVY

BERKSFILE:THIS IS A COOKBOOK

50

site  :opscode

cookbook  'apt'cookbook  'build-­‐essential'cookbook  'python'metadata

CLOUD SAVVY

BERKSFILE:THIS IS A COOKBOOK

51

site  :opscode

cookbook  'apt'cookbook  'build-­‐essential'cookbook  'python'metadata

CLOUD SAVVY

RUN Test KitchEN

52

Good Luck!

$  kitchen  converge

CLOUD SAVVY 53

CLOUD SAVVY

WHAT FAILED?

54

Failed  to  complete  #converge  action

CLOUD SAVVY

metadata.RB:What is this THING??

55

name  "chefnovaclient"version  "1.0.0"description  "Installs  the  novaclient."maintainer  "Hart  Hoover"maintainer_email  "hart.hoover@rackspace.com"

depends  "python"depends  "apt"

supports  "ubuntu"

CLOUD SAVVY

RUN Test KitchEN

56

Good Luck!

$  kitchen  converge

CLOUD SAVVY 57

Congrats!

You installed something...

CLOUD SAVVY 57

Congrats!

You installed something...

but STILL not what we need.

CLOUD SAVVY

TIME TO WRITE RECIPES

58

CLOUD SAVVY

TIME TO WRITE RECIPES

59

$  berks  cookbook  .

Don’t overwrite stuff

CLOUD SAVVY

Default RECIPE:recipes/default.rb

60

include_recipe  "apt"include_recipe  "python::pip"

%w{git  python-­‐dev  build-­‐essential}.each  do  |pkg|   package  pkg  do     action  :install   endend

python_pip  "rackspace-­‐novaclient"  do   action  :installend

CLOUD SAVVY 61

include_recipe  "apt"include_recipe  "python::pip"

%w{git  python-­‐dev  build-­‐essential}.each  do  |pkg|   package  pkg  do     action  :install   endend

python_pip  "rackspace-­‐novaclient"  do   action  :installend

Default RECIPE:recipes/default.rb

CLOUD SAVVY 62

include_recipe  "apt"include_recipe  "python::pip"

%w{git  python-­‐dev  build-­‐essential}.each  do  |pkg|   package  pkg  do     action  :install   endend

python_pip  "rackspace-­‐novaclient"  do   action  :installend

Default RECIPE:recipes/default.rb

CLOUD SAVVY 63

include_recipe  "apt"include_recipe  "python::pip"

%w{git  python-­‐dev  build-­‐essential}.each  do  |pkg|   package  pkg  do     action  :install   endend

python_pip  "rackspace-­‐novaclient"  do   action  :installend

Default RECIPE:recipes/default.rb

CLOUD SAVVY

EDIT YOUR RUN LIST

64

suites:-­‐  name:  default    run_list:        -­‐  recipe[chefnovaclient::default]    attributes:  {}

.kitchen.yaml

CLOUD SAVVY

EDIT YOUR RUN LIST

65

suites:-­‐  name:  default    run_list:        -­‐  recipe[chefnovaclient::default]    attributes:  {}

.kitchen.yaml

CLOUD SAVVY

RUN FOODCRITIC!

66

$  foodcritic  .

Everything good?

CLOUD SAVVY 67

FIX IT!

If Not:

CLOUD SAVVY

RUN Test KitchEN

68

Good Luck!

$  kitchen  converge

CLOUD SAVVY

Did it work?

69

$  kitchen  login  default$  nova  help

CLOUD SAVVY 70

CLOUD SAVVY 71

CLOUD SAVVY 72

SUPERNOVA

CLOUD SAVVY

Let’s MAKE AUTOMATED TESTs

73

$  mkdir  test/integration/default/bats

$  touch  test/integration/default/bats/supernova.bats

CLOUD SAVVY

TESTING

74

test/integration/default/bats/supernova.bats

#!/usr/bin/env  bats

@test  "supernova  is  installed"  {    which  supernova}

CLOUD SAVVY 75

@test  "supernova  config  exists"  {    cat  /home/vagrant/.supernova}

TESTINGtest/integration/default/bats/supernova.bats

CLOUD SAVVY 76

@test  "run  supernova"  {    supernova  myaccount  list}

TESTINGtest/integration/default/bats/supernova.bats

CLOUD SAVVY 77

@test  "novaclient  installed"  {    which  nova}

TESTINGtest/integration/default/bats/supernova.bats

CLOUD SAVVY

SUPERNOVA

78

recipes/default.rb

python_pip  "git+git://github.com/major/supernova.git"  do   action  :installend

template  "/home/vagrant/.supernova"  do    source  "supernova.erb"    mode  0600    owner  "vagrant"    group  "vagrant"end

CLOUD SAVVY

SuperNova

79

templates/default/supernova.erb[myaccount]OS_AUTH_URL=https://identity.api.rackspacecloud.com/v2.0/OS_VERSION=2.0OS_AUTH_SYSTEM=rackspaceOS_REGION_NAME=DFWOS_SERVICE_NAME=cloudserversOpenStackOS_TENANT_NAME=<%=  node['chefnovaclient']['username']  %>OS_USERNAME=<%=  node['chefnovaclient']['username']  %>OS_PASSWORD=<%=  node['chefnovaclient']['password']  %>OS_NO_CACHE=1NOVA_VOLUME_SERVICE_NAME=cloudBlockStorage

CLOUD SAVVY

SuperNova

80

templates/default/supernova.erb[myaccount]OS_AUTH_URL=https://identity.api.rackspacecloud.com/v2.0/OS_VERSION=2.0OS_AUTH_SYSTEM=rackspaceOS_REGION_NAME=DFWOS_SERVICE_NAME=cloudserversOpenStackOS_TENANT_NAME=<%=  node['chefnovaclient']['username']  %>OS_USERNAME=<%=  node['chefnovaclient']['username']  %>OS_PASSWORD=<%=  node['chefnovaclient']['password']  %>OS_NO_CACHE=1NOVA_VOLUME_SERVICE_NAME=cloudBlockStorage

CLOUD SAVVY

SuperNova

81

attributes/default.rb

default['chefnovaclient']['username']  =  "USERNAME"default['chefnovaclient']['password']  =  "APIKEY"

CLOUD SAVVY

RUN FOODCRITIC!

82

$  foodcritic  .

Everything good?

CLOUD SAVVY

RUN Test KitchEN

83

Good Luck!

$  kitchen  converge

CLOUD SAVVY

RUN YOUR Tests

84

Good Luck!

$  kitchen  verify

CLOUD SAVVY

“SAVE YOUR WORK”

85

CLOUD SAVVY

THANKYOU!

Recommended