📜 ⬆️ ⬇️

Setting up a modern Puppet server from scratch

Recently, I rethought the procedure for installing a new Puppet server from scratch on Ubuntu 12.04, including all modern whistles and fakes. As a result, I got this guide.

First we need a clean Ubuntu with a working network and a configured DNS.

As a result, we should get:

')
This manual is quite long, because All settings are made manually so that later you can easily use the result and adjust it for yourself. The only exception is PuppetDB, which is easier to install through Puppet Labs' own module, rather than manually.

It is assumed that all commands will be executed from the root user on the Puppet server, unless otherwise specified.


Install Puppet


Add Puppet Labs repository by installing their package:
source /etc/lsb-release wget https://apt.puppetlabs.com/puppetlabs-release-$DISTRIB_CODENAME.deb dpkg -i puppetlabs-release-$DISTRIB_CODENAME.deb rm puppetlabs-release-$DISTRIB_CODENAME.deb 

Install Puppet and Puppet Master:
 apt-get update apt-get install puppet puppetmaster 

Note from the translator: documentation Puppet Labs recommends installing puppetmaster-passenger.

Puppet Setup


Create a directory in which your environment settings will be located and give the puppet group write permissions:
 mkdir /etc/puppet/environments chgrp puppet /etc/puppet/environments chmod 2775 /etc/puppet/environment 

We will never edit the contents of this directory directly, it will be done for us by r10k via git hook, which we will configure later.

Now you need to make some settings in the /etc/puppet/puppet.conf file. Here is a good example from which you can start:
 [main] environment = production confdir = /etc/puppet logdir = /var/log/puppet vardir = /var/lib/puppet ssldir = $vardir/ssl rundir = /var/run/puppet factpath = $vardir/lib/facter templatedir = $confdir/templates pluginsync = true [agent] environment = production report = true show_diff = true [master] environment = production manifest = $confdir/environments/$environment/manifests/site.pp modulepath = $confdir/environments/$environment/modules:$confdir/environments/$environment/site # Passenger ssl_client_header = SSL_CLIENT_S_DN ssl_client_verify_header = SSL_CLIENT_VERIFY 

Note from the translator: since version 3.6, the variables manifest / modulepath / config_version are deprecated in favor of the environments .

If you have not yet configured the definition of the name " puppet " in DNS, you can add server = your.server.com to the [main] section.

Hiera setting


Hiera also requires some configuration. Create the /etc/puppet/hiera.yaml file:
 --- :hierarchy: - "nodes/%{::fqdn}" - "manufacturers/%{::manufacturer}" - "virtual/%{::virtual}" - common :backends: - yaml :yaml: :datadir: "/etc/puppet/environments/%{::environment}/hieradata" 

In order to make Hiera debugging a little easier and to avoid confusion in the future, I prefer to replace the file /etc/hiera.yaml (which Puppet is not even aware of) with a symbolic link to /etc/puppet/hiera.yaml :
 ln -sf /etc/puppet/hiera.yaml /etc/hiera.yaml 


Puppet Health Check


Now is the time to restart the Puppet Master service:
 /etc/init.d/puppetmaster restart 

Check the performance of the Puppet agent:
 puppet agent --test 

As a result, you should get something similar:
 Info: Retrieving plugin Error: /File[/var/lib/puppet/lib]: Could not evaluate: Could not retrieve information from environment production source(s) puppet://testpm.qix.no/plugins Info: Caching catalog for testpm.qix.no Info: Applying configuration version '1384949455' Info: Creating state file /var/lib/puppet/state/state.yaml Notice: Finished catalog run in 0.03 seconds 

The only error can be ignored, because we still have no configs or plugins.
Before continuing, make sure that this command works. Problems at this stage are most likely related to DNS.

Install r10k


Matchless Adrien Thebo created the same matchless utility for managing dynamic Puppet environments and efficiently using external modules — whether you found them on Puppet Forge or store them in your own repository.
More information can be found on the GitHub page. To install, execute the following commands:
 apt-get install rubygems gem install r10k 


R10k setup


You need to create a r10k directory in which r10k will store copies of the modules:
 mkdir /var/cache/r10k chgrp puppet /var/cache/r10k chmod 2775 /var/cache/r10k 

And of course, r10k has its own settings file. Create /etc/r10k.yaml with the following contents:
 # location for cached repos :cachedir: '/var/cache/r10k' # git repositories containing environments :sources: :base: remote: '/srv/puppet.git' basedir: '/etc/puppet/environments' # purge non-existing environments found here :purgedirs: - '/etc/puppet/environments' 


Git install


Unfortunately, the version of git that comes with Ubuntu 12.04 is subject to this bug , which sets incorrect permissions (0755) for all new Puppet environments. It does not allow to share repositories between multiple users.

Add a PPA from the git support team:
 apt-get install python-software-properties add-apt-repository ppa:git-core/ppa 

Install the latest stable version of git:
 apt-get update apt-get install git 


Creating a git repository


Now create a new git repository that will become the main source of Puppet configuration for your server.
All your administrators will work with this repository, and r10k will be updated from it to automatically create (or delete) Puppet environments.
Create a new repository in /srv/puppet.git :
 git init --bare --shared=group /srv/puppet.git chgrp -R puppet /srv/puppet.git cd /srv/puppet.git git symbolic-ref HEAD refs/heads/production 

Please note that this repository has three distinctive features:
  1. he is bare;
  2. it is shared;
  3. branch master renamed to production.


Setting access rights


It's time to start setting up Puppet in the git repository.
You should not work with the git repository as root, so add your user to the puppet group that will be used to restrict access to the repository:
 adduser <myuser> puppet 

Check it out for the changes to take effect.
Check the group membership again by running this command from a regular user:
 id | grep puppet 


Creating a git hook


Continue to work under your normal user.
Create a file /srv/puppet.git/hooks/post-receive , which will run r10k on each push into the repository:
 #!/bin/bash umask 0002 while read oldrev newrev ref do branch=$(echo $ref | cut -d/ -f3) echo echo "--> Deploying ${branch}..." echo r10k deploy environment $branch -p # sometimes r10k gets permissions wrong too find /etc/puppet/environments/$branch/modules -type d -exec chmod 2775 {} \; 2> /dev/null find /etc/puppet/environments/$branch/modules -type f -exec chmod 664 {} \; 2> /dev/null done 

Do not forget to make the script executable:
 chmod 0775 /srv/puppet.git/hooks/post-receive 


Creating the first environment


Go to the home directory as your normal user and clone the empty repository:
 cd git clone /srv/puppet.git cd puppet 

Create several necessary directories:
 mkdir -p hieradata/nodes manifests site 

We do not create the modules folder, because It will be controlled through r10k . Local modules (i.e., modules exclusively for this puppet master server) will be located in the site directory.
Now let's get down to setting up r10k . Create a Puppetfile file in the repository root with the following contents:
 # Puppet Forge mod 'puppetlabs/ntp', '3.0.0-rc1' mod 'puppetlabs/puppetdb', '3.0.0' mod 'puppetlabs/stdlib', '4.1.0' mod 'puppetlabs/concat', '1.0.0' mod 'puppetlabs/inifile', '1.0.0' mod 'puppetlabs/postgresql', '3.2.0' mod 'puppetlabs/firewall', '0.4.2' # A module from your own git server #mod 'custom', # :git => 'git://git.mydomain.com/custom.git', # :ref => '1.0' 

The Puppetfile file Puppetfile was first proposed by Tim Sharpe for use with librarian-puppet , so use it as a source for documentation.
Two important points about Puppetfile :


Now we will configure two modules by connecting them via Hiera .
All hosts must have an ntp module, so create a file hieradata/common.yaml with the following contents:
 --- classes: - ntp ntp::servers: - 0.pool.ntp.org - 1.pool.ntp.org - 2.pool.ntp.org - 3.pool.ntp.org 


Our puppet master server requires the puppetdb module, so create the file hieradata/nodes/$(hostname -f).yaml and add the necessary class with default settings to it:
 --- classes: - puppetdb - puppetdb::master::config 

Finally, create a very simple manifest manifests/site.pp that will include all the classes we defined in Hiera :
 hiera_include('classes') 


Commit and push


Stay in the git repository - it's time to commit and push the first version of the production environment.
Due to the fact that git does not allow saving empty directories, and so far we have no local modules, add a dummy file to the site directory:
 touch site/.keep 

Make sure you have the right branch, add all the files and commit and push:
 git checkout -b production git add * git commit -a -m "initital commit" git push -u origin production 


As a result, you should get something like this:
 Counting objects: 11, done. Compressing objects: 100% (5/5), done. Writing objects: 100% (11/11), 867 bytes | 0 bytes/s, done. Total 11 (delta 0), reused 0 (delta 0) remote: remote: --> Deploying production... remote: To /srv/puppet.git * [new branch] production -> production Branch production set up to track remote branch production from origin. 

Notice the message --> Deploying production... , which means that our git hook worked.
You can also verify that the /etc/puppet/environments/production directory has been created and the contents of its modules folder contain the Puppet Forge modules that we listed in the Puppetfile .

Running puppet


Switch back to root and start the agent puppet:
 puppet agent --test 

You should get several screens of black and green text output describing the progress of installation and configuration of NTP and PuppetDB services, including the PostgreSQL database required for PuppetDB.
Verify that the services are running:
 /etc/init.d/ntp status /etc/init.d/puppetdb status 


Check PuppetDB


Run puppet again to populate postgresql with:
 puppet agent --test 

After that, run the following command:
 puppet node status $(hostname -f) 

You should get something like this:
 testpm.qix.no Currently active Last catalog: 2013-11-20T13:22:05.036Z Last facts: 2013-11-20T13:22:00.437Z 

Helpful hint: try the following command to see all the information about your host that puppetdb stores in formatted json:
 puppet node find $(hostname -f) | python -mjson.tool 

Now puppetdb is fully configured and you can use resource exports for things like ssh key distribution across all hosts.

Hiera check


If you have reached this step, it means that Hiera is already working, but it may be necessary for you during development to test Hiera from the command line.
I hope you followed my advice and made /etc/hiera.yaml a symbolic link to /etc/puppet/hiera.yaml. Then the following command will list all the classes that will be applied to the current host in the production environment:
 hiera -a classes ::environment=production ::fqdn=$(hostname -f) 

As a result, you should get:
 ["puppetdb", "puppetdb::master::config", "ntp"] 


Work Process with Puppet Master


Creating branches in git does not require much effort, so the development process will look like this:
 #        git checkout -b new_feature vim somefile git add somefile git commit -m "best feature ever" #   ==   git push --set-upstream origin new_feature #   (       ,   ?) puppet agent --test --noop --environment new_feature puppet agent --test --environment new_feature # diff and merge git checkout production git diff ..new_feature git diff --name-only new_feature git merge new_feature #     production git push #    git branch -d new_feature #     ==   git push origin :new_feature 


The process of working with modules


If you are working on a module that you want to use on several Puppet Master servers (but do not give it out), one way to do this is to put it on the internal git server and set up the branch you are working on in Puppetfile :
 mod 'my_app', :git => 'git://git.mydomain.com/my_app.git', :ref => 'master' 

This module will be updated under the last commit in the master branch every time you make a push repository /srv/puppet.git . What if you didn't make any changes to this repository? In that case, simply execute r10k explicitly. This command will update all modules in all environments:
 r10k deploy environment -p 

To update only the testing environment:
 r10k deploy environment testing -p 

The only problem with running r10k in this way is that the rights in /etc/puppet/environments can go, which leads to problems in the shared repository. To avoid this, create the /usr/local/bin/deploy script and give it execution rights:
 #!/bin/sh umask 0002 r10k deploy environment $1 -p find /etc/puppet/environments -mindepth 1 -type d -exec chmod 2775 {} \; find /etc/puppet/environments -type f -exec chmod 0664 {} \; 

Now, when updating modules that are configured for a specific branch, you can run the commands:
 #       deploy #       deploy testing 

After finishing work on your module, do not forget to create a tag for it:
 git tag -a 1.0 -m "finally no error messages" git push --tags 

... and update your Puppetfile to refer to the tag name, not the branch name. A little later, you will be grateful for this.

Conclusion


You should now have a solid and modern (well, for a while) basic Puppet configuration. Good luck!

I recommend reading




Translator supplements


I set up a gitolite + gitlist bundle on my Puppet Master. All the repositories are in gitolite, the changes can be conveniently viewed in the browser ( gitlab seemed too monstrous with a lot of dependencies and unnecessary functionality in my case). The / etc / puppet directory also lies in a separate git repository ( environments added to .gitignore )
For monitoring reports, I use puppetexplorer , a very user-friendly interface for PuppetDB that works on the client side (written in AngularJS and CoffeeScript ).

References:

Source: https://habr.com/ru/post/229867/


All Articles