Puppet mit r10k

  Lioh Möller   Lesezeit: 11 Minuten

Mithilfe von r10k und Hiera lassen sich zeitgemässe Konfigurationsmanagement-Systeme aufbauen.

puppet mit r10k

Bei r10k handelt es sich um ein Toolset zur Bereitstellung von Puppet Environments und Modulen. In Kombination mit Hiera kann so ein zeitgemässes Configmanagement realisiert werden. Im folgenden Beispiel kommt darüber hinaus GitLab zur Konfigurationsverwaltung zum Einsatz.

Die Installation erfolgt auf dem Puppet Server, idealerweise in Kombination mit Foreman. Sofern Puppet aus den offiziellen Quellen installiert wurde, bietet es sich an, zunächst die PATH-Variable zu erweitern:

vi /root/.bashrc

# Puppet path
if ! [[ "$PATH" =~ "/opt/puppetlabs/puppet/bin" ]]
then
    PATH="/opt/puppetlabs/puppet/bin/:$PATH"
fi
export PATH

Daraufhin kann das r10k gem installiert werden:

/opt/puppetlabs/puppet/bin/gem install r10k

r10k erwartet die Konfiguration in der Datei: /etc/puppetlabs/r10k/r10k.yaml:

vi /etc/puppetlabs/r10k/r10k.yaml

# The location to use for storing cached Git repos
:cachedir: '/var/cache/r10k'

deploy:
  purge_levels: [ 'puppetfile' ]

# A list of git repositories to create
sources:
  # This will clone the git repository and instantiate an environment per
  # branch in /etc/puppet/environments
  itsystems:
    remote: 'git@gitlab.yourdomain.tld:group/r10k.git'
    basedir: '/etc/puppetlabs/code/environments'

postrun: ['/usr/local/bin/fix_perms.sh']

Der Parameter remote muss an die eigenen Gegebenheiten angepasst werden. Das Konto, unter dem r10k ausgeführt wird, muss in der Lage sein, auf das Repository lesend zugreifen zu können. Im Folgenden wird davon ausgegangen, dass r10k im Root Kontext läuft. Dazu muss ein entsprechendes SSH Schlüsselpaar (ohne Passphrase) erzeugt werden und der PublicKey zu einem Git-Useraccount hinzugefügt werden, der Leserechte auf das r10k Repository sowie die Puppet Module hat.

Dabei ist zu beachten, dass r10k die Puppet Environments anhand der Branch-Namen erstellt. So empfiehlt sich etwa die Main-Branch in myorg_production umzubenennen und eine weitere Branch myorg_development zu erstellen, wobei myorg an die eigenen Gegebenheiten angepasst werden sollte.

Das in der r10k Konfiguration angegebene Script fix_perms.sh korrigiert die Rechte und setzt den passenden SELinux-Kontext:

vi /usr/local/bin/fix_perms.sh

#!/bin/bash

chown -R apache: /etc/puppetlabs/code/environments/
restorecon -Fr /etc/puppetlabs/code/environments/

Dieses muss als ausführbar markiert werden:

chmod +x /usr/local/bin/fix_perms.sh

hiera-eyaml

Mithilfe von hiera-eyaml lassen sich Daten wie Passwörter verschlüsseln. Es sollten keine unverschlüsselten sensitiven Daten in Puppet-Modulen hinterlegt werden.

Die Installation erfolgt ebenfalls mithilfe von gem:

/opt/puppetlabs/puppet/bin/gem install hiera-eyaml

Sofern noch nicht vorhande, muss ein entsprechendes Schlüsselpaar erzeugt werden.

Damit Puppet darauf zugreifen kann, empfiehlt sich, die Schlüssel in einem eyaml Verzeichnis unterhalb der Puppet Konfiguration abzulegen:

mkdir /etc/puppetlabs/puppet/eyaml

Die eigentlichen Schlüssel können daraufhin wie folgt erzeugt werden:

eyaml createkeys –pkcs7-private-key=/etc/puppetlabs/puppet/eyaml/private_key.pkcs7.pem –pkcs7-public-key=/etc/puppetlabs/puppet/eyaml/public_key.pkcs7.pem

chown -R puppet:puppet /etc/puppetlabs/puppet/eyaml/

chmod -R 0500 /etc/puppetlabs/puppet/eyaml

cp -r /etc/puppetlabs/puppet/eyaml /root/keys

r10k Git Repository

Nun muss das Git-Repository vorbereitet werden, welches in der Konfigurationsdatei r10k.yaml referenziert wird:

vi environment.conf

modulepath = modules:$basemodulepath

vi hiera.yaml

myorg sollte auch hier an die eigenen Gegebenheiten angepasst werden.

---
version: 5
defaults:
  datadir: "/etc/puppetlabs/code/environments/production/"
  data_hash: yaml_data
hierarchy:
  - name: "Secret data: per-node, per-datacenter, common"
    lookup_key: eyaml_lookup_key # eyaml backend
    paths:
      - "data/secrets/nodes/%{trusted.certname}.eyaml"  # Include explicit file extension
      - "data/secrets/location/%{facts.whereami}.eyaml"
      - "data/common.eyaml"
    options:
      pkcs7_private_key: /etc/puppetlabs/puppet/eyaml/private_key.pkcs7.pem
      pkcs7_public_key:  /etc/puppetlabs/puppet/eyaml/public_key.pkcs7.pem
  - name: "Secret Module data"
    globs:
      - "data/common_myorg-*.eyaml"
    lookup_key: eyaml_lookup_key # eyaml backend
    options:
      pkcs7_private_key: /etc/puppetlabs/puppet/eyaml/private_key.pkcs7.pem
      pkcs7_public_key:  /etc/puppetlabs/puppet/eyaml/public_key.pkcs7.pem
  - name: "Normal data: per-node, per-datacenter, common"
    data_hash: yaml_data # Standard yaml backend
    paths:
      - "data/nodes/%{trusted.certname}.yaml"
      - "data/location/%{facts.whereami}/%{facts.group}.yaml"
      - "data/groups/%{facts.group}.yaml"
      - "data/os/%{facts.os.family}.yaml"
      - "data/common.yaml"
  - name: "Module data"
    globs:
      - "data/common_myorg-*.yaml"

vi manifests/site.pp

Eine site.pp Konfiguration ist zwingend notwendig, auch wenn diese keine aktiven Inhalte hält.

## site.pp ##

# This file (/etc/puppetlabs/puppet/manifests/site.pp) is the main entry point
# used when an agent connects to a master and asks for an updated configuration.
#
# Global objects like filebuckets and resource defaults should go in this file,
# as should the default node definition. (The default node can be omitted
# if you use the console and don't define any other nodes in site.pp. See
# http://docs.puppetlabs.com/guides/language_guide.html#nodes for more on
# node definitions.)

## Active Configurations ##

# DEFAULT NODE
# Node definitions in this file are merged with node data from the console. See
# http://docs.puppetlabs.com/guides/language_guide.html#nodes for more on
# node definitions.

# The default node definition matches any node lacking a more specific node
# definition. If there are no other nodes in this file, classes declared here
# will be included in every node's catalog, *in addition* to any classes
# specified in the console for that node.

# node default {
#   hiera_include('classes')
# }

Beispiel Puppetfile (für myorg_production)

vi Puppetfile

forge 'https://forge.puppet.com'

# Modules from the Puppet Forge
# Versions should be updated to be the latest at the time you start
mod 'puppetlabs/accounts',     '4.0.0'
mod 'puppetlabs/apache',       '4.1.0'
mod 'puppetlabs/apt',          '7.0.0'
mod 'puppetlabs/concat',       '5.3.0'
mod 'puppetlabs/firewall',     '2.5.0'
mod 'puppetlabs/haproxy',      '4.2.0'
mod 'puppetlabs/inifile',      '3.0.0'
mod 'puppetlabs/java',         '6.3.0'
mod 'puppetlabs/powershell',   '4.0.0'
mod 'puppetlabs/pwshlib',      '0.5.1'
mod 'puppetlabs/stdlib',       '5.2.0'
mod 'puppetlabs/vcsrepo',      '2.4.0'
mod 'puppetlabs/mysql',        '10.2.1'
mod 'puppetlabs/xinetd',       '3.3.0'
mod 'puppetlabs/yumrepo_core', '1.0.7'
mod 'puppet/letsencrypt',      '5.0.0'
mod 'puppet/archive',          '4.1.0'
mod 'puppet/gitlab',           '5.1.0'
mod 'puppet/keepalived',       '2.2.0'
mod 'puppet/php',              '6.0.2'
mod 'puppet/zypprepo',         '2.2.2'
mod 'puppet/epel',             '3.1.0'
mod 'fraenki/galera',          '1.0.6'
mod 'elastic/elasticsearch',   '6.4.0'
mod 'elastic/elastic_stack',   '7.0.0'
mod 'elastic/kibana',          '6.3.1'
mod 'pcfens/filebeat',         '4.8.0'
mod 'richardc/datacat',        '0.6.2'
mod 'camptocamp/postfix',      '1.10.0'
mod 'puppetlabs/postgresql',   '6.8.0'

# Modules from Git
mod 'myorg_accounts',
  :git => 'git@gitlab.yourdomain.tld:myorg/puppet/myorg-myorg_accounts.git',
  :tag => '1.0.0'

mod 'data',
  :git          => 'git@gitlab.yourdomain.tld:myorg/puppet/myorg-myorg_hiera.git',
  :tag          => '1.0.0',
  :install_path => './'

Die Namen der Git-Repositoriers, welche die Puppet-Module enthalten, sollten der Namenskonvention myorg-myorg_function entsprechen, um beispielsweise von Foreman interpretiert werden zu können. myorg kann dabei wie zuvor angepasst werden.

Für die myorg_development Branch können beispielsweise die Puppet Module anstatt mit Tags mit branches referenziert werden:

  :branch       => 'main',

Auf dem Puppet Server sollte nun bereits ein Deployment ausgeführt werden können:

/opt/puppetlabs/puppet/bin/r10k deploy environment -p -v

GitLab Runner

Idealerweise erfolgt ein automatischer Aufruf nach Änderungen am r10k Repository mithilfe eines GitLab Runners, welcher auf dem Puppet Server installiert wird.

curl -L “https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.rpm.sh” | sudo bash`

Unter Foreman kann das Paket daraufhin wie folgt eingespielt werden

foreman-maintain packages install gitlab-runner

In den CI/CD Einstellungen des r10k Git Repositories finden sich Hinweise zur Registrierung des Runners. Dort sollte ein entsprechendes Tag mit angegeben werden, beispielsweise r10k.

sudo gitlab-runner register –url https://gitlab.mydomain.tld/ –registration-token $MYTOKEN

Beispiel /etc/gitlab-runner/config.toml

concurrent = 1
check_interval = 0

[session_server]
  session_timeout = 1800

[[runners]]
  name = "r10k_runner"
  url = "https://gitlab.mydomain.tld/"
  token = "not-secure"
  executor = "shell"
  [runners.custom_build_dir]
  [runners.cache]
    [runners.cache.s3]
    [runners.cache.gcs]
    [runners.cache.azure]

Damit r10k ohne Passwortabfrage im Kontext des gitlab-runner Benutzers ausgeführt werden kann, muss eine entsprechende sudoers Definition erstellt werden.

vi /etc/sudoers.d/gitlab-runner

Cmnd_Alias R10K = /opt/puppetlabs/puppet/bin/r10k deploy environment -p -v
gitlab-runner ALL = (root) NOPASSWD : R10K
Defaults:gitlab-runner !requiretty

Abschliessend erstellt man eine Pipeline Konfiguration im r10k Git-Repository:

trigger_r10k:
  stage: deploy
  script:
    - "sudo /opt/puppetlabs/puppet/bin/r10k deploy environment  -p -v"
  tags:
    - r10k
  variables:
    GIT_STRATEGY: clone

Nach der nächsten Änderung im myorg_production Repository, sollte der gitlab-runner automatisch das r10k Deployment ausführen.

Ein typischer Workflow sähe dann wie folgt aus: Man führt Änderungen an einem Puppet Module oder Hiera aus, erhöht die Tag-Nummer und pushed das Tag ins Repository. Daraufhin passt man die Tag-Referenz im r10K Puppetfile an und pushed diese ebenfalls. In diesem Moment werden automatisch die neuen Versionen der Puppet Module auf dem Server deployed.

Für myorg_development kann man einen ähnlichen Workflow etablieren, oder so wie zuvor angegeben eine Branch angeben und r10k wahlweise ebenfalls über den Runner ausführen, oder manuell direkt auf dem Server aufrufen. Letztendlich ist dies sehr individuell und insbesondere wenn man zusammenarbeitet, sollte man sich auf eine gemeinsame Vorgehensweise einigen.

Tags

r10k, Puppet, Hiera, Foreman

Es wurden noch keine Kommentare verfasst, sei der erste!