The typical puppet model consists of a puppet master and the puppet clients.
That said, it is possible to skip the puppet master completely and just use the puppet clients by themselves. (Called masterless puppet modules).
To do this, you wrap the puppet apply
command in a bash script.
Here is a simple example of a masterless puppet manifest which compiles the latest version of redis from source, then creates an RPM.
https://github.com/spuder/fpm-redis
Here is a more complex example we use at my company called builder. You can watch the presentation about it here:
https://www.youtube.com/watch?v=EFByexKKkIE
Builder is just a script that any developer can apply on any VM which will automatically install a product suite via puppet. It is closed source, but I will try my best to explain the basic architecture.
It is written so that when the developer executes builder, they are prompted for which version and edition of the software they want to install.
$ sudo ./builder.sh
"Welcome to Builder"
1) Enterprise
2) Basic
3) Quit
Please select an edition: 1
"You have selected: Enterprise"
1) 7.5.0
2) 7.6.0
3) 7.7.0
4) 7.8.0
5) Quit
Please select a release: 2
"You have selected 7.6.0, applying manifests"
One of the advantages of wrapping your puppet manifest in a bash script like this, is that you can simply write your own facter variables which can later be used. Looking at the simple example from github/spuder/fpm-redis :
Prepend the variables with an upper case 'FACTER'
cat fpm-redis
#!/bin/bash
export FACTER_REDIS_VERSION='2.8.8'
puppet apply ./manifests/init.pp
The puppet manifest can then refer to the lowercase variable (the word 'FACTER_' is stripped off automatically).
cat ./manifests/init.pp
class foo {
file { "${::redis_version}":
ensure => file,
content => 'foo'
}
}
include foo
Going back at the builder code, it is modularized so that there is a directory for each product that needs to be installed. This way you can define property files.
$ tree /tmp/builder
|
build
\_ Enterprise.prop
\_ Basic.prop
|
packages
\_ java_7
\_ manifests
\_ init.pp
\_ java_6
\_ manifests
\_ init.pp
\_ foo
\_ manifests
\_ init.pp
|
builder.sh
The property files are just bash script that contain environment variables, and also a list of puppet manifests to apply. Sometimes packages need to be installed in a particular order, so they are divided into pre and post operations.
$ cat Enterprise.prop
PRE_APPLY_LIST= "build/java_6/manifests/init.pp \
build/foo/manifests/init.pp"
POST_APPLY_LIST= "build/foobar/manifests/init.pp"
export FACTER_FOO='bar'
export FACTER_DB_PASSWORD='correct horse battery staple'
$ cat Basic.prop
PRE_APPLY_LIST= "build/java_7"
export FACTER_HERP='derp'
Going back to the menu prompt mentioned earlier. Builder generated the list of menu options by iterating over the build directory.
$ cat /tmp/builder.sh
# prompt the user for which product
OPTIONS=`ls build/*.prop`
for opt in $OPTIONS
do
PP_APPLY=$opt
break
done
# import the variables from the property file
source $PP_APPLY
# install the desired packages
puppet apply $PRE_APPLY_LIST
puppet apply $POST_APPLY_LIST
This is a great way to leverage the advantages of puppet, without needing a puppet master.
ssh
via public keys and have a server-side script loop over your client nodes installing the Puppet client on each. – Joseph R. May 16 '14 at 16:45