Table of Contents

Overview

Puppet uses its own language in order to assure that changes a properly propagated, in this section, we will use DSL do automate a lot of tasks like:

All that will be accross our infrastructure, which unfortunetely is only 3 servers:

So let's start with the basic understanding of how DSL works. Puppet architecture is comprised by:

Once an object is created it has to go through the chain of release as follows:

Resources

As already explained, Puppet has in-build resources and function, we can describe all in-built resources as so:

List in-build resources

[root@puppetmaster demo]# puppet describe --list
These are the types known to puppet:
augeas          - Apply a change or an array of changes to the  ...
cron            - Installs and manages cron jobs
exec            - Executes external commands
file            - Manages files, including their content, owner ...
filebucket      - A repository for storing and retrieving file  ...
group           - Manage groups
host            - Installs and manages host entries
mount           - Manages mounted filesystems, including puttin ...
notify          - Sends an arbitrary message, specified as a st ...
package         - Manage packages
resources       - This is a metatype that can manage other reso ...
schedule        - Define schedules for Puppet
scheduled_task  - Installs and manages Windows Scheduled Tasks
selboolean      - Manages SELinux booleans on systems with SELi ...
selmodule       - Manages loading and unloading of SELinux poli ...
service         - Manage running services
ssh_authorized_key - Manages SSH authorized keys
sshkey          - Installs and manages ssh host keys
stage           - A resource type for creating new run stages
tidy            - Remove unwanted files based on specific crite ...
user            - Manage users
whit            - Whits are internal artifacts of Puppet's curr ...
yumrepo         - The client-side description of a yum reposito ...
zfs             - Manage zfs
zone            - Manages Solaris zones
zpool           - Manage zpools
[root@puppetmaster demo]#

Let's discuss some of them here.

User

To create a user, we will use a simple resource (e.g. function: user, to ensure that it exist)

Create user

[root@puppetmaster demo]# vi demouser.pp
user { "julienandonov":
  ensure => "present",
}
:wq

Then we can validate the code, for syntax error using the parser:

Check syntax

--If error exists
[root@puppetmaster demo]# puppet parser validate demouser.pp
Error: Could not parse for environment production: Syntax error at 'ensure' (file: /var/tmp/demo/demouser.pp, line: 2, column: 3)
[root@puppetmaster demo]# 

-If no error exists
[root@puppetmaster demo]# puppet parser validate demouser.pp
[root@puppetmaster demo]#

We can test if the application of the change will be possible:

Test

[root@puppetmaster demo]# puppet apply --noop demouser.pp
Notice: Compiled catalog for puppetmaster.example.com in environment production in 0.03 seconds
Notice: /Stage[main]/Main/User[julienandonov]/ensure: current_value 'absent', should be 'present' (noop)
Notice: Class[Main]: Would have triggered 'refresh' from 1 event
Notice: Stage[main]: Would have triggered 'refresh' from 1 event
Notice: Applied catalog in 0.01 seconds

Finally we can apply the change:

Apply

[root@puppetmaster demo]# puppet apply demouser.pp
Notice: Compiled catalog for puppetmaster.example.com in environment production in 0.01 seconds
Notice: /Stage[main]/Main/User[julienandonov]/ensure: created
Notice: Applied catalog in 0.20 seconds
[root@puppetmaster demo]#

We can also see that the user is created on the master server:

Check Results

[root@puppetmaster demo]# id julienandonov
uid=1001(julienandonov) gid=1001(julienandonov) groups=1001(julienandonov)
[root@puppetmaster demo]#

Modify

What if we want to modify the user, let's say put the UID as 7777 and the shell as /bin/sh. Well, we can use the same file with more attributes:

Additional Attributes

[root@puppetmaster demo]# vi demouser.pp
user { "julienandonov":
  ensure => "present",
  uid => "7777",                       <- Specified the Uid
  shell => "/bin/bash",                <- Specified the shell
}
:wq

As before, we can Check, test and apply the patch:

Check & Test & Apply the changes

--Check Syntax
[root@puppetmaster demo]# puppet parser validate demouser.pp

--Perform Dry run
[root@puppetmaster demo]# puppet apply --noop demouser.pp
Notice: Compiled catalog for puppetmaster.example.com in environment production in 0.01 seconds
Notice: /Stage[main]/Main/User[julienandonov]/uid: current_value 1001, should be 7777 (noop)
Notice: Class[Main]: Would have triggered 'refresh' from 1 event
Notice: Stage[main]: Would have triggered 'refresh' from 1 event
Notice: Applied catalog in 0.01 seconds

--Apply changes
[root@puppetmaster demo]# puppet apply demouser.pp
Notice: Compiled catalog for puppetmaster.example.com in environment production in 0.01 seconds
Notice: /Stage[main]/Main/User[julienandonov]/uid: uid changed 1001 to 7777
Notice: Applied catalog in 0.07 seconds

--Verify
[root@puppetmaster demo]# id julienandonov
uid=7777(julienandonov) gid=1001(julienandonov) groups=1001(julienandonov)
[root@puppetmaster demo]#

File

The File resource is as easy to be used as user. Let's see which attributes are in that resource:

Check File Attributes

[root@puppetmaster demo]# puppet describe file
*******************************************************
Parameters
----------
- **owner**
    The user to whom the file should belong.  Argument can be a user name or
    auser ID.
- **group**
    Which group should own the file.  Argument can be either a group
    name or a group ID.
- **ensure**
    Whether the file should exist, and if so what kind of file it should be.
    Possible values are `present`, `absent`, `file`, `directory`, and
    `link`.
- **mode**
    The desired permissions mode for the file, in symbolic or numeric
    notation. This value **must** be specified as a string;

There are many more, but we will focuse only on these 4. So let's create our DSL file:

Create DSL File

[root@puppetmaster demo]# vi demouser.pp
user { "julienandonov":
  ensure => "present",
  uid => "7777",
  shell => "/bin/bash",
}
:wq

Now, we can check the syntax, dry run and finally apply the changes:

Syntax Check, Dry Run & Apply

--Check Syntax
[root@puppetmaster demo]# puppet parser validate demofile.pp

--Dry Run
[root@puppetmaster demo]# puppet apply --noop demofile.pp
Notice: Compiled catalog for puppetmaster.example.com in environment production in 0.01 seconds
Notice: /Stage[main]/Main/File[/var/tmp/testfile]/ensure: current_value 'absent', should be 'present' (noop)
Notice: Class[Main]: Would have triggered 'refresh' from 1 event
Notice: Stage[main]: Would have triggered 'refresh' from 1 event
Notice: Applied catalog in 0.02 seconds

--Apply Changes
[root@puppetmaster demo]# puppet apply demofile.pp
Notice: Compiled catalog for puppetmaster.example.com in environment production in 0.01 seconds
Notice: /Stage[main]/Main/File[/var/tmp/testfile]/ensure: created
Notice: Applied catalog in 0.01 seconds

--Verify Results
[root@puppetmaster demo]# ls -lart /var/tmp/testfile
-rwxrwxrwx. 1 julienandonov julienandonov 0 Nov 20 05:20 /var/tmp/testfile
[root@puppetmaster demo]#