Upload
puppet-labs
View
4.102
Download
0
Embed Size (px)
Citation preview
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
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 != Data
Example: configure a service on different platformsShouldn’t have to update every file in a module
PACKAGE/FILE/SERVICEHumble 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/SERVICENothing inherently wrongOverly simpleVery staticGenerally requires overhaul for different platforms
RUDIMENTARY DATA/LOGIC SEPARATIONclass 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/nrpe/nrpe.cfg', require => Package['nagios-nrpe-server'], }
service { 'mysql-server': name => $mysql::params::server_service, ensure => running, enable => true, subscribe => File['my.cnf'], }}
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'}
USING PARAMS, GOOD:
Force user to supply dataFail 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) {}
USING DATA BINDINGDefine data in a data store
filedatabaseForeman
Automatically 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: '10.126.8.0/24'
# $datadir/qa.mysite.local.yaml---mysql::params::allow_hosts: '10.134.8.0/24'
MODULES AS INTERFACESPuppet simplifies management of servicesDefines how people interact with that servicePuppet modules define an interface for that service
Creates two challengesWhat options are supported?What options should users configure?
BE OPINIONATEDCannot make every option tunableYou’ll go insane
Require 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 bad
1.0.0 Initial release for managing cacti1.1.1 Change server param 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.0
Backwards incompatible changes
Changing class namesChanging parameter namesDropping platform support
MINOR RELEASESExample: x.y.0
Backwards compatible features
Adding support for new platformsAdding parametersAdding features
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 PRIVATE?The actual resources used in your classes and defines
Resources themselves are implementation, notClasses that are documented as private
If 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 it
3.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 layer
Not really.
DISCOVERY VIA THE FORGEPuppet Forge has 1000+ modulesProvides a single point to discover and install modulesEasy access to documentation
READMECHANGELOGType & 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
POPULARITY = MORE WORKThings users are good at:
Finding bugsFiling feature requestsRequesting things like “documentation”Finding more bugs
Funny 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