designing puppet: roles/profiles pattern

108
Designing Puppet: Roles / Profiles Design Pattern Puppet Camp Stockholm, Feb 2013 Thursday, 7 February 13

Upload: puppet-labs

Post on 10-May-2015

30.816 views

Category:

Technology


3 download

DESCRIPTION

"Designing Puppet: Roles/Profiles Pattern" by Craig Dunn of Puppet Labs, at Puppet Camp Stockholm 2013.

TRANSCRIPT

Page 1: Designing Puppet: Roles/Profiles Pattern

Designing Puppet:

Roles / Profiles Design Pattern

Puppet Camp Stockholm, Feb 2013

Thursday, 7 February 13

Page 2: Designing Puppet: Roles/Profiles Pattern

Hello

• Craig Dunn

• Puppet user since 2008 as an IT contractor

• Started with 0.24

• Joined Puppet Labs in June 2012

• @crayfishX

• Freenode IRC: crayfishx

Thursday, 7 February 13

Page 3: Designing Puppet: Roles/Profiles Pattern

Agenda

• How people typically design Puppet

• Real-world case study

• Thinking about components

• Designing Puppet for your users

• Node classification

• Data separation

Thursday, 7 February 13

Page 4: Designing Puppet: Roles/Profiles Pattern

Background

• Originally a blog post written in May 2012

• Advocated by many Puppet Labs Engineers

• Based on a real world solution

• Several community members have adopted with success

Thursday, 7 February 13

Page 5: Designing Puppet: Roles/Profiles Pattern

Designing Puppet

• You write awesome modules

• You classify them to your node

Thursday, 7 February 13

Page 6: Designing Puppet: Roles/Profiles Pattern

Designing Puppet

Modules

Node Classification

Thursday, 7 February 13

Page 7: Designing Puppet: Roles/Profiles Pattern

Down the road...

• Your infrastructure grows

• Business requirements will change

• Your Puppet code feels bulky and high maintenence

• There will always be edge cases eventually

• You decide it needs refactoring

Thursday, 7 February 13

Page 8: Designing Puppet: Roles/Profiles Pattern

Danger Signs

• Resources being declared in two modules

• You don’t know where your implementation “fits”

• Lot’s of logic at a node level

• Repetition and duplication

• The if statement is your go-to-guy

Thursday, 7 February 13

Page 9: Designing Puppet: Roles/Profiles Pattern

Write good modules

• Should manage only it’s own resources

• Should be granular

• Should be portable

Thursday, 7 February 13

Page 10: Designing Puppet: Roles/Profiles Pattern

Thinking beyond the module....

• Puppet is a code base

• How do I design an effective framework

• Gluing everything together

Thursday, 7 February 13

Page 11: Designing Puppet: Roles/Profiles Pattern

Node-level logic

• Risks duplication and repetition

• No guarantee of consistency

• TMI!

Thursday, 7 February 13

Page 12: Designing Puppet: Roles/Profiles Pattern

Node-level logicnode basil { class { ‘apache’: version => ‘latest’, } class { ‘motd’: } class { ‘ssh’: } class { ‘users’: default_shell => ‘/bin/false’, } Class[‘ssh’] -> Class[‘users’]}

Thursday, 7 February 13

Page 13: Designing Puppet: Roles/Profiles Pattern

Node-level logic

• What happens when I have 1000 nodes

• Or 10,000 nodes!!

• That’s a lot of code!

• So where should implement this?

Thursday, 7 February 13

Page 14: Designing Puppet: Roles/Profiles Pattern

Designing Puppet

• Provide business logic to classification

• Provide an abstraction layer for implementation of components

• Make code adaptable to complex requirements

• Reduce node-level logic

• Reduce functionality overlap

Thursday, 7 February 13

Page 15: Designing Puppet: Roles/Profiles Pattern

What is the worse thing that is

going to happen to your Puppet code?

Thursday, 7 February 13

Page 16: Designing Puppet: Roles/Profiles Pattern

Business requirements

Thursday, 7 February 13

Page 17: Designing Puppet: Roles/Profiles Pattern

Business logic does not align with technology

Thursday, 7 February 13

Page 18: Designing Puppet: Roles/Profiles Pattern

Case study

• Real world problem

• Solved through design

Thursday, 7 February 13

Page 19: Designing Puppet: Roles/Profiles Pattern

Case study

“We have 3 applications we

need to deploy using Puppet”

Thursday, 7 February 13

Page 20: Designing Puppet: Roles/Profiles Pattern

The business view

Application Y Application Z

Application X

Thursday, 7 February 13

Page 21: Designing Puppet: Roles/Profiles Pattern

Go forth and Puppetize!

Thursday, 7 February 13

Page 22: Designing Puppet: Roles/Profiles Pattern

Go forth and Puppetize!

And we jumped right in...

Thursday, 7 February 13

Page 23: Designing Puppet: Roles/Profiles Pattern

Things got painful

Thursday, 7 February 13

Page 24: Designing Puppet: Roles/Profiles Pattern

Problems

• These applications aren’t that different

• They seem to share a whole bunch of similarities

• Implementation differed on different environments and locations

• Writing 3 separate modules creates conflicts and duplication

Thursday, 7 February 13

Page 25: Designing Puppet: Roles/Profiles Pattern

Our code was hacky

Thursday, 7 February 13

Page 26: Designing Puppet: Roles/Profiles Pattern

We are trying to code business logic.

Thursday, 7 February 13

Page 27: Designing Puppet: Roles/Profiles Pattern

Stop thinking about what it looks like

• Break everything down into components

• Granularity is the key

• Think about what it actually is

Thursday, 7 February 13

Page 28: Designing Puppet: Roles/Profiles Pattern

What we realised

• Each application stack is a collection of a subset of the same Java apps implemented in different ways

Thursday, 7 February 13

Page 29: Designing Puppet: Roles/Profiles Pattern

The business view

Application Y Application Z

Application X

Thursday, 7 February 13

Page 30: Designing Puppet: Roles/Profiles Pattern

The technical reality

Application YApplication Z

Application X

Thursday, 7 February 13

Page 31: Designing Puppet: Roles/Profiles Pattern

We only have one application

Implemented many different ways

Thursday, 7 February 13

Page 32: Designing Puppet: Roles/Profiles Pattern

So we had an idea!

• Reduce each Java sub application into granular Puppet modules

• Create a code layer responsible for implementation

• Let’s call them profiles

Thursday, 7 February 13

Page 33: Designing Puppet: Roles/Profiles Pattern

class profiles::x { include tomcat include mysql include componenta include componentb componentb::resource { ‘name’: ensure => present, }}

class profiles::y { include tomcat include mysql include componenta include componentc include componentd}

class profiles::z { include tomcat include mysql include componenta include componentb include componentd include dependancy Class[‘dependancy’] -> Class[‘componentd’]}

Thursday, 7 February 13

Page 34: Designing Puppet: Roles/Profiles Pattern

class profiles::application { include tomcat include mysql include componenta}

class profiles::application::x inherits profiles::application { include componentb componentb::resource { ‘name’: ensure => present, }}

class profiles::application::y inherits profiles::application { include componentc include componentd}

class profiles::application::z inherits profiles::application { include componentb include componentd include dependancy Class[‘dependancy’] -> Class[‘componentd’]}

Use inheritance for abstraction within profiles

Thursday, 7 February 13

Page 35: Designing Puppet: Roles/Profiles Pattern

Profiles and Components

Resources

Thursday, 7 February 13

Page 36: Designing Puppet: Roles/Profiles Pattern

Profiles and Components

Resources

Components: Resource modelling

Thursday, 7 February 13

Page 37: Designing Puppet: Roles/Profiles Pattern

Profiles and Components

Resources

Components: Resource modelling

Profiles : Implementation

Thursday, 7 February 13

Page 38: Designing Puppet: Roles/Profiles Pattern

In reality it was worse

Thursday, 7 February 13

Page 39: Designing Puppet: Roles/Profiles Pattern

In reality it was worse

• 2 different deployment types made up of over 15 server types each

Thursday, 7 February 13

Page 40: Designing Puppet: Roles/Profiles Pattern

In reality it was worse

• 2 different deployment types made up of over 15 server types each

• 10+ locations

Thursday, 7 February 13

Page 41: Designing Puppet: Roles/Profiles Pattern

In reality it was worse

• 2 different deployment types made up of over 15 server types each

• 10+ locations

• 4 environment types

Thursday, 7 February 13

Page 42: Designing Puppet: Roles/Profiles Pattern

In reality it was worse

• 2 different deployment types made up of over 15 server types each

• 10+ locations

• 4 environment types

• Every installation was an edge case!

Thursday, 7 February 13

Page 43: Designing Puppet: Roles/Profiles Pattern

In reality it was worse

• 2 different deployment types made up of over 15 server types each

• 10+ locations

• 4 environment types

• Every installation was an edge case!

• My slides weren’t big enough.

Thursday, 7 February 13

Page 44: Designing Puppet: Roles/Profiles Pattern

Lessons learned

• Granularity is good

• Don’t assume business logic will directly translate to technology

• Abstraction is awesome.... but that’s nothing new....

Thursday, 7 February 13

Page 45: Designing Puppet: Roles/Profiles Pattern

Abstraction is a core principle of coding

• Functions are abstracted by methods

• Methods abstracted by classes and modules

• They are abstracted with libraries

• Puppet is code!

Thursday, 7 February 13

Page 46: Designing Puppet: Roles/Profiles Pattern

Puppet is all about abstraction

• Data is abstracted by Hiera

• Providers are abstracted by types

• Resources are abstracted by classes

• Classes are abstracted by modules

Thursday, 7 February 13

Page 47: Designing Puppet: Roles/Profiles Pattern

Puppet is all about abstraction

• Data is abstracted by Hiera

• Providers are abstracted by types

• Resources are abstracted by classes

• Classes are abstracted by modules

• Modules are abstracted by profiles

Thursday, 7 February 13

Page 48: Designing Puppet: Roles/Profiles Pattern

Focussing on Abstraction

• We’ve turned business logic into a technology stack

• Can we translate that back into business logic?

• Why would we even want to do that?

Thursday, 7 February 13

Page 49: Designing Puppet: Roles/Profiles Pattern

UAT Cluster node

include securityinclude usersinclude ntpinclude ssh::serverinclude customappinclude tomcat::server

class { ‘jenkins’: require => Class[‘tomcat::server’],}

include mysqldatabase { ‘apptest’: ensure => present,}

Our example configuration model:

Thursday, 7 February 13

Page 50: Designing Puppet: Roles/Profiles Pattern

Think about the usersMeet John, Susan and Bill.

Thursday, 7 February 13

Page 51: Designing Puppet: Roles/Profiles Pattern

John is a Sysadmin

• Wants to ensure all servers have kernel hardening, NTP and SSH Server installed

• Wants to manage what packages, services, files and other resources

• Is responsible for maintaining all the components of a UAT cluster server

Thursday, 7 February 13

Page 52: Designing Puppet: Roles/Profiles Pattern

Susan is an application specialist

• Cares that a UAT Cluster node requires MySQL Server, Tomcat Server and Jenkins server installed.

Thursday, 7 February 13

Page 53: Designing Puppet: Roles/Profiles Pattern

Bill is an IT manager

• Bill cares that the server is a UAT Cluster node

Thursday, 7 February 13

Page 54: Designing Puppet: Roles/Profiles Pattern

What do they care about?

• John cares about modelling all resources

• Susan cares about the technology stack

• Bill cares about the business logic

Thursday, 7 February 13

Page 55: Designing Puppet: Roles/Profiles Pattern

In Puppet

• Resource modelling is done in component modules

• The technology stack is defined in profiles

• Where do we represent the business logic for Bill?

Thursday, 7 February 13

Page 56: Designing Puppet: Roles/Profiles Pattern

Introducing Roles

• Represent business logic, not technology

• Define a set of technology stacks (profiles) that make up the logical role

• Allow the business to manage how the infrastructure looks without defining what it is

Thursday, 7 February 13

Page 57: Designing Puppet: Roles/Profiles Pattern

A node can only have one role

• A role can include as many profiles as required to define itself

• If a node requires two roles, it has by definition become a new role

Thursday, 7 February 13

Page 58: Designing Puppet: Roles/Profiles Pattern

A node can only have one role

• A role can include as many profiles as required to define itself

• If a node requires two roles, it has by definition become a new role

• Something couldn’t be a lion and a kangaroo at the same time!

Thursday, 7 February 13

Page 59: Designing Puppet: Roles/Profiles Pattern

It would be a Lingaroo

Thursday, 7 February 13

Page 60: Designing Puppet: Roles/Profiles Pattern

Roles

• One-to-one to nodes

• One-to-many to profiles

• Only implement profiles

Thursday, 7 February 13

Page 61: Designing Puppet: Roles/Profiles Pattern

Example role

class role::uat_server { include profiles::base include profiles::customapp include profiles::test_tools}

Thursday, 7 February 13

Page 62: Designing Puppet: Roles/Profiles Pattern

Classification

• Node classification simply assigns roles to nodes

• Roles expose profiles

Thursday, 7 February 13

Page 63: Designing Puppet: Roles/Profiles Pattern

Classification

node ‘craig.puppetlabs.vm’ { include roles::uat_server}

Thursday, 7 February 13

Page 64: Designing Puppet: Roles/Profiles Pattern

Classification

Thursday, 7 February 13

Page 65: Designing Puppet: Roles/Profiles Pattern

The Stack

Resources

Thursday, 7 February 13

Page 66: Designing Puppet: Roles/Profiles Pattern

The Stack

Resources

Components: Resource modelling

Thursday, 7 February 13

Page 67: Designing Puppet: Roles/Profiles Pattern

The Stack

Resources

Components: Resource modelling

Profiles : Implementation

Thursday, 7 February 13

Page 68: Designing Puppet: Roles/Profiles Pattern

The Stack

Resources

Components: Resource modelling

Profiles : Implementation

Roles : Business Logic

Thursday, 7 February 13

Page 69: Designing Puppet: Roles/Profiles Pattern

Terminology

• Profiles and Roles are Puppet modules

• Components are Puppet modules responsible for modelling resources

• Everything is a module

Thursday, 7 February 13

Page 70: Designing Puppet: Roles/Profiles Pattern

Naming conventions

• Components should be named after what they manage (apache, ssh, mysql)

• Profiles should be named after the logical stack they implement (database, bastion, email)

• Roles should be named in business logic convention (uat_server, web_cluster, application, archive)

Thursday, 7 February 13

Page 71: Designing Puppet: Roles/Profiles Pattern

Hiera OverviewLet’s talk about data!

Thursday, 7 February 13

Page 72: Designing Puppet: Roles/Profiles Pattern

Managing infrastructure

Dev

Thursday, 7 February 13

Page 73: Designing Puppet: Roles/Profiles Pattern

Managing infrastructure

Dev

QA

Thursday, 7 February 13

Page 74: Designing Puppet: Roles/Profiles Pattern

Managing infrastructure

Dev

QA

Production

Thursday, 7 February 13

Page 75: Designing Puppet: Roles/Profiles Pattern

Managing infrastructure

Dev

QA

Production

DC1

Thursday, 7 February 13

Page 76: Designing Puppet: Roles/Profiles Pattern

Managing infrastructure

Dev

QA

Production

DC1 DC2 DC3

Thursday, 7 February 13

Page 77: Designing Puppet: Roles/Profiles Pattern

Managing data in Puppet is hard.

Thursday, 7 February 13

Page 78: Designing Puppet: Roles/Profiles Pattern

Without Hiera?if ( $::environment == ‘dev’ ) { $ntpserver = ‘192.168.2.1’} else { if ( $::fqdn == ‘host4.mycorp.com’) { $ntpserver = ‘127.0.0.1’ } else { $ntpserver = ‘213.21.6.4’ }}

Thursday, 7 February 13

Page 79: Designing Puppet: Roles/Profiles Pattern

With Hiera?$ntpserver = hiera(‘ntpserver’)

Thursday, 7 February 13

Page 80: Designing Puppet: Roles/Profiles Pattern

Hierarchical lookups

• Hiera uses facter facts to determine a hierarchy

• Top down hierarchy for overriding configuration values based on roles, environments, locations.... or anything else

• And do this without any coding!

Thursday, 7 February 13

Page 81: Designing Puppet: Roles/Profiles Pattern

Separation of data from code

• Puppet modules without hard-coded data are easily shared and more re-usable

• Infrastructure configuration can be managed without needing to edit Puppet code

Thursday, 7 February 13

Page 82: Designing Puppet: Roles/Profiles Pattern

Pluggable Backends

• Source data from multiple locations

• Data source is abstracted from code

Thursday, 7 February 13

Page 83: Designing Puppet: Roles/Profiles Pattern

Pluggable Backends

• Source data from multiple locations

• Data source is abstracted from code

• hiera-gpg

• hiera-http

• hiera-mysql

• hiera-redis

• hiera-json

• hiera-zookeeper

Thursday, 7 February 13

Page 84: Designing Puppet: Roles/Profiles Pattern

Data Separation

• Use Hiera to abstract your data from your code

• Components and profiles can source data from Hiera

Thursday, 7 February 13

Page 85: Designing Puppet: Roles/Profiles Pattern

Profiles and Hiera

• Use Hiera to model your data

• Use profiles to model your implementation

Thursday, 7 February 13

Page 86: Designing Puppet: Roles/Profiles Pattern

The Stack

Resources

Components: Resource modelling

Profiles : Implementation

Roles : Business Logic

Thursday, 7 February 13

Page 87: Designing Puppet: Roles/Profiles Pattern

The Stack

Resources

Components: Resource modelling

Profiles : Implementation

Roles : Business Logic

Hiera:Data

Thursday, 7 February 13

Page 88: Designing Puppet: Roles/Profiles Pattern

Classification

• Assigning classes to a node

• You can classify within Puppet code (site.pp)

• You can use an External Node Classifier (ENC)

Thursday, 7 February 13

Page 89: Designing Puppet: Roles/Profiles Pattern

Leveraging an ENC

• You can classify your nodes however you want

• Puppet Dashboard

• Enterprise Console

• Foreman

• Site.pp

• Custom script

Thursday, 7 February 13

Page 90: Designing Puppet: Roles/Profiles Pattern

Leveraging an ENC

• An ENC should classify a node to it’s role

• Nothing else

Thursday, 7 February 13

Page 91: Designing Puppet: Roles/Profiles Pattern

The Stack

Resources

Components: Resource modelling

Profiles : Implementation

Roles : Business Logic

Hiera:Data

Thursday, 7 February 13

Page 92: Designing Puppet: Roles/Profiles Pattern

The Stack

Resources

Components: Resource modelling

Profiles : Implementation

Roles : Business Logic

Hiera:Data

Classifier

Thursday, 7 February 13

Page 93: Designing Puppet: Roles/Profiles Pattern

Key benefits

• Reduced node-level logic to a role.

• Gain the ability to be flexible with implementation

• Business logic improves managability by non-Puppet users

• Edge cases are now easy to solve

Thursday, 7 February 13

Page 94: Designing Puppet: Roles/Profiles Pattern

Enough Preaching!

Thursday, 7 February 13

Page 95: Designing Puppet: Roles/Profiles Pattern

This is not the way to design Puppet... It’s a

way.

Thursday, 7 February 13

Page 96: Designing Puppet: Roles/Profiles Pattern

Can I implement this design without roles?

Thursday, 7 February 13

Page 97: Designing Puppet: Roles/Profiles Pattern

Can I implement this design without roles?

• Yes.

• You lose the layer of abstraction that exposes business logic

Thursday, 7 February 13

Page 98: Designing Puppet: Roles/Profiles Pattern

Can my roles be defined in my ENC?

Thursday, 7 February 13

Page 99: Designing Puppet: Roles/Profiles Pattern

Can my roles be defined in my ENC?

• Yes.

• Keeping it in code makes it versionable

Thursday, 7 February 13

Page 100: Designing Puppet: Roles/Profiles Pattern

Can’t I just use Hiera to define profiles?

Thursday, 7 February 13

Page 101: Designing Puppet: Roles/Profiles Pattern

Can’t I just use Hiera to define profiles?

• Technically yes.

• You lose the flexibility to implement code logic in profiles and it may become restrictive

• You could possibly use: https://github.com/ripienaar/hiera-puppet-nodes

Thursday, 7 February 13

Page 102: Designing Puppet: Roles/Profiles Pattern

The fundamental concepts....

Thursday, 7 February 13

Page 103: Designing Puppet: Roles/Profiles Pattern

The fundamental concepts....

• Abstraction, abstraction, abstraction

Thursday, 7 February 13

Page 104: Designing Puppet: Roles/Profiles Pattern

The fundamental concepts....

• Abstraction, abstraction, abstraction

• Decoupling business logic, implementation and resource modelling.

Thursday, 7 February 13

Page 105: Designing Puppet: Roles/Profiles Pattern

The fundamental concepts....

• Abstraction, abstraction, abstraction

• Decoupling business logic, implementation and resource modelling.

• Separating data and code

Thursday, 7 February 13

Page 106: Designing Puppet: Roles/Profiles Pattern

The fundamental concepts....

• Abstraction, abstraction, abstraction

• Decoupling business logic, implementation and resource modelling.

• Separating data and code

• Reducing node-level complexity

Thursday, 7 February 13

Page 108: Designing Puppet: Roles/Profiles Pattern

Thank you. Questions?

• Follow me at @crayfishX

• Bug me on Freenode: crayfishx

Enjoy the rest of Puppet Camp!

In memory of Giles Constant, who spent many nights debating Puppet design patterns with me over copious amounts of beerand helped me on my journey of discovery learning how to implement Puppet properly. R.I.P

Thursday, 7 February 13