SlideShare a Scribd company logo
WRITING & SHARING
GREAT MODULES
Cody Herriges, Puppet Labs
Twitter: @odyrf | Freenode: odyi
WHO IS THIS GUY?
Destiny was written in the 6th grade.
Professional Services @puppetlabs, ~2 years
Operations Engineer @puppetlabs, ~1 year
Integration Engineer @puppetlabs, ~1 month
THINGS I DO
Old public modules (The PS era)
puppetlabs-java_ks: java keystore management
puppetlabs-corosync: build pacemaker clusters
Less old public modules (The Operations era)
puppetlabs-apacheds: stands up Apache Directory
Server
puppetlabs-ldap_entry: manipulates an ldap server
puppetlabs-stunnel: set up SSL tunnels
Lately
puppet-openstack: build your openstack
LET’S TALK ABOUT
MODULES
BEST PRACTICES
Traditional development: 50+ years to mature
Modern config. mgmt: 15 years, max
Best practices are evolving
SO WHERE DO WE START?
Separate your logic and configuration
Know your interface
Use semantic versioning
Reuse everything
Leverage the community
DATA/LOGIC
SEPARATION
SEPARATE LOGIC FROM DATA
Logic != Data
Example: configuring a service on different platforms
Shouldn’t have to update every file in a module
PACKAGE/FILE/SERVICE
Humble beginnings for many modules
class 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/SERVICE
Nothing inherently wrong
Overly simple
Very static
Generally requires overhaul for different platforms
RUDIMENTARY DATA/LOGIC SEPARATION
class mysql::server {
include mysql::params
package { 'mysql-server':
name => $mysql::params::server_package,
ensure => present,
}
file { 'my.cnf':
path => $mysql::params::server_config,
ensure => present,
source => 'puppet:///modules/mysql/my.cnf',
require => Package['mysql-server'],
}
service { 'mysql-server':
name => $mysql::params::server_service,
ensure => running,
HARDCODING TUNABLE VALUES
Want to prevent people from reusing your modules?
Hardcode everything!
BAD PARAMS USE
Params class = good
Why is this bad?
Site specific defaults?
INSECURE DEFAULTS‽
class mysql::params {
$allow_hosts = '172.16.0.1/24'
$root_password = 'changeme'
$root_user = 'root'
}
GOOD PARAMS USE
Force user to supply data
Fail fast
class 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 BINDING
DATA BINDING
New in Puppet 3: data binding
Provides a method for configuring modules
USING DATA BINDING
Define data in a data store
file
database
web service
Automatically load data in the relevant manifests
It is hierarchical
USING DATA BINDING
class 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'
USING MODULES AS
INTERFACES
MODULES AS INTERFACES
Puppet simplifies management of services
Defines how people interact with that service
Puppet modules define an interface for that service
Creates two challenges
What options are supported?
What options should users configure?
BE OPINIONATED
Cannot make every option tunable
You’ll go insane
Require mandatory data
Add parameters for frequently changed data
Offer an ‘override’ option
BUT OTHER OPINIONS ARE NICE TOO
You can’t always support every option
Allow people to directly insert their own configuration
OVERRIDE EXAMPLE: PARTIAL TEMPLATES
Module provides template fragments
User 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 TEMPLATES
Example: my_nginx_app/templates/nginx-
vhost.conf.erb
server {
<%= 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;
}
}
SEMVER
WITHOUT SEMANTIC VERSIONING
A cautionary tale of versioning gone bad
1.0.0 Initial release for managing cacti
1.1.1 Change serverparam to servername
1.1.2 Move params from cacti::data to cacti::params
1.2.0 Updated README
1.2.1 Drops support for CentOS 5
1.3.0 This module now manages munin
2.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 BORING
API breakage means upgrading is dangerous
Nobody wants to upgrade if it means uncertainty
Semantic versioning helps mitigate this
WHAT IS SEMVER?
Version strings should have meaning
Releases match the format x.y.z
Values indicate what’s changed in that version
MAJOR RELEASES
Example: x.0.0
Backwards incompatible changes
Changing class names
Changing parameter names
Dropping platform support
MINOR RELEASES
Example: x.y.0
Backwards compatible features
Adding support for new platforms
Adding parameters
Adding features
PATCH RELEASES
Example: x.y.z
Bugfixes
Documentation
Tests
Anything that can’t be called a feature
SEMVER AS A CONTRACT
If you use SemVer, you’re making an agreement to avoid
making breaking changes
What is a breaking change?
What’s public?
What’s private?
WHAT IS PUBLIC?
Publicly exposed classes
Class parameters
The final behavior of your class
WHAT IS PRIVATE?
The actual resources used in your classes and defines
As long as they result in the same functionality
Classes that are documented as private
If you document that a class is private, people shouldn’t
use it
SAFETY IN SEMVER
SemVer takes the risk out of upgrading
You can understand the implications of upgrading right
away
How Puppet is doing it
3.1.0: Better support for Ruby code loading
3.1.1: Security fixes
3.2.0: External CA support, types & providers for
OpenWRT
4.0.0: Tachyon based transport layer
MAKE OTHER PEOPLE DO
YOUR WORK
AKA
REUSE MODULES
REUSE MODULES
Writing good code is hard.
Make other people do your work.
Being upstream is hard.
DISCOVERY VIA THE FORGE
Puppet Forge has close to 1200 modules
Provides a single point to discover and install modules
Easy access to documentation
README
Release notes
Auto generated Type & provider documentation
GET DEPENDENCIES FROM THE FORGE
root@example:~# puppet module install puppetlabs/mysql
Notice: Preparing to install into /etc/puppet/modules ...
Notice: Downloading from https://forge.puppetlabs.com ...
Notice: Installing -- do not interrupt ...
/etc/puppet/modules
└─┬ puppetlabs-mysql (v0.6.1)
└── puppetlabs-stdlib (v4.1.0)
COLLABORATE ON EXISTING MODULES
Lots of good modules are out there
Encourage people to publish on the Forge
Help improve existing modules
Only you can prevent ecosystem fragmentation
SMALL CONTRIBUTIONS HELP
Documentation
Bug fixes
Issue reports
ESTABLISH A
COMMUNITY
SURVIVING SUCCESS
Your module is a hit!
Prepare for a deluge of bug reports and feature requests
POPULARITY = MORE WORK
Things users are good at:
Finding bugs
Filing feature requests
Requesting things like “documentation”
Finding more bugs
BUILD YOUR COMMUNITY
Bug reports = people care
Show people how to help
Ask for pull requests
Guide people through the contribution process
Find people to give commit rights to
END
QUESTIONS?

More Related Content

PDF
Writing & Sharing Great Modules on the Puppet Forge
Puppet
 
PDF
Troubleshooting the Puppet Enterprise Stack
Puppet
 
PDF
Automated Java Deployments With Rpm
Martin Jackson
 
PDF
Ansible automation tool with modules
mohamedmoharam
 
PDF
Symfony finally swiped right on envvars
Sam Marley-Jarrett
 
PPTX
How to create a secured cloudera cluster
Tiago Simões
 
PDF
From Dev to DevOps - Codemotion ES 2012
Carlos Sanchez
 
PDF
Aeon mike guide transparent ssl filtering (1)
Conrad Cruz
 
Writing & Sharing Great Modules on the Puppet Forge
Puppet
 
Troubleshooting the Puppet Enterprise Stack
Puppet
 
Automated Java Deployments With Rpm
Martin Jackson
 
Ansible automation tool with modules
mohamedmoharam
 
Symfony finally swiped right on envvars
Sam Marley-Jarrett
 
How to create a secured cloudera cluster
Tiago Simões
 
From Dev to DevOps - Codemotion ES 2012
Carlos Sanchez
 
Aeon mike guide transparent ssl filtering (1)
Conrad Cruz
 

What's hot (19)

PDF
Aeon mike guide transparent ssl filtering
Conrad Cruz
 
PPTX
Php psr standard 2014 01-22
Võ Duy Tuấn
 
ODP
Forget MAMP and WAMP, Use Virtual Box to Have a Real Ubuntu Server
aaroncouch
 
PDF
Capistrano
Bryan McLellan
 
PDF
Apache2 BootCamp : Getting Started With Apache
Wildan Maulana
 
PDF
How to Develop Puppet Modules: From Source to the Forge With Zero Clicks
Carlos Sanchez
 
PPT
Architecting cloud
Tahsin Hasan
 
PPT
Hadoop on ec2
Mark Kerzner
 
PDF
Puppet Camp Berlin 2015: Pedro Pessoa | Puppet at the center of everything - ...
NETWAYS
 
PPTX
How to create a multi tenancy for an interactive data analysis with jupyter h...
Tiago Simões
 
PPTX
Deployment with Fabric
andymccurdy
 
KEY
Making Your Capistrano Recipe Book
Tim Riley
 
PDF
Useful Kafka tools
Dale Lane
 
PDF
Ansible : what's ansible & use case by REX
Saewoong Lee
 
PDF
Infrastructureascode slideshare-160331143725
miguel dominguez
 
PDF
DevOps(3) : Ansible - (MOSG)
Soshi Nemoto
 
KEY
From Dev to DevOps - FOSDEM 2012
Carlos Sanchez
 
KEY
Puppet for Java developers - JavaZone NO 2012
Carlos Sanchez
 
PDF
Mysql administration
beben benzy
 
Aeon mike guide transparent ssl filtering
Conrad Cruz
 
Php psr standard 2014 01-22
Võ Duy Tuấn
 
Forget MAMP and WAMP, Use Virtual Box to Have a Real Ubuntu Server
aaroncouch
 
Capistrano
Bryan McLellan
 
Apache2 BootCamp : Getting Started With Apache
Wildan Maulana
 
How to Develop Puppet Modules: From Source to the Forge With Zero Clicks
Carlos Sanchez
 
Architecting cloud
Tahsin Hasan
 
Hadoop on ec2
Mark Kerzner
 
Puppet Camp Berlin 2015: Pedro Pessoa | Puppet at the center of everything - ...
NETWAYS
 
How to create a multi tenancy for an interactive data analysis with jupyter h...
Tiago Simões
 
Deployment with Fabric
andymccurdy
 
Making Your Capistrano Recipe Book
Tim Riley
 
Useful Kafka tools
Dale Lane
 
Ansible : what's ansible & use case by REX
Saewoong Lee
 
Infrastructureascode slideshare-160331143725
miguel dominguez
 
DevOps(3) : Ansible - (MOSG)
Soshi Nemoto
 
From Dev to DevOps - FOSDEM 2012
Carlos Sanchez
 
Puppet for Java developers - JavaZone NO 2012
Carlos Sanchez
 
Mysql administration
beben benzy
 
Ad

Similar to Writing & Sharing Great Modules - Puppet Camp Boston (20)

PDF
Creating a mature puppet system
rkhatibi
 
PDF
Creating a Mature Puppet System
Puppet
 
PDF
20090514 Introducing Puppet To Sasag
garrett honeycutt
 
PDF
Writing & Sharing Great Modules on the Puppet Forge - Puppet Camp Raleigh
Puppet
 
PPTX
Puppetizing Your Organization
Robert Nelson
 
PDF
PuppetConf 2017: How People Actually Write Puppet- Gareth Rushgrove, Puppet
Puppet
 
KEY
20100425 Configuration Management With Puppet Lfnw
garrett honeycutt
 
PDF
Using Puppet - Real World Configuration Management
James Turnbull
 
PDF
PuppetCamp SEA 1 - The State of Puppet
OlinData
 
PDF
The State of Puppet
Puppet
 
PDF
PuppetCamp SEA 1 - The State of Puppet
Walter Heck
 
PDF
Writing and Publishing Puppet Modules - PuppetConf 2014
Puppet
 
PPTX
Puppet camp amsterdam
Vladimir Lazarenko
 
PDF
Lessons I Learned While Scaling to 5000 Puppet Agents
Puppet
 
KEY
Portable infrastructure with puppet
lkanies
 
PDF
Writing and Sharing Great Modules with the Puppet Forge
Puppet
 
PDF
Puppet camp london nov 2014 slides (1)
Puppet
 
PDF
Workflow story: Theory versus Practice in large enterprises by Marcin Piebiak
NETWAYS
 
PDF
Workflow story: Theory versus practice in Large Enterprises
Puppet
 
PDF
Puppet buero20 presentation
Martin Alfke
 
Creating a mature puppet system
rkhatibi
 
Creating a Mature Puppet System
Puppet
 
20090514 Introducing Puppet To Sasag
garrett honeycutt
 
Writing & Sharing Great Modules on the Puppet Forge - Puppet Camp Raleigh
Puppet
 
Puppetizing Your Organization
Robert Nelson
 
PuppetConf 2017: How People Actually Write Puppet- Gareth Rushgrove, Puppet
Puppet
 
20100425 Configuration Management With Puppet Lfnw
garrett honeycutt
 
Using Puppet - Real World Configuration Management
James Turnbull
 
PuppetCamp SEA 1 - The State of Puppet
OlinData
 
The State of Puppet
Puppet
 
PuppetCamp SEA 1 - The State of Puppet
Walter Heck
 
Writing and Publishing Puppet Modules - PuppetConf 2014
Puppet
 
Puppet camp amsterdam
Vladimir Lazarenko
 
Lessons I Learned While Scaling to 5000 Puppet Agents
Puppet
 
Portable infrastructure with puppet
lkanies
 
Writing and Sharing Great Modules with the Puppet Forge
Puppet
 
Puppet camp london nov 2014 slides (1)
Puppet
 
Workflow story: Theory versus Practice in large enterprises by Marcin Piebiak
NETWAYS
 
Workflow story: Theory versus practice in Large Enterprises
Puppet
 
Puppet buero20 presentation
Martin Alfke
 
Ad

More from Puppet (20)

PPTX
Puppet Community Day: Planning the Future Together
Puppet
 
PPTX
The Evolution of Puppet: Key Changes and Modernization Tips
Puppet
 
PPTX
Can You Help Me Upgrade to Puppet 8? Tips, Tools & Best Practices for Your Up...
Puppet
 
PPTX
Bolt Dynamic Inventory: Making Puppet Easier
Puppet
 
PPTX
Customizing Reporting with the Puppet Report Processor
Puppet
 
PPTX
Puppet at ConfigMgmtCamp 2025 Sponsor Deck
Puppet
 
PPTX
The State of Puppet in 2025: A Presentation from Developer Relations Lead Dav...
Puppet
 
PPTX
Let Red be Red and Green be Green: The Automated Workflow Restarter in GitHub...
Puppet
 
PDF
Puppet camp2021 testing modules and controlrepo
Puppet
 
PPTX
Puppetcamp r10kyaml
Puppet
 
PDF
2021 04-15 operational verification (with notes)
Puppet
 
PPTX
Puppet camp vscode
Puppet
 
PDF
Modules of the twenties
Puppet
 
PDF
Applying Roles and Profiles method to compliance code
Puppet
 
PPTX
KGI compliance as-code approach
Puppet
 
PDF
Enforce compliance policy with model-driven automation
Puppet
 
PDF
Keynote: Puppet camp compliance
Puppet
 
PPTX
Automating it management with Puppet + ServiceNow
Puppet
 
PPTX
Puppet: The best way to harden Windows
Puppet
 
PPTX
Simplified Patch Management with Puppet - Oct. 2020
Puppet
 
Puppet Community Day: Planning the Future Together
Puppet
 
The Evolution of Puppet: Key Changes and Modernization Tips
Puppet
 
Can You Help Me Upgrade to Puppet 8? Tips, Tools & Best Practices for Your Up...
Puppet
 
Bolt Dynamic Inventory: Making Puppet Easier
Puppet
 
Customizing Reporting with the Puppet Report Processor
Puppet
 
Puppet at ConfigMgmtCamp 2025 Sponsor Deck
Puppet
 
The State of Puppet in 2025: A Presentation from Developer Relations Lead Dav...
Puppet
 
Let Red be Red and Green be Green: The Automated Workflow Restarter in GitHub...
Puppet
 
Puppet camp2021 testing modules and controlrepo
Puppet
 
Puppetcamp r10kyaml
Puppet
 
2021 04-15 operational verification (with notes)
Puppet
 
Puppet camp vscode
Puppet
 
Modules of the twenties
Puppet
 
Applying Roles and Profiles method to compliance code
Puppet
 
KGI compliance as-code approach
Puppet
 
Enforce compliance policy with model-driven automation
Puppet
 
Keynote: Puppet camp compliance
Puppet
 
Automating it management with Puppet + ServiceNow
Puppet
 
Puppet: The best way to harden Windows
Puppet
 
Simplified Patch Management with Puppet - Oct. 2020
Puppet
 

Writing & Sharing Great Modules - Puppet Camp Boston

  • 1. WRITING & SHARING GREAT MODULES Cody Herriges, Puppet Labs Twitter: @odyrf | Freenode: odyi
  • 2. WHO IS THIS GUY? Destiny was written in the 6th grade. Professional Services @puppetlabs, ~2 years Operations Engineer @puppetlabs, ~1 year Integration Engineer @puppetlabs, ~1 month
  • 3. THINGS I DO Old public modules (The PS era) puppetlabs-java_ks: java keystore management puppetlabs-corosync: build pacemaker clusters Less old public modules (The Operations era) puppetlabs-apacheds: stands up Apache Directory Server puppetlabs-ldap_entry: manipulates an ldap server puppetlabs-stunnel: set up SSL tunnels Lately puppet-openstack: build your openstack
  • 5. BEST PRACTICES Traditional development: 50+ years to mature Modern config. mgmt: 15 years, max Best practices are evolving
  • 6. SO WHERE DO WE START? Separate your logic and configuration Know your interface Use semantic versioning Reuse everything Leverage the community
  • 8. SEPARATE LOGIC FROM DATA Logic != Data Example: configuring a service on different platforms Shouldn’t have to update every file in a module
  • 9. PACKAGE/FILE/SERVICE Humble beginnings for many modules class 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'], } }
  • 10. PROBLEMS WITH PACKAGE/FILE/SERVICE Nothing inherently wrong Overly simple Very static Generally requires overhaul for different platforms
  • 11. RUDIMENTARY DATA/LOGIC SEPARATION class mysql::server { include mysql::params package { 'mysql-server': name => $mysql::params::server_package, ensure => present, } file { 'my.cnf': path => $mysql::params::server_config, ensure => present, source => 'puppet:///modules/mysql/my.cnf', require => Package['mysql-server'], } service { 'mysql-server': name => $mysql::params::server_service, ensure => running,
  • 12. HARDCODING TUNABLE VALUES Want to prevent people from reusing your modules? Hardcode everything!
  • 13. BAD PARAMS USE Params class = good Why is this bad? Site specific defaults? INSECURE DEFAULTS‽ class mysql::params { $allow_hosts = '172.16.0.1/24' $root_password = 'changeme' $root_user = 'root' }
  • 14. GOOD PARAMS USE Force user to supply data Fail fast class 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. DATA BINDING New in Puppet 3: data binding Provides a method for configuring modules
  • 17. USING DATA BINDING Define data in a data store file database web service Automatically load data in the relevant manifests It is hierarchical
  • 18. USING DATA BINDING class 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. MODULES AS INTERFACES Puppet simplifies management of services Defines how people interact with that service Puppet modules define an interface for that service Creates two challenges What options are supported? What options should users configure?
  • 21. BE OPINIONATED Cannot make every option tunable You’ll go insane Require mandatory data Add parameters for frequently changed data Offer an ‘override’ option
  • 22. BUT OTHER OPINIONS ARE NICE TOO You can’t always support every option Allow people to directly insert their own configuration
  • 23. OVERRIDE EXAMPLE: PARTIAL TEMPLATES Module provides template fragments User assembles these into a full config
  • 24. 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 -%>
  • 25. USING PARTIAL TEMPLATES Example: my_nginx_app/templates/nginx- vhost.conf.erb server { <%= 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. WITHOUT SEMANTIC VERSIONING A cautionary tale of versioning gone bad 1.0.0 Initial release for managing cacti 1.1.1 Change serverparam to servername 1.1.2 Move params from cacti::data to cacti::params 1.2.0 Updated README 1.2.1 Drops support for CentOS 5 1.3.0 This module now manages munin 2.0.0 I can update versions whenever I want? 10.51.100 THIS IS AWESOME! -4.number.999999999999 I’VE CREATED A MONSTER
  • 28. UPGRADING SHOULD BE BORING API breakage means upgrading is dangerous Nobody wants to upgrade if it means uncertainty Semantic versioning helps mitigate this
  • 29. WHAT IS SEMVER? Version strings should have meaning Releases match the format x.y.z Values indicate what’s changed in that version
  • 30. MAJOR RELEASES Example: x.0.0 Backwards incompatible changes Changing class names Changing parameter names Dropping platform support
  • 31. MINOR RELEASES Example: x.y.0 Backwards compatible features Adding support for new platforms Adding parameters Adding features
  • 33. SEMVER AS A CONTRACT If you use SemVer, you’re making an agreement to avoid making breaking changes What is a breaking change? What’s public? What’s private?
  • 34. WHAT IS PUBLIC? Publicly exposed classes Class parameters The final behavior of your class
  • 35. WHAT IS PRIVATE? The actual resources used in your classes and defines As long as they result in the same functionality Classes that are documented as private If you document that a class is private, people shouldn’t use it
  • 36. SAFETY IN SEMVER SemVer takes the risk out of upgrading You can understand the implications of upgrading right away How Puppet is doing it 3.1.0: Better support for Ruby code loading 3.1.1: Security fixes 3.2.0: External CA support, types & providers for OpenWRT 4.0.0: Tachyon based transport layer
  • 37. MAKE OTHER PEOPLE DO YOUR WORK
  • 38. AKA
  • 40. REUSE MODULES Writing good code is hard. Make other people do your work. Being upstream is hard.
  • 41. DISCOVERY VIA THE FORGE Puppet Forge has close to 1200 modules Provides a single point to discover and install modules Easy access to documentation README Release notes Auto generated Type & provider documentation
  • 42. GET DEPENDENCIES FROM THE FORGE root@example:~# puppet module install puppetlabs/mysql Notice: Preparing to install into /etc/puppet/modules ... Notice: Downloading from https://forge.puppetlabs.com ... Notice: Installing -- do not interrupt ... /etc/puppet/modules └─┬ puppetlabs-mysql (v0.6.1) └── puppetlabs-stdlib (v4.1.0)
  • 43. COLLABORATE ON EXISTING MODULES Lots of good modules are out there Encourage people to publish on the Forge Help improve existing modules Only you can prevent ecosystem fragmentation
  • 46. SURVIVING SUCCESS Your module is a hit! Prepare for a deluge of bug reports and feature requests
  • 47. POPULARITY = MORE WORK Things users are good at: Finding bugs Filing feature requests Requesting things like “documentation” Finding more bugs
  • 48. BUILD YOUR COMMUNITY Bug reports = people care Show people how to help Ask for pull requests Guide people through the contribution process Find people to give commit rights to