SlideShare a Scribd company logo
How to develop
Puppet Modules
From source to the Forge
with zero clicks
Carlos Sanchez
@csanchez
http://csanchez.org
http://maestrodev.com
@csanchez Apache
Maven
ASF
Member
Eclipse
Foundation
csanchez.org
maestrodev.com
Modules
We use 50 modules
DEV QA OPS
Modules ARE software
oh my
Versions
Dependencies
Incompabilities
Specs
RSpec-Puppet
Gemfile
source 'https://rubygems.org'
group :rake do
gem 'puppet'
gem 'rake'
gem 'puppet-lint'
gem 'rspec-puppet'
end
modules
{module}/
spec/
spec_helper.rb
classes/
{class}_spec.pp
definitions/
fixtures/
hosts/
maven::maven
class maven::maven(
$version = '3.0.5',
$repo = {
#url => 'http://repo1.maven.org/maven2',
#username => '',
#password => '',
} ) {
if "x${repo['url']}x" != 'xx' {
wget::authfetch { 'fetch-maven':
source => "${repo['url']}/.../$version/apache-maven-${version}-bin.tar.gz",
destination => $archive,
user => $repo['username'],
password => $repo['password'],
before => Exec['maven-untar'],
}
} else {
wget::fetch { 'fetch-maven':
source => "http://archive.apache.org/.../apache-maven-${version}-bin.tar.gz",
destination => $archive,
before => Exec['maven-untar'],
}
}
rspec-puppet
require 'spec_helper'
describe 'maven::maven' do
context "when downloading maven from another repo" do
let(:params) { { :repo => {
'url' => 'http://repo1.maven.org/maven2',
'username' => 'u',
'password' => 'p'
}
} }
it 'should fetch maven with username and password' do
should contain_wget__authfetch('fetch-maven').with(
'source' => 'http://repo1.maven.org/...ven-3.0.5-bin.tar.gz',
'user' => 'u',
'password' => 'p')
end
end
end
hosts
node 'agent' inherits 'parent' {
include wget
include maestro::test::dependencies
include maestro_nodes::agentrvm
}
hosts
require 'spec_helper'
describe 'agent' do
it do should contain_class('maestro::agent').with(
'agent_name' => 'agent-01',
'stomp_host' => 'maestro.maestrodev.net')
end
it { should_not contain_service('maestro') }
it { should_not contain_service('activemq') }
it { should_not contain_service('jenkins') }
it { should_not contain_service('postgresqld') }
it { should_not contain_service('maestro-test-hub') }
it { should_not contain_service('sonar') }
it { should_not contain_service('archiva') }
end
rspec-puppet with facts
require 'spec_helper'
describe 'wget' do
context 'running on OS X' do
let(:facts) { {:operatingsystem => 'Darwin'} }
it { should_not contain_package('wget') }
end
context 'running on CentOS' do
let(:facts) { {:operatingsystem => 'CentOS'} }
it { should contain_package('wget') }
end
context 'no version specified' do
it { should contain_package('wget').with_ensure('installed') }
end
context 'version is 1.2.3' do
let(:params) { {:version => '1.2.3'} }
it { should contain_package('wget').with_ensure('1.2.3') }
end
end
shared_context
shared_context :centos do
let(:facts) {{
:operatingsystem => 'CentOS',
:kernel => 'Linux',
:osfamily => 'RedHat'
}}
end
describe 'maestro::maestro' do
include_context :centos
...
end
extending for reuse
describe 'maestro::maestro' do
include_context :centos
let(:facts) { super().merge({
:operatingsystem => 'RedHat'
})}
end
shared_examples
require 'spec_helper'
describe 'nginx::package' do
shared_examples 'redhat' do |operatingsystem|
let(:facts) {{ :operatingsystem => operatingsystem }}
it { should contain_package('nginx') }
it { should contain_package('gd') }
it { should contain_package('libXpm') }
it { should contain_package('libxslt') }
it { should contain_yumrepo('nginx-release').with_enabled('1') }
end
shared_examples 'debian' do |operatingsystem|
let(:facts) {{ :operatingsystem => operatingsystem }}
it { should contain_file('/etc/apt/sources.list.d/nginx.list') }
end
shared_examples (cont.)
context 'RedHat' do
it_behaves_like 'redhat', 'centos'
it_behaves_like 'redhat', 'fedora'
it_behaves_like 'redhat', 'rhel'
it_behaves_like 'redhat', 'redhat'
it_behaves_like 'redhat', 'scientific'
end
context 'debian' do
it_behaves_like 'debian', 'debian'
it_behaves_like 'debian', 'ubuntu'
end
context 'other' do
let(:facts) {{ :operatingsystem => 'xxx' }}
it { expect { subject }.to raise_error(Puppet::Error, /Module
nginx is not supported on xxx/) }
end
end
puppetlabs_spec_helper
Gemfile
source 'https://rubygems.org'
group :rake do
gem 'puppet'
gem 'rspec-puppet'
gem 'rake'
gem 'puppet-lint'
gem 'puppetlabs_spec_helper'
end
Rakefile
require 'puppetlabs_spec_helper/rake_tasks'
build # Build puppet module package
clean # Clean a built module package
coverage # Generate code coverage information
lint # Check puppet manifests with puppet-lint
spec # Run spec tests in a clean fixtures directory
spec_clean # Clean up the fixtures directory
spec_prep # Create the fixtures directory
spec_standalone # Run spec tests on an existing fixtures directory
spec/spec_helper.rb
require 'puppetlabs_spec_helper/module_spec_helper'
RSpec.configure do |c|
c.before(:each) do
Puppet::Util::Log.level = :warning
Puppet::Util::Log.newdestination(:console)
end
end
.fixtures
# bring modules into spec/fixtures
fixtures:
repositories:
firewall: "git://github.com/puppetlabs/puppetlabs-firewall"
stdlib:
repo: "git://github.com/puppetlabs/puppetlabs-stdlib"
ref: "2.6.0"
symlinks:
my_module: "#{source_dir}"
librarian-puppet
Gemfile
source 'https://rubygems.org'
group :rake do
gem 'puppet'
gem 'rspec-puppet'
gem 'rake'
gem 'puppet-lint'
gem 'puppetlabs_spec_helper'
gem 'librarian-puppet-maestrodev'
end
Puppetfile
forge 'http://forge.puppetlabs.com'
mod 'maestrodev/activemq', '>=1.0'
mod 'saz/limits', ">=2.0.1"
mod 'maestrodev/maestro_nodes', '>=1.1.0'
mod 'maestrodev/maestro_demo', '>=1.0.2'
mod 'maestrodev', :path => './private_modules/maestrodev'
mod 'nginx', :git => 'https://github.com/jfryman/puppet-nginx.git'
Puppetfile.lock
FORGE
remote: http://forge.puppetlabs.com
specs:
jfryman/nginx (0.0.2)
puppetlabs/stdlib (>= 0.1.6)
maestrodev/activemq (1.2.0)
maestrodev/wget (>= 1.0.0)
maestrodev/android (1.1.0)
maestrodev/wget (>= 1.0.0)
maestrodev/ant (1.0.4)
maestrodev/wget (>= 0.0.1)
maestrodev/archiva (1.1.0)
maestrodev/wget (>= 1.0.0)
maestrodev/git (1.0.1)
maestrodev/jenkins (1.0.1)
maestrodev/maestro (1.2.13)
maestrodev/maven (>= 1.0.0)
maestrodev/wget (>= 1.0.0)
puppetlabs/postgresql (= 2.0.1)
puppetlabs/stdlib (>= 2.5.1)
maestrodev/maestro_demo (1.0.5)
maestrodev/android (>= 1.1.0)
maestrodev/maestro (>= 1.2.0)
puppetlabs/postgresql (= 2.0.1)
maestrodev/maestro_nodes (1.3.0)
jfryman/nginx (>= 0.0.0)
maestrodev/activemq (>= 1.0.0)
maestrodev/ant (>= 1.0.3)
maestrodev/archiva (>= 1.0.0)
maestrodev/git (>= 1.0.0)
maestrodev/jenkins (>= 1.0.0)
maestrodev/maestro (>= 1.1.0)
maestrodev/maven (>= 0.0.2)
maestrodev/rvm (>= 1.0.0)
maestrodev/sonar (>= 1.0.0)
maestrodev/ssh_keygen (>=
1.0.0)
maestrodev/statsd (>= 0.0.0)
maestrodev/svn (>= 1.0.0)
puppetlabs/java (>= 0.3.0)
puppetlabs/mongodb (>= 0.1.0)
puppetlabs/nodejs (>= 0.3.0)
puppetlabs/ntp (>= 0.0.0)
stahnma/epel (>= 0.0.0)
maestrodev/maven (1.1.2)
maestrodev/wget (>= 1.0.0)
maestrodev/rvm (1.1.5)
maestrodev/sonar (1.0.0)
maestrodev/maven (>= 0.0.2)
maestrodev/wget (>= 0.0.1)
puppetlabs/stdlib (>= 2.3.0)
maestrodev/ssh_keygen (1.0.0)
maestrodev/statsd (1.0.3)
puppetlabs/nodejs (>= 0.2.0)
maestrodev/svn (1.1.0)
maestrodev/wget (1.2.0)
puppetlabs/apt (1.2.0)
puppetlabs/stdlib (>= 2.2.1)
puppetlabs/firewall (0.4.0)
puppetlabs/java (1.0.1)
puppetlabs/stdlib (>= 0.1.6)
puppetlabs/mongodb (0.1.0)
puppetlabs/apt (>= 0.0.2)
puppetlabs/nodejs (0.3.0)
puppetlabs/apt (>= 0.0.3)
puppetlabs/stdlib (>= 2.0.0)
puppetlabs/ntp (1.0.1)
puppetlabs/stdlib (>= 0.1.6)
puppetlabs/postgresql (2.0.1)
puppetlabs/apt (< 2.0.0, >=
1.1.0)
puppetlabs/firewall (>= 0.0.4)
puppetlabs/stdlib (< 4.0.0, >=
3.2.0)
puppetlabs/stdlib (3.2.0)
saz/limits (2.0.1)
stahnma/epel (0.0.5)
GIT
remote: https://github.com/jfryman/
puppet-nginx.git
ref: master
sha:
fd4e3c5a3719132bacabe6238ad2ad31fa3ba
48c
specs:
nginx (0.0.2)
puppetlabs/stdlib (>= 0.1.6)
PATH
remote: ./private_modules/
maestrodev
specs:
maestrodev (0.0.1)
DEPENDENCIES
maestrodev (>= 0)
maestrodev/activemq (>= 1.0)
maestrodev/maestro_demo (>= 1.0.2)
maestrodev/maestro_nodes (>= 1.1.0)
nginx (>= 0)
saz/limits (>= 2.0.1)
librarian-puppet
clean # Cleans out the cache and install paths.
init # Initializes the current directory
install # Resolves and installs all of the dependencies you
specify
outdated # Lists outdated dependencies.
package # Cache the puppet modules in vendor/puppet/cache
show # Shows dependencies
update # Updates and installs the dependencies you specify
librarian-puppet for fixtures
# use librarian-puppet to manage fixtures instead
of .fixtures.yml. Offers more possibilities like explicit version
management, forge downloads,...
task :librarian_spec_prep do
sh "librarian-puppet install --path=spec/fixtures/modules/"
end
task :spec_prep => :librarian_spec_prep
.fixtures
fixtures:
symlinks:
my_module: "#{source_dir}"
Vagrant
tests/init.pp
stage { 'epel':
before => Stage['rvm-install']
}
class { 'epel': stage => 'epel' } ->
class { 'rvm': }
Vagrantfile
Vagrant.configure("2") do |config|
config.vm.synced_folder ".", "/etc/puppet/modules/rvm"
# install the epel module needed for rvm in CentOS
config.vm.provision :shell, :inline => "test -d /etc/puppet/modules/epel || puppet
module install stahnma/epel -v 0.0.3"
config.vm.provision :puppet do |puppet|
puppet.manifests_path = "tests"
puppet.manifest_file = "init.pp"
end
config.vm.define :centos63 do |config|
config.vm.box = "CentOS-6.3-x86_64-minimal"
config.vm.box_url = "https://repo.maestrodev.com/archiva/repository/public-releases/
com/maestrodev/vagrant/CentOS/6.3/CentOS-6.3-x86_64-minimal.box"
end
config.vm.define :centos64 do |config|
config.vm.box = "CentOS-6.4-x86_64-minimal"
config.vm.box_url = "https://repo.maestrodev.com/archiva/repository/public-releases/
com/maestrodev/vagrant/CentOS/6.4/CentOS-6.4-x86_64-minimal.box"
end
end
Rakefile
desc "Integration test with Vagrant"
task :integration do
sh %{vagrant destroy --force}
sh %{vagrant up}
sh %{vagrant destroy --force}
end
Rakefile
# start one at a time
desc "Integration test with Vagrant"
task :integration do
sh %{vagrant destroy --force}
["centos63", "centos64"].each do |vm|
sh %{vagrant up #{vm}}
sh %{vagrant destroy --force #{vm}}
end
sh %{vagrant destroy --force}
end
Blacksmith
gem 'puppet-blacksmith'
Rakefile
require 'puppet_blacksmith/rake_tasks'
Rake
module:bump # Bump module version to the next minor
module:bump_commit # Bump version and git commit
module:clean # Runs clean again
module:push # Push module to the Puppet Forge
module:release # Release the Puppet module, doing a
clean, build, tag, push, bump_commit
and git push
module:tag # Git tag with the current module version
~/.puppetforge.yml
---
forge: https://forge.puppetlabs.com
username: myusername
password: mypassword
just remember
create project in the Forge first
(not yet implemented)
2.0.0 is built as a library to be reused
All together
Maven module
http://github.com/maestrodev/puppet-maven
Modulefile
name 'maestrodev-maven'
version '1.1.3'
author 'maestrodev'
license 'Apache License, Version 2.0'
project_page 'http://github.com/maestrodev/puppet-maven'
source 'http://github.com/maestrodev/puppet-maven'
summary 'Apache Maven module for Puppet'
description 'A Puppet module to download artifacts from Maven
repositories'
dependency 'maestrodev/wget', '>=1.0.0'
Gemfile
source 'https://rubygems.org'
group :rake do
gem 'puppet', '>=2.7.20'
gem 'rspec-puppet', '>=0.1.3'
gem 'rake', '>=0.9.2.2'
gem 'puppet-lint', '>=0.1.12'
gem 'puppetlabs_spec_helper'
gem 'puppet-blacksmith', '>=1.0.5'
gem 'librarian-puppet-maestrodev', '>=0.9.8'
end
Rakefile
require 'bundler'
Bundler.require(:rake)
require 'rake/clean'
CLEAN.include('spec/fixtures/', 'doc', 'pkg')
CLOBBER.include('.tmp', '.librarian')
require 'puppetlabs_spec_helper/rake_tasks'
require 'puppet_blacksmith/rake_tasks'
task :librarian_spec_prep do
sh "librarian-puppet install --path=spec/fixtures/modules/"
end
task :spec_prep => :librarian_spec_prep
task :default => [:clean, :spec]
Rakefile (cont.)
desc "Integration test with Vagrant"
task :integration do
sh %{vagrant destroy --force}
failed = []
["centos64", "debian6"].each do |vm|
sh %{vagrant up #{vm}} do |ok|
if ok
sh %{vagrant destroy --force #{vm}}
else
failed << vm
end
end
end
fail("Machines failed to start: #{failed.join(', ')}")
end
.fixtures.yml
fixtures:
symlinks:
maven: "#{source_dir}"
Puppetfile
forge 'http://forge.puppetlabs.com'
mod 'maestrodev/wget', '>=1.0.0'
Integrating
modules
modules
PREVIEW
code
DEV
DEMO
EVAL
CLIENT
modulesmodulesmodules
codecodecode
manifests
Automate!
librarian-puppet to fetch modules
Vagrant box
Integration tests
cucumber
junit
selenium
...
Vagrant integration
tests
Use local Puppet files and modules
config.vm.share_folder "puppet",
"/etc/puppet",
".",
:create => true,
:owner => "puppet",
:group => "puppet"
Share logs
config.vm.share_folder "jenkins-logs",
"/var/log/jenkins",
"target/logs/jenkins",
:create => true,
:extra => "dmode=777,fmode=666"
Save downloaded files in host
config.vm.share_folder "repo2",
"/var/lib/jenkins/.m2/repository",
File.expand_path("~/.m2/repository"),
:extra => "dmode=777,fmode=666"
config.vm.share_folder "yum",
"/var/cache/yum",
File.expand_path("~/.maestro/yum"),
:owner => "root",
:group => "root
Provision
config.vm.provision :puppet do |puppet|
puppet.manifests_path = "manifests"
puppet.manifest_file = "site.pp"
puppet.pp_path = "/etc/puppet"
puppet.options = ["--verbose"]
puppet.facter = {}
end
Run!
vagrant destroy --force
vagrant up
rake integration
Forward looking
Auto update
Automatically update all the modules and tell me if
it’s broken
bonus point: automatically edit the Gemfile,
Puppetfile, Modulefile constraints
csanchez@maestrodev.com
carlos@apache.org
@csanchez
Thanks!
http://csanchez.org
http://maestrodev.com
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/

More Related Content

What's hot

From Dev to DevOps
From Dev to DevOpsFrom Dev to DevOps
From Dev to DevOps
Agile Spain
 
DevOps(4) : Ansible(2) - (MOSG)
DevOps(4) : Ansible(2) - (MOSG)DevOps(4) : Ansible(2) - (MOSG)
DevOps(4) : Ansible(2) - (MOSG)
Soshi Nemoto
 
Preparation study of_docker - (MOSG)
Preparation study of_docker  - (MOSG)Preparation study of_docker  - (MOSG)
Preparation study of_docker - (MOSG)
Soshi Nemoto
 
Configuration Surgery with Augeas
Configuration Surgery with AugeasConfiguration Surgery with Augeas
Configuration Surgery with Augeas
Puppet
 
DevOps(3) : Ansible - (MOSG)
DevOps(3) : Ansible - (MOSG)DevOps(3) : Ansible - (MOSG)
DevOps(3) : Ansible - (MOSG)
Soshi Nemoto
 
10 Million hits a day with WordPress using a $15 VPS
10 Million hits a day  with WordPress using a $15 VPS10 Million hits a day  with WordPress using a $15 VPS
10 Million hits a day with WordPress using a $15 VPS
Paolo Tonin
 
Continuous infrastructure testing
Continuous infrastructure testingContinuous infrastructure testing
Continuous infrastructure testing
Daniel Paulus
 
Puppet fundamentals
Puppet fundamentalsPuppet fundamentals
Puppet fundamentals
Murali Boyapati
 
Making Your Capistrano Recipe Book
Making Your Capistrano Recipe BookMaking Your Capistrano Recipe Book
Making Your Capistrano Recipe Book
Tim Riley
 
Ansible 實戰:top down 觀點
Ansible 實戰:top down 觀點Ansible 實戰:top down 觀點
Ansible 實戰:top down 觀點
William Yeh
 
DevOps(2) : Vagrant - (MOSG)
DevOps(2) : Vagrant  -  (MOSG)DevOps(2) : Vagrant  -  (MOSG)
DevOps(2) : Vagrant - (MOSG)
Soshi Nemoto
 
PuppetCamp SEA 1 - Puppet Deployment at OnApp
PuppetCamp SEA 1 - Puppet Deployment  at OnAppPuppetCamp SEA 1 - Puppet Deployment  at OnApp
PuppetCamp SEA 1 - Puppet Deployment at OnApp
Walter Heck
 
PuppetCamp SEA 1 - Use of Puppet
PuppetCamp SEA 1 - Use of PuppetPuppetCamp SEA 1 - Use of Puppet
PuppetCamp SEA 1 - Use of Puppet
Walter Heck
 
Fabric workshop(1) - (MOSG)
Fabric workshop(1) - (MOSG)Fabric workshop(1) - (MOSG)
Fabric workshop(1) - (MOSG)
Soshi Nemoto
 
Augeas, swiss knife resources for your puppet tree
Augeas, swiss knife resources for your puppet treeAugeas, swiss knife resources for your puppet tree
Augeas, swiss knife resources for your puppet tree
Julien Pivotto
 
Test-Driven Infrastructure with Ansible, Test Kitchen, Serverspec and RSpec
Test-Driven Infrastructure with Ansible, Test Kitchen, Serverspec and RSpecTest-Driven Infrastructure with Ansible, Test Kitchen, Serverspec and RSpec
Test-Driven Infrastructure with Ansible, Test Kitchen, Serverspec and RSpec
Martin Etmajer
 
Instruction: dev environment
Instruction: dev environmentInstruction: dev environment
Instruction: dev environment
Soshi Nemoto
 
Ansible not only for Dummies
Ansible not only for DummiesAnsible not only for Dummies
Ansible not only for Dummies
Łukasz Proszek
 
Automated infrastructure is on the menu
Automated infrastructure is on the menuAutomated infrastructure is on the menu
Automated infrastructure is on the menu
jtimberman
 
Beaker: Automated, Cloud-Based Acceptance Testing - PuppetConf 2014
Beaker: Automated, Cloud-Based Acceptance Testing - PuppetConf 2014Beaker: Automated, Cloud-Based Acceptance Testing - PuppetConf 2014
Beaker: Automated, Cloud-Based Acceptance Testing - PuppetConf 2014
Puppet
 

What's hot (20)

From Dev to DevOps
From Dev to DevOpsFrom Dev to DevOps
From Dev to DevOps
 
DevOps(4) : Ansible(2) - (MOSG)
DevOps(4) : Ansible(2) - (MOSG)DevOps(4) : Ansible(2) - (MOSG)
DevOps(4) : Ansible(2) - (MOSG)
 
Preparation study of_docker - (MOSG)
Preparation study of_docker  - (MOSG)Preparation study of_docker  - (MOSG)
Preparation study of_docker - (MOSG)
 
Configuration Surgery with Augeas
Configuration Surgery with AugeasConfiguration Surgery with Augeas
Configuration Surgery with Augeas
 
DevOps(3) : Ansible - (MOSG)
DevOps(3) : Ansible - (MOSG)DevOps(3) : Ansible - (MOSG)
DevOps(3) : Ansible - (MOSG)
 
10 Million hits a day with WordPress using a $15 VPS
10 Million hits a day  with WordPress using a $15 VPS10 Million hits a day  with WordPress using a $15 VPS
10 Million hits a day with WordPress using a $15 VPS
 
Continuous infrastructure testing
Continuous infrastructure testingContinuous infrastructure testing
Continuous infrastructure testing
 
Puppet fundamentals
Puppet fundamentalsPuppet fundamentals
Puppet fundamentals
 
Making Your Capistrano Recipe Book
Making Your Capistrano Recipe BookMaking Your Capistrano Recipe Book
Making Your Capistrano Recipe Book
 
Ansible 實戰:top down 觀點
Ansible 實戰:top down 觀點Ansible 實戰:top down 觀點
Ansible 實戰:top down 觀點
 
DevOps(2) : Vagrant - (MOSG)
DevOps(2) : Vagrant  -  (MOSG)DevOps(2) : Vagrant  -  (MOSG)
DevOps(2) : Vagrant - (MOSG)
 
PuppetCamp SEA 1 - Puppet Deployment at OnApp
PuppetCamp SEA 1 - Puppet Deployment  at OnAppPuppetCamp SEA 1 - Puppet Deployment  at OnApp
PuppetCamp SEA 1 - Puppet Deployment at OnApp
 
PuppetCamp SEA 1 - Use of Puppet
PuppetCamp SEA 1 - Use of PuppetPuppetCamp SEA 1 - Use of Puppet
PuppetCamp SEA 1 - Use of Puppet
 
Fabric workshop(1) - (MOSG)
Fabric workshop(1) - (MOSG)Fabric workshop(1) - (MOSG)
Fabric workshop(1) - (MOSG)
 
Augeas, swiss knife resources for your puppet tree
Augeas, swiss knife resources for your puppet treeAugeas, swiss knife resources for your puppet tree
Augeas, swiss knife resources for your puppet tree
 
Test-Driven Infrastructure with Ansible, Test Kitchen, Serverspec and RSpec
Test-Driven Infrastructure with Ansible, Test Kitchen, Serverspec and RSpecTest-Driven Infrastructure with Ansible, Test Kitchen, Serverspec and RSpec
Test-Driven Infrastructure with Ansible, Test Kitchen, Serverspec and RSpec
 
Instruction: dev environment
Instruction: dev environmentInstruction: dev environment
Instruction: dev environment
 
Ansible not only for Dummies
Ansible not only for DummiesAnsible not only for Dummies
Ansible not only for Dummies
 
Automated infrastructure is on the menu
Automated infrastructure is on the menuAutomated infrastructure is on the menu
Automated infrastructure is on the menu
 
Beaker: Automated, Cloud-Based Acceptance Testing - PuppetConf 2014
Beaker: Automated, Cloud-Based Acceptance Testing - PuppetConf 2014Beaker: Automated, Cloud-Based Acceptance Testing - PuppetConf 2014
Beaker: Automated, Cloud-Based Acceptance Testing - PuppetConf 2014
 

Similar to How to Develop Puppet Modules: From Source to the Forge With Zero Clicks

Puppet
PuppetPuppet
Puppet @ Seat
Puppet @ SeatPuppet @ Seat
Puppet @ Seat
Alessandro Franceschi
 
Linuxday.at - Lightning Talk
Linuxday.at - Lightning TalkLinuxday.at - Lightning Talk
Linuxday.at - Lightning TalkJan Gehring
 
Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days ...
Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days ...Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days ...
Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days ...
Carlos Sanchez
 
Stanford Hackathon - Puppet Modules
Stanford Hackathon - Puppet ModulesStanford Hackathon - Puppet Modules
Stanford Hackathon - Puppet Modules
Puppet
 
Stack kicker devopsdays-london-2013
Stack kicker devopsdays-london-2013Stack kicker devopsdays-london-2013
Stack kicker devopsdays-london-2013Simon McCartney
 
Node.js - async for the rest of us.
Node.js - async for the rest of us.Node.js - async for the rest of us.
Node.js - async for the rest of us.
Mike Brevoort
 
Isolated development in python
Isolated development in pythonIsolated development in python
Isolated development in python
Andrés J. Díaz
 
Writing & Sharing Great Modules - Puppet Camp Boston
Writing & Sharing Great Modules - Puppet Camp BostonWriting & Sharing Great Modules - Puppet Camp Boston
Writing & Sharing Great Modules - Puppet Camp Boston
Puppet
 
Developing IT infrastructures with Puppet
Developing IT infrastructures with PuppetDeveloping IT infrastructures with Puppet
Developing IT infrastructures with Puppet
Alessandro Franceschi
 
Ansible loves Python, Python Philadelphia meetup
Ansible loves Python, Python Philadelphia meetupAnsible loves Python, Python Philadelphia meetup
Ansible loves Python, Python Philadelphia meetup
Greg DeKoenigsberg
 
Writing and Publishing Puppet Modules - PuppetConf 2014
Writing and Publishing Puppet Modules - PuppetConf 2014Writing and Publishing Puppet Modules - PuppetConf 2014
Writing and Publishing Puppet Modules - PuppetConf 2014
Puppet
 
20090514 Introducing Puppet To Sasag
20090514 Introducing Puppet To Sasag20090514 Introducing Puppet To Sasag
20090514 Introducing Puppet To Sasaggarrett honeycutt
 
Play vs Rails
Play vs RailsPlay vs Rails
Play vs Rails
Daniel Cukier
 
Puppet and the HashiStack
Puppet and the HashiStackPuppet and the HashiStack
Puppet and the HashiStack
Bram Vogelaar
 
Harmonious Development: Via Vagrant and Puppet
Harmonious Development: Via Vagrant and PuppetHarmonious Development: Via Vagrant and Puppet
Harmonious Development: Via Vagrant and Puppet
Achieve Internet
 

Similar to How to Develop Puppet Modules: From Source to the Forge With Zero Clicks (20)

Puppet
PuppetPuppet
Puppet
 
Puppet @ Seat
Puppet @ SeatPuppet @ Seat
Puppet @ Seat
 
Linuxday.at - Lightning Talk
Linuxday.at - Lightning TalkLinuxday.at - Lightning Talk
Linuxday.at - Lightning Talk
 
Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days ...
Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days ...Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days ...
Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days ...
 
Stanford Hackathon - Puppet Modules
Stanford Hackathon - Puppet ModulesStanford Hackathon - Puppet Modules
Stanford Hackathon - Puppet Modules
 
Cooking with Chef
Cooking with ChefCooking with Chef
Cooking with Chef
 
Stack kicker devopsdays-london-2013
Stack kicker devopsdays-london-2013Stack kicker devopsdays-london-2013
Stack kicker devopsdays-london-2013
 
Node.js - async for the rest of us.
Node.js - async for the rest of us.Node.js - async for the rest of us.
Node.js - async for the rest of us.
 
Isolated development in python
Isolated development in pythonIsolated development in python
Isolated development in python
 
Writing & Sharing Great Modules - Puppet Camp Boston
Writing & Sharing Great Modules - Puppet Camp BostonWriting & Sharing Great Modules - Puppet Camp Boston
Writing & Sharing Great Modules - Puppet Camp Boston
 
Developing IT infrastructures with Puppet
Developing IT infrastructures with PuppetDeveloping IT infrastructures with Puppet
Developing IT infrastructures with Puppet
 
Puppet
PuppetPuppet
Puppet
 
Ansible loves Python, Python Philadelphia meetup
Ansible loves Python, Python Philadelphia meetupAnsible loves Python, Python Philadelphia meetup
Ansible loves Python, Python Philadelphia meetup
 
Writing and Publishing Puppet Modules - PuppetConf 2014
Writing and Publishing Puppet Modules - PuppetConf 2014Writing and Publishing Puppet Modules - PuppetConf 2014
Writing and Publishing Puppet Modules - PuppetConf 2014
 
EC2
EC2EC2
EC2
 
infra-as-code
infra-as-codeinfra-as-code
infra-as-code
 
20090514 Introducing Puppet To Sasag
20090514 Introducing Puppet To Sasag20090514 Introducing Puppet To Sasag
20090514 Introducing Puppet To Sasag
 
Play vs Rails
Play vs RailsPlay vs Rails
Play vs Rails
 
Puppet and the HashiStack
Puppet and the HashiStackPuppet and the HashiStack
Puppet and the HashiStack
 
Harmonious Development: Via Vagrant and Puppet
Harmonious Development: Via Vagrant and PuppetHarmonious Development: Via Vagrant and Puppet
Harmonious Development: Via Vagrant and Puppet
 

More from Carlos Sanchez

Using Containers for Continuous Integration and Continuous Delivery. KubeCon ...
Using Containers for Continuous Integration and Continuous Delivery. KubeCon ...Using Containers for Continuous Integration and Continuous Delivery. KubeCon ...
Using Containers for Continuous Integration and Continuous Delivery. KubeCon ...
Carlos Sanchez
 
Using Kubernetes for Continuous Integration and Continuous Delivery
Using Kubernetes for Continuous Integration and Continuous DeliveryUsing Kubernetes for Continuous Integration and Continuous Delivery
Using Kubernetes for Continuous Integration and Continuous Delivery
Carlos Sanchez
 
Divide and Conquer: Easier Continuous Delivery using Micro-Services
Divide and Conquer: Easier Continuous Delivery using Micro-ServicesDivide and Conquer: Easier Continuous Delivery using Micro-Services
Divide and Conquer: Easier Continuous Delivery using Micro-Services
Carlos Sanchez
 
Using Kubernetes for Continuous Integration and Continuous Delivery. Java2days
Using Kubernetes for Continuous Integration and Continuous Delivery. Java2daysUsing Kubernetes for Continuous Integration and Continuous Delivery. Java2days
Using Kubernetes for Continuous Integration and Continuous Delivery. Java2days
Carlos Sanchez
 
Using Containers for Continuous Integration and Continuous Delivery
Using Containers for Continuous Integration and Continuous DeliveryUsing Containers for Continuous Integration and Continuous Delivery
Using Containers for Continuous Integration and Continuous Delivery
Carlos Sanchez
 
Divide and Conquer: Easier Continuous Delivery using Micro-Services
Divide and Conquer: Easier Continuous Delivery using Micro-ServicesDivide and Conquer: Easier Continuous Delivery using Micro-Services
Divide and Conquer: Easier Continuous Delivery using Micro-Services
Carlos Sanchez
 
Using Containers for Building and Testing: Docker, Kubernetes and Mesos. FOSD...
Using Containers for Building and Testing: Docker, Kubernetes and Mesos. FOSD...Using Containers for Building and Testing: Docker, Kubernetes and Mesos. FOSD...
Using Containers for Building and Testing: Docker, Kubernetes and Mesos. FOSD...
Carlos Sanchez
 
Testing Distributed Micro Services. Agile Testing Days 2017
Testing Distributed Micro Services. Agile Testing Days 2017Testing Distributed Micro Services. Agile Testing Days 2017
Testing Distributed Micro Services. Agile Testing Days 2017
Carlos Sanchez
 
CI and CD at Scale: Scaling Jenkins with Docker and Apache Mesos
CI and CD at Scale: Scaling Jenkins with Docker and Apache MesosCI and CD at Scale: Scaling Jenkins with Docker and Apache Mesos
CI and CD at Scale: Scaling Jenkins with Docker and Apache Mesos
Carlos Sanchez
 
From Monolith to Docker Distributed Applications
From Monolith to Docker Distributed ApplicationsFrom Monolith to Docker Distributed Applications
From Monolith to Docker Distributed Applications
Carlos Sanchez
 
From Monolith to Docker Distributed Applications. JavaOne
From Monolith to Docker Distributed Applications. JavaOneFrom Monolith to Docker Distributed Applications. JavaOne
From Monolith to Docker Distributed Applications. JavaOne
Carlos Sanchez
 
Scaling Jenkins with Docker: Swarm, Kubernetes or Mesos?
Scaling Jenkins with Docker: Swarm, Kubernetes or Mesos?Scaling Jenkins with Docker: Swarm, Kubernetes or Mesos?
Scaling Jenkins with Docker: Swarm, Kubernetes or Mesos?
Carlos Sanchez
 
CI and CD at Scale: Scaling Jenkins with Docker and Apache Mesos
CI and CD at Scale: Scaling Jenkins with Docker and Apache MesosCI and CD at Scale: Scaling Jenkins with Docker and Apache Mesos
CI and CD at Scale: Scaling Jenkins with Docker and Apache Mesos
Carlos Sanchez
 
From Monolith to Docker Distributed Applications
From Monolith to Docker Distributed ApplicationsFrom Monolith to Docker Distributed Applications
From Monolith to Docker Distributed Applications
Carlos Sanchez
 
Scaling Jenkins with Docker and Kubernetes
Scaling Jenkins with Docker and KubernetesScaling Jenkins with Docker and Kubernetes
Scaling Jenkins with Docker and Kubernetes
Carlos Sanchez
 
Using Docker for Testing
Using Docker for TestingUsing Docker for Testing
Using Docker for Testing
Carlos Sanchez
 
Scaling Docker with Kubernetes
Scaling Docker with KubernetesScaling Docker with Kubernetes
Scaling Docker with Kubernetes
Carlos Sanchez
 
Scaling Jenkins with Docker and Kubernetes
Scaling Jenkins with Docker and KubernetesScaling Jenkins with Docker and Kubernetes
Scaling Jenkins with Docker and Kubernetes
Carlos Sanchez
 
Scaling Docker with Kubernetes
Scaling Docker with KubernetesScaling Docker with Kubernetes
Scaling Docker with Kubernetes
Carlos Sanchez
 
Enterprise Build And Test In The Cloud
Enterprise Build And Test In The CloudEnterprise Build And Test In The Cloud
Enterprise Build And Test In The Cloud
Carlos Sanchez
 

More from Carlos Sanchez (20)

Using Containers for Continuous Integration and Continuous Delivery. KubeCon ...
Using Containers for Continuous Integration and Continuous Delivery. KubeCon ...Using Containers for Continuous Integration and Continuous Delivery. KubeCon ...
Using Containers for Continuous Integration and Continuous Delivery. KubeCon ...
 
Using Kubernetes for Continuous Integration and Continuous Delivery
Using Kubernetes for Continuous Integration and Continuous DeliveryUsing Kubernetes for Continuous Integration and Continuous Delivery
Using Kubernetes for Continuous Integration and Continuous Delivery
 
Divide and Conquer: Easier Continuous Delivery using Micro-Services
Divide and Conquer: Easier Continuous Delivery using Micro-ServicesDivide and Conquer: Easier Continuous Delivery using Micro-Services
Divide and Conquer: Easier Continuous Delivery using Micro-Services
 
Using Kubernetes for Continuous Integration and Continuous Delivery. Java2days
Using Kubernetes for Continuous Integration and Continuous Delivery. Java2daysUsing Kubernetes for Continuous Integration and Continuous Delivery. Java2days
Using Kubernetes for Continuous Integration and Continuous Delivery. Java2days
 
Using Containers for Continuous Integration and Continuous Delivery
Using Containers for Continuous Integration and Continuous DeliveryUsing Containers for Continuous Integration and Continuous Delivery
Using Containers for Continuous Integration and Continuous Delivery
 
Divide and Conquer: Easier Continuous Delivery using Micro-Services
Divide and Conquer: Easier Continuous Delivery using Micro-ServicesDivide and Conquer: Easier Continuous Delivery using Micro-Services
Divide and Conquer: Easier Continuous Delivery using Micro-Services
 
Using Containers for Building and Testing: Docker, Kubernetes and Mesos. FOSD...
Using Containers for Building and Testing: Docker, Kubernetes and Mesos. FOSD...Using Containers for Building and Testing: Docker, Kubernetes and Mesos. FOSD...
Using Containers for Building and Testing: Docker, Kubernetes and Mesos. FOSD...
 
Testing Distributed Micro Services. Agile Testing Days 2017
Testing Distributed Micro Services. Agile Testing Days 2017Testing Distributed Micro Services. Agile Testing Days 2017
Testing Distributed Micro Services. Agile Testing Days 2017
 
CI and CD at Scale: Scaling Jenkins with Docker and Apache Mesos
CI and CD at Scale: Scaling Jenkins with Docker and Apache MesosCI and CD at Scale: Scaling Jenkins with Docker and Apache Mesos
CI and CD at Scale: Scaling Jenkins with Docker and Apache Mesos
 
From Monolith to Docker Distributed Applications
From Monolith to Docker Distributed ApplicationsFrom Monolith to Docker Distributed Applications
From Monolith to Docker Distributed Applications
 
From Monolith to Docker Distributed Applications. JavaOne
From Monolith to Docker Distributed Applications. JavaOneFrom Monolith to Docker Distributed Applications. JavaOne
From Monolith to Docker Distributed Applications. JavaOne
 
Scaling Jenkins with Docker: Swarm, Kubernetes or Mesos?
Scaling Jenkins with Docker: Swarm, Kubernetes or Mesos?Scaling Jenkins with Docker: Swarm, Kubernetes or Mesos?
Scaling Jenkins with Docker: Swarm, Kubernetes or Mesos?
 
CI and CD at Scale: Scaling Jenkins with Docker and Apache Mesos
CI and CD at Scale: Scaling Jenkins with Docker and Apache MesosCI and CD at Scale: Scaling Jenkins with Docker and Apache Mesos
CI and CD at Scale: Scaling Jenkins with Docker and Apache Mesos
 
From Monolith to Docker Distributed Applications
From Monolith to Docker Distributed ApplicationsFrom Monolith to Docker Distributed Applications
From Monolith to Docker Distributed Applications
 
Scaling Jenkins with Docker and Kubernetes
Scaling Jenkins with Docker and KubernetesScaling Jenkins with Docker and Kubernetes
Scaling Jenkins with Docker and Kubernetes
 
Using Docker for Testing
Using Docker for TestingUsing Docker for Testing
Using Docker for Testing
 
Scaling Docker with Kubernetes
Scaling Docker with KubernetesScaling Docker with Kubernetes
Scaling Docker with Kubernetes
 
Scaling Jenkins with Docker and Kubernetes
Scaling Jenkins with Docker and KubernetesScaling Jenkins with Docker and Kubernetes
Scaling Jenkins with Docker and Kubernetes
 
Scaling Docker with Kubernetes
Scaling Docker with KubernetesScaling Docker with Kubernetes
Scaling Docker with Kubernetes
 
Enterprise Build And Test In The Cloud
Enterprise Build And Test In The CloudEnterprise Build And Test In The Cloud
Enterprise Build And Test In The Cloud
 

Recently uploaded

Essentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with ParametersEssentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with Parameters
Safe Software
 
Generating a custom Ruby SDK for your web service or Rails API using Smithy
Generating a custom Ruby SDK for your web service or Rails API using SmithyGenerating a custom Ruby SDK for your web service or Rails API using Smithy
Generating a custom Ruby SDK for your web service or Rails API using Smithy
g2nightmarescribd
 
Connector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a buttonConnector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a button
DianaGray10
 
The Future of Platform Engineering
The Future of Platform EngineeringThe Future of Platform Engineering
The Future of Platform Engineering
Jemma Hussein Allen
 
UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3
DianaGray10
 
GraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge GraphGraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge Graph
Guy Korland
 
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Tobias Schneck
 
Assuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyesAssuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyes
ThousandEyes
 
Knowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and backKnowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and back
Elena Simperl
 
Epistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI supportEpistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI support
Alan Dix
 
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
Product School
 
Key Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdfKey Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdf
Cheryl Hung
 
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Ramesh Iyer
 
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Product School
 
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
UiPathCommunity
 
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
James Anderson
 
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Thierry Lestable
 
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdfFIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance
 
Leading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdfLeading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdf
OnBoard
 
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdfFIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance
 

Recently uploaded (20)

Essentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with ParametersEssentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with Parameters
 
Generating a custom Ruby SDK for your web service or Rails API using Smithy
Generating a custom Ruby SDK for your web service or Rails API using SmithyGenerating a custom Ruby SDK for your web service or Rails API using Smithy
Generating a custom Ruby SDK for your web service or Rails API using Smithy
 
Connector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a buttonConnector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a button
 
The Future of Platform Engineering
The Future of Platform EngineeringThe Future of Platform Engineering
The Future of Platform Engineering
 
UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3
 
GraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge GraphGraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge Graph
 
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
 
Assuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyesAssuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyes
 
Knowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and backKnowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and back
 
Epistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI supportEpistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI support
 
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
 
Key Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdfKey Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdf
 
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
 
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...
 
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
 
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
 
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
 
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdfFIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
 
Leading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdfLeading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdf
 
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdfFIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
 

How to Develop Puppet Modules: From Source to the Forge With Zero Clicks

  • 1. How to develop Puppet Modules From source to the Forge with zero clicks Carlos Sanchez @csanchez http://csanchez.org http://maestrodev.com
  • 4.
  • 5.
  • 6. We use 50 modules
  • 7.
  • 8. DEV QA OPS Modules ARE software
  • 10.
  • 11. Specs
  • 13. Gemfile source 'https://rubygems.org' group :rake do gem 'puppet' gem 'rake' gem 'puppet-lint' gem 'rspec-puppet' end
  • 15. maven::maven class maven::maven( $version = '3.0.5', $repo = { #url => 'http://repo1.maven.org/maven2', #username => '', #password => '', } ) { if "x${repo['url']}x" != 'xx' { wget::authfetch { 'fetch-maven': source => "${repo['url']}/.../$version/apache-maven-${version}-bin.tar.gz", destination => $archive, user => $repo['username'], password => $repo['password'], before => Exec['maven-untar'], } } else { wget::fetch { 'fetch-maven': source => "http://archive.apache.org/.../apache-maven-${version}-bin.tar.gz", destination => $archive, before => Exec['maven-untar'], } }
  • 16. rspec-puppet require 'spec_helper' describe 'maven::maven' do context "when downloading maven from another repo" do let(:params) { { :repo => { 'url' => 'http://repo1.maven.org/maven2', 'username' => 'u', 'password' => 'p' } } } it 'should fetch maven with username and password' do should contain_wget__authfetch('fetch-maven').with( 'source' => 'http://repo1.maven.org/...ven-3.0.5-bin.tar.gz', 'user' => 'u', 'password' => 'p') end end end
  • 17. hosts node 'agent' inherits 'parent' { include wget include maestro::test::dependencies include maestro_nodes::agentrvm }
  • 18. hosts require 'spec_helper' describe 'agent' do it do should contain_class('maestro::agent').with( 'agent_name' => 'agent-01', 'stomp_host' => 'maestro.maestrodev.net') end it { should_not contain_service('maestro') } it { should_not contain_service('activemq') } it { should_not contain_service('jenkins') } it { should_not contain_service('postgresqld') } it { should_not contain_service('maestro-test-hub') } it { should_not contain_service('sonar') } it { should_not contain_service('archiva') } end
  • 19. rspec-puppet with facts require 'spec_helper' describe 'wget' do context 'running on OS X' do let(:facts) { {:operatingsystem => 'Darwin'} } it { should_not contain_package('wget') } end context 'running on CentOS' do let(:facts) { {:operatingsystem => 'CentOS'} } it { should contain_package('wget') } end context 'no version specified' do it { should contain_package('wget').with_ensure('installed') } end context 'version is 1.2.3' do let(:params) { {:version => '1.2.3'} } it { should contain_package('wget').with_ensure('1.2.3') } end end
  • 20. shared_context shared_context :centos do let(:facts) {{ :operatingsystem => 'CentOS', :kernel => 'Linux', :osfamily => 'RedHat' }} end describe 'maestro::maestro' do include_context :centos ... end
  • 21. extending for reuse describe 'maestro::maestro' do include_context :centos let(:facts) { super().merge({ :operatingsystem => 'RedHat' })} end
  • 22. shared_examples require 'spec_helper' describe 'nginx::package' do shared_examples 'redhat' do |operatingsystem| let(:facts) {{ :operatingsystem => operatingsystem }} it { should contain_package('nginx') } it { should contain_package('gd') } it { should contain_package('libXpm') } it { should contain_package('libxslt') } it { should contain_yumrepo('nginx-release').with_enabled('1') } end shared_examples 'debian' do |operatingsystem| let(:facts) {{ :operatingsystem => operatingsystem }} it { should contain_file('/etc/apt/sources.list.d/nginx.list') } end
  • 23. shared_examples (cont.) context 'RedHat' do it_behaves_like 'redhat', 'centos' it_behaves_like 'redhat', 'fedora' it_behaves_like 'redhat', 'rhel' it_behaves_like 'redhat', 'redhat' it_behaves_like 'redhat', 'scientific' end context 'debian' do it_behaves_like 'debian', 'debian' it_behaves_like 'debian', 'ubuntu' end context 'other' do let(:facts) {{ :operatingsystem => 'xxx' }} it { expect { subject }.to raise_error(Puppet::Error, /Module nginx is not supported on xxx/) } end end
  • 25. Gemfile source 'https://rubygems.org' group :rake do gem 'puppet' gem 'rspec-puppet' gem 'rake' gem 'puppet-lint' gem 'puppetlabs_spec_helper' end
  • 26. Rakefile require 'puppetlabs_spec_helper/rake_tasks' build # Build puppet module package clean # Clean a built module package coverage # Generate code coverage information lint # Check puppet manifests with puppet-lint spec # Run spec tests in a clean fixtures directory spec_clean # Clean up the fixtures directory spec_prep # Create the fixtures directory spec_standalone # Run spec tests on an existing fixtures directory
  • 27. spec/spec_helper.rb require 'puppetlabs_spec_helper/module_spec_helper' RSpec.configure do |c| c.before(:each) do Puppet::Util::Log.level = :warning Puppet::Util::Log.newdestination(:console) end end
  • 28. .fixtures # bring modules into spec/fixtures fixtures: repositories: firewall: "git://github.com/puppetlabs/puppetlabs-firewall" stdlib: repo: "git://github.com/puppetlabs/puppetlabs-stdlib" ref: "2.6.0" symlinks: my_module: "#{source_dir}"
  • 30. Gemfile source 'https://rubygems.org' group :rake do gem 'puppet' gem 'rspec-puppet' gem 'rake' gem 'puppet-lint' gem 'puppetlabs_spec_helper' gem 'librarian-puppet-maestrodev' end
  • 31. Puppetfile forge 'http://forge.puppetlabs.com' mod 'maestrodev/activemq', '>=1.0' mod 'saz/limits', ">=2.0.1" mod 'maestrodev/maestro_nodes', '>=1.1.0' mod 'maestrodev/maestro_demo', '>=1.0.2' mod 'maestrodev', :path => './private_modules/maestrodev' mod 'nginx', :git => 'https://github.com/jfryman/puppet-nginx.git'
  • 32.
  • 33. Puppetfile.lock FORGE remote: http://forge.puppetlabs.com specs: jfryman/nginx (0.0.2) puppetlabs/stdlib (>= 0.1.6) maestrodev/activemq (1.2.0) maestrodev/wget (>= 1.0.0) maestrodev/android (1.1.0) maestrodev/wget (>= 1.0.0) maestrodev/ant (1.0.4) maestrodev/wget (>= 0.0.1) maestrodev/archiva (1.1.0) maestrodev/wget (>= 1.0.0) maestrodev/git (1.0.1) maestrodev/jenkins (1.0.1) maestrodev/maestro (1.2.13) maestrodev/maven (>= 1.0.0) maestrodev/wget (>= 1.0.0) puppetlabs/postgresql (= 2.0.1) puppetlabs/stdlib (>= 2.5.1) maestrodev/maestro_demo (1.0.5) maestrodev/android (>= 1.1.0) maestrodev/maestro (>= 1.2.0) puppetlabs/postgresql (= 2.0.1) maestrodev/maestro_nodes (1.3.0) jfryman/nginx (>= 0.0.0) maestrodev/activemq (>= 1.0.0) maestrodev/ant (>= 1.0.3) maestrodev/archiva (>= 1.0.0) maestrodev/git (>= 1.0.0) maestrodev/jenkins (>= 1.0.0) maestrodev/maestro (>= 1.1.0) maestrodev/maven (>= 0.0.2) maestrodev/rvm (>= 1.0.0) maestrodev/sonar (>= 1.0.0) maestrodev/ssh_keygen (>= 1.0.0) maestrodev/statsd (>= 0.0.0) maestrodev/svn (>= 1.0.0) puppetlabs/java (>= 0.3.0) puppetlabs/mongodb (>= 0.1.0) puppetlabs/nodejs (>= 0.3.0) puppetlabs/ntp (>= 0.0.0) stahnma/epel (>= 0.0.0) maestrodev/maven (1.1.2) maestrodev/wget (>= 1.0.0) maestrodev/rvm (1.1.5) maestrodev/sonar (1.0.0) maestrodev/maven (>= 0.0.2) maestrodev/wget (>= 0.0.1) puppetlabs/stdlib (>= 2.3.0) maestrodev/ssh_keygen (1.0.0) maestrodev/statsd (1.0.3) puppetlabs/nodejs (>= 0.2.0) maestrodev/svn (1.1.0) maestrodev/wget (1.2.0) puppetlabs/apt (1.2.0) puppetlabs/stdlib (>= 2.2.1) puppetlabs/firewall (0.4.0) puppetlabs/java (1.0.1) puppetlabs/stdlib (>= 0.1.6) puppetlabs/mongodb (0.1.0) puppetlabs/apt (>= 0.0.2) puppetlabs/nodejs (0.3.0) puppetlabs/apt (>= 0.0.3) puppetlabs/stdlib (>= 2.0.0) puppetlabs/ntp (1.0.1) puppetlabs/stdlib (>= 0.1.6) puppetlabs/postgresql (2.0.1) puppetlabs/apt (< 2.0.0, >= 1.1.0) puppetlabs/firewall (>= 0.0.4) puppetlabs/stdlib (< 4.0.0, >= 3.2.0) puppetlabs/stdlib (3.2.0) saz/limits (2.0.1) stahnma/epel (0.0.5) GIT remote: https://github.com/jfryman/ puppet-nginx.git ref: master sha: fd4e3c5a3719132bacabe6238ad2ad31fa3ba 48c specs: nginx (0.0.2) puppetlabs/stdlib (>= 0.1.6) PATH remote: ./private_modules/ maestrodev specs: maestrodev (0.0.1) DEPENDENCIES maestrodev (>= 0) maestrodev/activemq (>= 1.0) maestrodev/maestro_demo (>= 1.0.2) maestrodev/maestro_nodes (>= 1.1.0) nginx (>= 0) saz/limits (>= 2.0.1)
  • 34. librarian-puppet clean # Cleans out the cache and install paths. init # Initializes the current directory install # Resolves and installs all of the dependencies you specify outdated # Lists outdated dependencies. package # Cache the puppet modules in vendor/puppet/cache show # Shows dependencies update # Updates and installs the dependencies you specify
  • 35. librarian-puppet for fixtures # use librarian-puppet to manage fixtures instead of .fixtures.yml. Offers more possibilities like explicit version management, forge downloads,... task :librarian_spec_prep do sh "librarian-puppet install --path=spec/fixtures/modules/" end task :spec_prep => :librarian_spec_prep
  • 38. tests/init.pp stage { 'epel': before => Stage['rvm-install'] } class { 'epel': stage => 'epel' } -> class { 'rvm': }
  • 39. Vagrantfile Vagrant.configure("2") do |config| config.vm.synced_folder ".", "/etc/puppet/modules/rvm" # install the epel module needed for rvm in CentOS config.vm.provision :shell, :inline => "test -d /etc/puppet/modules/epel || puppet module install stahnma/epel -v 0.0.3" config.vm.provision :puppet do |puppet| puppet.manifests_path = "tests" puppet.manifest_file = "init.pp" end config.vm.define :centos63 do |config| config.vm.box = "CentOS-6.3-x86_64-minimal" config.vm.box_url = "https://repo.maestrodev.com/archiva/repository/public-releases/ com/maestrodev/vagrant/CentOS/6.3/CentOS-6.3-x86_64-minimal.box" end config.vm.define :centos64 do |config| config.vm.box = "CentOS-6.4-x86_64-minimal" config.vm.box_url = "https://repo.maestrodev.com/archiva/repository/public-releases/ com/maestrodev/vagrant/CentOS/6.4/CentOS-6.4-x86_64-minimal.box" end end
  • 40. Rakefile desc "Integration test with Vagrant" task :integration do sh %{vagrant destroy --force} sh %{vagrant up} sh %{vagrant destroy --force} end
  • 41. Rakefile # start one at a time desc "Integration test with Vagrant" task :integration do sh %{vagrant destroy --force} ["centos63", "centos64"].each do |vm| sh %{vagrant up #{vm}} sh %{vagrant destroy --force #{vm}} end sh %{vagrant destroy --force} end
  • 42.
  • 45.
  • 47. Rake module:bump # Bump module version to the next minor module:bump_commit # Bump version and git commit module:clean # Runs clean again module:push # Push module to the Puppet Forge module:release # Release the Puppet module, doing a clean, build, tag, push, bump_commit and git push module:tag # Git tag with the current module version
  • 49. just remember create project in the Forge first (not yet implemented) 2.0.0 is built as a library to be reused
  • 52. Modulefile name 'maestrodev-maven' version '1.1.3' author 'maestrodev' license 'Apache License, Version 2.0' project_page 'http://github.com/maestrodev/puppet-maven' source 'http://github.com/maestrodev/puppet-maven' summary 'Apache Maven module for Puppet' description 'A Puppet module to download artifacts from Maven repositories' dependency 'maestrodev/wget', '>=1.0.0'
  • 53. Gemfile source 'https://rubygems.org' group :rake do gem 'puppet', '>=2.7.20' gem 'rspec-puppet', '>=0.1.3' gem 'rake', '>=0.9.2.2' gem 'puppet-lint', '>=0.1.12' gem 'puppetlabs_spec_helper' gem 'puppet-blacksmith', '>=1.0.5' gem 'librarian-puppet-maestrodev', '>=0.9.8' end
  • 54. Rakefile require 'bundler' Bundler.require(:rake) require 'rake/clean' CLEAN.include('spec/fixtures/', 'doc', 'pkg') CLOBBER.include('.tmp', '.librarian') require 'puppetlabs_spec_helper/rake_tasks' require 'puppet_blacksmith/rake_tasks' task :librarian_spec_prep do sh "librarian-puppet install --path=spec/fixtures/modules/" end task :spec_prep => :librarian_spec_prep task :default => [:clean, :spec]
  • 55. Rakefile (cont.) desc "Integration test with Vagrant" task :integration do sh %{vagrant destroy --force} failed = [] ["centos64", "debian6"].each do |vm| sh %{vagrant up #{vm}} do |ok| if ok sh %{vagrant destroy --force #{vm}} else failed << vm end end end fail("Machines failed to start: #{failed.join(', ')}") end
  • 59.
  • 60.
  • 62. Automate! librarian-puppet to fetch modules Vagrant box Integration tests cucumber junit selenium ...
  • 64. Use local Puppet files and modules config.vm.share_folder "puppet", "/etc/puppet", ".", :create => true, :owner => "puppet", :group => "puppet"
  • 66. Save downloaded files in host config.vm.share_folder "repo2", "/var/lib/jenkins/.m2/repository", File.expand_path("~/.m2/repository"), :extra => "dmode=777,fmode=666" config.vm.share_folder "yum", "/var/cache/yum", File.expand_path("~/.maestro/yum"), :owner => "root", :group => "root
  • 67. Provision config.vm.provision :puppet do |puppet| puppet.manifests_path = "manifests" puppet.manifest_file = "site.pp" puppet.pp_path = "/etc/puppet" puppet.options = ["--verbose"] puppet.facter = {} end
  • 70. Auto update Automatically update all the modules and tell me if it’s broken bonus point: automatically edit the Gemfile, Puppetfile, Modulefile constraints
  • 72. 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/