SlideShare a Scribd company logo
A Puppet Approach
To Application
Deployment And
Automation In Nokia


Oliver Hookins
Principal Engineer – Services & Developer Experience
Who am I?
- Rockstar SysAdmin
Who am I?
- Puppet User since 0.23
- Working in Nokia's Location-Based
  Services for 1.5 years
- Previously at Anchor Systems
  (manages GitHub infrastructure
  with Puppet)
- Love/Hate Relationship with Ruby
What do we do?
- “Location Based Services”
- Diverse collection of applications
- Rapidly moving environment,
  competing directly with well-known
  giants in the services arena
- Large, traditionally-organised
  company with heavy change
  control
What do we do?
What do we do?
The Problem Domain
- Deployment consistent across
  environments
- Reduce duplication of effort (and as
  a by-product, human errors)
- Increase testing, feedback of errors,
  reliability.
The Legacy System
The 1.0 Puppet System
New Problems
- Node definitions
- Lack of trust built-in
- Code constantly evolving
- Not enough testing to counter poor
  Puppet knowledge
- Victim of our own success
BDD
Goals
- Approach more like traditional
  software development
- Better versioning of components
- Testing, testing, testing!
- Automation using Jenkins
- Easier deployments
- Better developer tools
Testing
Jenkins
- CI/build tool
- Split testing into stages
- simple tests (lint, --parseonly,
  templates) – take < 2min to run
- compile tests (using Faces) –
  should take < 10min
- integration (full-deploy) - ??
- Use in production! (canary)
- Eventually: continuous deployment
API Approach
- Expose a well-defined interface
- Remove host-, role-, DC- (etc)
  specifics from modules
- Drive configuration “through the
  front door”
- Remove need to look at the code
  (basically reverse engineering)
ENC
- Write one!
  … or try Dashboard
- Seriously, it unlocks Puppet's
  potential
Why not use extlookup?
- Equivalent of global variables in
  programming, bad!
- No well-defined interface to
  classes/defines
- Requires that you code-dive to find
  out how to use a class/define
- Well-defined API and general
  documentation should be sufficient
- Can't easily test code in isolation
Class Introspection
# Prepare a hash to dump out the API
h = {}
h['class'] = {}
h['define'] = {}

# Inspect the PP file
file = 'foo.pp'
Puppet[:manifest] = file
File.open(file, 'r').readlines().each do |l|
  if /^(class|define)s+([^({s]+)/
    tipe = $~[1] # capture the type of object we found
    id = $~[2] # we want the class/define name

    # Grab the arguments and class/define name
    args = Puppet::Resource::Type.find(id).to_pson_data_hash['arguments']
    klass = Puppet::Resource::Type.find(id).to_pson_data_hash['name']
  end
end

h[tipe][klass] = args
Class Introspection
# Prepare a hash to dump out the API
h = {}
h['class'] = {}
h['define'] = {}

# Inspect the PP file
file = 'foo.pp'
Puppet[:manifest] = file
File.open(file, 'r').readlines().each do |l|
  if /^(class|define)s+([^({s]+)/
    tipe = $~[1] # capture the type of object we found
    id = $~[2] # we want the class/define name

    # Grab the arguments and class/define name
    args = Puppet::Resource::Type.find(id).to_pson_data_hash['arguments']
    klass = Puppet::Resource::Type.find(id).to_pson_data_hash['name']
  end
end

h[tipe][klass] = args
Class Introspection
# Prepare a hash to dump out the API
h = {}
h['class'] = {}
h['define'] = {}

# Inspect the PP file
file = 'foo.pp'
Puppet[:manifest] = file
File.open(file, 'r').readlines().each do |l|
  if /^(class|define)s+([^({s]+)/
    tipe = $~[1] # capture the type of object we found
    id = $~[2] # we want the class/define name

    # Grab the arguments and class/define name
    args = Puppet::Resource::Type.find(id).to_pson_data_hash['arguments']
    klass = Puppet::Resource::Type.find(id).to_pson_data_hash['name']
  end
end

h[tipe][klass] = args
Class Introspection
# Prepare a hash to dump out the API
h = {}
h['class'] = {}
h['define'] = {}

# Inspect the PP file
file = 'foo.pp'
Puppet[:manifest] = file
File.open(file, 'r').readlines().each do |l|
  if /^(class|define)s+([^({s]+)/
    tipe = $~[1] # capture the type of object we found
    id = $~[2] # we want the class/define name

    # Grab the arguments and class/define name
    args = Puppet::Resource::Type.find(id).to_pson_data_hash['arguments']
    klass = Puppet::Resource::Type.find(id).to_pson_data_hash['name']
  end
end

h[tipe][klass] = args
Class Introspection
# Prepare a hash to dump out the API
h = {}
h['class'] = {}
h['define'] = {}

# Inspect the PP file
file = 'foo.pp'
Puppet[:manifest] = file
File.open(file, 'r').readlines().each do |l|
  if /^(class|define)s+([^({s]+)/
    tipe = $~[1] # capture the type of object we found
    id = $~[2] # we want the class/define name

    # Grab the arguments and class/define name
    args = Puppet::Resource::Type.find(id).to_pson_data_hash['arguments']
    klass = Puppet::Resource::Type.find(id).to_pson_data_hash['name']
  end
end

h[tipe][klass] = args
Class Introspection
Now you have a YAML interface definition:

  class: 
    postfix: 
      root_email: /dev/null
      relayhost: 
      inet_interfaces: localhost
      alias_maps: hash:/etc/aliases
      mynetworks: ""
Class Introspection
- “Canary” testing
- Interface documentation (have a
  look at the :doc string as well)
- Generate web forms
Module Organisation
“Dist”
 - Provides “platform” services, as
   well as APIs for application
   modules to use
 - Stable, defined release cycle
 - Should be of sufficient quality that
   app teams cannot resist using it
 - Eventually delegate maintenance to
   specialist teams
Module Organisation
“Dist”
 - Pull in things from Moduleforge, or
   just use Moduleforge (in future)
Module Organisation
“App”
 - Blueprints for how to deploy
   applications
 - Uses Dist APIs rather than
   reimplement functionality
 - Sets up development environments
   for application – still unsure of
   correct approach for this
Packaging
Packaging
http://hunnur.com/blog/2010/10/dynamic-git-branch-puppet-environments/


 - Modules under /etc/puppet/modules
 - Each has metadata files (version of
   app, version of dist)
 - Module path:
$confdir/environments/$environment/app:
$confdir/environments/$environment/dist
 - Spec file creates symlinks from
actual app and dist to above locations
Environment Change
def get_node_previous_environment(fqdn)
  factsdir = File.join(get_node_yamldir(), 'facts')
  File.directory?(factsdir) or raise NoFactsDirectoryError,
factsdir

 # Inspect the client machine's facts
 factsfile = File.join(factsdir, "#{fqdn}.yaml")
 if [nil, ''].include?fqdn or not File.exist?(factsfile)
   raise(NoClientFactsError,factsfile)
 end

  # Create a Puppet::Node object from the stored YAML object
  y = YAML.load_file(factsfile)
  p = Puppet::Node::Facts.new(y.name, y.values)
  p.values['environment']
end
Environment Change
def get_node_previous_environment(fqdn)
  factsdir = File.join(get_node_yamldir(), 'facts')
  File.directory?(factsdir) or raise NoFactsDirectoryError,
factsdir

 # Inspect the client machine's facts
 factsfile = File.join(factsdir, "#{fqdn}.yaml")
 if [nil, ''].include?fqdn or not File.exist?(factsfile)
   raise(NoClientFactsError,factsfile)
 end

  # Create a Puppet::Node object from the stored YAML object
  y = YAML.load_file(factsfile)
  p = Puppet::Node::Facts.new(y.name, y.values)
  p.values['environment']
end
Environment Change
def get_node_previous_environment(fqdn)
  factsdir = File.join(get_node_yamldir(), 'facts')
  File.directory?(factsdir) or raise NoFactsDirectoryError,
factsdir

 # Inspect the client machine's facts
 factsfile = File.join(factsdir, "#{fqdn}.yaml")
 if [nil, ''].include?fqdn or not File.exist?(factsfile)
   raise(NoClientFactsError,factsfile)
 end

  # Create a Puppet::Node object from the stored YAML object
  y = YAML.load_file(factsfile)
  p = Puppet::Node::Facts.new(y.name, y.values)
  p.values['environment']
end
Environment Change
def get_node_previous_environment(fqdn)
  factsdir = File.join(get_node_yamldir(), 'facts')
  File.directory?(factsdir) or raise NoFactsDirectoryError,
factsdir

 # Inspect the client machine's facts
 factsfile = File.join(factsdir, "#{fqdn}.yaml")
 if [nil, ''].include?fqdn or not File.exist?(factsfile)
   raise(NoClientFactsError,factsfile)
 end

  # Create a Puppet::Node object from the stored YAML object
  y = YAML.load_file(factsfile)
  p = Puppet::Node::Facts.new(y.name, y.values)
  p.values['environment']
end
Environment Change
if node_puppetenvironment != oldenv then
  Puppet.notice("Changing environment from #{oldenv} to
               #{node_puppetenvironment} for node #{fqdn}")
  y = {}
  y['parameters'] = {}
  y['environment'] = node_puppetenvironment
  y['classes'] = {}
  y['classes']['puppet::client'] = {}
  y['classes']['puppet::client']['puppet_environment'] =
                               node_puppetenvironment.clone
  # YAML catches duplicate references
  y['classes']['puppet::client']['puppetmaster'] =
                                          node_puppetmaster
end
Environment Change
if node_puppetenvironment != oldenv then
  Puppet.notice("Changing environment from #{oldenv} to
               #{node_puppetenvironment} for node #{fqdn}")
  y = {}
  y['parameters'] = {}
  y['environment'] = node_puppetenvironment
  y['classes'] = {}
  y['classes']['puppet::client'] = {}
  y['classes']['puppet::client']['puppet_environment'] =
                               node_puppetenvironment.clone
  # YAML catches duplicate references
  y['classes']['puppet::client']['puppetmaster'] =
                                          node_puppetmaster
end
Environment Change
if node_puppetenvironment != oldenv then
  Puppet.notice("Changing environment from #{oldenv} to
               #{node_puppetenvironment} for node #{fqdn}")
  y = {}
  y['parameters'] = {}
  y['environment'] = node_puppetenvironment
  y['classes'] = {}
  y['classes']['puppet::client'] = {}
  y['classes']['puppet::client']['puppet_environment'] =
                               node_puppetenvironment.clone
  # YAML catches duplicate references
  y['classes']['puppet::client']['puppetmaster'] =
                                          node_puppetmaster
end
Our ENC
Our ENC
vars:
  puppet_version: 2.6.7
  ntp_servers:
    - 192.0.2.1
    - 192.0.2.2
    - 192.0.2.3
  repo_server: repo.ny.example.com
  accounts:
    - bofh
    - peon
  myapp_version: 3.0.0

classes:
  platform:
    puppet_version: ${puppet_version}
    ntp_servers: ${ntp_servers}
    repo_server: ${repo_server}
    accounts: ${accounts}
  myapp:
    version: ${myapp_version}
Future
Future
- Deployment strategy not entirely
  worked out
- Developer workflows still could be
  improved (some promising work in
  this area, e.g. cloudsmith/geppetto
  (IDE integration))
Thank You!
oliver.hookins@nokia.com
   ohookins@gmail.com
 http://paperairoplane.net/

   P.S. We're Hiring!
Attributions
- Photo on slide 8 by dandeluca, available under a Creative Commons Attribution licence
- Photo on slide 9 by graemenewcomb, available under a
Creative Commons Attribution licence
- Photo on slide 11 by seenful, available under a Creative Commons Attribution licence
- Photo on slide 13 by f-oxymoron, available under a Creative Commons Attribution licence
- Photo on slide 28 by oskay, available under a Creative Commons Attribution licence
- Photo on slide 39 by kirrilyrobert, available under a Creative Commons Attribution licence

More Related Content

PDF
Puppi. Puppet strings to the shell
PDF
Puppet modules for Fun and Profit
PDF
Puppet @ Seat
PDF
Anatomy of a reusable module
PDF
Puppet modules: A Holistic Approach - Geneva
PDF
Puppet control-repo 
to the next level
PDF
Can you upgrade to Puppet 4.x?
PDF
Puppet modules: An Holistic Approach
Puppi. Puppet strings to the shell
Puppet modules for Fun and Profit
Puppet @ Seat
Anatomy of a reusable module
Puppet modules: A Holistic Approach - Geneva
Puppet control-repo 
to the next level
Can you upgrade to Puppet 4.x?
Puppet modules: An Holistic Approach

What's hot (20)

PDF
Puppet Camp Phoenix 2015: Managing Files via Puppet: Let Me Count The Ways (B...
PDF
ReUse Your (Puppet) Modules!
PDF
Intro to-puppet
PDF
Configuration Surgery with Augeas
PDF
Doing It Wrong with Puppet -
PDF
Replacing "exec" with a type and provider: Return manifests to a declarative ...
PDF
PuppetCamp SEA 1 - Version Control with Puppet
PDF
Ansible leveraging 2.0
PDF
Puppet for Sys Admins
PPTX
Troubleshooting Puppet
PDF
Puppet Continuous Integration with PE and GitLab
PPTX
Webinar - Managing Files with Puppet
ODP
Aura Project for PHP
PPTX
DevOps with Fabric
PPTX
Webinar - Windows Application Management with Puppet
PDF
Hacking ansible
PPTX
Php on the Web and Desktop
PDF
PuppetConf 2017: Puppet Tasks: Taming ssh in a "for" loop- Alex Dreyer, Puppet
PDF
Using Puppet on Linux, Windows, and Mac OSX
PDF
Puppet: What _not_ to do
Puppet Camp Phoenix 2015: Managing Files via Puppet: Let Me Count The Ways (B...
ReUse Your (Puppet) Modules!
Intro to-puppet
Configuration Surgery with Augeas
Doing It Wrong with Puppet -
Replacing "exec" with a type and provider: Return manifests to a declarative ...
PuppetCamp SEA 1 - Version Control with Puppet
Ansible leveraging 2.0
Puppet for Sys Admins
Troubleshooting Puppet
Puppet Continuous Integration with PE and GitLab
Webinar - Managing Files with Puppet
Aura Project for PHP
DevOps with Fabric
Webinar - Windows Application Management with Puppet
Hacking ansible
Php on the Web and Desktop
PuppetConf 2017: Puppet Tasks: Taming ssh in a "for" loop- Alex Dreyer, Puppet
Using Puppet on Linux, Windows, and Mac OSX
Puppet: What _not_ to do
Ad

Viewers also liked (6)

PDF
Automating and Accelerating Application Deployments to IBM WebSphere without ...
PDF
Puppet overview
PDF
Introduction to puppet
PPTX
Automated Deployments with Ansible
PPTX
Automated Deployment Pipeline using Jenkins, Puppet, Mcollective and AWS
PPTX
Introduction to Puppet Enterprise
Automating and Accelerating Application Deployments to IBM WebSphere without ...
Puppet overview
Introduction to puppet
Automated Deployments with Ansible
Automated Deployment Pipeline using Jenkins, Puppet, Mcollective and AWS
Introduction to Puppet Enterprise
Ad

Similar to Oliver hookins puppetcamp2011 (20)

PPS
A Presentation about Puppet that I've made at the OSSPAC conference
KEY
Puppet for Java developers - JavaZone NO 2012
PDF
Modules of the twenties
PDF
Systems Automation with Puppet
PDF
Developing IT infrastructures with Puppet
PDF
Puppet getting started by Dirk Götz
PDF
TDD with Puppet Tutorial presented at Cascadia IT Conference 2014-03-07
PDF
Puppet Modules for Fun and Profit
PDF
The Grand Puppet Sub-Systems Tour - Nicholas Fagerlund, Puppet Labs
PPTX
Puppet atbazaarvoice
PDF
Using Puppet - Real World Configuration Management
PPT
Puppet
KEY
modern module development - Ken Barber 2012 Edinburgh Puppet Camp
PDF
20090514 Introducing Puppet To Sasag
PDF
PuppetCamp SEA 1 - Puppet Deployment at OnApp
PDF
Puppet Deployment at OnApp
PDF
PuppetCamp SEA 1 - Puppet Deployment at OnApp
ODP
Who pulls the strings?
PDF
Puppet Camp DC 2015: Stop Writing Puppet Modules: A Guide to Best Practices i...
PDF
Puppet Camp Atlanta 2014: Continuous Deployment of Puppet Modules
A Presentation about Puppet that I've made at the OSSPAC conference
Puppet for Java developers - JavaZone NO 2012
Modules of the twenties
Systems Automation with Puppet
Developing IT infrastructures with Puppet
Puppet getting started by Dirk Götz
TDD with Puppet Tutorial presented at Cascadia IT Conference 2014-03-07
Puppet Modules for Fun and Profit
The Grand Puppet Sub-Systems Tour - Nicholas Fagerlund, Puppet Labs
Puppet atbazaarvoice
Using Puppet - Real World Configuration Management
Puppet
modern module development - Ken Barber 2012 Edinburgh Puppet Camp
20090514 Introducing Puppet To Sasag
PuppetCamp SEA 1 - Puppet Deployment at OnApp
Puppet Deployment at OnApp
PuppetCamp SEA 1 - Puppet Deployment at OnApp
Who pulls the strings?
Puppet Camp DC 2015: Stop Writing Puppet Modules: A Guide to Best Practices i...
Puppet Camp Atlanta 2014: Continuous Deployment of Puppet Modules

More from Puppet (20)

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

Recently uploaded (20)

PDF
Empathic Computing: Creating Shared Understanding
PDF
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
PDF
Approach and Philosophy of On baking technology
PPTX
PA Analog/Digital System: The Backbone of Modern Surveillance and Communication
PDF
Dropbox Q2 2025 Financial Results & Investor Presentation
PDF
Spectral efficient network and resource selection model in 5G networks
PDF
Review of recent advances in non-invasive hemoglobin estimation
PPTX
Digital-Transformation-Roadmap-for-Companies.pptx
PPTX
Understanding_Digital_Forensics_Presentation.pptx
PPTX
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
PPT
“AI and Expert System Decision Support & Business Intelligence Systems”
PDF
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
PDF
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
PDF
Per capita expenditure prediction using model stacking based on satellite ima...
PPTX
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
PDF
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
PDF
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
PPTX
Cloud computing and distributed systems.
PPT
Teaching material agriculture food technology
PDF
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
Empathic Computing: Creating Shared Understanding
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
Approach and Philosophy of On baking technology
PA Analog/Digital System: The Backbone of Modern Surveillance and Communication
Dropbox Q2 2025 Financial Results & Investor Presentation
Spectral efficient network and resource selection model in 5G networks
Review of recent advances in non-invasive hemoglobin estimation
Digital-Transformation-Roadmap-for-Companies.pptx
Understanding_Digital_Forensics_Presentation.pptx
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
“AI and Expert System Decision Support & Business Intelligence Systems”
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
Per capita expenditure prediction using model stacking based on satellite ima...
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
Cloud computing and distributed systems.
Teaching material agriculture food technology
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...

Oliver hookins puppetcamp2011