Your SlideShare is downloading. ×
0
Building Reusable Puppet Modules
Building Reusable Puppet Modules
Building Reusable Puppet Modules
Building Reusable Puppet Modules
Building Reusable Puppet Modules
Building Reusable Puppet Modules
Building Reusable Puppet Modules
Building Reusable Puppet Modules
Building Reusable Puppet Modules
Building Reusable Puppet Modules
Building Reusable Puppet Modules
Building Reusable Puppet Modules
Building Reusable Puppet Modules
Building Reusable Puppet Modules
Building Reusable Puppet Modules
Building Reusable Puppet Modules
Building Reusable Puppet Modules
Building Reusable Puppet Modules
Building Reusable Puppet Modules
Building Reusable Puppet Modules
Building Reusable Puppet Modules
Building Reusable Puppet Modules
Building Reusable Puppet Modules
Building Reusable Puppet Modules
Building Reusable Puppet Modules
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Building Reusable Puppet Modules

2,595

Published on

"Building Reusable Puppet Modules" by Jon Topper at Puppet Camp London 2013. Find a Puppet Camp near you: https://puppetlabs.com/community/puppet-camp/

"Building Reusable Puppet Modules" by Jon Topper at Puppet Camp London 2013. Find a Puppet Camp near you: https://puppetlabs.com/community/puppet-camp/

Published in: Technology
0 Comments
4 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
2,595
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
26
Comments
0
Likes
4
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. Building Reusable Modules Jon TopperTuesday, 2 April 13
  • 2. Jon who? ★ 12 years professional Linux sysadmin experience ★ Principal Consultant, The Scale Factory ★ 4.5 years using Puppet (since 0.24) ★ 4 full-time staff + subcontractors ★ >20 customer infrastructures deployedTuesday, 2 April 13
  • 3. Our Problem Domain ★ Multiple customers ★ Multiple Linux distributions ★ Multiple application environments ★ Adding new features over time ★ Requirement to support old deployments ★ Multiple individuals contributingTuesday, 2 April 13
  • 4. Your Problem Domain? ★ Multiple teams in a large organisation ★ Forge contributionsTuesday, 2 April 13
  • 5. Our Approach role_web role_db role_lb defaults yum firewall apache mysql varnish firewall stdlib concatTuesday, 2 April 13
  • 6. Reusable? ★ Use the same modules ★ In different combinations ★ To solve different problems ★ Without modificationTuesday, 2 April 13
  • 7. Single Responsibility Install MySQL Configure MySQL Start MySQL ✔ Install MySQL Configure MySQL Install Apache Install mod_php Install Wordpress Configure MySQL grants Configure Wordpress ✘Tuesday, 2 April 13
  • 8. Low Coupling ★ Changes in highly coupled modules necessitate changes in others ★ Limit coupling where possible ★ Examples of coupling: ★ Using variables from another class ★ Requiring specific resources from another class ★ Any other use of non-public interfacesTuesday, 2 April 13
  • 9. # sf_apache/manifests/init.pp class sf_apache::service { service { “httpd”: ensure => running } } # sf_puppetmaster/manifests/init.pp class sf_puppetmaster::config { file { “/etc/httpd/conf.d/puppetmaster.conf”: notify => Class[“sf_apache::service”], } } ✔ file { “/etc/httpd/conf.d/puppetmaster.conf”: notify => Service[“httpd”], } ✘Tuesday, 2 April 13
  • 10. Tell, Don’t Ask class apache::config( $port = 80 ) { ... } ✔ class apache::config { case $hostname { /devel/: { $port = 8080 } default: { $port = 80 } } ... } ✘Tuesday, 2 April 13
  • 11. Tell, Don’t Ask: Exception class apache::params { case $osfamily { RedHat: { $conf_d_path = "/etc/httpd/conf.d" $user = apache } Debian: { $conf_d_path = "/etc/apache2/conf.d" $user = www-data } } } ✔Tuesday, 2 April 13
  • 12. Parameters ★ Check user parameters for syntax ★ Choose sensible defaults ★ Document the module’s public interface ★ Write tests for that interfaceTuesday, 2 April 13
  • 13. Open/Closed Principle ★ Modules should be open for extension ★ But closed for modification ★ Ensures backward compatibility ★ Tests prove that compatibilityTuesday, 2 April 13
  • 14. Open/Closed Principle define sf_firewall::basic( $proto, $dport = undef, $source = undef, $destination = undef, $action, ){ # Create a basic firewall rule # Assumes ‘INPUT’ chain }Tuesday, 2 April 13
  • 15. Open/Closed Principle define sf_firewall::basic( $proto, $dport = undef, $source = undef, $destination = undef, $action, $chain, ){ # Create a basic firewall rule. Chain now # a required parameter with no default } ✘Tuesday, 2 April 13
  • 16. Open/Closed Principle define sf_firewall::basic( $proto, $dport = undef, $source = undef, $destination = undef, $action, $chain = ‘INPUT’ ){ # Create a basic firewall rule. Chain now # defaults to ‘INPUT’ but can be changed. } ✔Tuesday, 2 April 13
  • 17. Automated Test Pipeline ★ Smoke Tests ★ Unit Tests ★ Integration TestsTuesday, 2 April 13
  • 18. Smoke Testing ★ puppet-lint to enforce house style ★ puppet parser validate to check syntax ★ Evaluate ERB templates to check syntaxTuesday, 2 April 13
  • 19. Unit Testing: rspec-puppet ★ Rapid feedback testing ★ Can easily target multiple ruby/puppet version combinations ★ Test your module’s behaviour - not Puppet’s ★ Aim for Condition Coverage across behaviour that varies on parameter ★ Doesn’t guarantee that your module will work as planned in the real world!Tuesday, 2 April 13
  • 20. Condition Coverage class sf_firewall::params { case $osfamily { RedHat: { $persist_command = "/sbin/iptables-save > /etc/sysconfig/iptables" } Debian: { $persist_command = "/sbin/iptables-save > /etc/iptables/rules.v4" } }Tuesday, 2 April 13
  • 21. Condition Coverage describe ‘sf_firewall’, :type => ‘class’ do def self.test_standard_behaviour ... end context "on a RedHat OS" do let :facts do { :osfamily => RedHat } end it { should contain_exec(persist-firewall).with_command( "/sbin/iptables-save > /etc/sysconfig/iptables" )} test_standard_behaviour endTuesday, 2 April 13
  • 22. Integration Testing: Cumberbatch ★ Based on Cucumber ★ Uses Vagrant to start virtual machines ★ Runs puppet manifests for real ★ Tests outcomes ★ Rolls back VM state and tries different manifests ★ Does it all again for a different OS version ★ Very slow!Tuesday, 2 April 13
  • 23. Integration Testing: Cumberbatch Scenario: Basic install of Apache Given there is a running VM called "server" When I apply a puppet manifest containing: """ include cucumber_defaults class { sf_apache: Port => 80, Children => 10 } """ Then a second manifest application should do nothing And there should be 11 processes called “httpd” running And the Apache module “core_module” should be loaded And the Apache module “rpaf_module” should be loaded And a process called “httpd” should be listening on TCP port 80 And a GET request to http://localhost/server-status/ should return an http status of 200Tuesday, 2 April 13
  • 24. Questions?Tuesday, 2 April 13
  • 25. Jon Topper jon@scalefactory.com http://www.scalefactory.com/ Twitter: @jtopperTuesday, 2 April 13

×