SlideShare a Scribd company logo
LEARNING
PUPPET
- 03
SlideBook (Book on slides)
Inspired by Slidedoc -
http://www.duarte.com
-Vishal Biyani
www.vishalbiyani.com
Configuring
aa
server
with
puppet
www.vishalbiyani.comLearning Puppet
What we will learn? Here is what we are going to do in this chapter
Write a very basic manifest which will install and configure tomcat &
run the manifest and see if it actually works?
Move manifest code into a class and package into module – thus
learning how to create module and basics of module
Make class configurable so that we can pass parameters for certain
things – for example port on which tomcat will run etc.
3|
Refactor code to separate configurable parameters, make it modular
in terms of class design & organization etc.
Learn what is containment (Sounds like enlightenment isn't it? ☺)
Finally use templates and ERB templatinging language to manage
configuration files of software being installed
That seems a lot?That’s going to be super easy though!
www.vishalbiyani.comLearning Puppet
First tomcat run! Now let’s log on to agent_0 and fire command:
In our first cut we want to do a few basic things:
install tomcat, start/run it and there should be a
way to test it in browser if it is working right. For
testing part we will install the “ROOT” app which
shows tomcat home page.Where to put all this
code? In the /etc/puppet/manifests/site.pp under
one of nodes.Our site.pp looks like:
1 node 'puppet.learn.com' {
2 package {'vim-enhanced.x86_64':
3 ensure => present,
4 }
5 }
6 node '0.pagent.vb.com' {
7 package { 'tomcat6':
So that will install & bring up tomcat.To check simply hit the
ip_address:8080* (Or find out the IP address that would get assigned from
Vagrantfile, in my case it is 192.168.17.10).You should see tomcat
homepage:
4|
7 package { 'tomcat6':
8 ensure => installed,
9 }
10
11 service { 'tomcat6':
12 ensure => running,
13 }
14 package { 'tomcat6-webapps':
15 ensure => installed,
16 require => Package['tomcat6'],
17 }
18 }
19 node '1.pagent.vb.com' {
20 }
In above snippet we have added lines from 7 – 17
to get done what we want. First we are declaring
that package tomcat6 should be installed,
secondly it should be running. In last block we are
installing the “ROOT” app which is named as
tomcat-webapps and also forming a relation on
installation of tomcat.
To get IP address of agent fire command “ifconfig” – here the IP address in
block eth1 would be accessible from your machine
So we have a basic tomcat server running but there are quite a few things
that need to be taken care of for example:
•Note that our current code will only work on certain operating systems – for
example if package name on a OS anything different than tomcat6 – then it
won’t work.
•Similarly adding code this way to node definition is not scalable for sure.
We need to move the code somewhere else.
But this is a good start for our first cut; we will refine this much more in
coming pages/slides!
www.vishalbiyani.comLearning Puppet
Creating a module! Let’s understand what all goes in module we created:
Gemfile is a where you define dependencies using the dependency
management tool in Ruby: Bundler
Manifests – is where most of the code we write will go.The special file here
is init.pp – this file has class with name same as module name (tomcat).
Note that all other classes should have same name for file in which class is
defined (Best practice) except for init.pp.
Metadata.json stores basic information about your module which you filled
in while generating module.
Rakefile is like a make file in C – which defined tasks for your codebase. And
you know what a README.md is for isn’t it?
Spec directory
Tests is where tests for our module live!
For this chapter we are only going to touch files in manifests directory!
Let’s get our house in order!We put bunch of lines
in node definition to getTomcat up and running
but we want to distribute our tomcat magic code
to others so that they can do the same. Let’s
wrap all of code in a module. For that let’s first
create a barebones module, on master node
navigate to /etc/puppet/modules and fire:
1 sudo puppet module generate learn-tomcat
sudo mv learn-tomcat tomcat
The name we gave is a combination of username
(learn) and module name (tomcat) which is
separated by dash and is the convention followed
5|
For this chapter we are only going to touch files in manifests directory!
If you look at the init.pp in manifests, you will see:
So let’s move the code we had defined inside node definition in this class.
That makes our module functional. If someone has to install tomcat, all one
has to do is in node definition (Try on your setup!):
The effect is same as previous slide.Our first ever module for tomcat is
ready.Our class still does not follow the best coding practices & design
patterns but we will fix that soon too!
* The name of module vs. the combo name of username-modulename is
a known bug and will be fixed in Puppet 4.0 I stumbled on this during
exercise so I added that command. Check
https://tickets.puppetlabs.com/browse/PUP-3124
separated by dash and is the convention followed
by puppet.You will be asked with bunch of
questions and you can fill them or leave blank!
And we need to rename the module name to
tomcat as the username-module name combo
needs to be only in metadata file*. And puppet
generates a basic structure of a module for us!
tomcat/
|── Gemfile
|── manifests
| |── init.pp
|── metadata.json
|── Rakefile
|── README.md
|── spec
| |── classes
| | └── init_spec.rb
| |── spec_helper.rb
|── tests
|── init.pp
1 class tomcat {
2 }
1 node '0.pagent.vb.com' {
2 include tomcat
3 }
www.vishalbiyani.comLearning Puppet
Making things parameterized!
Parameterization – first thing we want to do is
make some of hardcoded values to be passed as
parameters so that end user can customize the
module as per need. For this first of all we create
a class params.pp in manifests directory, that
way parameters will be managed in a different
class and can be referred from all over the
module. Also note that we have default values for
all parameters so even if end user does not
provide them when calling tomcat module, our
code won’t break!
1 class tomcat::params {
2 $package_name = 'tomcat6'
3 $package_ensure = 'installed'
4 $service_manage = true
5 $service_name = 'tomcat6'
6 $service_ensure = 'running'
7 $service_port = '8080'
8 $root_webapp_name = 'tomcat6-webapps‘
9 $root_webapp_ensure = 'installed'
10 }
6|
code won’t break!
Once we get introduced to Hiera in upcoming chapters, we will move the configuration parameters from params.pp to Hiera. We
are for now using loosely called “params class” pattern
Now we will inherit params class in our tomcat
class (init.pp) so that all parameters are
available. Moreover we will take parameters as
class arguments and in case they are not
provided, default values will do magic. You might
have noticed that our code for installing tomcat
etc. is missing – we will take care of that in a
moment. Notice the way we are all namespacing
all classes like “tomcat::params”?
1 class tomcat (
2 $package_name = $tomcat::params::service_name,
3 $package_ensure = $tomcat::params::package_ensure,
4 $service_manage = $tomcat::params::service_manage,
5 $service_name = $tomcat::params::service_name,
6 $service_ensure = $tomcat::params::service_ensure,
7 $service_port = $tomcat::params::service_port,
8 ) inherits ::tomcat::params {
9
10 }
www.vishalbiyani.comLearning Puppet
Code into logical classes
Next we want to break the code logic into
appropriate blocks.We are primarily doing a few
things – managing packages (installing them)
and once they are done then managing service
(Starting tomcat etc.). So it makes sense to add
the relevant chunk in relevant classes.
Our first step of getting packages and installing
them is grouped into install.pp which does same
thing but uses parameters instead of hardcoded
values of package names & states. Looks neat
isn’t it?
1 class tomcat::install inherits tomcat {
2 package { 'tomcat6':
3 name => $package_name,
4 ensure => $package_ensure,
5 }
6 package {'tomcat6-webapps':
7 name => $root_webapp_name,
8 ensure => $root_webapp_ensure,
9 require => Package['tomcat6'],
10 }
11 }
1 class tomcat::service inherits tomcat {
2 if ! ($service_ensure in ['stopped','running']){Next we manage services in service.pp. Here we
7|
2 if ! ($service_ensure in ['stopped','running']){
3 fail("Service status must be one of stopped or running")
4 }
5 if $service_manage == true {
6 service {'tomcat6':
7 ensure => $service_ensure,
8 name => $service_name,
9 }
10 }
11 }
Next we manage services in service.pp. Here we
add a small check to ensure user has not passed
invalid values for service status before we
actually start service.We are also letting user
decide weather service should be started or not
with $service_manage parameter. Rest all is old
code in new bottle (of beer or wine ;) )
1 class tomcat::config inherits tomcat {
2 }
We are adding one more class – config.pp and
leaving it blank, just for future you know!
So we defined classes but never invoked them?
How will this work? It will, in next slide ;)
www.vishalbiyani.comLearning Puppet
Get Set Go..Finally we add the meat to main block of our
original class – tomcat (init.pp).We are using a
magic word – contain and then declaring the
three classes we defined in a specific order.
Because we don’t want to start tomcat service
before it is installed isn’t it? BTWWTH is this
contain?We will understand that in next slide but
for now understand that we are scoping them in
current context so that even if someone declares
them elsewhere with include – we are not
affected! (Remember that irrespective of number
of includes – it is executes only once?)
1 class tomcat (
2 $package_name = $tomcat::params::service_name,
3 $package_ensure = $tomcat::params::package_ensure,
4 $service_manage = $tomcat::params::service_manage,
5 $service_name = $tomcat::params::service_name,
6 $service_ensure = $tomcat::params::service_ensure,
7 $service_port = $tomcat::params::service_port,
8 ) inherits ::tomcat::params {
9 contain tomcat::config
10 contain tomcat::install
11 contain tomcat::service
12
13 Class['tomcat::config'] ->
14 Class['tomcat::install'] ->
15 Class['tomcat::service']
16 }
8|There is an excellent document on Puppet website which talks about good module design, our design is loosely
based on that, it is a MUST read: https://docs.puppetlabs.com/guides/module_guides/bgtm.html
What changes in node classification declaration
from last modification? Not much. Doing a
puppet run on agent would have same effect but
now our code is much cleaner & well structured. If
you need to pass parameters then we will have to
use the resource declaration way as shown in
second code snippet for node declaration:
1 node '0.pagent.vb.com' {
2 include tomcat
3 }
1 node '0.pagent.vb.com' {
2 class {'tomcat':
3 service_ensure => 'stopped',
4 }
5 }
If you noticed something – if you try changing the
port of service to anything other than 8080 – that
does not work, because we have not yet coded for
that.We will do that in next chapter but before
we finish let’s go over what containment is ?
Why can not we pass parameters in include way of class declaration above?
Why we had to fall back to resource based declaration? If you use include
function to declare classes then configuration parameters should ideally
come from Hiera and we will see how in upcoming chapters. It is suggested
to use include way of declaring going forward as we already covered in
chapter 2
www.vishalbiyani.comLearning Puppet
Containment &
Anchor pattern
So how do you contain classes? It is very simple syntax – in include like as
well as resource like declaration. For resource like, you will need to use all 4
lines below and in case of include like only line number 4 is needed!
Containment can be a tricky topic to understand
if we ignore basics, so let’s recap them once more:
•In puppet sequence of execution is not
guaranteed unless you explicitly form that
relationship (Between two resources).
•“include” type of declaration can be done
multiple times although the execution will
happen only once
•Thirdly if you define a resource within a class –
1 class {'tomcat::service':
2 service_ensure => 'stopped',
3 }
4 contain 'tomcat::service'
But there is a small problem – contain function was introduced in Puppet
enterprise 3.2 and puppet open source 3.4. So if you are using versions prior
to those, you will need to use puppetlabs/stdlibs module along with anchor
resource type.This is named “anchor containment pattern”. Let’s look at
some code and then digest it, our above declaration with anchor pattern
now will look like:
1 anchor['tomcat_start:'] ->
9|
•Thirdly if you define a resource within a class –
then you can be sure that the resource code will
be executed after class starts and before class
ends – this is basically called containment of that
resource to class. Resources and defined types by
default are contained.
Now let’s imagine you defined a class A.You
included A in another class B and many other
places. But puppet does not guarantee that A will
be executed within B by default.This means
classes by default are not contained and need to
be contained explicitly.Why? See footnote!
Classes are not contained by default is intentional. Imagine you declared “include class_name” n number of places and
puppet had to contain the class everywhere? At the same time when we design a large module, we want to make sure
parent class can contain other classes. Creating classes to have logical division is a good practice as we already saw!
1 anchor['tomcat_start:'] ->
2 Class['tomcat::service':] ->
3 anchor['tomcat_end':]
4 # Almost same as 'contain tomcat::service'
So here is what is happening:
•The class to be contained should be between two anchors.These anchors
should be unique within containing class.
•You must form relationship between class to be contained and anchors
such that there is one anchor before and after the contained class (-> forms
this relationship)
•Anchor code does not affect the execution – it is only to facilitate the
containment!
www.vishalbiyani.comLearning Puppet
1
Node classification and how to add relevant
infrastructure code to a node
What did we learn?
2
How to create module, it’s basic structure and how
to it all forms together
3
Good practices for class design & parameterization
of classes for configurable values.
10|
4
Calling classes from a module for a given node &
configuring it as per need
5
Containment of classes & why anchor pattern is
needed for certain versions of puppet

More Related Content

PDF
Learning puppet chapter 2
Vishal Biyani
 
PDF
Learning Puppet Chapter 1
Vishal Biyani
 
PDF
Puppet for Sys Admins
Puppet
 
PDF
Puppet modules: An Holistic Approach
Alessandro Franceschi
 
PDF
Can you upgrade to Puppet 4.x?
Martin Alfke
 
PDF
High Quality Symfony Bundles tutorial - Dutch PHP Conference 2014
Matthias Noback
 
PPTX
Enjoying the Journey from Puppet 3.x to Puppet 4.x (PuppetConf 2016)
Robert Nelson
 
PDF
Developing IT infrastructures with Puppet
Alessandro Franceschi
 
Learning puppet chapter 2
Vishal Biyani
 
Learning Puppet Chapter 1
Vishal Biyani
 
Puppet for Sys Admins
Puppet
 
Puppet modules: An Holistic Approach
Alessandro Franceschi
 
Can you upgrade to Puppet 4.x?
Martin Alfke
 
High Quality Symfony Bundles tutorial - Dutch PHP Conference 2014
Matthias Noback
 
Enjoying the Journey from Puppet 3.x to Puppet 4.x (PuppetConf 2016)
Robert Nelson
 
Developing IT infrastructures with Puppet
Alessandro Franceschi
 

What's hot (20)

PDF
Puppi. Puppet strings to the shell
Alessandro Franceschi
 
PDF
Twig: Friendly Curly Braces Invade Your Templates!
Ryan Weaver
 
PDF
Being Dangerous with Twig
Ryan Weaver
 
PDF
Writing & Sharing Great Modules on the Puppet Forge
Puppet
 
PDF
Getting started with Puppet
jeyg
 
PDF
Troubleshooting the Puppet Enterprise Stack
Puppet
 
PDF
Doing It Wrong with Puppet -
Puppet
 
PDF
Puppet camp2021 testing modules and controlrepo
Puppet
 
PPTX
Auto Deploy Deep Dive – vBrownBag Style
Robert Nelson
 
PDF
Nginx pres
James Fuller
 
PDF
Hands-on with the Symfony2 Framework
Ryan Weaver
 
PDF
Power of Puppet 4
Martin Alfke
 
PDF
Puppet Systems Infrastructure Construction Kit
Alessandro Franceschi
 
ODP
Mastering Namespaces in PHP
Nick Belhomme
 
PDF
Creating a mature puppet system
rkhatibi
 
PDF
Maven 3.0 at Øredev
Matthew McCullough
 
ODP
Intro To Spring Python
gturnquist
 
PDF
Php simple
PrinceGuru MS
 
PDF
Fighting Fear-Driven-Development With PHPUnit
James Fuller
 
PDF
Modules of the twenties
Puppet
 
Puppi. Puppet strings to the shell
Alessandro Franceschi
 
Twig: Friendly Curly Braces Invade Your Templates!
Ryan Weaver
 
Being Dangerous with Twig
Ryan Weaver
 
Writing & Sharing Great Modules on the Puppet Forge
Puppet
 
Getting started with Puppet
jeyg
 
Troubleshooting the Puppet Enterprise Stack
Puppet
 
Doing It Wrong with Puppet -
Puppet
 
Puppet camp2021 testing modules and controlrepo
Puppet
 
Auto Deploy Deep Dive – vBrownBag Style
Robert Nelson
 
Nginx pres
James Fuller
 
Hands-on with the Symfony2 Framework
Ryan Weaver
 
Power of Puppet 4
Martin Alfke
 
Puppet Systems Infrastructure Construction Kit
Alessandro Franceschi
 
Mastering Namespaces in PHP
Nick Belhomme
 
Creating a mature puppet system
rkhatibi
 
Maven 3.0 at Øredev
Matthew McCullough
 
Intro To Spring Python
gturnquist
 
Php simple
PrinceGuru MS
 
Fighting Fear-Driven-Development With PHPUnit
James Fuller
 
Modules of the twenties
Puppet
 
Ad

Viewers also liked (20)

DOCX
Puppet vs. Chef - The Battle Wages On
CloudCheckr
 
PDF
DevOps Cardiff - Puppet vs Chef vs Ansible
Mark Phillips
 
PDF
Certifiable Puppet Professional: Puppet's new Education Certification Curriculum
Puppet
 
PPTX
Why we are migrating to Chef from Puppet
Yu Yamanaka
 
PDF
Puppet Camp Paris 2014: Achieving Continuous Delivery and DevOps with Puppet
Puppet
 
PDF
DevOps: What is This Puppet You Speak Of?
Rob Reynolds
 
PPTX
Deliver on DevOps with Puppet Application Orchestration Webinar 11/19/15
Puppet
 
PDF
Puppet devops wdec
Wojciech Dec
 
PDF
Learn Puppet : Quest Guide for the Learning VM
Kumaran Balachandran
 
PDF
Chef vs. Puppet in the Cloud: How Telepictures and MoneySuperMarket Do It
RightScale
 
ODP
Cfengine vs Puppet vs Chef: A Guide for Stressed Developers
Ron Toland
 
PPT
Prologue, Myers Psychology 9e
Charleen Gribben
 
PDF
Devops : Automate Your Infrastructure with Puppet
Edureka!
 
PPTX
GitFlow, SourceTree and GitLab
Shinu Suresh
 
ODP
Foreman in your datacenter
lzap
 
PDF
Git and GitHub for Documentation
Anne Gentle
 
PDF
Puppet 3 em 2017
Taciano Tres
 
DOC
Todd_Paulk_DevOps_resume_revised
Todd Paulk
 
PDF
Git best practices workshop
Otto Kekäläinen
 
ODP
Foreman in Your Data Center :OSDC 2015
Stephen Benjamin
 
Puppet vs. Chef - The Battle Wages On
CloudCheckr
 
DevOps Cardiff - Puppet vs Chef vs Ansible
Mark Phillips
 
Certifiable Puppet Professional: Puppet's new Education Certification Curriculum
Puppet
 
Why we are migrating to Chef from Puppet
Yu Yamanaka
 
Puppet Camp Paris 2014: Achieving Continuous Delivery and DevOps with Puppet
Puppet
 
DevOps: What is This Puppet You Speak Of?
Rob Reynolds
 
Deliver on DevOps with Puppet Application Orchestration Webinar 11/19/15
Puppet
 
Puppet devops wdec
Wojciech Dec
 
Learn Puppet : Quest Guide for the Learning VM
Kumaran Balachandran
 
Chef vs. Puppet in the Cloud: How Telepictures and MoneySuperMarket Do It
RightScale
 
Cfengine vs Puppet vs Chef: A Guide for Stressed Developers
Ron Toland
 
Prologue, Myers Psychology 9e
Charleen Gribben
 
Devops : Automate Your Infrastructure with Puppet
Edureka!
 
GitFlow, SourceTree and GitLab
Shinu Suresh
 
Foreman in your datacenter
lzap
 
Git and GitHub for Documentation
Anne Gentle
 
Puppet 3 em 2017
Taciano Tres
 
Todd_Paulk_DevOps_resume_revised
Todd Paulk
 
Git best practices workshop
Otto Kekäläinen
 
Foreman in Your Data Center :OSDC 2015
Stephen Benjamin
 
Ad

Similar to Learning puppet chapter 3 (20)

DOCX
matmultHomework3.pdfNames of Files to Submit matmult..docx
andreecapon
 
PPTX
Puppet quick start guide
Suhan Dharmasuriya
 
PDF
Pp w tomee
Felix Gomez del Alamo
 
PPT
Demystifying Maven
Mike Desjardins
 
PDF
PrestaShop Kathmandu Ecommerce Meetup #2
Hem Pokhrel
 
PDF
The Django Book chapter 4 templates (supplement)
Vincent Chien
 
PDF
Mc sl54 051_ (1)
AnkitKumar2343
 
PPT
Debugging and Error handling
Suite Solutions
 
PDF
Buffer overflow tutorial
hughpearse
 
PPT
Apache TomEE - Tomcat with a kick
Vishwanath Krishnamurthi
 
PDF
Cacoo enterprise installation_manual
joseig23
 
PDF
Fullstack Academy - Awesome Web Dev Tips & Tricks
Frances Coronel
 
PDF
Parrot tutorial
HarikaReddy115
 
DOCX
Objectives Assignment 09 Applications of Stacks COS.docx
dunhamadell
 
PDF
How To Install Openbravo ERP 2.50 MP43 in Ubuntu
Wirabumi Software
 
ODP
Makefiles Bioinfo
Giovanni Marco Dall'Olio
 
PDF
Mallet
Shatakirti Er
 
DOCX
LMP1 IO and Filesystems=========================Welcome .docx
manningchassidy
 
PPTX
Dost.jar and fo.jar
Suite Solutions
 
PPS
A Presentation about Puppet that I've made at the OSSPAC conference
ohadlevy
 
matmultHomework3.pdfNames of Files to Submit matmult..docx
andreecapon
 
Puppet quick start guide
Suhan Dharmasuriya
 
Demystifying Maven
Mike Desjardins
 
PrestaShop Kathmandu Ecommerce Meetup #2
Hem Pokhrel
 
The Django Book chapter 4 templates (supplement)
Vincent Chien
 
Mc sl54 051_ (1)
AnkitKumar2343
 
Debugging and Error handling
Suite Solutions
 
Buffer overflow tutorial
hughpearse
 
Apache TomEE - Tomcat with a kick
Vishwanath Krishnamurthi
 
Cacoo enterprise installation_manual
joseig23
 
Fullstack Academy - Awesome Web Dev Tips & Tricks
Frances Coronel
 
Parrot tutorial
HarikaReddy115
 
Objectives Assignment 09 Applications of Stacks COS.docx
dunhamadell
 
How To Install Openbravo ERP 2.50 MP43 in Ubuntu
Wirabumi Software
 
Makefiles Bioinfo
Giovanni Marco Dall'Olio
 
LMP1 IO and Filesystems=========================Welcome .docx
manningchassidy
 
Dost.jar and fo.jar
Suite Solutions
 
A Presentation about Puppet that I've made at the OSSPAC conference
ohadlevy
 

More from Vishal Biyani (15)

PDF
Gophercon 2018: Kubernetes api golang
Vishal Biyani
 
PPTX
Serverless Summit India 2017: Fission
Vishal Biyani
 
PPTX
SaltStack Advanced Concepts
Vishal Biyani
 
PPTX
Kubernetes 101 Workshop
Vishal Biyani
 
PPTX
Serverless Pune meetup 3
Vishal Biyani
 
PPTX
Container Conf 2017: Rancher Kubernetes
Vishal Biyani
 
PPTX
Serverless Pune Meetup 1
Vishal Biyani
 
PPTX
Setting up Kubernetes with tectonic
Vishal Biyani
 
PPTX
Introduction to Kubernetes
Vishal Biyani
 
PDF
Mulesoft cloudhub
Vishal Biyani
 
PDF
Dell boomi
Vishal Biyani
 
PDF
Using CI for continuous delivery Part 3
Vishal Biyani
 
PDF
Using CI for continuous delivery Part 2
Vishal Biyani
 
PDF
Using CI for continuous delivery Part 1
Vishal Biyani
 
PDF
Using CI for continuous delivery Part 4
Vishal Biyani
 
Gophercon 2018: Kubernetes api golang
Vishal Biyani
 
Serverless Summit India 2017: Fission
Vishal Biyani
 
SaltStack Advanced Concepts
Vishal Biyani
 
Kubernetes 101 Workshop
Vishal Biyani
 
Serverless Pune meetup 3
Vishal Biyani
 
Container Conf 2017: Rancher Kubernetes
Vishal Biyani
 
Serverless Pune Meetup 1
Vishal Biyani
 
Setting up Kubernetes with tectonic
Vishal Biyani
 
Introduction to Kubernetes
Vishal Biyani
 
Mulesoft cloudhub
Vishal Biyani
 
Dell boomi
Vishal Biyani
 
Using CI for continuous delivery Part 3
Vishal Biyani
 
Using CI for continuous delivery Part 2
Vishal Biyani
 
Using CI for continuous delivery Part 1
Vishal Biyani
 
Using CI for continuous delivery Part 4
Vishal Biyani
 

Recently uploaded (20)

PDF
Applitools Platform Pulse: What's New and What's Coming - July 2025
Applitools
 
PPT
Activate_Methodology_Summary presentatio
annapureddyn
 
PDF
New Download MiniTool Partition Wizard Crack Latest Version 2025
imang66g
 
PDF
WatchTraderHub - Watch Dealer software with inventory management and multi-ch...
WatchDealer Pavel
 
PDF
An Experience-Based Look at AI Lead Generation Pricing, Features & B2B Results
Thomas albart
 
PDF
Using licensed Data Loss Prevention (DLP) as a strategic proactive data secur...
Q-Advise
 
PPTX
ConcordeApp: Engineering Global Impact & Unlocking Billions in Event ROI with AI
chastechaste14
 
PDF
Summary Of Odoo 18.1 to 18.4 : The Way For Odoo 19
CandidRoot Solutions Private Limited
 
PDF
New Download FL Studio Crack Full Version [Latest 2025]
imang66g
 
PPTX
slidesgo-unlocking-the-code-the-dynamic-dance-of-variables-and-constants-2024...
kr2589474
 
PDF
49784907924775488180_LRN2959_Data_Pump_23ai.pdf
Abilash868456
 
PPTX
Explanation about Structures in C language.pptx
Veeral Rathod
 
PPTX
Web Testing.pptx528278vshbuqffqhhqiwnwuq
studylike474
 
PPTX
ASSIGNMENT_1[1][1][1][1][1] (1) variables.pptx
kr2589474
 
PDF
Salesforce Implementation Services Provider.pdf
VALiNTRY360
 
PPTX
Presentation about Database and Database Administrator
abhishekchauhan86963
 
PDF
Bandai Playdia The Book - David Glotz
BluePanther6
 
PPTX
Presentation about variables and constant.pptx
kr2589474
 
PPTX
GALILEO CRS SYSTEM | GALILEO TRAVEL SOFTWARE
philipnathen82
 
PDF
ChatPharo: an Open Architecture for Understanding How to Talk Live to LLMs
ESUG
 
Applitools Platform Pulse: What's New and What's Coming - July 2025
Applitools
 
Activate_Methodology_Summary presentatio
annapureddyn
 
New Download MiniTool Partition Wizard Crack Latest Version 2025
imang66g
 
WatchTraderHub - Watch Dealer software with inventory management and multi-ch...
WatchDealer Pavel
 
An Experience-Based Look at AI Lead Generation Pricing, Features & B2B Results
Thomas albart
 
Using licensed Data Loss Prevention (DLP) as a strategic proactive data secur...
Q-Advise
 
ConcordeApp: Engineering Global Impact & Unlocking Billions in Event ROI with AI
chastechaste14
 
Summary Of Odoo 18.1 to 18.4 : The Way For Odoo 19
CandidRoot Solutions Private Limited
 
New Download FL Studio Crack Full Version [Latest 2025]
imang66g
 
slidesgo-unlocking-the-code-the-dynamic-dance-of-variables-and-constants-2024...
kr2589474
 
49784907924775488180_LRN2959_Data_Pump_23ai.pdf
Abilash868456
 
Explanation about Structures in C language.pptx
Veeral Rathod
 
Web Testing.pptx528278vshbuqffqhhqiwnwuq
studylike474
 
ASSIGNMENT_1[1][1][1][1][1] (1) variables.pptx
kr2589474
 
Salesforce Implementation Services Provider.pdf
VALiNTRY360
 
Presentation about Database and Database Administrator
abhishekchauhan86963
 
Bandai Playdia The Book - David Glotz
BluePanther6
 
Presentation about variables and constant.pptx
kr2589474
 
GALILEO CRS SYSTEM | GALILEO TRAVEL SOFTWARE
philipnathen82
 
ChatPharo: an Open Architecture for Understanding How to Talk Live to LLMs
ESUG
 

Learning puppet chapter 3

  • 1. LEARNING PUPPET - 03 SlideBook (Book on slides) Inspired by Slidedoc - http://www.duarte.com -Vishal Biyani www.vishalbiyani.com
  • 3. www.vishalbiyani.comLearning Puppet What we will learn? Here is what we are going to do in this chapter Write a very basic manifest which will install and configure tomcat & run the manifest and see if it actually works? Move manifest code into a class and package into module – thus learning how to create module and basics of module Make class configurable so that we can pass parameters for certain things – for example port on which tomcat will run etc. 3| Refactor code to separate configurable parameters, make it modular in terms of class design & organization etc. Learn what is containment (Sounds like enlightenment isn't it? ☺) Finally use templates and ERB templatinging language to manage configuration files of software being installed That seems a lot?That’s going to be super easy though!
  • 4. www.vishalbiyani.comLearning Puppet First tomcat run! Now let’s log on to agent_0 and fire command: In our first cut we want to do a few basic things: install tomcat, start/run it and there should be a way to test it in browser if it is working right. For testing part we will install the “ROOT” app which shows tomcat home page.Where to put all this code? In the /etc/puppet/manifests/site.pp under one of nodes.Our site.pp looks like: 1 node 'puppet.learn.com' { 2 package {'vim-enhanced.x86_64': 3 ensure => present, 4 } 5 } 6 node '0.pagent.vb.com' { 7 package { 'tomcat6': So that will install & bring up tomcat.To check simply hit the ip_address:8080* (Or find out the IP address that would get assigned from Vagrantfile, in my case it is 192.168.17.10).You should see tomcat homepage: 4| 7 package { 'tomcat6': 8 ensure => installed, 9 } 10 11 service { 'tomcat6': 12 ensure => running, 13 } 14 package { 'tomcat6-webapps': 15 ensure => installed, 16 require => Package['tomcat6'], 17 } 18 } 19 node '1.pagent.vb.com' { 20 } In above snippet we have added lines from 7 – 17 to get done what we want. First we are declaring that package tomcat6 should be installed, secondly it should be running. In last block we are installing the “ROOT” app which is named as tomcat-webapps and also forming a relation on installation of tomcat. To get IP address of agent fire command “ifconfig” – here the IP address in block eth1 would be accessible from your machine So we have a basic tomcat server running but there are quite a few things that need to be taken care of for example: •Note that our current code will only work on certain operating systems – for example if package name on a OS anything different than tomcat6 – then it won’t work. •Similarly adding code this way to node definition is not scalable for sure. We need to move the code somewhere else. But this is a good start for our first cut; we will refine this much more in coming pages/slides!
  • 5. www.vishalbiyani.comLearning Puppet Creating a module! Let’s understand what all goes in module we created: Gemfile is a where you define dependencies using the dependency management tool in Ruby: Bundler Manifests – is where most of the code we write will go.The special file here is init.pp – this file has class with name same as module name (tomcat). Note that all other classes should have same name for file in which class is defined (Best practice) except for init.pp. Metadata.json stores basic information about your module which you filled in while generating module. Rakefile is like a make file in C – which defined tasks for your codebase. And you know what a README.md is for isn’t it? Spec directory Tests is where tests for our module live! For this chapter we are only going to touch files in manifests directory! Let’s get our house in order!We put bunch of lines in node definition to getTomcat up and running but we want to distribute our tomcat magic code to others so that they can do the same. Let’s wrap all of code in a module. For that let’s first create a barebones module, on master node navigate to /etc/puppet/modules and fire: 1 sudo puppet module generate learn-tomcat sudo mv learn-tomcat tomcat The name we gave is a combination of username (learn) and module name (tomcat) which is separated by dash and is the convention followed 5| For this chapter we are only going to touch files in manifests directory! If you look at the init.pp in manifests, you will see: So let’s move the code we had defined inside node definition in this class. That makes our module functional. If someone has to install tomcat, all one has to do is in node definition (Try on your setup!): The effect is same as previous slide.Our first ever module for tomcat is ready.Our class still does not follow the best coding practices & design patterns but we will fix that soon too! * The name of module vs. the combo name of username-modulename is a known bug and will be fixed in Puppet 4.0 I stumbled on this during exercise so I added that command. Check https://tickets.puppetlabs.com/browse/PUP-3124 separated by dash and is the convention followed by puppet.You will be asked with bunch of questions and you can fill them or leave blank! And we need to rename the module name to tomcat as the username-module name combo needs to be only in metadata file*. And puppet generates a basic structure of a module for us! tomcat/ |── Gemfile |── manifests | |── init.pp |── metadata.json |── Rakefile |── README.md |── spec | |── classes | | └── init_spec.rb | |── spec_helper.rb |── tests |── init.pp 1 class tomcat { 2 } 1 node '0.pagent.vb.com' { 2 include tomcat 3 }
  • 6. www.vishalbiyani.comLearning Puppet Making things parameterized! Parameterization – first thing we want to do is make some of hardcoded values to be passed as parameters so that end user can customize the module as per need. For this first of all we create a class params.pp in manifests directory, that way parameters will be managed in a different class and can be referred from all over the module. Also note that we have default values for all parameters so even if end user does not provide them when calling tomcat module, our code won’t break! 1 class tomcat::params { 2 $package_name = 'tomcat6' 3 $package_ensure = 'installed' 4 $service_manage = true 5 $service_name = 'tomcat6' 6 $service_ensure = 'running' 7 $service_port = '8080' 8 $root_webapp_name = 'tomcat6-webapps‘ 9 $root_webapp_ensure = 'installed' 10 } 6| code won’t break! Once we get introduced to Hiera in upcoming chapters, we will move the configuration parameters from params.pp to Hiera. We are for now using loosely called “params class” pattern Now we will inherit params class in our tomcat class (init.pp) so that all parameters are available. Moreover we will take parameters as class arguments and in case they are not provided, default values will do magic. You might have noticed that our code for installing tomcat etc. is missing – we will take care of that in a moment. Notice the way we are all namespacing all classes like “tomcat::params”? 1 class tomcat ( 2 $package_name = $tomcat::params::service_name, 3 $package_ensure = $tomcat::params::package_ensure, 4 $service_manage = $tomcat::params::service_manage, 5 $service_name = $tomcat::params::service_name, 6 $service_ensure = $tomcat::params::service_ensure, 7 $service_port = $tomcat::params::service_port, 8 ) inherits ::tomcat::params { 9 10 }
  • 7. www.vishalbiyani.comLearning Puppet Code into logical classes Next we want to break the code logic into appropriate blocks.We are primarily doing a few things – managing packages (installing them) and once they are done then managing service (Starting tomcat etc.). So it makes sense to add the relevant chunk in relevant classes. Our first step of getting packages and installing them is grouped into install.pp which does same thing but uses parameters instead of hardcoded values of package names & states. Looks neat isn’t it? 1 class tomcat::install inherits tomcat { 2 package { 'tomcat6': 3 name => $package_name, 4 ensure => $package_ensure, 5 } 6 package {'tomcat6-webapps': 7 name => $root_webapp_name, 8 ensure => $root_webapp_ensure, 9 require => Package['tomcat6'], 10 } 11 } 1 class tomcat::service inherits tomcat { 2 if ! ($service_ensure in ['stopped','running']){Next we manage services in service.pp. Here we 7| 2 if ! ($service_ensure in ['stopped','running']){ 3 fail("Service status must be one of stopped or running") 4 } 5 if $service_manage == true { 6 service {'tomcat6': 7 ensure => $service_ensure, 8 name => $service_name, 9 } 10 } 11 } Next we manage services in service.pp. Here we add a small check to ensure user has not passed invalid values for service status before we actually start service.We are also letting user decide weather service should be started or not with $service_manage parameter. Rest all is old code in new bottle (of beer or wine ;) ) 1 class tomcat::config inherits tomcat { 2 } We are adding one more class – config.pp and leaving it blank, just for future you know! So we defined classes but never invoked them? How will this work? It will, in next slide ;)
  • 8. www.vishalbiyani.comLearning Puppet Get Set Go..Finally we add the meat to main block of our original class – tomcat (init.pp).We are using a magic word – contain and then declaring the three classes we defined in a specific order. Because we don’t want to start tomcat service before it is installed isn’t it? BTWWTH is this contain?We will understand that in next slide but for now understand that we are scoping them in current context so that even if someone declares them elsewhere with include – we are not affected! (Remember that irrespective of number of includes – it is executes only once?) 1 class tomcat ( 2 $package_name = $tomcat::params::service_name, 3 $package_ensure = $tomcat::params::package_ensure, 4 $service_manage = $tomcat::params::service_manage, 5 $service_name = $tomcat::params::service_name, 6 $service_ensure = $tomcat::params::service_ensure, 7 $service_port = $tomcat::params::service_port, 8 ) inherits ::tomcat::params { 9 contain tomcat::config 10 contain tomcat::install 11 contain tomcat::service 12 13 Class['tomcat::config'] -> 14 Class['tomcat::install'] -> 15 Class['tomcat::service'] 16 } 8|There is an excellent document on Puppet website which talks about good module design, our design is loosely based on that, it is a MUST read: https://docs.puppetlabs.com/guides/module_guides/bgtm.html What changes in node classification declaration from last modification? Not much. Doing a puppet run on agent would have same effect but now our code is much cleaner & well structured. If you need to pass parameters then we will have to use the resource declaration way as shown in second code snippet for node declaration: 1 node '0.pagent.vb.com' { 2 include tomcat 3 } 1 node '0.pagent.vb.com' { 2 class {'tomcat': 3 service_ensure => 'stopped', 4 } 5 } If you noticed something – if you try changing the port of service to anything other than 8080 – that does not work, because we have not yet coded for that.We will do that in next chapter but before we finish let’s go over what containment is ? Why can not we pass parameters in include way of class declaration above? Why we had to fall back to resource based declaration? If you use include function to declare classes then configuration parameters should ideally come from Hiera and we will see how in upcoming chapters. It is suggested to use include way of declaring going forward as we already covered in chapter 2
  • 9. www.vishalbiyani.comLearning Puppet Containment & Anchor pattern So how do you contain classes? It is very simple syntax – in include like as well as resource like declaration. For resource like, you will need to use all 4 lines below and in case of include like only line number 4 is needed! Containment can be a tricky topic to understand if we ignore basics, so let’s recap them once more: •In puppet sequence of execution is not guaranteed unless you explicitly form that relationship (Between two resources). •“include” type of declaration can be done multiple times although the execution will happen only once •Thirdly if you define a resource within a class – 1 class {'tomcat::service': 2 service_ensure => 'stopped', 3 } 4 contain 'tomcat::service' But there is a small problem – contain function was introduced in Puppet enterprise 3.2 and puppet open source 3.4. So if you are using versions prior to those, you will need to use puppetlabs/stdlibs module along with anchor resource type.This is named “anchor containment pattern”. Let’s look at some code and then digest it, our above declaration with anchor pattern now will look like: 1 anchor['tomcat_start:'] -> 9| •Thirdly if you define a resource within a class – then you can be sure that the resource code will be executed after class starts and before class ends – this is basically called containment of that resource to class. Resources and defined types by default are contained. Now let’s imagine you defined a class A.You included A in another class B and many other places. But puppet does not guarantee that A will be executed within B by default.This means classes by default are not contained and need to be contained explicitly.Why? See footnote! Classes are not contained by default is intentional. Imagine you declared “include class_name” n number of places and puppet had to contain the class everywhere? At the same time when we design a large module, we want to make sure parent class can contain other classes. Creating classes to have logical division is a good practice as we already saw! 1 anchor['tomcat_start:'] -> 2 Class['tomcat::service':] -> 3 anchor['tomcat_end':] 4 # Almost same as 'contain tomcat::service' So here is what is happening: •The class to be contained should be between two anchors.These anchors should be unique within containing class. •You must form relationship between class to be contained and anchors such that there is one anchor before and after the contained class (-> forms this relationship) •Anchor code does not affect the execution – it is only to facilitate the containment!
  • 10. www.vishalbiyani.comLearning Puppet 1 Node classification and how to add relevant infrastructure code to a node What did we learn? 2 How to create module, it’s basic structure and how to it all forms together 3 Good practices for class design & parameterization of classes for configurable values. 10| 4 Calling classes from a module for a given node & configuring it as per need 5 Containment of classes & why anchor pattern is needed for certain versions of puppet