+ All Categories
Home > Technology > Refactor Dance - Puppet Labs 'Best Practices'

Refactor Dance - Puppet Labs 'Best Practices'

Date post: 05-Dec-2014
Category:
Upload: gary-larizza
View: 352 times
Download: 3 times
Share this document with a friend
Description:
Gary Larizza's 1.5 hour talk from Puppetconf 2014 about best practices for refactoring Puppet code into Roles & Profiles, Hiera, R10k, and more.
77
2014 Presented by The Refactor Dance Gary Larizza Professional Services | Puppet Labs @glarizza
Transcript
Page 1: Refactor Dance - Puppet Labs 'Best Practices'

2014

Presented by

The Refactor DanceGary Larizza Professional Services | Puppet Labs @glarizza

Page 2: Refactor Dance - Puppet Labs 'Best Practices'

Presented by

http://bit.ly/refactordance

Page 3: Refactor Dance - Puppet Labs 'Best Practices'

Presented by

Page 4: Refactor Dance - Puppet Labs 'Best Practices'

Presented by

Worst. Hands-on. Ever

Page 5: Refactor Dance - Puppet Labs 'Best Practices'

Presented by

• Abstraction and data separation • Data Hierarchy • Classification • Workflow • Sticky points and caveats

Page 6: Refactor Dance - Puppet Labs 'Best Practices'

Presented by

Classification

Implementation Implementation

Page 7: Refactor Dance - Puppet Labs 'Best Practices'

Presented by

Role

Profile ProfileHiera

Component Modules

Page 8: Refactor Dance - Puppet Labs 'Best Practices'

Presented by

roles::application_server

profiles::java profiles::tomcat

Hiera

Component Modules

Page 9: Refactor Dance - Puppet Labs 'Best Practices'

Presented by

Component Modules

Page 10: Refactor Dance - Puppet Labs 'Best Practices'

Presented by

Stop writing custom goddamn component

modules

Page 11: Refactor Dance - Puppet Labs 'Best Practices'

Presented by

$httpd_root = "/opt/corp/data/http" package { ‘httpd’: ensure => latest, } file { “/opt/corp/data/http/conf.d”: owner => "httpd", ensure => directory; “/opt/corp/data/http/conf.d/corp.conf”: owner => "httpd", ensure => file; }

Page 12: Refactor Dance - Puppet Labs 'Best Practices'

Presented by

Stop writing component modules

• Too many ‘okay’ modules

• Maintenance & upkeep

• You are not unique

• You are entirely too lazy

Page 13: Refactor Dance - Puppet Labs 'Best Practices'

Presented by

Parameterize your classes

Page 14: Refactor Dance - Puppet Labs 'Best Practices'

Presented by

class apache {! case $::osfamily {! 'RedHat': {! $confdir = ‘/etc/httpd/conf‘! $conffile = “${confdir}/httpd.conf”! }! 'Debian': {! $confdir = ‘/etc/apache2/conf‘! $conffile = “${confdir}/apache2.conf”! }! }!}

Page 15: Refactor Dance - Puppet Labs 'Best Practices'

Presented by

class apache (! $confdir = $apache::params::confdir,! $conffile = $apache::params::conffile,!) inherits apache::params {! file { $confdir:! ensure => directory,! }! file { $conffile:! ensure => file,! content => template(’apache/apache.conf.erb’),! }!}

Page 16: Refactor Dance - Puppet Labs 'Best Practices'

Presented by

Parameterize classes

• Parameters = API

• Single-entry classes

• The ‘Forge test’

Page 17: Refactor Dance - Puppet Labs 'Best Practices'

Presented by

Params & shareable data

Page 18: Refactor Dance - Puppet Labs 'Best Practices'

Presented by

class apache::params {! case $::osfamily {! 'RedHat': {! $confdir = ‘/etc/httpd/conf‘! $conffile = “${confdir}/httpd.conf”! }! 'Debian': {! $confdir = ‘/etc/apache2/conf‘! $conffile = “${confdir}/apache2.conf”! }! }!}

Page 19: Refactor Dance - Puppet Labs 'Best Practices'

Presented by

Shareable data

• OS-specific data != private data

• Sane defaults

• Validation…

Page 20: Refactor Dance - Puppet Labs 'Best Practices'

Presented by

Validation

Page 21: Refactor Dance - Puppet Labs 'Best Practices'

Presented by

class xinetd (! $confdir = $apache::params::confdir,! $conffile = $apache::params::conffile,!) inherits xinetd::params {! file { $confdir:! ensure => directory,! }! file { $conffile:! ensure => file,! content => template(’apache/apache.conf.erb’),! }!}

Page 22: Refactor Dance - Puppet Labs 'Best Practices'

Presented by

class xinetd (! $confdir = $apache::params::confdir,! $conffile = $apache::params::conffile,!) inherits xinetd::params {! validate_absolute_path($confdir)! validate_absolute_path($conffile)! file { $confdir:! ensure => directory,! }! file { $conffile:! ensure => file,! content => template(’apache/apache.conf.erb’),! }!}

Page 23: Refactor Dance - Puppet Labs 'Best Practices'

Presented by

Validation

• Functions in puppetlabs-stdlib

• Never pass unvalidated data to resources

Page 24: Refactor Dance - Puppet Labs 'Best Practices'

Presented by

Class containment

Page 25: Refactor Dance - Puppet Labs 'Best Practices'

Presented by

class mysql::server (! ## params here!) inherits mysql::params {!!

include ::mysql::server::install! include ::mysql::server::config! include ::mysql::server::service!!

}

Page 26: Refactor Dance - Puppet Labs 'Best Practices'

Presented by

class mysql::server (! ## params here!) inherits mysql::params {!!

include ::mysql::server::install! include ::mysql::server::config! include ::mysql::server::service!!

anchor { ‘mysql:start’: }! -> Class[‘mysql::server::install’]! -> Class[‘mysql::server::config’]! -> Class[‘mysql::server::service’]! -> anchor { ‘mysql:end’: }!}

Page 27: Refactor Dance - Puppet Labs 'Best Practices'

Presented by

class mysql::server (! ## params here!) inherits mysql::params {!!

contain ::mysql::server::install! contain ::mysql::server::config! contain ::mysql::server::service!!

}* Puppet ≥ 3.4.0

Page 28: Refactor Dance - Puppet Labs 'Best Practices'

Presented by

Class containment

• Before Puppet 3.4.0 - use anchors

• After Puppet 3.4.0 - use contain

Page 29: Refactor Dance - Puppet Labs 'Best Practices'

Presented by

Hiera

Page 30: Refactor Dance - Puppet Labs 'Best Practices'

Presented by

class data_in_code {! case $::application_tier {! 'dev': {! $java_version = '6.0.3'! $tomcat_version = '6.0'! }!!

'test': {! $java_version = '7.0.1'! $tomcat_version = '7.0'! }! }!}

Page 31: Refactor Dance - Puppet Labs 'Best Practices'

Presented by

class data_in_code {! $java_version = hiera(’java_version’)! $tomcat_version = hiera(’tomcat_version’)!}

Page 32: Refactor Dance - Puppet Labs 'Best Practices'

Presented by

--- :backends: - yaml

:yaml: :datadir: /etc/puppetlabs/puppet/hieradata

:hierarchy: - “nodes/%{::clientcert}” - “location/%{::location}" - “tier/%{::application_tier}" - common

hiera.yaml

Page 33: Refactor Dance - Puppet Labs 'Best Practices'

Presented by

--- java_version: 7.0 tomcat_version: 8.0

dev.yaml

--- java_version: 6.0 tomcat_version: 7.0

prod.yaml

Page 34: Refactor Dance - Puppet Labs 'Best Practices'

Presented by

Where’s $osfamily?!

Page 35: Refactor Dance - Puppet Labs 'Best Practices'

Presented by

What’s an Application

Tier?

Page 36: Refactor Dance - Puppet Labs 'Best Practices'

Presented by

‘Application tier’

• Long lived • Data usually separate • ‘The Data’

!

!

!

‘Environment’

• Short lived • Migration path to ‘production’ • ‘The Model’

!

!

!

Page 37: Refactor Dance - Puppet Labs 'Best Practices'

Presented by

Hierarchy structure?

• How/where is data different?

• Most -> least specific

• Folders are your friends

Page 38: Refactor Dance - Puppet Labs 'Best Practices'

Presented by

Profiles

Page 39: Refactor Dance - Puppet Labs 'Best Practices'

Presented by

But first… a question:

Page 40: Refactor Dance - Puppet Labs 'Best Practices'

Presented by

include apache!

class { ‘apache’: }!

vs.!

Page 41: Refactor Dance - Puppet Labs 'Best Practices'

Presented by

include apache!include apache!include apache!include apache!include apache!

Page 42: Refactor Dance - Puppet Labs 'Best Practices'

Presented by

class { ‘apache’: }!include apache!

Page 43: Refactor Dance - Puppet Labs 'Best Practices'

Presented by

include apache!class { ‘apache’: }!include apache!

Page 44: Refactor Dance - Puppet Labs 'Best Practices'

Presented by

Namespacing

Page 45: Refactor Dance - Puppet Labs 'Best Practices'

Presented by

class data_in_code {! $java_version = hiera(’java_version’)! $tomcat_version = hiera(’tomcat_version’)!!

notify { “Java is: ${java_version}”: }!}

Page 46: Refactor Dance - Puppet Labs 'Best Practices'

Presented by

class data_in_code {! $java_version = hiera(’java_version’)! $tomcat_version = hiera(’tomcat_version’)!!

notify { “Java is: ${data_in_code::java_version}”: }!}

Page 47: Refactor Dance - Puppet Labs 'Best Practices'

Presented by

class profiles::jenkins {! include jenkins!}

Page 48: Refactor Dance - Puppet Labs 'Best Practices'

Presented by

class profiles::jenkins {! include ???????!}

Page 49: Refactor Dance - Puppet Labs 'Best Practices'

Presented by

class profiles::jenkins {! include ::jenkins!}

Page 50: Refactor Dance - Puppet Labs 'Best Practices'

Presented by

Data separation

Page 51: Refactor Dance - Puppet Labs 'Best Practices'

Presented by

class data_in_code {! case $::application_tier {! 'dev': {! $java_version = '6.0.3'! $tomcat_version = '6.0'! }!!

'test': {! $java_version = '7.0.1'! $tomcat_version = '7.0'! }! }!}

Page 52: Refactor Dance - Puppet Labs 'Best Practices'

Presented by

class profiles::tomcat {! $java_version = hiera(’java_version’)! $tomcat_version = hiera(’tomcat_version’)!!

class { ’::tomcat’:! version => $tomcat_version,! }!!

class { ’::java’:! version => $java_version,! }!}

Page 53: Refactor Dance - Puppet Labs 'Best Practices'

Presented by

class apache {! file { ‘/opt/custom/key.pem’:! ensure => file,! source => ’puppet:///modules/apache/key.pem'! }!!

file { ‘/things/that/dont/belong/in/apache’:! ensure => file,! source => ’puppet:///modules/apache/blargh'! } !}

class apache {! file { ‘/opt/custom/key.pem’:! ensure => file,! source => ’puppet:///modules/apache/key.pem'! }!!

file { ‘/things/that/dont/belong/in/apache’:! ensure => file,! source => ’puppet:///modules/apache/blargh'! } !}

Page 54: Refactor Dance - Puppet Labs 'Best Practices'

Presented by

class profiles::apache {! include apache! $keypath = hiera(’apache_keypath’)!!

file { “${keypath}/key.pem”:! ensure => file,! source => ’puppet:///modules/profiles/key.pem'! }!!

file { ‘/things/that/dont/belong/in/apache’:! ensure => file,! source => ’puppet:///modules/profiles/blargh'! }!}

Page 55: Refactor Dance - Puppet Labs 'Best Practices'

Presented by

Dependencies

Page 56: Refactor Dance - Puppet Labs 'Best Practices'

Presented by

class tomcat {! class { ‘java’:! version => ‘6.0’,! }!!

Class[‘java’]! -> Class[‘tomcat’]!}

Page 57: Refactor Dance - Puppet Labs 'Best Practices'

Presented by

class profiles::tomcat {! $java_version = hiera(’java_version’)! $tomcat_version = hiera(’tomcat_version’)!!

class { ‘::java’:! version => $java_version,! }! class { ‘::tomcat’:! version => $tomcat_version,! }!!

Class[‘::java’]! -> Class[‘::tomcat’]!}

Page 58: Refactor Dance - Puppet Labs 'Best Practices'

Presented by

class profiles::tomcat {! include profiles::java! $tomcat_version = hiera(’tomcat_version’)! ! class { ‘::tomcat’:! version => $tomcat_version,! }!!

Class[‘profiles::java’]! -> Class[‘::tomcat’]!}

Page 59: Refactor Dance - Puppet Labs 'Best Practices'

Presented by

Profiles

• Hiera for business-specific data

• Proprietary resources

• Inter-class dependencies and containment

• Implementation ‘libraries’

Page 60: Refactor Dance - Puppet Labs 'Best Practices'

Presented by

Roles

Page 61: Refactor Dance - Puppet Labs 'Best Practices'

Presented by

Classification

Page 62: Refactor Dance - Puppet Labs 'Best Practices'

Presented by

denuatapp06p

falcor

Page 63: Refactor Dance - Puppet Labs 'Best Practices'

Presented by

roles::app_server::pci

roles::proxy

Page 64: Refactor Dance - Puppet Labs 'Best Practices'

Presented by

class roles {! include profiles::security::base! include profiles::mycorp::users! include profiles::mycorp::os_base!}

Page 65: Refactor Dance - Puppet Labs 'Best Practices'

Presented by

class roles::app_server inherits roles {! include profiles::tomcat! include profiles::our_app! include profiles::shibboleth!!

Class[‘profiles::tomcat’]! -> Class[‘profiles::our_app’]! -> Class[‘profiles::shibboleth’]!}

Page 66: Refactor Dance - Puppet Labs 'Best Practices'

Presented by

class roles::app_server::pci inherits roles::app_server {! include profiles::pci!}

Page 67: Refactor Dance - Puppet Labs 'Best Practices'

Presented by

class roles::app_server::pci {! include profiles::security::base! include profiles::mycorp::users! include profiles::mycorp::os_base! include profiles::pci! include profiles::tomcat! include profiles::our_app! include profiles::shibboleth! include profiles::pci!!

Class[‘profiles::java’]! -> Class[‘profiles::our_app’]! -> Class[‘profiles::shibboleth’]!}

Page 68: Refactor Dance - Puppet Labs 'Best Practices'

Presented by

Roles

• Hostnames minus Hiera

• Technology-independent

• Inheritance makes sense (or not)

Page 69: Refactor Dance - Puppet Labs 'Best Practices'

Presented by

Workflow

Page 70: Refactor Dance - Puppet Labs 'Best Practices'

Presented by

Module Pinning

Page 71: Refactor Dance - Puppet Labs 'Best Practices'

Presented by

forge "http://forge.puppetlabs.com"!!

# Modules from the Puppet Forge!mod "puppetlabs/apache"!mod "puppetlabs/ntp"!!

# Modules from Github using various references!mod 'notifyme',! :git => 'git://github.com/glarizza/puppet-notifyme',! :ref => '50c01703b2e3e352520a9a2271ea4947fe17a51f'!!

mod 'profiles',! :git => 'git://github.com/glarizza/puppet-profiles',! :ref => '3611ae4253ff01762f9bda1d93620edf8f9a3b22'

Page 72: Refactor Dance - Puppet Labs 'Best Practices'

Presented by

R10k - Bad name, good robot

1. Ensuring modules based on a Puppetfile 2. Dynamically creating Puppet environments

Page 73: Refactor Dance - Puppet Labs 'Best Practices'

Presented by

PuppetfileManifestHieradata

Control Repository

Page 74: Refactor Dance - Puppet Labs 'Best Practices'

Presented by

PuppetfileManifestHieradata

PuppetfileManifestHieradata

PuppetfileManifestHieradata

Page 75: Refactor Dance - Puppet Labs 'Best Practices'

Presented by

PuppetfileManifestHieradata

PuppetfileManifestHieradata

PuppetfileManifestHieradata

Puppet Environment Puppet Environment

BranchBranch

Page 76: Refactor Dance - Puppet Labs 'Best Practices'

Presented by

Demo

Page 77: Refactor Dance - Puppet Labs 'Best Practices'

Presented by

Summary• Simple, generic component modules

• Extract company-specific data with Hiera

• Layer implementation with Profiles

• Classification with Profiles

• R10k for module pinning/workflow


Recommended