Writing & Sharing Great Modules on the Puppet Forge
Upcoming SlideShare
Loading in...5

Writing & Sharing Great Modules on the Puppet Forge



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

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



Total Views
Views on SlideShare
Embed Views



3 Embeds 14

https://twitter.com 10
http://puppetlabs.com 3
https://puppetlabs.com 1



Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
Post Comment
Edit your comment

Writing & Sharing Great Modules on the Puppet Forge Writing & Sharing Great Modules on the Puppet Forge Presentation Transcript

  • 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 deployment, powered by robotsvagrant-hosts: it’s always a DNS problemvagrant-pe_build: From zero to PE in vagrant up
  • OTHER THINGS I DOTalk too fastIf I become completely unintelligibleslow me down
  • BEST PRACTICES‽Traditional development: 40+ years to matureModern config. mgmt: 15 years, maxBest practices haven’t yet been established
  • SO WHERE DO WE START?Separate your logic and configurationKnow your interfaceUse semantic versioningReuse everythingUse the community
  • SEPARATE LOGIC FROM DATALogic != DataExample: configure a service on different platformsShouldn’t have to update every file in a module
  • 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],}}
  • PROBLEMS WITH PACKAGE/FILE/SERVICENothing inherently wrongOverly simpleVery staticGenerally requires overhaul for different platforms
  • 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],}}
  • 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_hosts =$root_user = root# ¯_(ツ)_/¯$root_password = changeme}
  • 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) {}
  • 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---mysql::params::allow_hosts: $datadir/qa.mysite.local.yaml---mysql::params::allow_hosts:
  • 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?
  • BE OPINIONATEDCannot make every option tunableYou’ll go insaneRequire mandatory dataAdd parameters for frequently changed dataOffer an ‘override’ option
  • 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 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 -%>
  • 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;}}
  • 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
  • UPGRADING SHOULD BE BORINGAPI breaks mean upgrading is dangerousNobody wants to upgrade if it means explosionsSemantic versioning helps mitigate this
  • WHAT IS SEMVER?Version strings should have meaningReleases match the format x.y.zValues indicate what’s changed in that version
  • MAJOR RELEASESExample: x.0.0Backwards incompatible changesChanging class namesChanging parameter namesDropping platform support
  • 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’s public?What’s private?
  • 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 that are documented as privateIf you document that a class is private, people shouldn’tuse it
  • 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.
  • AKA
  • 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 documentationREADMECHANGELOGType & provider documentation
  • 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
  • COLLABORATE ON EXISTING MODULESLots of good modules are out thereEncourage people to publish on the ForgeHelp improve existing modulesOnl you can prevent ecosystem fragmentation
  • SMALL CONTRIBUTIONS HELPDocumentationBug fixesIssue reports
  • 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”Finding more bugsFunny how these match how you can help othercontributors
  • HARNESS YOUR USERSBug reports = people careShow people how to helpAsk for pull requestsGuide people through the contribution process