summaryrefslogtreecommitdiffstats
path: root/documentation/big-picture.page
blob: a828e25c2b343ab1400f20f7a12b7391f8703ef7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
---
inMenu: true
title: The Big Picture
---

# Big picture

Puppet is a **declarative language** for expressing system configuration, a
**client and server** for distributing it, and a **library** for realizing the
configuration. 

Rather than approaching server management by automating current techniques,
Puppet reframes the problem by providing a language to express the
relationships between servers, the services they provide, and the primitive
objects that compose those services.  Rather than handling the detail of how
to achieve a certain configuration or provide a given service, Puppet users
can simply express their desired configuration using the abstractions they're
used to handling, like ``service`` and ``node``, and Puppet is responsible for
either achieving the configuration or providing the user enough information to
fix any encountered problems.

This document is a supplement to the [Introduction](introduction.html) and it is assumed that
readers are familiar with the contents of that document.

# Less Detail, More Information

A correct configuration must obviously provide the appropriate details, but a
configuration tool should understand that the details are generally the easy
part.  The hard part of system configuration is understanding the
complex relationships between services and the objects that comprise those
services.  One of the primary goals of Puppet is to allow users to push the
details into lower levels of the configuration and pull the relationships into
the foreground.

For instance, take a typical Apache web server deployment.  Puppet allows one
to encapsulate all of the primitives necessary for successful deployment into
one reusable object, and that object can even be abstracted to support
multiple apache versions.  Here's how a simple apache definition might look
for a Debian server (Debian uses ``apache`` for 1.x versions and ``apache2``
for 2.x versions):

    define apache(version, conf, user, group) {
        # abstract across apache1 and apache2
        $name = $version ? {
            1 => "apache",
            2 => "apache2"
        }
        package{ $name:
            install => true
        }

        file { $conf:
            user => $user,
            group => $group,
            source => $conf
        }

        # we want the service to restart if the config file changes
        # or if the package gets upgraded
        service { $name:
            running => true,
            requires => [file[$conf], package[$name]]
        }
    }

Now, with this configuration, one can easily set multiple servers up to run
different versions of apache.  The key benefit here is that the information
necessary to run apache correctly is separated from the decision to do so on a
given host.  For example:

    # import our apache definition file
    import "apache"

    node server1 {
        # use a locally-available config file
        apache {
            version => 1,
            conf => "/nfs/configs/apache/server1.conf",
            user => www-data,
            group => www-data
        }
    }

    node server2 {
        # use a config that we pull from elsewhere
        apache {
            version => 2,
            conf => "http://configserver/configs/server2/httpd.conf"
            user => www-data,
            group => www-data
        }
    }

Notice that our node configuration only specifies 1) that a given server is
running Apache, and 2) the information necessary to differentiate this
instance of apache from another instance.  If a given detail is going to be
the same for all apache instances (such as the fact that the service should be
running and that it should be restarted if the configuration file changes),
then that detail does not have to be specified every time an Apache instance
is configured.

# Describing Configuration

Puppet's declarative language separates the "what" of the configuration from
the "how".  The "how" is pushed into the library, which generally provides the
ability to manage a given entity on multiple platforms, isolating the Puppet
user from platform details.

### Language Example: Class Hierarchy Using Inherit

Inheritance can be used to override default values defined in base classes:

    class base {
        file { "/etc/sudoers":
            owner => root,
            group => root,
            mode => 440
        }
    }

    # FreeBSD has a "wheel" group instead of a "root" group
    class freebsd inherits base {
        file { "/etc/sudoers":
            group => wheel,
        }
        
    }

# Distributing Configuration

The Puppet framework Library consists of a client and server. 

(picture/diagram: client, server, site-config -> host-config)

A Puppet server is aware of the full configuration. As some component's
configuration aspects depend on the configuration of other components (e.g. the
firewall config includes the ports used by webservers), generating
configuration for a component requires being aware of full configuration.

A Puppet client that runs on a specific host (or perhaps the same host as its
Puppet Server) is generally only concerned with the components to be configured
on that host.

Puppet Clients normally request or "pull" configuration from their server. The
Server processes the configuration request for the host using a pre-generated
tree model of the classes and definitions from the site-config. 

When configuration needs to be "pushed" to the clients, the Server can be asked
to attempt to trigger each client to request "pull" a new host configuration. 

Example: Puppet server, library

You can read more about the Puppet language in the Introduction_.  (Add link to
user manual, when it's written)


# Realizing the Configuration

The Puppet Client Library contains the component knowledge of how to reach
desired states and configurations for several objects: File, Package, etc.

Example: Puppet Client, library:

 ...todo: file: transfer, mode, ownership...

You can read more about the Puppet language in the Introduction_.
(Add link to user manual, when it's written)

Some components such as the webserver and firewall, from the simple-website
example, require additional code to reach "closure". "Closure" is when the
component is entirely responsible for implementing its own configuration.

Much as database applications abstract the mechanics of storing, indexing, and
searching their data, a component ideally should abstract the specifics of how
to store, confirm, and implement its requested configuration.

*$Id$*