WRITING & SHARINGGREAT MODULESAdrien Thebo, Puppet LabsTwitter: @nullfinch | Freenode: finch
WHO IS THIS GUY?On/Off Ops/Dev, ~8 yearsOperations Engineer @puppetlabs, 2 yearsCommunity Developer @puppetlabs, 3 months
THINGS I DOpuppet-network: cross-platform network configurationpuppet-portage: Puppet ♥ Gentoor10k: smarter Puppet deploym...
OTHER THINGS I DOTalk too fastIf I become completely unintelligibleslow me down
LET’S TALK ABOUTMODULES
BEST PRACTICES‽Traditional development: 40+ years to matureModern config. mgmt: 15 years, maxBest practices haven’t yet be...
SO WHERE DO WE START?Separate your logic and configurationKnow your interfaceUse semantic versioningReuse everythingUse th...
DATA/LOGICSEPARATION
SEPARATE LOGIC FROM DATALogic != DataExample: configure a service on different platformsShouldn’t have to update every fil...
PACKAGE/FILE/SERVICEHumble beginnings for many modulesclass mysql::server {package { mysql-server:ensure => present,}file ...
PROBLEMS WITH PACKAGE/FILE/SERVICENothing inherently wrongOverly simpleVery staticGenerally requires overhaul for differen...
RUDIMENTARY DATA/LOGIC SEPARATIONclass mysql::server {include mysql::paramspackage { mysql-server:name => $mysql::params::...
HARDCODING TUNABLE VALUESWant to prevent people from reusing your modules?Hardcode everything!
USING PARAMS, BAD:Params class = goodWhy is this bad?Site specific defaults?INSECURE DEFAULTS‽class mysql::params {$allow_...
USING PARAMS, GOOD:Force user to supply dataFail fastclass mysql::params($allow_hosts, # Force the module user to fill thi...
DATA BINDING
DATA BINDINGNew in Puppet 3: data bindingProvides a method for configuring modules
USING DATA BINDINGDefine data in a data storefiledatabaseForemanAutomatically load data in the relevant manifests
USING DATA BINDINGclass mysql::params($allow_hosts,$database_password,$database_user = root) {}# $datadir/common.yaml---my...
USING MODULES ASINTERFACES
MODULES AS INTERFACESPuppet simplifies management of servicesDefines how people interact with that servicePuppet modules d...
BE OPINIONATEDCannot make every option tunableYou’ll go insaneRequire mandatory dataAdd parameters for frequently changed ...
BUT OTHER OPINIONS ARE NICE TOOYou can’t always support every optionAllow people to directly insert their own configuration
OVERRIDE EXAMPLE: PARTIAL TEMPLATESModule provides template fragmentsUser assembles these into a full config
CREATING A PARTIAL TEMPLATE<%# nginx/templates/vhost/_listen.conf.erb %><%# Configuration fragment for listening on IPv4 a...
USING PARTIAL TEMPLATESExample: my_nginx_app/templates/nginx-vhost.conf.erbserver {<%= scope.function_template([nginx/vhos...
SEMVER
WITHOUT SEMANTIC VERSIONINGA cautionary tale of versioning gone bad1.0.0 Initial release for managing cacti1.1.1 Change se...
UPGRADING SHOULD BE BORINGAPI breaks mean upgrading is dangerousNobody wants to upgrade if it means explosionsSemantic ver...
WHAT IS SEMVER?Version strings should have meaningReleases match the format x.y.zValues indicate what’s changed in that ve...
MAJOR RELEASESExample: x.0.0Backwards incompatible changesChanging class namesChanging parameter namesDropping platform su...
MINOR RELEASESExample: x.y.0Backwards compatible featuresAdding support for new platformsAdding parametersAdding features
PATCH RELEASESExample: x.y.zBugfixesDocumentationTestsAnything that can’t be called a feature
SEMVER AS A CONTRACTIf you use SemVer, you’re making an agreement to avoidmaking breaking changesWhat is a breaking change...
WHAT IS PUBLIC?Publicly exposed classesClass parametersThe final behavior of your class
WHAT IS PRIVATE?The actual resources used in your classes and definesResources themselves are implementation, notClasses t...
SAFETY IN SEMVERSemVer takes the risk out of upgradingYou can understand the implications of upgrading rightawayHow Puppet...
MAKE OTHER PEOPLE DOYOUR WORK
AKA
REUSE MODULES
REUSE MODULESWriting good code is hard.Make other people do your work.
DISCOVERY VIA THE FORGEPuppet Forge has 1000+ modulesProvides a single point to discover and install modulesEasy access to...
GET DEPENDENCIES FROM THE FORGEgrey% puppet module search postgresNotice: Searching https://forge.puppetlabs.com ...NAME D...
COLLABORATE ON EXISTING MODULESLots of good modules are out thereEncourage people to publish on the ForgeHelp improve exis...
SMALL CONTRIBUTIONS HELPDocumentationBug fixesIssue reports
ESTABLISH ACOMMUNITY
SURVIVING SUCCESSYour module is a hit!Prepare for a deluge of bug reports and feature requests
POPULARITY = MORE WORKThings users are good at:Finding bugsFiling feature requestsRequesting things like “documentation”Fi...
HARNESS YOUR USERSBug reports = people careShow people how to helpAsk for pull requestsGuide people through the contributi...
ENDQUESTIONS?COMMENTS?SNARKYREMARKS?AWKWARD SILENCE?
CREDITSPRESENTATION DONE WITH REVEAL.JS
Upcoming SlideShare
Loading in...5
×

Writing & Sharing Great Modules on the Puppet Forge

4,108

Published on

"Writing & Sharing Great Modules on the Puppet Forge" by Adrien Thebo of Puppet Labs at Puppet Camp Austin 2013.

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

No Downloads
Views
Total Views
4,108
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
31
Comments
0
Likes
9
Embeds 0
No embeds

No notes for slide

Transcript of "Writing & Sharing Great Modules on the Puppet Forge"

  1. 1. WRITING & SHARINGGREAT MODULESAdrien Thebo, Puppet LabsTwitter: @nullfinch | Freenode: finch
  2. 2. WHO IS THIS GUY?On/Off Ops/Dev, ~8 yearsOperations Engineer @puppetlabs, 2 yearsCommunity Developer @puppetlabs, 3 months
  3. 3. THINGS I DOpuppet-network: cross-platform network configurationpuppet-portage: Puppet ♥ Gentoor10k: smarter Puppet deployment, powered by robotsvagrant-hosts: it’s always a DNS problemvagrant-pe_build: From zero to PE in vagrant up
  4. 4. OTHER THINGS I DOTalk too fastIf I become completely unintelligibleslow me down
  5. 5. LET’S TALK ABOUTMODULES
  6. 6. BEST PRACTICES‽Traditional development: 40+ years to matureModern config. mgmt: 15 years, maxBest practices haven’t yet been established
  7. 7. SO WHERE DO WE START?Separate your logic and configurationKnow your interfaceUse semantic versioningReuse everythingUse the community
  8. 8. DATA/LOGICSEPARATION
  9. 9. SEPARATE LOGIC FROM DATALogic != DataExample: configure a service on different platformsShouldn’t have to update every file in a module
  10. 10. PACKAGE/FILE/SERVICEHumble beginnings for many modulesclass mysql::server {package { mysql-server:ensure => present,}file { /etc/mysql/my.cnf:ensure => present,content => template(mysql/server/my.cnf.erb),require => Package[mysql-server],}service { mysqld:ensure => running,enable => true,subscribe => File[/etc/mysql/my.conf],}}
  11. 11. PROBLEMS WITH PACKAGE/FILE/SERVICENothing inherently wrongOverly simpleVery staticGenerally requires overhaul for different platforms
  12. 12. RUDIMENTARY DATA/LOGIC SEPARATIONclass mysql::server {include mysql::paramspackage { mysql-server:name => $mysql::params::server_package,ensure => present,}file { my.cnf:path => $mysql::params::server_config,ensure => present,source => puppet:///modules/nrpe/nrpe.cfg,require => Package[nagios-nrpe-server],}service { mysql-server:name => $mysql::params::server_service,ensure => running,enable => true,subscribe => File[my.cnf],}}
  13. 13. HARDCODING TUNABLE VALUESWant to prevent people from reusing your modules?Hardcode everything!
  14. 14. USING PARAMS, BAD:Params class = goodWhy is this bad?Site specific defaults?INSECURE DEFAULTS‽class mysql::params {$allow_hosts = 0.0.0.0/0$root_user = root# ¯_(ツ)_/¯$root_password = changeme}
  15. 15. USING PARAMS, GOOD:Force user to supply dataFail fastclass mysql::params($allow_hosts, # Force the module user to fill this out$root_password, # Fail fast rather than potentially use bad data$root_user = root # Sane default) {}
  16. 16. DATA BINDING
  17. 17. DATA BINDINGNew in Puppet 3: data bindingProvides a method for configuring modules
  18. 18. USING DATA BINDINGDefine data in a data storefiledatabaseForemanAutomatically load data in the relevant manifests
  19. 19. USING DATA BINDINGclass mysql::params($allow_hosts,$database_password,$database_user = root) {}# $datadir/common.yaml---mysql::params::allow_hosts: 10.126.8.0/24# $datadir/qa.mysite.local.yaml---mysql::params::allow_hosts: 10.134.8.0/24
  20. 20. USING MODULES ASINTERFACES
  21. 21. MODULES AS INTERFACESPuppet simplifies management of servicesDefines how people interact with that servicePuppet modules define an interface for that serviceCreates two challengesWhat options are supported?What options should users configure?
  22. 22. BE OPINIONATEDCannot make every option tunableYou’ll go insaneRequire mandatory dataAdd parameters for frequently changed dataOffer an ‘override’ option
  23. 23. BUT OTHER OPINIONS ARE NICE TOOYou can’t always support every optionAllow people to directly insert their own configuration
  24. 24. OVERRIDE EXAMPLE: PARTIAL TEMPLATESModule provides template fragmentsUser assembles these into a full config
  25. 25. CREATING A PARTIAL TEMPLATE<%# nginx/templates/vhost/_listen.conf.erb %><%# Configuration fragment for listening on IPv4 and IPv6 with SSL %><% unless @sslonly -%>listen <%= port %>;<% if scope.lookupvar(::ipaddress6) -%>listen [::]:<%= port %>;<% end -%><% end -%><% if ssl -%>listen <%= ssl_port %> ssl;<% if scope.lookupvar(::ipaddress6) -%>listen [::]:<%= ssl_port %> ssl;<% end -%><% end -%>
  26. 26. USING PARTIAL TEMPLATESExample: my_nginx_app/templates/nginx-vhost.conf.erbserver {<%= scope.function_template([nginx/vhost/_listen.conf.erb]) %>root /usr/share/empty;location / {proxy_pass <%= @proto %>://workers;proxy_redirect off;proxy_next_upstream error timeout invalid_header http_500 http_503;proxy_connect_timeout 5;}}
  27. 27. SEMVER
  28. 28. WITHOUT SEMANTIC VERSIONINGA cautionary tale of versioning gone bad1.0.0 Initial release for managing cacti1.1.1 Change serverparam to servername1.1.2 Move params from cacti::data to cacti::params1.2.0 Updated README1.2.1 Drops support for CentOS 51.3.0 This module now manages munin2.0.0 I can update versions whenever I want?10.51.100 THIS IS AWESOME!-4.number.999999999999 I’VE CREATED A MONSTER
  29. 29. UPGRADING SHOULD BE BORINGAPI breaks mean upgrading is dangerousNobody wants to upgrade if it means explosionsSemantic versioning helps mitigate this
  30. 30. WHAT IS SEMVER?Version strings should have meaningReleases match the format x.y.zValues indicate what’s changed in that version
  31. 31. MAJOR RELEASESExample: x.0.0Backwards incompatible changesChanging class namesChanging parameter namesDropping platform support
  32. 32. MINOR RELEASESExample: x.y.0Backwards compatible featuresAdding support for new platformsAdding parametersAdding features
  33. 33. PATCH RELEASESExample: x.y.zBugfixesDocumentationTestsAnything that can’t be called a feature
  34. 34. SEMVER AS A CONTRACTIf you use SemVer, you’re making an agreement to avoidmaking breaking changesWhat is a breaking change?What’s public?What’s private?
  35. 35. WHAT IS PUBLIC?Publicly exposed classesClass parametersThe final behavior of your class
  36. 36. WHAT IS PRIVATE?The actual resources used in your classes and definesResources themselves are implementation, notClasses that are documented as privateIf you document that a class is private, people shouldn’tuse it
  37. 37. SAFETY IN SEMVERSemVer takes the risk out of upgradingYou can understand the implications of upgrading rightawayHow Puppet does it3.1.0: Better support for Ruby code loading3.1.1: Security fixes3.2.0: External CA support, types & providers forOpenWRT4.0.0: Tachyon based transport layerNot really.
  38. 38. MAKE OTHER PEOPLE DOYOUR WORK
  39. 39. AKA
  40. 40. REUSE MODULES
  41. 41. REUSE MODULESWriting good code is hard.Make other people do your work.
  42. 42. DISCOVERY VIA THE FORGEPuppet Forge has 1000+ modulesProvides a single point to discover and install modulesEasy access to documentationREADMECHANGELOGType & provider documentation
  43. 43. GET DEPENDENCIES FROM THE FORGEgrey% puppet module search postgresNotice: Searching https://forge.puppetlabs.com ...NAME DESCRIPTIONknowshan-phppgadmin Install and configure phpPgAdminDropPod-postgres A basic type for managing Postgrescamptocamp-pgconf Manage postgresql.conf entriesinkling-postgresql PostgreSQL defined resource typesakumria-postgresql Install and configure the Postgresqlpuppetlabs-postgresql PostgreSQL defined resource types
  44. 44. COLLABORATE ON EXISTING MODULESLots of good modules are out thereEncourage people to publish on the ForgeHelp improve existing modulesOnl you can prevent ecosystem fragmentation
  45. 45. SMALL CONTRIBUTIONS HELPDocumentationBug fixesIssue reports
  46. 46. ESTABLISH ACOMMUNITY
  47. 47. SURVIVING SUCCESSYour module is a hit!Prepare for a deluge of bug reports and feature requests
  48. 48. POPULARITY = MORE WORKThings users are good at:Finding bugsFiling feature requestsRequesting things like “documentation”Finding more bugsFunny how these match how you can help othercontributors
  49. 49. HARNESS YOUR USERSBug reports = people careShow people how to helpAsk for pull requestsGuide people through the contribution process
  50. 50. ENDQUESTIONS?COMMENTS?SNARKYREMARKS?AWKWARD SILENCE?
  51. 51. CREDITSPRESENTATION DONE WITH REVEAL.JS
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×