Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days 2013

67
Infrastructure testing with Jenkins, Puppet and Vagrant Carlos Sanchez @csanchez http://csanchez.org http://maestrodev.com

description

Extend Continuous Integration to automatically test your infrastructure. Continuous Integration can be extended to test deployments and production environments, in a Continuous Delivery cycle, using infrastructure-as-code tools like Puppet, allowing to manage multiple servers and their configurations, and test the infrastructure the same way continuous integration tools do with developers’ code. Puppet is an infrastructure-as-code tool that allows easy and automated provisioning of servers, defining the packages, configuration, services, … in code. Enabling DevOps culture, tools like Puppet help drive Agile development all the way to operations and systems administration, and along with continuous integration tools like Jenkins, it is a key piece to accomplish repeatability and continuous delivery, automating the operations side during development, QA or production, and enabling testing of systems configuration. Using Vagrant, a command line automation layer for VirtualBox, we can easily spin off virtual machines with the same configuration as production servers, run our test suite, and tear them down afterwards. We will show how to set up automated testing of an application and associated infrastructure and configurations, creating on demand virtual machines for testing, as part of your continuous integration process.

Transcript of Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days 2013

Page 1: Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days 2013

Infrastructure testing with Jenkins, Puppet and Vagrant

Carlos Sanchez@csanchezhttp://csanchez.orghttp://maestrodev.com

Page 3: Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days 2013

How we got here

Page 4: Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days 2013

Agile

planningiterative developmentcontinuous integration

release soon, release often

Page 5: Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days 2013
Page 6: Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days 2013
Page 7: Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days 2013

Fear of changeRisky deployments

It works on my machine!Siloisation

Dev Change vs. Ops stability

Page 8: Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days 2013

OPs requirements

Operating Systemconfig filespackages installedmulti stage configurationsdevQApre-productionproduction

Page 9: Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days 2013

Deployment

How do I deploy this?documentationmanual stepsprone to errors

Page 10: Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days 2013

Cloud

How do I deploy this?to hundreds of servers

Page 11: Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days 2013
Page 12: Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days 2013

DevOps

Page 13: Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days 2013

DevQaOps ?

Page 14: Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days 2013
Page 15: Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days 2013

DEV QA OPS

Page 16: Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days 2013

DEV

QA

OPS

Page 17: Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days 2013

SpecsPackagesVersions

DEV PROD

Page 18: Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days 2013

TestabilityDEV QA

Page 19: Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days 2013

MetricsLogsSecurity updates

DEV PROD

Page 20: Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days 2013

is not about the toolsbut

how can I implement IT

Page 21: Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days 2013

Tools can enable change in behavior and eventually change culturePatrick Debois

Page 22: Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days 2013

everyone is intelligent enoughevery tool is cloud enabledevery tool is DevOps(tm)

Page 23: Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days 2013

3 key concepts

Page 24: Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days 2013

Continuous Delivery

Page 25: Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days 2013

Continuous delivery

Page 26: Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days 2013

Infrastructure as Codeit’s all been invented, now it’s standardized

Page 27: Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days 2013

manifestsruby-likeERB templates

exec { "maven-untar": command => "tar xf /tmp/x.tgz", cwd => "/opt", creates => "/opt/apache-maven-${version}", path => ["/bin"], } -> file { "/usr/bin/mvn": ensure => link, target => "/opt/apache-maven-${version}/bin/mvn", } file { "/usr/local/bin/mvn": ensure => absent, require => Exec["maven-untar"], } file { "$home/.mavenrc": mode => "0600", owner => $user, content => template("maven/mavenrc.erb"), require => User[$user], }

Page 28: Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days 2013

infrastructureIS code

package { 'openssh-server': ensure => present,}

Page 29: Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days 2013

declarative modelstate vs processno scripting

service { 'ntp': name => 'ntpd', ensure => running, }

Page 30: Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days 2013

Follow development best practicestaggingbranchingreleasingdev, QA, production

new solutions

new challenges

Page 31: Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days 2013

Self servicing

Page 32: Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days 2013

Infrastructure always availablevirtualization & cloudempower developersreduce time-to-market

Page 33: Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days 2013

devs buy-inWith great power comes great responsibility

Page 34: Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days 2013

Vagrantempower developersdev-ops collaborationautomation

Page 35: Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days 2013

Vagrant

Page 36: Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days 2013

Vagrant

Virtual and cloud automationVirtualBox

VMWare Fusion

AWS

Rackspace

Easy Puppet and Chef provisioningKeep VM configuration for different projects

Share boxes and configuration files across teamsbase box + configuration files

Page 37: Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days 2013

Vagrant base boxes

www.vagrantbox.espuppet-vagrant-boxes.puppetlabs.com

anywhere! just (big) files

Page 38: Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days 2013

using Vagrant

$ gem install vagrant$ vagrant box add centos-6.0-x86_64 \ http://dl.dropbox.com/u/1627760/centos-6.0-x86_64.box $ vagrant init myproject$ vagrant up$ vagrant ssh$ vagrant suspend$ vagrant resume$ vagrant destroy

Page 39: Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days 2013

Vagrant.configure("2") do |config|

# Every Vagrant virtual environment requires a box to build off of. config.vm.box = "CentOS-6.4-x86_64-minimal" config.vm.box_url = "https://.../CentOS-6.4-x86_64-minimal.box"

# web server config.vm.define :www do |config| config.vm.hostname = "www.acme.local" config.vm.network "forwarded_port", guest: 80, host: 10080 config.vm.network "private_network", ip: "192.168.33.12" end

config.vm.provision :puppet do |puppet| puppet.module_path = "modules" puppet.manifest_file = "site.pp" end

end

Vagrant

Page 40: Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days 2013

Geppetto

Page 42: Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days 2013

Maven and Puppet

Page 43: Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days 2013

What am I doing to automate deployment

Ant tasks pluginssh commands

Assembly pluginCargo

Capistrano

Page 44: Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days 2013

What can I do to automate deployment

Handle full deployment including infrastructurenot just webapp deployment

Help Ops with clear, automated manifestsAbility to reproduce production environmentsin local box using Vagrant / VirtualBox / VMWare

Use the right tool for the right job

Page 45: Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days 2013

Maven-Puppet module

A Maven Puppet module

https://github.com/maestrodev/puppet-maven

fetches Maven artifacts from the repomanages them with Puppet

no more extra packaging

Page 46: Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days 2013

Installing Maven

$repo1 = { id => "myrepo", username => "myuser", password => "mypassword", url => "http://repo.acme.com",}

# Install Mavenclass { "maven::maven": version => "2.2.1",} ->

# Create a settings.xml with the repo credentialsclass { "maven::settings" : servers => [$repo1],}

Page 47: Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days 2013

New Maven type

maven { "/tmp/maven-core-2.2.1.jar": id => "org.apache.maven:maven-core:jar:2.2.1", repos => ["http://repo1.maven.apache.org/maven2",

"http://mirrors.ibiblio.org/pub/mirrors/maven2"], }

Page 48: Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days 2013

New Maven type

maven { "/tmp/maven-core-2.2.1.jar": groupId => "org.apache.maven", artifactId => "maven-core", version => "2.2.1", packaging => "jar", repos => ["http://repo1.maven.apache.org/maven2",

"http://mirrors.ibiblio.org/pub/mirrors/maven2"], }

Page 49: Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days 2013

Examples

Page 50: Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days 2013

Infrastructure

Jenkins

Archiva

wwwhttpd

QAhttpd,

tomcat, postgres

tomcat1tomcat

dbpostgres

Page 51: Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days 2013

Tomcat cluster + postgres

postgresdb.acme.com

tomcattomcat1.acme.com

httpdwww.acme.com

tomcattomcat2.acme.com ...

Page 52: Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days 2013

Continuous Delivery

developer

commit git repo

jenkins

binary repository

QA vm

db

tomcat*

www

post commit hook

build

integration testing

production

Page 53: Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days 2013

Puppet Modules required

$ bundle install && librarian-puppet install

forge 'http://forge.puppetlabs.com'

mod 'puppetlabs/java', '>=1.0.0'mod 'puppetlabs/apache', '>=0.9.0'mod 'puppetlabs/postgresql', '>=3.0.0'mod 'puppetlabs/firewall'mod 'camptocamp/tomcat', :git => 'https://github.com/carlossg/puppet-tomcat.git', :ref => 'setclasspath'mod 'maestrodev/maven', '>=1.0.0'mod 'stahnma/epel', '>=0.0.2'mod 'maestrodev/avahi', '>=1.0.0'mod 'acme', :path => 'mymodules/acme'

Page 54: Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days 2013

mymodules/acme/manifests/db_node.pp

class 'acme::db_node' {

class { 'postgresql::server': ip_mask_allow_all_users => '192.168.0.0/0', listen_addresses => '*', postgres_password => 'postgres', } ->

postgresql::server::db { 'appfuse': user => 'appfuse', password => 'appfuse', grant => 'all', }

firewall { '100 allow postgres': proto => 'tcp', port => '5432', action => 'accept', }}

Page 55: Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days 2013

mymodules/acme/manifests/tomcat_node.pp I

class acme::tomcat_node( $db_host = 'db.local', $repo = 'http://carlos-mbook-pro.local:8000/repository/all/', $appfuse_version = '2.2.2-SNAPSHOT', $service = 'tomcat-appfuse', $app_name = 'appfuse', $tomcat_root = '/srv/tomcat') {

# install java class { 'java': }

# install tomcat class { 'tomcat': } ->

# create a tomcat server instance for appfuse # It allows having multiple independent tomcat servers in different ports tomcat::instance { 'appfuse': ensure => present, http_port => 8080, }

# where the war needs to be installed $webapp = "${tomcat_root}/${app_name}/webapps/ROOT"

Page 56: Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days 2013

mymodules/acme/manifests/tomcat_node.pp II

# install maven and download appfuse war file from our archiva instance class { 'wget': } -> class { 'maven::maven' : version => '3.0.4', } -> # clean up to deploy the next snapshot exec { "rm -rf ${webapp}*": } -> maven { "${webapp}.war": id => "org.appfuse:appfuse-spring:${appfuse_version}:war", repos => [$repo], require => File["${tomcat_root}/${app_name}/webapps"], notify => Service[$service], } ->

firewall { '100 allow tomcat': proto => 'tcp', port => '8080', action => 'accept', }}

Page 57: Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days 2013

mymodules/acme/manifests/www_node.pp

class acme::www_node($tomcat_host = 'tomcat1.local') {

class { 'apache': } class { 'apache::mod::proxy_http': }

# create a virtualhost that will proxy the tomcat server apache::vhost { "${::hostname}.local": port => 80, docroot => '/var/www', proxy_dest => "http://${tomcat_host}:8080", }

firewall { '100 allow apache': proto => 'tcp', port => '80', action => 'accept', }}

Page 58: Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days 2013

manifests/site.pp

import 'nodes/*.pp'

node ‘parent’ { class {'epel': } ->

class {'avahi': firewall => true, }}

Page 59: Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days 2013

manifests/nodes/tomcat.pp

# tomcat1.acme.com, tomcat2.acme.com,...node /tomcat\d\..*/ inherits ‘parent’ {

file {'/etc/motd': content => ”tomcat server: ${::hostname}\n”, }

class {'acme::tomcat_node'}}

Page 60: Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days 2013

manifests/nodes/qa.pp

node /qa\..*/ inherits ‘parent’ { class {'acme::db_node': }

class {'acme::tomcat_node': db_host => 'localhost', }

class {'acme::www_node': tomcat_host => 'localhost', }}

Page 61: Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days 2013

Infrastructure unit testing

Page 62: Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days 2013

rspec-puppet

Unit testing your puppet manifestsEnsuring packages, config files, services,...

Page 63: Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days 2013

spec/hosts/db_spec.pp

require 'rspec-puppet'

describe 'db.acme.com' do let(:facts) { { :osfamily => 'RedHat', :operatingsystem => 'CentOS', :operatingsystemrelease => ‘6.3’} }

it { should contain_class('postgresql::server') }end

Page 64: Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days 2013

spec/hosts/www_spec.pp

require 'rspec-puppet'

describe 'www.acme.com' do let(:facts) { { :osfamily => 'RedHat', :operatingsystem => 'CentOS', :operatingsystemrelease => ‘6.3’} }

it { should contain_package('httpd') }end

Page 65: Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days 2013

Example code and slides

Available athttp://slideshare.csanchez.org

http://github.csanchez.orghttp://blog.csanchez.org

Page 66: Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days 2013

[email protected]@apache.org@csanchez

Danke!

http://csanchez.orghttp://maestrodev.com

Page 67: Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days 2013

Photo Credits

Brick wall - Luis Argerichhttp://www.flickr.com/photos/lrargerich/4353397797/

Agile vs. Iterative flow - Christopher Littlehttp://en.wikipedia.org/wiki/File:Agile-vs-iterative-flow.jpg

DevOps - Rajiv.Panthttp://en.wikipedia.org/wiki/File:Devops.png

Pimientos de Padron - Howard Walfishhttp://www.flickr.com/photos/h-bomb/4868400647/

Compiling - XKCDhttp://xkcd.com/303/

Printer in 1568 - Meggs, Philip Bhttp://en.wikipedia.org/wiki/File:Printer_in_1568-ce.png

Relativity - M. C. Escherhttp://en.wikipedia.org/wiki/File:Escher%27s_Relativity.jpg

Teacher and class - Herald Posthttp://www.flickr.com/photos/heraldpost/5169295832/