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.
36. Vagrant
Virtual and cloud automation
VirtualBox
VMWare Fusion
AWS
Rackspace
Easy Puppet and Chef provisioning
Keep VM configuration for different projects
Share boxes and configuration files across teams
base box + configuration files
39. Vagrant
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
43. What am I doing to automate deployment
Ant tasks plugin
ssh commands
Assembly plugin
Cargo
Capistrano
44. What can I do to automate deployment
Handle full deployment including infrastructure
not just webapp deployment
Help Ops with clear, automated manifests
Ability to reproduce production environments
in local box using Vagrant / VirtualBox / VMWare
Use the right tool for the right job
45. Maven-Puppet module
A Maven Puppet module
https://github.com/maestrodev/puppet-maven
fetches Maven artifacts from the repo
manages them with Puppet
no more extra packaging
46. Installing Maven
$repo1 = {
id => "myrepo",
username => "myuser",
password => "mypassword",
url => "http://repo.acme.com",
}
# Install Maven
class { "maven::maven":
version => "2.2.1",
} ->
# Create a settings.xml with the repo credentials
class { "maven::settings" :
servers => [$repo1],
}
47. 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"],
}
48. 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"],
}
53. 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'
54. 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
proto
port
action
}
}
{ '100 allow postgres':
=> 'tcp',
=> '5432',
=> 'accept',
55. 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"
56. 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
proto
port
action
}
}
{ '100 allow tomcat':
=> 'tcp',
=> '8080',
=> 'accept',
57. 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',
}
}
67. Photo Credits
Brick wall - Luis Argerich
http://www.flickr.com/photos/lrargerich/4353397797/
Agile vs. Iterative flow - Christopher Little
http://en.wikipedia.org/wiki/File:Agile-vs-iterative-flow.jpg
DevOps - Rajiv.Pant
http://en.wikipedia.org/wiki/File:Devops.png
Pimientos de Padron - Howard Walfish
http://www.flickr.com/photos/h-bomb/4868400647/
Compiling - XKCD
http://xkcd.com/303/
Printer in 1568 - Meggs, Philip B
http://en.wikipedia.org/wiki/File:Printer_in_1568-ce.png
Relativity - M. C. Escher
http://en.wikipedia.org/wiki/File:Escher%27s_Relativity.jpg
Teacher and class - Herald Post
http://www.flickr.com/photos/heraldpost/5169295832/