Now lets setup a initial puppet master server. This entry will only show a basic setup to get you started. I'll add more advanced tutorials after this :)
Let's get started!
The initial file structure under /etc/puppet
[root@puppetmaster puppet]# ls -l
-rw-r--r-- 1 root root 4133 May 22 19:29 auth.conf
-rw-r--r-- 1 root root 1462 May 22 19:27 fileserver.conf
drwxr-xr-x 2 root root 4096 May 22 19:29 manifests
drwxr-xr-x. 2 root root 4096 May 22 19:29 modules
-rw-r--r-- 1 root root 853 Jun 4 09:40 puppet.conf
Now lets start the puppet master, and confirm that it's running.
[root@puppetmaster test]# /etc/init.d/puppetmaster start
Starting puppetmaster: [ OK ]
[root@puppetmaster test]# ps aux | grep puppet
puppet 15012 0.4 2.2 141272 42484 ? Ssl 12:58 0:00 /usr/bin/ruby /usr/bin/puppet master
root 15017 0.0 0.0 103244 828 pts/0 S+ 12:58 0:00 grep puppet
For this tutorial we will run the server and agent on the same server. Next, we will be invoking the puppet agent manually with the following command,
[root@puppetmaster test]# puppet agent --test --server puppetmaster.domain.co.za
Info: Retrieving plugin
Info: Caching catalog for puppetmaster.domain.co.za
Info: Applying configuration version '1370343823'
Notice: Finished catalog run in 0.07 seconds
From this you can see that nothing has been applied to this server. We need to setup the manifests and create a test module to see any action.
Now we will focus on the manifests and modules folders. The rest of the configs can be left at default configurations.
The Manifests
Manifests contains the site, included modules and node (clients) configurations. These configurations can be located in one file or be split up into multiple files. The approach that we are going to follow is having the files split. This way the directory structure looks neater and cleaner.
Under the manifest directory the following files must be created,
site.pp
#
#site.pp
#
#
# First file read, contains site configuration for puppet master
#
#########
#import modules and nodes
import "modules"
import "nodes"
filebucket { main: server => puppetmaster}
#global defaults
File {backup => main}
Exec {path => "/usr/bin:/usr/sbin:/bin:/sbin"}
This file shows the imports of the bottom two files, modules and nodes, plus it sets defaults for backing up of files and finally sets the default path environment for when we want to execute linux commands from puppet.
modules.pp
#
#modules.pp
#
#import test modules
import "test"
In this file you import modules that has been created under the modules folder, we will create the test module a little bit later.
nodes.pp
#
#nodes.pp
# This file contains all the configurations for nodes
#
# Future node definition.
This file is used to add modules to the servers that we need to specify later. We will leave this blank for now. Lets continue to create our first puppet module.
The Modules
Firstly we need to create the module structure. We can do it manually or have puppet create the structure for us. In this example we will create the necessary directories.
[root@puppetmaster modules]# mkdir -p test/{manifests,templates,files}
[root@puppetmaster modules]# ls -l test/
total 12
drwxr-xr-x 2 root root 4096 Jun 4 12:08 files
drwxr-xr-x 2 root root 4096 Jun 4 12:08 manifests
drwxr-xr-x 2 root root 4096 Jun 4 12:08 templates
The
files directory contains files associated with this module, if can be static configuration files, scripts that you need to have with your module, anything that you module requires to work. For our example we will add the script called
test-script.sh.
This module will not work without a manifest, the manifest tells puppet what to do. So in our manifests we will have puppet deploy the
test-script.sh and execute it for us.
init.pp
#init.pp
class test {
file{"/tmp/test_script.sh":
owner => root,
group => root,
mode => 755,
source => "puppet:///modules/test/test_script.sh",
ensure => file;
}->
exec{"/tmp/test_script.sh":
cwd => "/tmp",
}
# this "->" means that exec must only run if the file exist. the above can also be written as
#
#file{"/tmp/test_script.sh":
# owner => root,
# group => root,
# mode => 755,
# source => "puppet:///modules/test/test_script.sh",
# ensure => file;
#}
#exec{"/tmp/test_script.sh":
# cwd => "/tmp",
# requires => File["/tmp/test_script.sh"]
#}
# test both. This is just a small introduction into inheritance in puppet.
$hn = $fqdn
$ip = $ipaddress_eth0
$virtual = $is_virtual
$dist = $lsbdistdescription
file{"/tmp/info.txt":
owner => nobody,
group => root,
mode => 644,
content => template("test/info_txt.erb"),
}
}
Last folder called templates will be used to keep configuration templates. Sometimes you want to have different configurations depending on the server or setup. A good example of template usage is when you have to manage many virtual hosts under apache or nginx. We will visit this at a later stage.
For now lets create a small template under templates that will generate a file containing the server name and ip address. Get the file here
info_txt.erb
Templates are called from the manifests. Review
init.pp and look for a file directive called
/tmp/info.txt on how to invoke a template.
So finally we have a test module. The directory structure should finally look like this,
[root@host modules]# ls -l */*
test/files:
total 4
-rw-r--r-- 1 root root 83 Jun 4 12:49 test_script.sh
test/manifests:
total 4
-rw-r--r-- 1 root root 772 Jun 4 12:49 init.pp
test/templates:
total 4
-rw-r--r-- 1 root root 75 Jun 4 12:49 info_txt.erb
At this point if you run puppet agent again, nothing will be applied to the current host. We now need to setup the node.pp to tell puppet that this nodes needs the test module applied to it. Let's proceed!
/etc/puppet/manifests/node.pp
#
#nodes.pp
# This file contains all the configurations for nodes
#
node "puppetmaster.domain.co.za" {
class{test:} # apply the test module to this node
}
Now lets run the puppet agent manually again, and test the results.
[root@puppetmaster tmp]# puppet agent --test --server puppetmaster.domain.co.za
Info: Retrieving plugin
Info: Caching catalog for puppetmaster.domain.co.za
Info: Applying configuration version '1370345145'
Notice: /Stage[main]/Test/File[/tmp/test_script.sh]/ensure: defined content as '{md5}1de0c2752e957cafb6380ee53240850b'
Notice: /Stage[main]/Test/Exec[/tmp/test_script.sh]/returns: executed successfully
Notice: /Stage[main]/Test/File[/tmp/info.txt]/ensure: defined content as '{md5}8e344aa44044ed692b510f5f23c672f3'
Notice: Finished catalog run in 0.30 seconds
[root@puppetmaster tmp]# cat info.txt
#info_txt.erb
#Deployed by puppet
fqdn is puppetmaster.domain.co.za
my ip is 192.168.13.253
I am a Virtual Machine
Linux Distro is CentOS release 6.4 (Final)
[root@puppetmaster tmp]# ls -l
total 12
-rw-r--r-- 1 nobody root 159 Jun 4 13:31 info.txt
-rwxr-xr-x 1 root root 83 Jun 4 13:31 test_script.sh
[root@puppetmaster tmp]#
From the top, the notice entries shows you that the script has been deployed and successfully executed. Next template file was created with the content that we defined. Now we test that the template added the correct information by catting the file, and the final ls -l shows the files that's been created.
And that's it for the initial setup of a puppet master. Remember that the puppet master and client is on the same server. Next time I will show you how to add a puppet client to a puppet master.
Cheers,
Dan