Puppet installation and configuration. Centralized setup with Puppet


Not long ago, on the pages of the magazine, we looked at the Cfengine remote configuration management system for UNIX machines, which greatly simplifies the life of a system administrator by automating the steps to configure many network nodes. But, no matter how convenient Cfengine is, it has many disadvantages that a system called Puppet does not have.

Imagine yourself in the role of a system administrator, responsible for maintaining the functionality of hundreds of machines running UNIX-type operating systems. Each of them requires configuration, periodic updating and monitoring, and it is assumed that many of them perform similar functions.

Two thirds are workstations, a few more are routers, and the rest are several web servers and data storage. Question: how to manage all this business? The simplest answer is to simply connect to each of them using SSH and make the necessary changes. However, this method has two problems. Firstly, it is very labor-intensive. Secondly, the administrator will constantly have to perform many monotonous actions (for example, to update OpenOffice.org on all workstations, you will have to execute the same commands several dozen times). You can try to avoid this problem by writing several scripts that will connect to each machine themselves and execute pre-written commands. But here, too, problems await you.

Scripts will constantly have to be modified to adapt them to each task; Scripts will have to take into account differences in operating systems and versions, and they will have to be debugged for a long time before being applied to running machines. In general, not comme il faut. The correct answer is to use so-called remote configuration management systems, the best known representatives of which are the open source systems Cfengine and Puppet. Such systems take on all the responsibilities for bringing the machine configuration to the desired form, requiring the administrator only to describe the final state of the system in a special language (for example, a description of which packages should be installed in the OS, which lines should be added to configuration files, which commands must be executed, etc.). After this, all nodes themselves will receive information about the required state from the server and auto-configure the system. Thanks to this mechanism, new machines can be fully configured without human intervention, and existing ones can be reconfigured by adding just a few lines to the state description.

Puppet?

We have already devoted an entire article to the Cfengine system, so today we will focus on the Puppet system, which can well be called its ideological successor. Puppet was developed by Luke Kanies, who got tired of Cfengine's limitations and decided to create a better version from scratch. If you've already used Cfenfine, you'll probably find Puppet a more convenient and powerful system. Puppet's state language is more high-level and flexible, so administrators don't have to worry about things like writing separate rules for each OS type or detailing how to perform trivial actions. Puppet allows its master to focus on what he wants to do, instead of how to do it (for example, to install a specific package on any of the system's supported OS, you just need to write literally a few lines saying "Install this program" instead of describing the commands, necessary for its installation). Puppet is written in a simple Ruby language, which makes it easy to adapt it to a specific task and expand its functionality (a flexible system of plugins is provided).

Additionally, unlike Cfengine's development model, which essentially revolves around one person, Puppet has a large community of enthusiasts who make improvements to the code, share configuration examples, and write documentation.

Overall, Puppet comes across as a more modern and well-designed system. Like Cfengine, it supports almost all modern UNIX-like operating systems (including MacOS X), and can also run in the Cygwin environment on top of Windows. Its dependency list only includes the Ruby interpreter and the Factor tool, so there should be no problems with installation (to be fair, Cfengine's dependency list is even shorter).

Installation

Like Cfengne, Puppet is a client-server system that consists of a control server and slave nodes. The server stores a description of the final states of the nodes (which in Puppet terms is called a manifest) and waits for them to connect. Every half hour (by default), the client connects to the server, receives from it a description of the final state, compares it with the current one and, if it and/or the described state has changed, reconfigures the system, and then goes to sleep. Communication is carried out through an encrypted channel, so attacks based on substitution of the state description are excluded (but if an attacker takes over the server, then all nodes will be under his control).

Puppet is included in the repositories of all popular distributions, so installing it should not be difficult. For example, on Debian/Ubuntu the Puppet client can be installed like this:

$ sudo apt-get install puppet

And the server is like this:

$ sudo apt-get install puppet puppetmaster

The client and server configuration files are stored in the /etc/puppet directory. The most important of these is the file /etc/puppet/manifests/site.pp, which contains the manifest.

It stores a description of the states and should only exist on the server. For ease of debugging, let’s add a simple configuration to it:


class passwd(
file("/etc/passwd":
owner => root,
group => root,
mode => 644,
}
}
node default(
include passwd
}

These lines describe a condition where the owner of the /etc/passwd file must be root and its permissions are set to 644. We'll take a closer look at the manifest file format in the next section. The second most important file is /etc/puppet/puppet.conf. It sets the configuration of the server and clients, so it must be present on all machines organized in the Puppet network. In Ubuntu, this file contains the minimum necessary and in most cases sufficient settings. Below they are given with comments:

# vi /etc/puppet/puppet.conf
# Standard directory paths
logdir=/var/log/puppet
vardir=/var/lib/puppet
ssldir=/var/lib/puppet/ssl
rundir=/var/run/puppet
# Facter tool location,
# used to obtain information about the OS
factpath=$vardir/lib/facter
# Synchronize plugins
# (installed plugins on the server - they are copied to clients)
pluginsync=true
# Catalog with templates (read about them below)
templatedir=$confdir/templates
# Synchronization with etckeeper
# (who knows, will understand, others don’t need it)
prerun_command=/etc/puppet/etckeeper-commitpre
postrun_command=/etc/puppet/etckeeper-commitpost

The configuration file can include a large number of different options, information about which can be obtained by generating a default config:

$ sudo puppetmasterd -genconfig > /etc/puppet/
puppetd.conf.default

The default client config is generated using another command:

$ sudo puppet -genconfig > /etc/puppet/puppetd.conf.default

The files fileserver.conf and auth.conf are used to configure the file server (read about this in the “File Server” section) and authentication. There is no point in touching them yet. Once configuration is complete, the Puppet server must be restarted:

$ sudo /etc/init.d/puppetmaster restart

After which he will be ready to accept customer requests. However, without a signed certificate, no client will be able to receive the manifest from the server and configure the machine.

Therefore, we must run the Puppet clients in test mode so that they can submit their certificates to the server for signing (by the way, this can be done on all machines at the same time using the shmux tool):

$ sudo puppetd -server puppet-server.com -verbose -test

We return to the server and receive a list of certificates ready for signing:

$ sudo puppetca --list

Select a host from the list and sign its certificate:

$ sudo puppetca --sign nomad.grinder.com

Or we sign everything at once:

$ sudo puppetca --sign --all

Now you can launch clients in combat mode. But first you need to enter the name of the Puppet server in the configuration file (by default its name is just puppet):

$sudo su
# echo "" >> /etc/puppet/puppet.conf
# echo "server=puppet-server.com" >> /etc/puppet/puppet.conf
# exit

Launching clients:

$ sudo /etc/init.d/puppet start

State description language

As mentioned above, Puppet uses its own language for describing the final state of the operating system, with the help of which the system administrator specifies what form the OS components should be brought to in order for it to achieve the desired state. This is a rather complex language, which, nevertheless, is much simpler than any programming language. If you are at least superficially familiar with the bash scripting language, you will easily understand the Puppet language. The key element of the language is the resources that are used to describe what form one of the OS components should be converted to. For example, the following simple resource describes the desired state of the /etc/passwd file:

# vi /etc/puppet/manifests/site.pp
file("/etc/passwd":
owner => "root"
}

Here file is the resource type. There are several dozen of them in total, ranging from resources that manage files, as in this example, to packages and services. The line /etc/passwd is the name of the resource.

In the case of the file type, the name is the same as the path to the file, but in some other types the name can be arbitrary. The line owner => "root" describes setting the owner attribute to root, that is, it says that the owner of the specified file must be an administrator.

Each type of resource has its own set of attributes available for modification, plus there are special meta attributes that can be used in any resource. One of the important qualities of resources is the ability to link to them. This can be used to form dependency chains. The following entry creates the /etc/group resource, which depends on the /etc/passwd resource (dependencies are specified using the require meta attribute):

# vi /etc/puppet/manifests/site.pp
file("/etc/group":
require => File["/etc/passwd"],
owner => "root",
}

This means that the /etc/group resource can be configured (brought to the described form) only when the /etc/passwd resource is configured. Resources can be grouped into collections of resources called classes. This is necessary in order to combine resources that are similar in meaning and type of task performed into one abstract resource. For example, for convenience, we could combine the installation and launch of the nginx web server into one abstract resource of the same name:

# vi /etc/puppet/manifests/site.pp
class nginx(
package("nginx":
ensure => installed
}
service("nginx":
ensure => running,
require => Package["nginx"],
}
}

Here, the package resource type is used to install the nginx package on the system, and service is used to launch the service of the same name. With require we force the system to start the service only if the package has been successfully installed. The convenience of classes is that they can also be included depending on:

# vi /etc/puppet/manifests/site.pp
service("squid":
ensure => running,
require => Class["nginx"],
}

As in real OOP languages, classes can inherit from each other and override attributes:

# vi /etc/puppet/manifests/site.pp
class passwd(
file("/etc/passwd":
owner => "root",
group => "root",
}
}
class passwd-bsd inherits passwd (
File["/etc/passwd"] ( group => "wheel" )
}

Here, the passwd-bsd class inherits from passwd to override the group attribute of the /etc/passwd resource (on BSD systems, /etc/passwd belongs to the wheel group, so we created a separate class for such systems). Later we will look at a more correct and obvious way to select alternative attribute values ​​using conditions.

Variables are one of the integral components of any programming language, and Puppet has them too. Variables begin with a $ sign and can contain any number, string, or boolean value (true, false):

$want_apache = true
$apache_version = "2.2.14"

One of the most powerful variable-related features of Puppet is its integration with the facter machine information tool. This utility returns all machine-specific information in the form of key-value pairs, which are turned into variables of the same name in Puppet. Together with conditional instructions in the Puppet language, they can be used to alter resource attributes depending on the properties of the machine.

For example, the passwd class described above can be easily rewritten to automatically select an attribute depending on the OS type (without the class itself being needed):

# vi /etc/puppet/manifests/site.pp
file("/etc/passwd":
owner => "root",
group => $kernel ? (
Linux => "root",
FreeBSD => "wheel",
},
}

Depending on which OS this fragment of the manifest will be analyzed on, the value of the group attribute will be either root or wheel. In addition to the conditional operator, the Puppet language also supports the case selection operator, which can be used to create a particular resource depending on the value of a variable:

# vi /etc/puppet/manifests/site.pp
case $operatingsystem (
redhat: (service("httpd": ensure => running))
debian: (service("apache": ensure => running))
default: ( service ( "apache2": ensure =>
running))
}

This code defines different variants of a resource of type service depending on the operating system (service names may differ between Linux distributions, so which service Puppet should run must be specified individually for each of them).

The default option is used if the value of the variable does not match any of the previous options. In addition to the previously discussed file, package, and service resource types, Puppet supports a large number of other resource types, including those created by third-party developers. Their detailed description, including examples, supported attributes and features, can be found in the official documentation - http://docs.puppetlabs.com/references/stable/type.html. Below is a list and brief description of the most used ones:

Popular Puppet resource types

  • cron - manage cron jobs
  • exec - run scripts and commands
  • file - file management
  • filebucket - file backup
  • group - group management
  • host - manage entries in the /etc/hosts file
  • interface - configuration of network interfaces
  • mount - mounting file systems
  • notify - send a message to the Puppet log file
  • package - package management
  • service - service management
  • sshkey - manage SSH keys
  • tidy - deleting files depending on conditions
  • user - user management
  • zones - Solaris zone management

The second most important element of the Puppet language after resources is nodes. With their help, the administrator can describe to which machines certain resources and classes should be applied. In other words, it is a way to specify an individual configuration for each of the machines participating in the Puppet network. The simplest example of a node is given at the beginning of the article in the “Installation” section:

# vi /etc/puppet/manifests/site.pp
node default(
include passwd
}

This is the definition of the default node, which includes the passwd resource/class. The name default means "all other nodes", so the passwd resource/class defined somewhere above will be configured on each of them. The include keyword is used here for convenience; in fact, all classes and resources can be described directly in the node description, but this is not recommended. In addition to default, in the node name you can specify the network name of the machine (then all resources described in the node will be configured only on this machine), or an arbitrary name (then this node can be inherited by another node). To understand how this all works together with classes and resources, let's look at an example of a ready-made Puppet manifest used to configure two network machines (a web server and an NTP server):

# vi /etc/puppet/manifests/site.pp
# Installing and running an SSH server
class sshd(
package ( openssh-server: ensure => installed )
service(sshd:
name => $operatingsystem ? (
fedora => "sshd",
debian => "ssh",
default => "sshd",
},
enable => true,
ensure => running,
}
}
# Install and run Apache
class httpd(
package ( httpd: ensure => installed )
service(httpd:
enable => true,
ensure => running,
}
}
# Installing and starting an NTP server
class ntpd(
package ( ntp-server: ensure => installed )
service (
ntp-server:
enable => true,
ensure => running,
}
}
# The base node, used only as the parent of all others
node base(
include sshd
}
# The node where the web server will be located
node web.server.com inherits base (
include httpd
}
# NTP server node
node ntp.server.com inherits base (
include ntpd
}

This seemingly simple configuration does quite a lot: it gets Apache installed and running on the machine at web.server.com and an NTP server installed and running on the machine. ntp.server.com. Additionally, both machines install an SSH server. This configuration is unlikely to suit even one administrator; it will have to be seriously improved in order to teach how to properly configure servers, receive fresh configs and other files from the main Puppet server.

However, it clearly shows the power of Puppet. Using a simple config, we made the machines install and run the necessary software themselves and maintain it in working order (if the server crashes, Puppet itself will reconfigure to bring the systems to the required state).

File server

Many remote administration tasks cannot be solved without copying additional files to the machines. These can be pre-prepared configs, web pages for Apache, packages not in the official repository, and much more. To ease the process of transferring these files to remote hosts, Puppet includes a file server.

File server settings are stored in the /etc/puppet/fileserver.conf file. To force Puppet to serve the contents of a specific directory to clients, you need to put a few lines in it:

# vi /etc/puppet/fileserver.conf
path = /var/puppet/files
allow *.server.com

These two lines indicate that the /var/puppet/files directory should be accessible to all hosts in the server.com domain. In addition, we can specify the full domain name of a permitted machine or its IP address, and also cut off unwanted ones using the deny directive. Any file in that directory can then be moved to the client using the file resource. For example:

# vi /etc/puppet/manifests/site.pp
file("/etc/httpd/conf/httpd.conf":
source => "puppet://httpd/httpd.conf",
mode => 644,
}

The httpd.conf file, located on the server in the /var/puppet/files/httpd directory, will be copied to the target machine along the path specified in the resource name.

conclusions

In this article, we've covered a very small portion of Puppet's capabilities. In fact, this is a complex system, which can only be fully described on the pages of a book. At the same time, Puppet is very easy to configure and maintain, especially since you can find a lot of examples of its configuration on the Web.

Info

  • Puppet uses the HTTP protocol, so it can be run under a web server to improve performance.
  • Puppet can be used to auto-configure and maintain a single local machine.
  • By combining Puppet, network OS installation (pxe-install), and self-building installation images, you can create a completely self-configuring network of machines that can be deployed with just one command.
  • Many large companies use Puppet in their work, such as Google, Fedora Project, Stanford University, Red Hat, Siemens IT Solution and SugarCRM.

Links

  • http://docs.puppetlabs.com - Puppet Documentation
  • http://docs.puppetlabs.com/guides/language_tutorial.html - Complete description of the Puppet language
  • http://docs.puppetlabs.com/references/stable/type.html - Resource types

Puppet is a cross-platform framework that allows system administrators to perform common tasks using code. The code allows you to perform various tasks from installing new programs to checking file permissions or updating user accounts. Puppet superior not only during the initial installation of the system, but throughout the entire life cycle of the system. In most cases puppet used in client/server configuration.

This section shows installation and configuration Puppet in a client/server configuration. This simple example demonstrates how to install Apache using Puppet.

Installation

For installation Puppet enter in terminal:

Sudo apt-get install puppetmaster

On the client machine(s), enter:

Sudo apt-get install puppet

Settings

Before setting up puppet you might want to add an entry DNS CNAME For puppet.example.com, Where example.com- this is your domain. Default clients Puppet check DNS for puppet.example.com as the puppet server name ( Puppet Master). See Domain Name Service for additional details on using DNS.

If you don't intend to use DNS, you can add entries to the /etc/hosts file on the server and client. For example, in the /etc/hosts file Puppet server add:

127.0.0.1 localhost.localdomain localhost puppet 192.168.1.17 meercat02.example.com meercat02

On every Puppet In the client, add an entry for the server:

192.168.1.16 meercat.example.com meercat puppet

Replace the IP addresses and domain names from the example with your actual server and client addresses and names.

Now let's set up some resources for apache2. Create a file /etc/puppet/manifests/site.pp containing the following:

Package ( "apache2": ensure => installed ) service ( "apache2": ensure => true, enable => true, require => Package["apache2"] )

Node "meercat02.example.com" ( include apache2 )

Replace meercat02.example.com to your current name Puppet client.

The final step for this simple Puppet server is to restart the service:

Sudo /etc/init.d/puppetmaster restart

Now on Puppet everything is configured on the server and it’s time to configure the client.

First, let's configure the service Puppet agent to launch. Edit /etc/default/puppet, replacing the value START on yes:

Sudo /etc/init.d/puppet start

Let's go back to Puppet server to sign the client certificate using the command:

Sudo puppetca --sign meercat02.example.com

Check /var/log/syslog for any configuration errors. If everything went well, the package apache2 and its dependencies will be installed to Puppet client.

This example is very simple and does not show many of the features and benefits. Puppet. For more information see

Some time ago, the list of servers in my bookmarks exceeded 200. As the number of servers increases, deploying any new configuration or installing new packages wastes a huge amount of time. So I decided to use puppet.
Puppet(English puppet) is a cross-platform client-server application that allows you to centrally manage the configuration of operating systems and programs installed on several computers. Puppet is written in the Ruby programming language.

They also say that puppet is a remote configuration management system, the most famous representatives of which are the open systems Cfengine and Puppet.

After reading the reviews, I decided to use puppet.

Puppet server installation and configuration:
Installing a puppet server:
Install puppet-server on OpenSuSE 11.4:

zipper in puppet-server

Let's change the server name to puppet:
/etc/HOSTNAME:

The DNS record must resolve to 127.0.0.2
cat /etc/hosts:

127.0.0.2 puppet.site puppet

Let's give the user rights puppet:

Let's start the Puppet Master service:

rcpuppetmasterd start

Let's add the launch of the puppet daemon to startup:

chkconfig -a puppetmasterd

Setting up a puppet server:
Let's define the directory where files will be stored that puppet-server will transfer to client machines in manifests of the file type.

vim /etc/puppet/fileserver


path /etc/puppet/files
allow *

mkdir /etc/puppet/files

chown -R puppet:puppet /etc/puppet/files

We will create a file of any content for deployment and testing on clients

touch /etc/puppet/files/puppettesting

Let's restart the puppet server:

rcpuppetmasterd restart

Puppet uses its own language for describing the final state of the operating system, with the help of which the system administrator indicates to what form the OS components should be brought in order for it to achieve the desired state. The state may mean the presence of a specific file, folder, running services, installed packages, updates, and more. All state settings are described in files or manifests, which are located in the directory: /etc/puppet/manifests. These files have names like *.pp.

Let's create the simplest manifesto:
/etc/puppet/manifests/1.file.pp:

file("/tmp/puppettetesting":
source => "puppet:///files/puppettesting",
}

To use this manifest:
puppet apply 1.file.pp

Installing and configuring the puppet client:

zipper in puppet

Let's give puppet rights to the user:

chown -R puppet.puppet /var/lib/puppet/

To establish a connection with the puppet server, the puppet client sends a request to confirm the certificate; after this request is confirmed on the server, the puppet client will begin to use the manifests intended for it. We will send a request to confirm the certificate:

On the server we can see what confirmation requests are pending:

"puppet-client.localdomain" (B5:12 :69 :63 :DE:19 :E9:75 :32 :2B:AA:74 :06:F6:8E:8A)

We confirm:

puppetca --sign "puppet-client.localdomain"

It's time to look at the simplest examples of creating manifests:
create a file /etc/puppet/manifests/site.pp:

node default(
file("/tmp/puppettetesting":
source => "puppet:///files/puppettesting",
}
service("ntp":
ensure => running,
enable => true ,
}
package("htop":
ensure => installed,
}
}

default - apply to all clients
file - this section says to create or overwrite the /tmp/puppettetesting file which is located on the server in the /etc/puppet/files directory
service: check whether the service is running, if not running, then start it, and also add it to startup
package: check if the htop package is installed on the client and if not, install it.

To check, run on the client:

As you can see, on the client, ntp was added to startup, the ntp daemon was launched, the htop package was installed, and the puppettetesting file was copied to the /tmp/ directory

info: Caching catalog for puppet-client.localdomain
info: Applying configuration version "1370163660"
notice: / Stage[ main] // Node[ default] / Service[ ntp] / ensure: ensure changed "stopped" to "running"
notice: / Stage[ main] // Node[ default] / Package[ htop ] / ensure: created
notice: / Stage[ main] // Node[ default] / File[ / tmp/ puppettesting] / ensure: defined content as "(md5)f2171ac69ba86781bea2b7c95d1c8e67"
notice: Finished catalog run in 3.95 seconds

In the next article I will describe more complex examples of creating manifests and the puppet-dashboard web interface.

Popular Puppet resource types
cron- managing cron jobs
exec- running scripts and commands
file- file management
filebucket- file backup
group- group management
host- managing entries in the /etc/hosts file
interface- configuration of network interfaces
mount- mounting file systems
notify- sending a message to the Puppet log file
package- package management
service- service management
sshkey- SSH key management
tidy- deleting files depending on conditions
user- user management
zones- Solaris zone management

Sergey Yaremchuk

Centralized configuration of UNIX systems using Puppet

Managing a large number of UNIX systems cannot be called convenient. To change one parameter, the administrator has to contact each machine; scripts can only partially help, and not in all situations.

It should be recognized that Windows network administrators are still in a more advantageous position. It is enough to change the group policy settings, and after a while all computers on the network, including those with a recently installed operating system, will “learn” about the innovation, if it concerns them, of course. Looking back over the long period of UNIX development, you can see that nothing like this ever caught on. There are solutions like kickstart that help with the initial installation of the operating system, but further development will require significant effort. Commercial solutions, like BladeLogic and OpsWare, solve the problem of automating settings only partially; their main advantage is the presence of a graphical interface, and only large organizations can afford to purchase them. There are, of course, projects that offer free solutions, but throughout their existence they have not been able to create a large community. For example, Cfengine is not very popular among administrators, although, in addition to Linux, it can be used in *BSD, Windows and Mac OS X. This may be due to the relative complexity of creating configurations. When describing tasks, it is necessary to take into account the characteristics of each specific system and manually control the sequence of actions when executing commands. That is, the administrator must remember that for some systems you should write adduser, for others - useradd, take into account the location of files on different systems, and so on. This complicates the process of writing commands by an order of magnitude; it is very difficult to create the correct configuration on the fly, and it is almost impossible to read the created configurations after a while. Despite the GPL license, Cfengine is essentially a one-man project who controls all changes and is not very interested in building an open society. As a result, the capabilities of Cfengine are quite satisfactory for the developer, but for other administrators it is rather an extra headache. To improve Cfengine, various add-ons were created by third-party developers, which often only made the situation worse. The author of several such modules for Cfengine, Luke Kanies, eventually decided to develop a similar tool, but without many of the shortcomings of Cfengine.

Puppet Features

Puppet, like Cfengine, is a client-server system that uses a declarative language to describe tasks and libraries to implement them. Clients periodically (every 30 minutes by default) connect to the central server and receive the latest configuration. If the received settings do not match the system state, they will be executed, and if necessary, a report on the operations performed will be sent to the server. The message server can save it to syslog or a file, create an RRD graph, and send it to the specified e-mail. Additional Transactional and Resource abstraction layers provide maximum compatibility with existing settings and applications, allowing you to focus on system objects without worrying about differences in implementation and description of detailed commands and file formats. The administrator operates only with the object type, Puppet takes care of the rest. Thus, the packages type knows about 17 package systems; the required one will be automatically recognized based on information about the version of the distribution or system, although, if necessary, the package manager can be set forcibly.

Unlike scripts, which are often impossible to use on other systems, Puppet configurations written by third-party administrators will mostly work without problems on any other network. Puppet CookBook already has three dozen ready-made recipes. Puppet currently officially supports the following operating systems and services: Debian, RedHat/Fedora, Solaris, SUSE, CentOS, Mac OS X, OpenBSD, Gentoo and MySQL, LDAP.

Puppet language

To move forward, you must first understand the basic elements and capabilities of the language. Language is one of Puppet's strengths. It describes the resources that the administrator plans to manage and the actions they take. Unlike most similar solutions, Puppet allows the language to simplify access to all similar resources on any system in a heterogeneous environment. A resource description typically consists of a name, type, and attributes. For example, let's point to the /etc/passwd file and set its attributes:

file("/etc/passwd":

Owner => root,

Group => root,

Mode => 644,

Now clients connecting to the server will copy the /etc/passwd file and set the specified attributes. You can define multiple resources in one rule, separating them using a semicolon. But what if the configuration file used on the server differs from the client ones or is not used at all? For example, this situation may arise when setting up VPN connections. In this case, you should point to the file using the source directive. There are two options here; you can, as usual, specify the path to another file, and also using the two supported URI protocols: file and puppet. In the first case, a link to an external NFS server is used; in the second option, an NFS-like service is launched on the Puppet server, which exports resources. In the latter case, the default path is relative to the puppet root directory – /etc/puppet. That is, the link puppet://server.domain.com/config/sshd_config will correspond to the file /etc/puppet/config/sshd_config. You can override this directory using the filebucket directive, although it is more correct to use the section of the same name in the /etc/puppet/fileserver.conf file. In this case, you can restrict access to the service to only certain addresses. For example, let's describe the config section:

Path /var/puppet/config

Allow *.domain.com

Allow 127.0.0.1

Allow 192.168.0.*

Allow 192.168.1.0/24

Deny *.wireless.domain.com

And then we refer to this section when describing the resource:

source => "puppet://server.domain.com/config/sshd_config"

Before the colon is the name of the resource. In the simplest cases, you can simply specify the full path to the file as the name. In more complex configurations it is better to use an alias or variables. The alias is set using the alias directive:

file("/etc/passwd":

Alias ​​=> passwd

Another option for creating an alias is good when you have to deal with different operating systems. For example, let's create a resource that describes the sshd_config file:

file(sshdconfig:

Name => $operatingsystem ? (

Solaris => "/usr/local/etc/ssh/sshd_config",

Default => "/etc/ssh/sshd_config"

In this example, we are faced with a choice. The file for Solaris is specified separately, for all others the file /etc/ssh/sshd_config will be selected. Now this resource can be accessed as sshdconfig, depending on the operating system the desired path will be selected. For example, we indicate that if the sshd daemon is running and a new file is received, the service should be restarted:

service(sshd:

Ensure => true,

Subscribe => File

Variables are often used when working with user data. For example, we describe the location of user home directories:

$homeroot = "/home"

Now the files of a specific user can be accessed as:

$(homeroot)/$name

The $name parameter will be filled with the user's account name. In some cases it is convenient to define a default value for some type. For example, for the exec type it is very common to specify the directories in which it should look for the executable file:

Exec ( path => "/usr/bin:/bin:/usr/sbin:/sbin" )

If you need to point to several nested files and directories, you can use the recurse parameter:

file("/etc/apache2/conf.d":

Source => "puppet:// puppet://server.domain.com/config/apache/conf.d",

Recurse => "true"

Multiple resources can be combined into classes or definitions. Classes are a complete description of a system or service and are used separately:

class linux (

File (

"/etc/passwd": owner => root, group => root, mode => 644;

"/etc/shadow": owner => root, group => root, mode => 440

As in object-oriented languages, classes can be overridden. For example, on FreeBSD the group owner of these files is wheel. Therefore, in order not to completely rewrite the resource, let’s create a new class freebsd, which will inherit the linux class:

class freebsd inherits linux (

File["/etc/passwd"] ( group => wheel );

File["/etc/shadow"] ( group => wheel )

For convenience, all classes can be placed in a separate file, which must be included using the include directive. Definitions can take multiple parameters as arguments, but do not support inheritance and are used when you need to describe reusable objects. For example, let's define the user's home directory and the commands needed to create a new account:

define user_homedir ($group, $fullname, $ingroups) (

User("$name":

Ensure => present,

Comment => "$fullname",

Gid => "$group",

Groups => $ingroups,

Membership => minimum,

Shell => "/bin/bash",

Home => "/home/$name",

Require => Group[$group],

Exec("$name homedir":

Command => "/bin/cp -R /etc/skel /home/$name; /bin/chown -R $name:$group /home/$name",

Creates => "/home/$name",

Require => User[$name],

Now, to create a new account, just contact user_homedir:

user_homedir("sergej":

Group => "sergej",

Fullname => "Sergej Jaremchuk",

Ingroups => ["media", " admin]

There are separate descriptions of nodes that support inheritance, as well as classes. When a client connects to the Puppet server, the corresponding node section will be searched and settings specific only to this computer will be provided. To describe all other systems, you can use node default. A description of all types is given in the “Type Reference” document, which must be read in any case, at least in order to understand all the capabilities of the Puppet language. Various types allow you to execute specified commands, including when certain conditions are met (for example, changing a configuration file), work with cron, user credentials and groups, computers, mounting resources, starting and stopping services, installing, updating and removing packages, working with SSH keys, Solaris zones, and so on. This is how you can easily force the list of packages in distributions using apt to be updated daily between 2 and 4 hours:

schedule(daily:

Period => daily,

Range =>

exec("/usr/bin/apt-get update":

Schedule => daily

The update for that period will be performed by each system only once, after which the task is considered completed and will be deleted from the client computer. The Puppet language supports other familiar structures: conditions, functions, arrays, comments, and the like.

Installing Puppet

Puppet requires Ruby (version 1.8.1 and above) with OpenSSL support and XMLRPC libraries, as well as the Faster library. The Ubuntu 7.04 repository that was used for the test installation already includes the puppy package:

$ sudo apt-cache search puppet

~$ ruby ​​-rxmlrpc/client -e "puts:yep"

yep

If no errors are received, then everything you need is already included. Files that describe the desired configuration of systems are called manifests in Puppet terminology. When launched, the daemon tries to read the file /etc/puppet/manifests/site.pp; if it is missing, it displays a warning message. When testing, you can tell the daemon to work in standalone mode, which does not require a manifest:

$ sudo /usr/bin/puppetmasterd --nonodes

If necessary, you can connect other files to site.pp, for example, with class descriptions. For a test run, you can enter the simplest instructions in this file.

class sudo(

File("/etc/sudoers":

Owner => root,

Group => root,

Mode => 440,

node default(

Include sudo

All configuration files, both server and client, are located in /etc/puppet. The fileserver.conf file, which we already talked about, is optional and is used only if Puppet will also work as a file server. On Ubuntu, this file exports the /etc/puppet/files subdirectory. The ssl subdirectory contains certificates and keys that will be used for encryption when connecting clients. Keys are created automatically the first time you start puppetmasterd; you can create them manually with the command:

$ sudo /usr/bin/puppetmasterd --mkusers

The puppetd.conf and puppetmasterd.conf files are similar. They indicate some parameters for the operation of daemons on the client system and server. The client file differs only in the presence of the server parameter, which points to the computer on which puppetmasterd is running:

server = grinder.com

logdir = /var/log/puppet

vardir = /var/lib/puppet

rundir = /var/run

# send a report to the server

report = true

To avoid typing everything manually, you can create a template using puppetd itself:

$ puppetd --genconfig > /etc/puppet/puppetd.conf

Similarly, you can create site.pp on the server:

$ puppetd --genmanifest > /etc/puppet/manifests/site.pp

Another file, tagmail.conf, allows you to specify email addresses to which reports will be sent. In the simplest case, you can use one line:

all: [email protected]

The configuration files are not enough for the client to connect to the server. To do this, you also need to sign the certificates.

First, to let the server know about the new computer, enter the command on the client system:

$ sudo puppetd --server grinder.com --waitforcert 60 –test

The firewall must allow connections on port 8140.

On the server we get a list of certificates that need to be signed:

$ sudo puppetca –list

nomad.grinder.com

And sign the client certificate:

$ sudo puppetca –sign nomad.grinder.com

Now the client can freely connect to the server and receive settings.

Unfortunately, it is impossible to show all the capabilities of Puppet within the article. But, as you can see, this is a functional and flexible tool that allows you to solve most of the problems of simultaneous administration of a large number of systems. And most importantly, the project managed to gather a small but constantly growing community. Therefore, let's hope that a good idea will not be allowed to die or go aside.

Good luck!

  1. BladeLogic project website – http://www.bladelogic.com.
  2. The OpsWare project website is http://www.opsware.com.
  3. The Cfengine project website is http://www.cfengine.org.
  4. The Puppet project website is http://reductivelabs.com/projects/puppet.
  5. Puppet CookBook - http://www.reductivelabs.com/trac/puppet/tagspuppet%2Crecipe.
  6. Faster Library –

When the number of servers you manage is less than ten, rarely does anyone think about their centralized management, this may not be required. When there are dozens of servers, centralized software and configuration management is extremely useful. When there are hundreds and thousands of servers, this is vital. There are many programs of this kind, for example: Chef, CFEngine, Puppet... It’s the latter that will be discussed in this post.

Puppet is considered one of the best solutions of this kind. It is used by companies such as Google, Citrix and Red Hat. This is a client-server application written in the Ruby programming language, which is distributed in two versions:

  • Puppet Open Source - completely free version
  • Puppet Enterprise - free for up to 10 servers, then licenses required

Let's consider installing the Puppet Open Source server and agent, which are included in the packages of most modern distributions. Next we will talk about Ubuntu 12.04 Precise Pangolin.

The back end of Puppet is called puppetmaster, let's start the installation from there:

:~# apt-get install puppetmaster

And now the client:

:~# apt-get install puppet

In the client configuration file /etc/puppet/puppet.conf you need to talk about the server by adding the following section:

Server=puppet.local report=true pluginsync=false

At the initial stage, it is better to turn off pluginsync.

Let's run the puppet client so that it creates a request for a certificate:

:~# puppetd --verbose --test info: Creating a new SSL key for linux.local info: Caching certificate for ca info: Creating a new SSL certificate request for linux.local info: Certificate Request fingerprint (md5): E5: EA:AC:5B:22:9A:BA:42:B8:A1:63:9E:1F:1F:23:51 Exiting; no certificate found and waitforcert is disabled

On the server, you need to check that the certificate request has been received and, if so, issue a certificate:

:~# puppetca --list "linux.local" (E5:EA:AC:5B:22:9A:BA:42:B8:A1:63:9E:1F:1F:23:51) :~# puppetca - -sign linux.local notice: Signed certificate request for linux.local notice: Removing file Puppet::SSL::CertificateRequest linux.local at "/var/lib/puppet/ssl/ca/requests/linux.local.pem"

Repeat the previous step on the client:

:~# puppetd --verbose --test info: Caching certificate for linux.local info: Retrieving plugin info: Caching certificate_revocation_list for ca info: Caching catalog for linux.local info: Applying configuration version "1356278451" info: Creating state file / var/lib/puppet/state/state.yaml notice: Finished catalog run in 0.02 seconds

Great, everything works. Let's move on to creating the first manifesto. Manifests, or configurations, are described in a special declarative language. We will immediately get used to good things, use a modular structure and classes. For example, let's write a module that will keep the file up to date /etc/hosts on all our servers.

Let's check where puppet looks for modules:

:~# puppet apply --configprint modulepath /etc/puppet/modules:/usr/share/puppet/modules

Create directories for your module

:~# cd /etc/puppet/modules :~# mkdir hosts; cd hosts; mkdir manifests; cd manifests

The first manifest, also known as the main module file, should be called init.pp

Class hosts ( # puppet.local host ( "puppet.local": ensure => "present", target => "/etc/hosts", ip => "192.168.0.1", host_aliases => "puppet", ) # linux.local host ( "linux.local": ensure => "present", target => "/etc/hosts", ip => "192.168.0.2", host_aliases => "linux", ) )

By default, puppet looks for a file /etc/puppet/manifests/site.pp to load the configuration, let's bring it to the following form:

Node default ( include hosts )

We check the manifest on the server:

:~# puppet apply --verbose /etc/puppet/manifests/site.pp info: Applying configuration version "1356281036" notice: /Stage//Host/ensure: created info: FileBucket adding (md5)notice: /Stage// Host/ensure: created notice: Finished catalog run in 0.03 seconds

On the client:

:~# ll /etc/hosts rw-r--r-- 1 root root 290 Dec 16 19:10 /etc/hosts :~# puppetd --verbose --test info: Caching catalog for linux.local info: Applying configuration version "1356283380" info: FileBucket adding (md5)notice: /Stage/Hosts/Host/ensure: created notice: /Stage/Hosts/Host/ensure: created notice: Finished catalog run in 0.04 seconds :~# ll /etc /hosts -rw-r--r-- 1 root root 551 Dec 23 20:43 /etc/hosts

After we are sure that everything is working, we allow the service to start, in /etc/default/puppet change:

# Start puppet on boot? START=yes

Starting the service

:~# service puppet start

Puppet will poll the puppetmaster server every 30 minutes for configuration changes and, if necessary, adjust the system accordingly.







2024 gtavrl.ru.