how to develop puppet modules: from source to the forge with zero clicks
DESCRIPTION
Puppet Modules are a great way to reuse code, share your development with other people and take advantage of the hundreds of modules already available in the community. But how to create, test and publish them as easily as possible? now that infrastructure is defined as code, we need to use development best practices to build, test, deploy and use Puppet modules themselves. Three steps for a fully automated process * Continuous Integration of Puppet Modules * Automatic release and upload to the Puppet Forge * Deploy to Puppet master Carlos Sanchez Architect, MaestroDev Carlos Sanchez is specialized in automation and quality of software development, QA and operations processes, from build tools and continuous integration to deployment automation, speaking on the subject in several conferences around the world. Involved in Open Source for over ten years, he is a member of the Apache Software Foundation amongst other open source groups, contributing to several projects, like Apache Maven. Currently works as Architect at MaestroDev, a company focusing on development and DevOps tools, from his home in Spain.TRANSCRIPT
![Page 1: How to Develop Puppet Modules: From Source to the Forge With Zero Clicks](https://reader034.vdocuments.site/reader034/viewer/2022042521/554f3e09b4c90572088b511c/html5/thumbnails/1.jpg)
How to develop Puppet ModulesFrom source to the Forge with zero clicks
Carlos Sanchez@csanchezhttp://csanchez.orghttp://maestrodev.com
![Page 2: How to Develop Puppet Modules: From Source to the Forge With Zero Clicks](https://reader034.vdocuments.site/reader034/viewer/2022042521/554f3e09b4c90572088b511c/html5/thumbnails/2.jpg)
@csanchez Apache Maven
ASF Member
Eclipse Foundation
csanchez.orgmaestrodev.com
![Page 3: How to Develop Puppet Modules: From Source to the Forge With Zero Clicks](https://reader034.vdocuments.site/reader034/viewer/2022042521/554f3e09b4c90572088b511c/html5/thumbnails/3.jpg)
Modules
![Page 4: How to Develop Puppet Modules: From Source to the Forge With Zero Clicks](https://reader034.vdocuments.site/reader034/viewer/2022042521/554f3e09b4c90572088b511c/html5/thumbnails/4.jpg)
![Page 5: How to Develop Puppet Modules: From Source to the Forge With Zero Clicks](https://reader034.vdocuments.site/reader034/viewer/2022042521/554f3e09b4c90572088b511c/html5/thumbnails/5.jpg)
![Page 6: How to Develop Puppet Modules: From Source to the Forge With Zero Clicks](https://reader034.vdocuments.site/reader034/viewer/2022042521/554f3e09b4c90572088b511c/html5/thumbnails/6.jpg)
We use 50 modules
![Page 7: How to Develop Puppet Modules: From Source to the Forge With Zero Clicks](https://reader034.vdocuments.site/reader034/viewer/2022042521/554f3e09b4c90572088b511c/html5/thumbnails/7.jpg)
![Page 8: How to Develop Puppet Modules: From Source to the Forge With Zero Clicks](https://reader034.vdocuments.site/reader034/viewer/2022042521/554f3e09b4c90572088b511c/html5/thumbnails/8.jpg)
DEV QA OPS
Modules ARE software
![Page 9: How to Develop Puppet Modules: From Source to the Forge With Zero Clicks](https://reader034.vdocuments.site/reader034/viewer/2022042521/554f3e09b4c90572088b511c/html5/thumbnails/9.jpg)
oh my
VersionsDependenciesIncompabilities
![Page 10: How to Develop Puppet Modules: From Source to the Forge With Zero Clicks](https://reader034.vdocuments.site/reader034/viewer/2022042521/554f3e09b4c90572088b511c/html5/thumbnails/10.jpg)
![Page 11: How to Develop Puppet Modules: From Source to the Forge With Zero Clicks](https://reader034.vdocuments.site/reader034/viewer/2022042521/554f3e09b4c90572088b511c/html5/thumbnails/11.jpg)
Specs
![Page 12: How to Develop Puppet Modules: From Source to the Forge With Zero Clicks](https://reader034.vdocuments.site/reader034/viewer/2022042521/554f3e09b4c90572088b511c/html5/thumbnails/12.jpg)
RSpec-Puppet
![Page 13: How to Develop Puppet Modules: From Source to the Forge With Zero Clicks](https://reader034.vdocuments.site/reader034/viewer/2022042521/554f3e09b4c90572088b511c/html5/thumbnails/13.jpg)
Gemfile
source 'https://rubygems.org'
group :rake do gem 'puppet' gem 'rake' gem 'puppet-lint' gem 'rspec-puppet'end
![Page 14: How to Develop Puppet Modules: From Source to the Forge With Zero Clicks](https://reader034.vdocuments.site/reader034/viewer/2022042521/554f3e09b4c90572088b511c/html5/thumbnails/14.jpg)
modules
{module}/ spec/ spec_helper.rb classes/ {class}_spec.pp definitions/ fixtures/ hosts/
![Page 15: How to Develop Puppet Modules: From Source to the Forge With Zero Clicks](https://reader034.vdocuments.site/reader034/viewer/2022042521/554f3e09b4c90572088b511c/html5/thumbnails/15.jpg)
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'], } }
![Page 16: How to Develop Puppet Modules: From Source to the Forge With Zero Clicks](https://reader034.vdocuments.site/reader034/viewer/2022042521/554f3e09b4c90572088b511c/html5/thumbnails/16.jpg)
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 endend
![Page 17: How to Develop Puppet Modules: From Source to the Forge With Zero Clicks](https://reader034.vdocuments.site/reader034/viewer/2022042521/554f3e09b4c90572088b511c/html5/thumbnails/17.jpg)
hosts
node 'agent' inherits 'parent' { include wget
include maestro::test::dependencies include maestro_nodes::agentrvm}
![Page 18: How to Develop Puppet Modules: From Source to the Forge With Zero Clicks](https://reader034.vdocuments.site/reader034/viewer/2022042521/554f3e09b4c90572088b511c/html5/thumbnails/18.jpg)
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
![Page 19: How to Develop Puppet Modules: From Source to the Forge With Zero Clicks](https://reader034.vdocuments.site/reader034/viewer/2022042521/554f3e09b4c90572088b511c/html5/thumbnails/19.jpg)
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') } endend
![Page 20: How to Develop Puppet Modules: From Source to the Forge With Zero Clicks](https://reader034.vdocuments.site/reader034/viewer/2022042521/554f3e09b4c90572088b511c/html5/thumbnails/20.jpg)
shared_context
shared_context :centos do
let(:facts) {{ :operatingsystem => 'CentOS', :kernel => 'Linux', :osfamily => 'RedHat' }}
end
describe 'maestro::maestro' do include_context :centos ...end
![Page 21: How to Develop Puppet Modules: From Source to the Forge With Zero Clicks](https://reader034.vdocuments.site/reader034/viewer/2022042521/554f3e09b4c90572088b511c/html5/thumbnails/21.jpg)
extending for reuse
describe 'maestro::maestro' do include_context :centos
let(:facts) { super().merge({ :operatingsystem => 'RedHat' })}end
![Page 22: How to Develop Puppet Modules: From Source to the Forge With Zero Clicks](https://reader034.vdocuments.site/reader034/viewer/2022042521/554f3e09b4c90572088b511c/html5/thumbnails/22.jpg)
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
![Page 23: How to Develop Puppet Modules: From Source to the Forge With Zero Clicks](https://reader034.vdocuments.site/reader034/viewer/2022042521/554f3e09b4c90572088b511c/html5/thumbnails/23.jpg)
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/) } endend
![Page 24: How to Develop Puppet Modules: From Source to the Forge With Zero Clicks](https://reader034.vdocuments.site/reader034/viewer/2022042521/554f3e09b4c90572088b511c/html5/thumbnails/24.jpg)
puppetlabs_spec_helper
![Page 25: How to Develop Puppet Modules: From Source to the Forge With Zero Clicks](https://reader034.vdocuments.site/reader034/viewer/2022042521/554f3e09b4c90572088b511c/html5/thumbnails/25.jpg)
Gemfile
source 'https://rubygems.org'
group :rake do gem 'puppet' gem 'rspec-puppet' gem 'rake' gem 'puppet-lint' gem 'puppetlabs_spec_helper'end
![Page 26: How to Develop Puppet Modules: From Source to the Forge With Zero Clicks](https://reader034.vdocuments.site/reader034/viewer/2022042521/554f3e09b4c90572088b511c/html5/thumbnails/26.jpg)
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
![Page 27: How to Develop Puppet Modules: From Source to the Forge With Zero Clicks](https://reader034.vdocuments.site/reader034/viewer/2022042521/554f3e09b4c90572088b511c/html5/thumbnails/27.jpg)
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
![Page 28: How to Develop Puppet Modules: From Source to the Forge With Zero Clicks](https://reader034.vdocuments.site/reader034/viewer/2022042521/554f3e09b4c90572088b511c/html5/thumbnails/28.jpg)
.fixtures
# bring modules into spec/fixturesfixtures: 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}"
![Page 29: How to Develop Puppet Modules: From Source to the Forge With Zero Clicks](https://reader034.vdocuments.site/reader034/viewer/2022042521/554f3e09b4c90572088b511c/html5/thumbnails/29.jpg)
librarian-puppet
![Page 30: How to Develop Puppet Modules: From Source to the Forge With Zero Clicks](https://reader034.vdocuments.site/reader034/viewer/2022042521/554f3e09b4c90572088b511c/html5/thumbnails/30.jpg)
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
![Page 31: How to Develop Puppet Modules: From Source to the Forge With Zero Clicks](https://reader034.vdocuments.site/reader034/viewer/2022042521/554f3e09b4c90572088b511c/html5/thumbnails/31.jpg)
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'
![Page 32: How to Develop Puppet Modules: From Source to the Forge With Zero Clicks](https://reader034.vdocuments.site/reader034/viewer/2022042521/554f3e09b4c90572088b511c/html5/thumbnails/32.jpg)
![Page 33: How to Develop Puppet Modules: From Source to the Forge With Zero Clicks](https://reader034.vdocuments.site/reader034/viewer/2022042521/554f3e09b4c90572088b511c/html5/thumbnails/33.jpg)
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: fd4e3c5a3719132bacabe6238ad2ad31fa3ba48c 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)
![Page 34: How to Develop Puppet Modules: From Source to the Forge With Zero Clicks](https://reader034.vdocuments.site/reader034/viewer/2022042521/554f3e09b4c90572088b511c/html5/thumbnails/34.jpg)
librarian-puppet
clean # Cleans out the cache and install paths.init # Initializes the current directoryinstall # Resolves and installs all of the dependencies you specifyoutdated # Lists outdated dependencies.package # Cache the puppet modules in vendor/puppet/cacheshow # Shows dependenciesupdate # Updates and installs the dependencies you specify
![Page 35: How to Develop Puppet Modules: From Source to the Forge With Zero Clicks](https://reader034.vdocuments.site/reader034/viewer/2022042521/554f3e09b4c90572088b511c/html5/thumbnails/35.jpg)
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
![Page 36: How to Develop Puppet Modules: From Source to the Forge With Zero Clicks](https://reader034.vdocuments.site/reader034/viewer/2022042521/554f3e09b4c90572088b511c/html5/thumbnails/36.jpg)
.fixtures
fixtures: symlinks: my_module: "#{source_dir}"
![Page 37: How to Develop Puppet Modules: From Source to the Forge With Zero Clicks](https://reader034.vdocuments.site/reader034/viewer/2022042521/554f3e09b4c90572088b511c/html5/thumbnails/37.jpg)
Vagrant
![Page 38: How to Develop Puppet Modules: From Source to the Forge With Zero Clicks](https://reader034.vdocuments.site/reader034/viewer/2022042521/554f3e09b4c90572088b511c/html5/thumbnails/38.jpg)
tests/init.pp
stage { 'epel': before => Stage['rvm-install']}
class { 'epel': stage => 'epel' } ->class { 'rvm': }
![Page 39: How to Develop Puppet Modules: From Source to the Forge With Zero Clicks](https://reader034.vdocuments.site/reader034/viewer/2022042521/554f3e09b4c90572088b511c/html5/thumbnails/39.jpg)
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
![Page 40: How to Develop Puppet Modules: From Source to the Forge With Zero Clicks](https://reader034.vdocuments.site/reader034/viewer/2022042521/554f3e09b4c90572088b511c/html5/thumbnails/40.jpg)
Rakefile
desc "Integration test with Vagrant"task :integration do sh %{vagrant destroy --force} sh %{vagrant up} sh %{vagrant destroy --force}end
![Page 41: How to Develop Puppet Modules: From Source to the Forge With Zero Clicks](https://reader034.vdocuments.site/reader034/viewer/2022042521/554f3e09b4c90572088b511c/html5/thumbnails/41.jpg)
Rakefile
# start one at a timedesc "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
![Page 42: How to Develop Puppet Modules: From Source to the Forge With Zero Clicks](https://reader034.vdocuments.site/reader034/viewer/2022042521/554f3e09b4c90572088b511c/html5/thumbnails/42.jpg)
![Page 43: How to Develop Puppet Modules: From Source to the Forge With Zero Clicks](https://reader034.vdocuments.site/reader034/viewer/2022042521/554f3e09b4c90572088b511c/html5/thumbnails/43.jpg)
Blacksmith
![Page 44: How to Develop Puppet Modules: From Source to the Forge With Zero Clicks](https://reader034.vdocuments.site/reader034/viewer/2022042521/554f3e09b4c90572088b511c/html5/thumbnails/44.jpg)
gem 'puppet-blacksmith'
![Page 45: How to Develop Puppet Modules: From Source to the Forge With Zero Clicks](https://reader034.vdocuments.site/reader034/viewer/2022042521/554f3e09b4c90572088b511c/html5/thumbnails/45.jpg)
![Page 46: How to Develop Puppet Modules: From Source to the Forge With Zero Clicks](https://reader034.vdocuments.site/reader034/viewer/2022042521/554f3e09b4c90572088b511c/html5/thumbnails/46.jpg)
Rakefile
require 'puppet_blacksmith/rake_tasks'
![Page 47: How to Develop Puppet Modules: From Source to the Forge With Zero Clicks](https://reader034.vdocuments.site/reader034/viewer/2022042521/554f3e09b4c90572088b511c/html5/thumbnails/47.jpg)
Rake
module:bump # Bump module version to the next minormodule:bump_commit # Bump version and git commitmodule:clean # Runs clean againmodule:push # Push module to the Puppet Forgemodule:release # Release the Puppet module, doing a clean, build, tag, push, bump_commit and git pushmodule:tag # Git tag with the current module version
![Page 48: How to Develop Puppet Modules: From Source to the Forge With Zero Clicks](https://reader034.vdocuments.site/reader034/viewer/2022042521/554f3e09b4c90572088b511c/html5/thumbnails/48.jpg)
~/.puppetforge.yml
---forge: https://forge.puppetlabs.comusername: myusernamepassword: mypassword
![Page 49: How to Develop Puppet Modules: From Source to the Forge With Zero Clicks](https://reader034.vdocuments.site/reader034/viewer/2022042521/554f3e09b4c90572088b511c/html5/thumbnails/49.jpg)
just remember
create project in the Forge first(not yet implemented)
2.0.0 is built as a library to be reused
![Page 50: How to Develop Puppet Modules: From Source to the Forge With Zero Clicks](https://reader034.vdocuments.site/reader034/viewer/2022042521/554f3e09b4c90572088b511c/html5/thumbnails/50.jpg)
All together
![Page 51: How to Develop Puppet Modules: From Source to the Forge With Zero Clicks](https://reader034.vdocuments.site/reader034/viewer/2022042521/554f3e09b4c90572088b511c/html5/thumbnails/51.jpg)
Maven module
http://github.com/maestrodev/puppet-maven
![Page 52: How to Develop Puppet Modules: From Source to the Forge With Zero Clicks](https://reader034.vdocuments.site/reader034/viewer/2022042521/554f3e09b4c90572088b511c/html5/thumbnails/52.jpg)
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'
![Page 53: How to Develop Puppet Modules: From Source to the Forge With Zero Clicks](https://reader034.vdocuments.site/reader034/viewer/2022042521/554f3e09b4c90572088b511c/html5/thumbnails/53.jpg)
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
![Page 54: How to Develop Puppet Modules: From Source to the Forge With Zero Clicks](https://reader034.vdocuments.site/reader034/viewer/2022042521/554f3e09b4c90572088b511c/html5/thumbnails/54.jpg)
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/"endtask :spec_prep => :librarian_spec_prep
task :default => [:clean, :spec]
![Page 55: How to Develop Puppet Modules: From Source to the Forge With Zero Clicks](https://reader034.vdocuments.site/reader034/viewer/2022042521/554f3e09b4c90572088b511c/html5/thumbnails/55.jpg)
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
![Page 56: How to Develop Puppet Modules: From Source to the Forge With Zero Clicks](https://reader034.vdocuments.site/reader034/viewer/2022042521/554f3e09b4c90572088b511c/html5/thumbnails/56.jpg)
.fixtures.yml
fixtures: symlinks: maven: "#{source_dir}"
![Page 57: How to Develop Puppet Modules: From Source to the Forge With Zero Clicks](https://reader034.vdocuments.site/reader034/viewer/2022042521/554f3e09b4c90572088b511c/html5/thumbnails/57.jpg)
Puppetfile
forge 'http://forge.puppetlabs.com'
mod 'maestrodev/wget', '>=1.0.0'
![Page 58: How to Develop Puppet Modules: From Source to the Forge With Zero Clicks](https://reader034.vdocuments.site/reader034/viewer/2022042521/554f3e09b4c90572088b511c/html5/thumbnails/58.jpg)
Integrating modules
![Page 59: How to Develop Puppet Modules: From Source to the Forge With Zero Clicks](https://reader034.vdocuments.site/reader034/viewer/2022042521/554f3e09b4c90572088b511c/html5/thumbnails/59.jpg)
![Page 60: How to Develop Puppet Modules: From Source to the Forge With Zero Clicks](https://reader034.vdocuments.site/reader034/viewer/2022042521/554f3e09b4c90572088b511c/html5/thumbnails/60.jpg)
![Page 61: How to Develop Puppet Modules: From Source to the Forge With Zero Clicks](https://reader034.vdocuments.site/reader034/viewer/2022042521/554f3e09b4c90572088b511c/html5/thumbnails/61.jpg)
modules
PREVIEW
code
DEV
DEMO
EVAL
CLIENT
modulesmodulesmodules
codecodecode
manifests
![Page 62: How to Develop Puppet Modules: From Source to the Forge With Zero Clicks](https://reader034.vdocuments.site/reader034/viewer/2022042521/554f3e09b4c90572088b511c/html5/thumbnails/62.jpg)
Automate!
librarian-puppet to fetch modulesVagrant box
Integration testscucumber
junitselenium
...
![Page 63: How to Develop Puppet Modules: From Source to the Forge With Zero Clicks](https://reader034.vdocuments.site/reader034/viewer/2022042521/554f3e09b4c90572088b511c/html5/thumbnails/63.jpg)
Vagrant integration tests
![Page 64: How to Develop Puppet Modules: From Source to the Forge With Zero Clicks](https://reader034.vdocuments.site/reader034/viewer/2022042521/554f3e09b4c90572088b511c/html5/thumbnails/64.jpg)
Use local Puppet files and modules
config.vm.share_folder "puppet", "/etc/puppet", ".", :create => true, :owner => "puppet", :group => "puppet"
![Page 65: How to Develop Puppet Modules: From Source to the Forge With Zero Clicks](https://reader034.vdocuments.site/reader034/viewer/2022042521/554f3e09b4c90572088b511c/html5/thumbnails/65.jpg)
Share logs
config.vm.share_folder "jenkins-logs", "/var/log/jenkins", "target/logs/jenkins", :create => true, :extra => "dmode=777,fmode=666"
![Page 66: How to Develop Puppet Modules: From Source to the Forge With Zero Clicks](https://reader034.vdocuments.site/reader034/viewer/2022042521/554f3e09b4c90572088b511c/html5/thumbnails/66.jpg)
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
![Page 67: How to Develop Puppet Modules: From Source to the Forge With Zero Clicks](https://reader034.vdocuments.site/reader034/viewer/2022042521/554f3e09b4c90572088b511c/html5/thumbnails/67.jpg)
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
![Page 68: How to Develop Puppet Modules: From Source to the Forge With Zero Clicks](https://reader034.vdocuments.site/reader034/viewer/2022042521/554f3e09b4c90572088b511c/html5/thumbnails/68.jpg)
Run!
vagrant destroy --force vagrant uprake integration
![Page 69: How to Develop Puppet Modules: From Source to the Forge With Zero Clicks](https://reader034.vdocuments.site/reader034/viewer/2022042521/554f3e09b4c90572088b511c/html5/thumbnails/69.jpg)
Forward looking
![Page 70: How to Develop Puppet Modules: From Source to the Forge With Zero Clicks](https://reader034.vdocuments.site/reader034/viewer/2022042521/554f3e09b4c90572088b511c/html5/thumbnails/70.jpg)
Auto update
Automatically update all the modules and tell me if it’s broken
bonus point: automatically edit the Gemfile, Puppetfile, Modulefile constraints
![Page 72: How to Develop Puppet Modules: From Source to the Forge With Zero Clicks](https://reader034.vdocuments.site/reader034/viewer/2022042521/554f3e09b4c90572088b511c/html5/thumbnails/72.jpg)
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/