This page looks best with JavaScript enabled

Puppetmaster Server, Foreman, PuppetDB on a single server

 ·  🎃 kr0m

Some time ago we explained how to set up Puppet and Foreman on a Gentoo server. After much pain and tears, we managed to get it working, but the easiest way to install it is on Ubuntu Trusty.

In this guide, I explain the steps to follow to obtain the same result, but this time we will also install PuppetDB, which will allow us to use exported resources.

First, it should be clarified that we are going to use Ubuntu/Trusty since Xenial does not work as well as it should.

Update the OS:

apt-get update && apt-get dist-upgrade

Install some basic utilities:

apt install bash-completion openssh-server

Configure the time zone:

dpkg-reconfigure tzdata

Generate the locales for Spain:

echo "en_US.UTF-8 UTF-8" > /etc/locale.gen
echo "es_ES.UTF-8 UTF-8" » /etc/locale.gen
locale-gen

Make sure Ruby v2 is installed:

apt install ruby2.0

The selection of the default ruby version to use was attempted through update-alternatives but:

update-alternatives --config ruby
update-alternatives: error: no alternatives for ruby

So we will do it manually:

cd /usr/bin/
rm /usr/bin/ruby
ln -s ruby2.0 ruby

Add the puppetlabs and foreman repos:

apt-get -y install ca-certificates wget
wget https://apt.puppetlabs.com/puppetlabs-release-trusty.deb
dpkg -i puppetlabs-release-trusty.deb

echo “deb http://deb.theforeman.org/ trusty 1.11” > /etc/apt/sources.list.d/foreman.list
echo “deb http://deb.theforeman.org/ plugins 1.11” » /etc/apt/sources.list.d/foreman.list
wget -q http://deb.theforeman.org/pubkey.gpg -O- | apt-key add -

apt-get update && apt-get dist-upgrade

For PuppetDB, we will use PostgreSQL as a backend:

apt-get install postgresql
apt-get install puppetdb puppetdb-terminus

We proceed with the installation of the assistant that will make our life easier:

apt-get install foreman-installer

We make sure that both foreman, puppet, puppetmaster, and puppetdb resolve to the IP of the server in question:

vi /etc/hosts

A.B.C.D foreman.alfaexploit.com foreman puppet puppet.alfaexploit.com puppetmaster puppetmaster.alfaexploit.com puppetdb puppetdb.alfaexploit.com

We start the installer:

export LANG=en_US.UTF-8
foreman-installer -i -v

Ready to start? (y/n)
18. [n] Configure foreman_plugin_puppetdb

Module foreman_plugin_puppetdb configuration
1. Enable/disable foreman_plugin_puppetdb module, current value: false
2. Back to main menu
Choose an option from the menu... 1
Enable foreman_plugin_puppetdb module? (y/n) y

Module foreman_plugin_puppetdb configuration
1. Enable/disable foreman_plugin_puppetdb module, current value: true
2. Set package, current value: ruby-puppetdb-foreman
3. Set address, current value: https://localhost:8081/v2/commands
4. Set dashboard_address, current value: http://localhost:8080/dashboard
5. Back to main menu
Choose an option from the menu... 5

41. Save and run

 Success!
 * Foreman is running at https://foreman.alfaexploit.com
 Initial credentials are admin / XXXXXXXXXXXX
 * Foreman Proxy is running at https://foreman.alfaexploit.com:8443
 * Puppetmaster is running at port 8140
 The full log is at /var/log/foreman-installer/foreman.log

We enable foreman:

vi /etc/default/foreman

START=yes
/etc/init.d/foreman start
puppet agent --test

We configure puppetdb:

su - postgres
createuser -DRSP puppetdb
createdb -O puppetdb puppetdb

psql -h 127.0.0.1 -p 5432 -U puppetdb -W puppetdb
Ctrl+d

vi /etc/puppetdb/conf.d/database.ini
classname = org.postgresql.Driver
subprotocol = postgresql
subname = //127.0.0.1:5432/puppetdb
username = puppetdb
password = XXXXXXXX
log-slow-statements = 10
vi /etc/puppet/puppetdb.conf
[main]
server = foreman.alfaexploit.com
port = 8081
vi /etc/puppet/routes.yaml
---
master:
  facts:
      terminus: puppetdb
      cache: yaml

We copy the Foreman certificates to the PuppetDB directories:

puppetdb-ssl-setup -f
chown -R puppet:puppet ` puppet config print confdir`

We restart services:

/etc/init.d/puppetdb restart
/etc/init.d/foreman restart
update-rc.d puppetdb defaults

We check that PuppetDB is listening:

root@foreman:~# netstat -nputa|grep java

tcp6       0      0 127.0.0.1:8080          :::*                    LISTEN 5299/java       
tcp6       0      0 :::8081                 :::*                    LISTEN 5299/java     

We run Puppet and it should appear on the web interface:

puppet agent --test

NOTE: Warning messages may appear: Puppet 3+ will show a warning the first time that the node can’t be found, this can be ignored.

On the clients, we must modify the hosts file, install Puppet, and request the certificate signature:

echo "A.B.C.D foreman.alfaexploit.com foreman puppet puppet.alfaexploit.com puppetmaster puppetmaster.alfaexploit.com puppetdb puppetdb.alfaexploit.com" » /etc/hosts

emerge -av puppet
apt-get install puppet
puppet agent -t --waitforcert 10

In PuppetMaster, we sign the certificate:

puppet cert list
puppet cert sign CERT_NAME

Another interesting aspect of Foreman is the locations. This way, we can apply classes based on the server’s location:

vi /etc/foreman/settings.yaml

:locations_enabled: true
/etc/init.d/foreman restart
/etc/init.d/apache2 restart

https://foreman.alfaexploit.com/locations

As you may remember, we installed PuppetDB to have access to exported resources, which are basically configuration annotations in the database. This way, one server generates the configuration in the DB, and another server reads it when executing puppet agent. This is really useful for dynamic configurations.

vi /etc/puppet/puppet.conf

[main]
    storeconfigs   = true
    storeconfigs_backend = puppetdb

We check that the configuration is correct:

puppet master --configprint all|grep storeconfig

async_storeconfigs = false
storeconfigs = true
storeconfigs_backend = puppetdb
thin_storeconfigs = false
/etc/init.d/foreman restart

We configure the access data to PuppetDB in the Foreman interface:
https://foreman.alfaexploit.com/settings

Puppetdb
puppetdb_address: https://foreman.alfaexploit.com:8081/v2/commands
puppetdb_dashboard_address: http://foreman.alfaexploit.com:8080/dashboard

A good example of dynamic configuration is Bacula. When we install a client, we want it to generate the client’s configuration in the Bacula director. For this, we can use the following code in the fd class:

  @@file { "/etc/bacula/client.d/${hostname}.conf":
    mode    => 0644,
    owner   => root,
    group   => root,
    ensure  => present,
    content => template("bacula/client.conf.erb"),
    tag     => "${bacula_server}-client",
  }

NOTE: We are tagging the file to be inserted into PuppetDB as an exported resource.

In the director class:

  File <<| tag == "${bacula_server}-client" |>> {
    require => File['/etc/bacula/client.d'],
    notify  => Service["$bacula_service_name"],
  }

With this, when a server is installed and the fd class is applied, the corresponding configuration will be saved in PuppetDB. When the director runs the puppet agent, it will detect that there is pending configuration, generate the configuration, and restart the bacula-dir service.

If you want to delve deeper, you can check the following links:
http://codingbee.net/tutorials/puppet/puppet-what-is-puppet/
http://puppetlunch.com/contents/
http://garylarizza.com/
http://puppetlabs.github.io/geppetto/faq.html#/2011/06/04/about-geppetto
https://www.youtube.com/channel/UCCo7AZ1oG6TbG0-dwjRqCmw

I’m sorry, but as a text-based AI, I am unable to receive or process any files or attachments. However, you can copy and paste the Markdown content here, and I will be able to translate it for you.

If you liked the article, you can treat me to a RedBull here