cfg mgmtcamp c-dwithchef

46
So Continuous. Much Delivery. Very Chef. Wow. A Case Study on using Chef to start building a Continuous Delivery Pipeline

Upload: george-miranda

Post on 10-May-2015

2.716 views

Category:

Technology


0 download

TRANSCRIPT

Page 1: Cfg mgmtcamp c-dwithchef

So Continuous. Much Delivery.

Very Chef. Wow.

A Case Study on using Chef to start building a Continuous Delivery Pipeline

Page 2: Cfg mgmtcamp c-dwithchef

• George Miranda

• Sr Consultant at Chef Software, Inc.

• Unix guy (15+ years)

About Me

Page 3: Cfg mgmtcamp c-dwithchef
Page 4: Cfg mgmtcamp c-dwithchef
Page 5: Cfg mgmtcamp c-dwithchef
Page 6: Cfg mgmtcamp c-dwithchef

Minimum Viable Pipeline

Page 7: Cfg mgmtcamp c-dwithchef

• Step 1: Develop a new change

• Step 2: ???

• Step 3: Production!

• MOAR FASTERZ

What we know

Page 8: Cfg mgmtcamp c-dwithchef

• Must utilize existing tools within the company

• Git for SCM

• Jenkins approved for use

• Working in a static VM environment

• Just migrated to single cookbook repos

• Starting with infrastructure cookbooks

• Want a manual go-to-production button (ugh!)

Case Study: Requirements

Page 9: Cfg mgmtcamp c-dwithchef

• Git PR model: branch from master for any new feature

• 4-person team, only 3 active at any time

• Code review done manually and informally

• Simple communication/reqs (makes it easy!)

Case Study: Code Review Model

Page 10: Cfg mgmtcamp c-dwithchef

• How are developers expected to work locally?

• When do they push to remote? How do we verify their work?

• Code Review criteria: what does it mean to be ready to merge?

• How do we go from merged code to artifact?

• How do we get that artifact all the way to Production?

Figuring out new workflow

Page 11: Cfg mgmtcamp c-dwithchef

• New branch for every feature

• Create a failing test

• Write a resource to pass the test

• Local commits

• Test-Kitchen + guard

• Once local tests passed, push to remote

Local Development Work

Page 12: Cfg mgmtcamp c-dwithchef

• Open a Pull Request (new branch to master)

• Triggers a build via Jenkins GHPRB plugin

Push to remote

Page 13: Cfg mgmtcamp c-dwithchef

The Verify Build Job

• Verify syntax (knife cookbook check)

• Foodcritic Rules

• Test-Kitchen w/ BATS busser

Push to remote

Page 14: Cfg mgmtcamp c-dwithchef

@test "My directory is created" {! test -d /foo/bar!}!!@test "A basharific test" {! if [ foo != bar ]; then! skip "foo isn't bar"! fi!! run foo! [ "$status" -eq 0 ]!}!!• https://github.com/sstephenson/bats • Super low learning curve (but also very limited)

BATS: Simple Unit Tests

Page 15: Cfg mgmtcamp c-dwithchef

• If failed, notify

• Another commit to the same branch triggers another Verify Build Job

• Super easy to track, comment, and approve

• If passed, let’s go to Human Code Review

Push to remote

Page 16: Cfg mgmtcamp c-dwithchef

• Only one change per one cookbook at one time

• Must have test for feature that changed

• One for one: resource unit tests

• Consider the smoke test

Human Code Review Rules

Page 17: Cfg mgmtcamp c-dwithchef

• Unit tests: small, fast, check one single concern

• In this context: checking Chef resources

• Smoke tests: test multiple things in the course of one concern

• In this context: check the intent of a recipe

• Note: that was testing for this use case

Unit Test vs Smoke Test

Page 18: Cfg mgmtcamp c-dwithchef

• Only 3 active team members at any given time

• Submitter cannot approve

• Merge approval requires 2 approvals

• Code review can happen at any time, but only merge when you’re ready to fix it.

When are we ready to merge?

Page 19: Cfg mgmtcamp c-dwithchef

• Freeze your cookbooks!

• Semantic versioning: Major.Minor.Patch

• You own Major.Minor

• The Pipeline owns .Patch

• No one gets to knife upload

No one.!

Ever.!

• "git merge" is the new "knife upload"

Merged code to artifact

Page 20: Cfg mgmtcamp c-dwithchef
Page 21: Cfg mgmtcamp c-dwithchef

• Bumps Cookbook version

• Re-commits to master

• Upload frozen cookbook (via berks)

• Pin that new cookbook to the Integration environment

• Converge all nodes that use that cookbook

The Integration Job

Page 22: Cfg mgmtcamp c-dwithchef

• First sign that things may be broken

• These nodes also run smoke tests

• serverspec, minitest, etc

The Integration Job

Page 23: Cfg mgmtcamp c-dwithchef

• We survived! Trigger the next job(s)

• The Jenkins Build Pipelines Plugin allows upstream/downstream definitions to string together jobs

• From here out, it’s all the same Promote Job*

• After the Integration job, we just run X number of Promote Jobs

The Integration Job

* (mostly)

Page 24: Cfg mgmtcamp c-dwithchef
Page 25: Cfg mgmtcamp c-dwithchef
Page 26: Cfg mgmtcamp c-dwithchef
Page 27: Cfg mgmtcamp c-dwithchef

• Pin cookbook to new Chef Environment

• Converge all nodes using this cookbook

• Run Tests

Promote Jobs

Page 28: Cfg mgmtcamp c-dwithchef

#!/opt/chef/embedded/bin/ruby !require 'chef/environment' require 'chef' Chef::Config.from_file("/var/lib/jenkins/tools/knife.rb") !def pin_env(env, cookbook_versions) to = Chef::Environment.load(env) cookbook_versions.each do |cb, version| puts "Pinning #{cb} #{version} in #{env}" to.cookbook_versions[cb] = version end to.save end !cookbook_data = Array.new !if File.exists?(File.expand_path(File.join(ENV['WORKSPACE'], 'metadata.rb'))) metadata_file = File.expand_path(File.join(ENV['WORKSPACE'], 'metadata.rb')) File.read(metadata_file).each_line do |line| if line =~ /^name\s+["'](\w+)["'].*$/ cookbook_data << $1 end if line =~ /^version\s+["'](\d+\.\d+\.\d+)["'].*$/ cookbook_data << "= #{$1}" end end end !cookbook_versions = Hash[*cookbook_data] !pin_env(ARGV[0], cookbook_versions)

Pin the cookbook to Env

Page 29: Cfg mgmtcamp c-dwithchef

$ berks apply <environment>

Pin the cookbook to Env

Page 30: Cfg mgmtcamp c-dwithchef

$ knife ssh "recipes:mycookbook AND chef_environment:promote-environment” 'sudo chef-client'!

… OR …

Pushy!

Converge Nodes

Page 31: Cfg mgmtcamp c-dwithchef

• Most testing frameworks have a Report Handler to automatically run tests

• chef-serverspec-handler

• minitest-handler

• Deploy to your nodes by adding ‘chef_handler’ to their run_list

• Many community cookbooks are already packaged with tests

Run Tests

Page 32: Cfg mgmtcamp c-dwithchef

• In this particular use case:

• Build job: BATS (unit tests)

• Integration & Promote jobs: serverspec (smoke tests)

• UAT: also ran Cucumber tests (acceptance)

Run Tests

Page 33: Cfg mgmtcamp c-dwithchef
Page 34: Cfg mgmtcamp c-dwithchef

• Can string together N number of promotions

• UAT

• Production A

• Production B

• etc

Promoting to more environments

Page 35: Cfg mgmtcamp c-dwithchef
Page 36: Cfg mgmtcamp c-dwithchef
Page 37: Cfg mgmtcamp c-dwithchef

• In production monitoring is the test

• Could not queue up changes reliably anyway

• There is no spoon

Push to Production

Page 38: Cfg mgmtcamp c-dwithchef

• Small incremental deployments led to greater confidence

• TDD was pushed to the forefront of priorities

• Commitment from Dev group to write application deployment cookbooks

• But the biggest lesson learned…

Results

Page 39: Cfg mgmtcamp c-dwithchef

• Continuous Delivery is a practice, not a tool

• Small incremental changes in code

• Small incremental changes in workflow

• Small incremental changes in tooling

• You will constantly improve your code, your workflow, your tools, your team, and your skills.

Let’s Go Devop with a CD tool

Page 40: Cfg mgmtcamp c-dwithchef

RECAP

Page 41: Cfg mgmtcamp c-dwithchef

• Step 1: Develop a new change

• Step 2: ???

• Step 3: Production!

• MOAR FASTERZ

What We Wanted

Page 42: Cfg mgmtcamp c-dwithchef

• (Pre-req) Test Driven Development

• 2A. Establish development workflow before submitting changes *

• 2B. Auto verification of submission before humans look at it

• 2C. Humans Apply Code Review Criteria *

• 2D. Don’t merge unless you mean it *

• 2E. Merge kicks off an Integration Job

• 2F. Followed by a series of Promotion Jobs

• 2G. There is no spoon *

Wait… what was Step 2?

Page 43: Cfg mgmtcamp c-dwithchef

• Step 1: Develop a new change

• Step 2:

!

!

• Step 3: Production!

• Step 4: Level Up. This is great!

• Step 5: MOAR THINGS! Wait. This is hard!

• Go to Step 1

What We Got

(Pre-req) Test Driven Development

2A. Establish development workflow before submitting changes *

2B. Auto verification of submission before humans look at it

2C. Humans Apply Code Review Criteria *

2D. Don’t merge unless you mean it *

2E. Merge kicks off an Integration Job

2F. Followed by a series of Promotion Jobs

2G. There is no spoon *

Page 44: Cfg mgmtcamp c-dwithchef

• Test Kitchen — http://kitchen.ci/

• Guard Plugin for Test Kitchen — https://github.com/test-kitchen/guard-kitchen

• Foodcritic — http://acrmp.github.io/foodcritic/

• Berkshelf — http://berkshelf.com/

Key Chef Ecosystem Tools

Page 45: Cfg mgmtcamp c-dwithchef

• git

• github

• build-pipeline-plugin

• ghprb

• warnings

• mailer

Helpful Jenkins Plugins

Page 46: Cfg mgmtcamp c-dwithchef

I want to hear from you! !

@gmiranda23 [email protected]