Puppet Module mittels r10k über Puppetfile deployen

Hier ein kurzer Überblick über mein aktuelles Management meiner Puppet Module und Manifests mittels r10k. Das Tool r10k kümmert sich darum, das aus einem Git-Branch innerhalb eines Repositories mit Puppet Code ein nutzbares Puppet Environment wird. Das unten stehende Setup läuft nun bereits seit einigen Monaten so produktiv und ich bin wirklich sehr zufrieden mit r10k.

Meine eigentliche r10k Konfiguration ist sehr einfach gehalten. Ich lasse ausschließlich ein Verzeichnis /etc/puppet/environments deployen, in dem ich alle Dateien und Verzeichnise ablege. Zwecks Performance handelt es sich bei diesem Verzeichnis um ein tmpfs. Ein globales Manifest oder globale Module gibt es nicht. Hiera liegt ebenfalls im environment Verzeichnis.

# /etc/environment.conf
---
:cachedir: /var/cache/r10k
:sources:
   :environments:
     remote: ssh://root@localhost/opt/puppet/environments.git
     basedir: /etc/puppet/environments

Hier ein kurzer Ausschnitt über den Aufbau des Git-Repositories. Der Masterbranch wurde von „master“ umbenannt in „production“, um hier mit Puppet auf einen gemeinsamen Nenner zu kommen. Aktuell gibt es zwei Branches: production und testing.

658084 drwxr-xr-x 10 root root 4.0K May 10 22:30 .
702437 drwxr-xr-x  3 root root 4.0K Dec 18  2014 ..
715811 -rw-r--r--  1 root root  207 Apr 30 21:50 environment.conf
832255 drwxr-xr-x 28 root root 4.0K Apr 30 21:57 forge/
658085 drwxr-xr-x  8 root root 4.0K Jul 14 22:56 .git
133592 drwxr-xr-x  4 root root 4.0K May 10 22:28 hieradata/
659093 drwxr-xr-x  2 root root 4.0K Apr 28 21:28 manifests/
659095 drwxr-xr-x 24 root root 4.0K May 10 21:59 modules/
718207 -rw-r--r--  1 root root 2.0K May 10 22:30 Puppetfile
727181 drwxr-xr-x 26 root root 4.0K Apr 30 21:56 puppetlabs/
658124 -rw-r--r--  1 root root    2 Dec 18  2014 README
727182 drwxr-xr-x 10 root root 4.0K Apr 30 21:56 theforeman/
659308 drwxr-xr-x  2 root root 4.0K Dec 18  2014 tools/

Die Modulpfade werden mit einer environment.conf konfiguriert. Dies hat den schönen Vorteil, das man hier sauber zwischen Testing und Production trennen kann und je nach Branch zusäzliche Verzeichnise ohne viel Aufwand einbringen kann. Die Trennung nach Quelle der Module ist einfach Geschmackssache und hat keinen wirklichen technischen Vorteil.

# environment.conf
modulepath = puppetlabs:theforeman:forge:modules:/etc/puppet/modules:/usr/share/puppet/modules
manifest = manifests
#config_version = get_environment_commit.sh
#environment_timeout = 180

Die eigentliche Logik für alle „externen“ Module liegt in der Datei „Puppetfile“. Dieses File wird von r10k je nach Wunsch bei jedem Deployment evaluiert. Dort können Module aus Git und SVN-Repos oder aber Module aus der Puppet Forge (Forge API) eingebunden werden. Hier noch eine Doku von Puppetlabs zum Thema Puppetfile. Hier meine momentane Konfiguration, mit der ich sehr glücklich bin (aufklappen, um die komplette Config zu sehen).

#!/usr/bin/env ruby
#^syntax detection

# puppetlabs
moduledir 'puppetlabs'
mod 'puppetlabs/acl'
mod 'puppetlabs/apt'
mod 'puppetlabs/activemq'
mod 'puppetlabs/apache'
mod 'puppetlabs/concat'
mod 'puppetlabs/corosync'
mod 'puppetlabs/dism'
mod 'puppetlabs/firewall'
mod 'puppetlabs/inifile'
mod 'puppetlabs/java'
mod 'puppetlabs/java_ks'
mod 'puppetlabs/mssql'
mod 'puppetlabs/mysql'
mod 'puppetlabs/ntp'
mod 'puppetlabs/postgresql'
mod 'puppetlabs/powershell'
mod 'puppetlabs/puppetdb'
mod 'puppetlabs/rabbitmq'
mod 'puppetlabs/reboot'
mod 'puppetlabs/registry'
mod 'puppetlabs/stdlib'
mod 'puppetlabs/vcsrepo'
mod 'puppetlabs/win_desktop_shortcut'
mod 'puppetlabs/xinetd'
# conflicts with theforeman/git
#mod 'puppetlabs/git'

# theforeman
moduledir 'theforeman'
mod 'concat_native', :git => 'https://github.com/theforeman/puppet-concat_native.git'
mod 'dhcp', :git => 'https://github.com/theforeman/puppet-dhcp.git'
mod 'dns', :git => 'https://github.com/theforeman/puppet-dns.git'
mod 'foreman', :git => 'https://github.com/theforeman/puppet-foreman.git'
mod 'foreman_proxy', :git => 'https://github.com/theforeman/puppet-foreman_proxy.git'
mod 'git', :git => 'https://github.com/theforeman/puppet-git.git'
mod 'puppet', :git => 'https://github.com/theforeman/puppet-puppet.git'
mod 'tftp', :git => 'https://github.com/theforeman/puppet-tftp.git'

# forge
moduledir 'forge'
mod 'acme/sysstat'
mod 'adrien/alternatives'
mod 'akumria/nullmailer'
mod 'crayfishx/gemsource'
mod 'darin/zypprepo'
mod 'duritong/trocla'
mod 'elasticsearch/logstash'
mod 'garethr/erlang'
mod 'hunner/hiera'
mod 'ispavailability/file_concat'
mod 'jdowning/rbenv'
mod 'liamjbennett/win_facts'
mod 'nanliu/staging'
mod 'pdxcat/collectd'
mod 'richardc/datacat'
mod 'rismoney/chocolatey'
mod 'rtyler/jenkins'
mod 'saz/memcached'
mod 'saz/sudo'
#mod 'spotify/puppetexplorer'
mod 'stahnma/epel'
mod 'thias/mailman'
mod 'thias/postfix'
mod 'thomasvandoren/etckeeper'
#mod 'wcooley/nss_pam_ldapd'
mod 'yguenane/authconfig'
mod 'ghoneycutt/dnsclient'

Wer genau hinsieht bemerkt hier das ich alle Module des Foreman Projekts immer aus dem GitHub Masterbranch ziehe. GitHub würde ich generell als Anlaufstelle für Foreman weiterempfehlen. Das Projekt Foreman bringt seine Updates nur sehr unregelmäßig in die Forge ein, wodurch man dann auf wichtige Features wie Support für den Puppetserver sehr lange warten oder gar komplett verzichten müsste.

Bei obiger Konfiguration handelt es sich um das Testing Environment. Das schöne an r10k in Zusammenhang mit einem Puppetfile ist, das auch hier das branchen ohne Probleme funktioniert. Währand ich mich in meinem Test-Environment z.B. immer auf die aktuellsten Versionen oder den Masterbranch bei GitHub ausrollen kann, ist es mir auch möglich Module auf gewisse Versionsstände zu pinnen.

# Pinnen auf einen commit (auch möglich: tags oder branches)
mod 'apache',
  :git    => 'https://github.com/puppetlabs/puppetlabs-apache',
  :commit => 'a0224412893d39463a4fde82887312b279f83e1b'

# Das ganze mit Modulen aus der Puppet Forge
mod 'puppetlabs/apache', '0.10.0'

Dadurch können alle Updates von externen Modulen „sanft“ eingeführt werden und durch alle Environments getestet werden.

Der Worklow bei der Modulentwicklung gestaltet sich dann wie folgt.

# Änderungen am Git-Repo durchführen und commiten
root@foreman01.linux-dev.de:/opt/puppet/environments.git
-bash# git commit -a -m "Neues Feature"
[production 9a5a113] Neues Feature
 1 file changed, 3 insertions(+)

# Push zum Remote
root@foreman01.linux-dev.de:/opt/puppet/environments.git
-bash# git push
Counting objects: 11, done.
Compressing objects: 100% (6/6), done.
Writing objects: 100% (6/6), 535 bytes, done.
Total 6 (delta 4), reused 0 (delta 0)
To git@intern01.linux-dev.de:/opt/git/environments.git
   36a61ec..9a5a113  production -> production

# Deployment aller Branches via r10k
root@foreman01.linux-dev.de:/opt/puppet/environments.git/modules
-bash# r10k deploy environment -v -p
[R10K::Action::Deploy::Environment - INFO] Deploying environment /etc/puppet/environments/testing
[R10K::Action::Deploy::Environment - INFO] Deploying environment /etc/puppet/environments/production

[R10K::Action::Deploy::Environment - INFO] Deploying module /etc/puppet/environments/production/puppetlabs/acl
[R10K::Action::Deploy::Environment - INFO] Deploying module /etc/puppet/environments/production/puppetlabs/apt
...
[R10K::Action::Deploy::Environment - INFO] Deploying module /etc/puppet/environments/production/theforeman/concat_native
[R10K::Action::Deploy::Environment - INFO] Deploying module /etc/puppet/environments/production/theforeman/dhcp
...
[R10K::Action::Deploy::Environment - INFO] Deploying module /etc/puppet/environments/production/forge/sysstat
[R10K::Action::Deploy::Environment - INFO] Deploying module /etc/puppet/environments/production/forge/alternatives
...

Je nach Bedarf kann man r10 mit oder ohne den Parameter „-p“ ausführen. Mit „-p“ wird das Puppetfile evaluiert und die Module aus der Forge bzw. GitHub eingebunden. Lässt man den Parameter weg, werden ausschließlich die Environments ausgerollt. Empehlenswert ist evtl. auch einen Post-Commit Hook in der Repository für r10k einzurichten. Hat man mehrere Master im Einsatz können die Tools ansible oder mcollective hier unterstützen.

Citrix NetScaler 11: A+ Rating bei Qualys SSL Labs

Qualys SSL LabsNachfolgend ein kurzes Cheat-Sheet, um für Webseiten, die auf bzw. hinter einem Citrix NetScaler gehostet sind beim SSL Test von Qualys für seine Webseite ein A+ zu erhalten. Dank NetScaler Version 11 ist dies nun endlich auch für die virtuellen VPX Appliances möglich.

Zunächst benötigt man eine eigene Ciphergruppe, die den Secrurity Standard etwas höher setzt, als die von Haus aus mitgelieferten Gruppen. Für MPX und SDX Appliances kann für den zu konfigurierenden vServer folgende Cipher Group verwendet werden.

add ssl cipher cipher_secure_default
bind ssl cipher cipher_secure_default -cipherName TLS1.2-ECDHE-RSA-AES256-GCM-SHA384
bind ssl cipher cipher_secure_default -cipherName TLS1.2-ECDHE-RSA-AES128-GCM-SHA256
bind ssl cipher cipher_secure_default -cipherName TLS1.2-ECDHE-RSA-AES-256-SHA384
bind ssl cipher cipher_secure_default -cipherName TLS1.2-ECDHE-RSA-AES-128-SHA256
bind ssl cipher cipher_secure_default -cipherName TLS1-ECDHE-RSA-AES256-SHA
bind ssl cipher cipher_secure_default -cipherName TLS1-ECDHE-RSA-AES128-SHA
bind ssl cipher cipher_secure_default -cipherName TLS1.2-DHE-RSA-AES256-GCM-SHA384
bind ssl cipher cipher_secure_default -cipherName TLS1.2-DHE-RSA-AES128-GCM-SHA256
bind ssl cipher cipher_secure_default -cipherName TLS1-DHE-RSA-AES-256-CBC-SHA
bind ssl cipher cipher_secure_default -cipherName TLS1-DHE-RSA-AES-128-CBC-SHA
bind ssl cipher cipher_secure_default -cipherName TLS1-AES-256-CBC-SHA
bind ssl cipher cipher_secure_default -cipherName TLS1-AES-128-CBC-SHA
bind ssl cipher cipher_secure_default -cipherName SSL3-DES-CBC3-SHA

Für die NetScaler VPX kann folgendes Set benutzt werden (hier werden aktuell nicht alle Ciphers unterstützt).

add ssl cipher cipher_secure_default_vpx
bind ssl cipher cipher_secure_default_vpx -cipherName TLS1.2-ECDHE-RSA-AES-128-SHA256
bind ssl cipher cipher_secure_default_vpx -cipherName TLS1-ECDHE-RSA-AES256-SHA
bind ssl cipher cipher_secure_default_vpx -cipherName TLS1-ECDHE-RSA-AES128-SHA
bind ssl cipher cipher_secure_default_vpx -cipherName TLS1-DHE-RSA-AES-256-CBC-SHA
bind ssl cipher cipher_secure_default_vpx -cipherName TLS1-DHE-RSA-AES-128-CBC-SHA
bind ssl cipher cipher_secure_default_vpx -cipherName TLS1-AES-256-CBC-SHA
bind ssl cipher cipher_secure_default_vpx -cipherName TLS1-AES-128-CBC-SHA
bind ssl cipher cipher_secure_default_vpx -cipherName SSL3-DES-CBC3-SHA

Zusätzlich benötigt man noch eine Rewrite Policy, um den HTTP STS Header in die Server Response einzufügen. Diese Policy kann entweder global oder für jeden vServer gebunden werden.

add rewrite action act_rewrite_inject_http_sts_header insert_http_header Strict-Transport-Security "\"max-age=31536000\""
add rewrite policy pol_rewrite_inject_http_sts_header true act_rewrite_inject_http_sts_header

Final sollte SSLv3 global oder lokal mittels SSL Profile deaktiviert werden.

add ssl profile prof_ssl_default -sessReuse ENABLED -sessTimeout 120 -ssl3 DISABLED

ProGet als bessere Chocolatey Repository Verwaltung

So, eine kleine Forsetzung vom letzten Beitrag. Ich hatte gezeigt das Chocolatey auch CIFS-Shares bzw. UNC-Pfade und lokale Verzeichnise als Install Source supportet. Für eine sehr kleine lokale Repository reicht das auch aus. Leider muss man dann natürlich auf das nette Feature von pushen von Paketen verzichten. Außerdem bin ich als Linux Admin selbst kein wirklicher Freund von CIFS. Generell war ich mit der Lösung nicht voll zufrieden.

Mein primäres Ziel war eigentlich einen NuGet.Server aufzusetzen. Versucht habe ich es, aber nach einigen Studen Arbeit in Visual Studio for Web und der Anpassung IIS Konfiguration habe ich es nun aufgegeben. Viel mehr als die Startseite funktionierte nicht, beim Package Discovery blieb es bei einem HTTP Error 404.

Durch das Debugging bin ich aber über eine Google Group an eine deutlich schönere und auch einfachere Lösung gestoßen. ProGet ist ein Repository Server für NuGet und Chocolatey mit kommerziellen Hintergrund, den es aber auch freie Version gibt.

Die Installation ist Windowstypisch extrem einfach. Durchklicken und es funktioniert. ProGet benötigt einen SQL-Server (SQL Express) und einen Webserver (wahlweise einen eigenen eine vorhandene IIS Instanz). Das wars.

ProGet

ProGet hat viele nette Features. Pakete können über Web oder den NuGet Push hochgeladen werden. Das Caching sowie das Staging von Paketen in verschiedenen Environments ist möglich und die Webadministration kann sauber in eine LDAP Struktur integriert werden.

An dieser Stelle sei nochmal erwähnt: Microsofts One-Get setzt auf dem Chocolatey Paketmanagement auf. Mit dem offiziellen Release von PowerShell v5 (aktuell ist das Projekt noch im „Preview“ Status) können diese Repositorys auch nativ in Windows genutzt werden.

Ich halte Chocolatey und NuGet für eine zukunftsweisende Lösung von einfacher Softwareverteilung unter Windows. Gerade dann, wenn man das ganze als eine Art Framework nutzt und in Puppet etc. einbindet. Wir werden sehen wie es mit dem Chocolatey Projekt weiter geht. Aktuell läuft hier auf Kickstarter ein Crowdfunding, mit dem sich das Projekt dann sein Büro einrichten möchte und eine kommerzielle „Chocolatey Enterprise“ Lösung schaffen möchte. Dazu kommt natürlich Microsoft, die durch One-Get hier auch einiges voran bringen sollten.

chocolatey unter Windows mit lokaler Repository

Ich bin aktuell dabei einige Software Pakete auf Windows Systeme möglichst automatisiert auszurollen. Das Ziel sollte sein dabei immer eine definierte Version, eventuell je nach Stage (development, qa, production) installiert zu haben. Als Tool zum Software Rollout und Configuration Management kommt selbstverständlch Puppet zum Einsatz. Bisher habe ich das über den standardmäßigen MSI Package Provider in Puppet gelöst.

Generell hat dies leider einige unschöne Nachteile. Einer ist, das man jedes mal sein Puppet Manifest anpassen muss um auf das korrekte MSI Paket zu verweisen. Mit Umwegen (z.B. statischen Namen auf einem CIFS-Share) könnte man das durchaus noch lösen und damit leben. Deutlich unschöner ist aber das man auf die schnelle nicht herausfinden kann, welche Pakete bisher überhaupt installiert wurden und vorallem in welcher Version, sollte es tatsächlich mal Probleme beim Rollout/Upgrade gegeben haben.

Eine Alternative ist hier chocolatey, das ich bereits seit längerem kenne und aktiv nutze. Das Tool chocolatey stellt eine Art APT-Repository für Windows bereit. Das Rad wude dabei nicht komplett neu entwickelt, sondern chocolatey nutzt NuGet als Backend. NuGet wird dem einen oder anderen Windows Developer ein Begriff sein und kann genutzt werden um Dependencies für Visual Studio Projekte herunterzuladen. Grundsätzlich könnte man also auch direkt NuGet benutzen. Leider hat das Command Line Util von Microsoft nicht alle Funktionen zur Verfügung, weshalb man aufwändig die Visual Studio Extensions installieren müsste.

Als offizielle Microsoft Lösung kann man künftig auch das OneGet Powershell CMDlet verwenden. Dies ist im Prinzip eine Implementation der Chocolatey Funktionalitäten, die in den neuen PowerShell und Windows Releases direkt einfließen soll. Auch OneGet basiert auf der NuGet API und kann somit z.B. mit chocolatey.org sprechen. Leider gibt es hier noch keinen Puppet Package Provider, was aber sicherlich nur eine Frage der Zeit ist.

Der chocolatey Client kann generell mit einem einzigen PowerShell Befehl installiert werden. Puppetlabs hat bereits ein offizielles Powershell Modul, was man dazu durchaus verwenden kann.

iex ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1'))

Das Problem an der chocolatey.org Repository ist für mich jedoch der Punkt, das es bis vor kurzem keinerlei Überprüfungen der Pakete gab. Dies hat sich zwar nun geändert, leider sind Pakete (z.B. NSClient++) massiv veraltet und somit kaum benutzbar. Dies war auch bis dato der Grund warum ich chocolatey in Produktion nicht in Betracht gezogen habe. Nun habe ich mich heute aber kurz mit dem Thema NuGet genauer auseinandergesetzt und festgestellt das das bauen eigener Pakete wirklich extrem simpel ist.

Für eine einfache Installation eine MSI Pakets benötigt man ledeglich zwei Dateien:

  • meinpaket.nuspec
  • tools/chocolateyInstall.ps1

Die meinpaket.nuspec (z.B. puppet.nuspec) ist im Prinzip ein Metafile, was das Paket beschreibt. Das ganze ist in einfachem XML aufgebaut.

<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
  <metadata>
    <id>puppet</id>
    <version>3.7.3</version>
    <authors>Puppetlabs</authors>
    <description>Puppet Agent for Windows</description>
    <language>en-US</language>
    <projectUrl>http://blog.simlau.net</projectUrl>
    <licenseUrl>http://blog.simlau.net</licenseUrl>
  </metadata>
</package>

Das zweite benötigte File ist die chocolateyInstall.ps1. Ein PowerShell Script, das die MSI Source angibt.

Install-ChocolateyPackage 'puppet' 'MSI' '/qn' 'http://downloads.puppetlabs.com/windows/puppet-3.7.3.msi' 'http://downloads.puppetlabs.com/windows/puppet-3.7.3-x64.msi' -validExitCodes @(0)

Das CMDlet „Install-ChocolateyPackage“ wird dabei von „cinst“ aufgerufen, um das Paket zu bauen. Angegeben werden neben dem Paketnamen und den Install Parametern (für das MSI-Paket) zwei URLs, jeweils eine für 32-Bit und eine für 64-Bit Installationen. Chocolatey wählt automatisch das passende Paket anhand der Systemarchitektur (und des entsprechenden HKEYs in der Registry) aus.

Wer Paket für chocolatey.org bauen will, sollte sich die Doku genauer ansehen. Es gibt „Powershell-Templates“, die verwendet werden sollten um z.B. Fehler bei Installationen abzufangen. Für ein Beispielpaket reicht der obige Code jedoch vollkommen aus.

Um nun ein Paket darus zu schnüren reicht ein einziger Befehl.

PS C:\Users\Simon\puppet> cpack.exe .\puppet.nuspec
Calling 'C:\ProgramData\chocolatey\chocolateyinstall\nuget.exe pack .\puppet.nuspec -NoPackageAnalysis -NonInteractive'

Es wird versucht, das Paket aus "puppet.nuspec" zu erstellen.
Das Paket "C:\Users\Simon\puppet\puppet.3.7.3nupkg" wurde erfolgreich erstellt.

Installieren kann man das Paket nun unter der Angabe des Parameters -source

cinst -source C:\Users\Simon\puppet puppet

Leider nicht dokumentiert ist, wie man die standardmäßige Repository „chocolatey.org“ für den Client deaktiviert, dies ist jedoch auch möglich. Chocolatey bringt unter C:\ProgramData\chocolatey\chocolateyinstall\chocolatey.config eine Konfigurationsdatei mit, in der die Standardrepository hinterlegt ist.

<?xml version="1.0"?>
<chocolatey>
    <useNuGetForSources>false</useNuGetForSources>
    <checksumFiles>true</checksumFiles>
    <virusCheck>false</virusCheck>
    <sources>
        <source id="chocolatey" value="https://chocolatey.org/api/v2/" />
    </sources>
</chocolatey>

Um nun nicht bei jedem „cinst“ die Source mit angeben zu müssen und zudem die chocolatey.org Repository zu deaktivieren, kann man die Zeile z.B. einfach wie folgt anpassen.

<source id="custom" value="C:\chocolatey_repo" />

Chocolatey kann hier auch mit UNC Pfaden umgehen, womit man das ganze auch auf einen internen CIFS-Share auslagern kann.

Alles nötige für das Management von chocolatey (Installation und Konfiguration) auf Windows habe ich bereits in ein Puppet Modul einfließen lassen, das ich beizeiten auch noch in der Puppet Forge veröffentlichen möchte.

LDAPAdmin Directory Browser

LDAPAdmin LDAPAdmin ist ein nettes Tool, was ich nun bereits seit längerer Zeit für mich und für Kunden verwende und ich kann es mittlerweile nur uneingeschränkt weiterempfehlen. Bei LDAPAdmin handelt es sich um ein Windows Tool, das die eher lästige Arbeit bei der Anbindung von Systemen an eine (Windows) LDAP-Authentifizierung etwas vereinfacht.

Es handelt es sich schlicht um einen recht einfach gehaltenen Browser für LDAP Verzeichnise. Man kann sich durch seine gewohnte Windows DC/OU-Struktur klicken und sich die DN zu Computer, User oder Group Objekten direkt in die Zwischenablage kopieren um Sie anschließend direkt für seinen LDAP Filter verwenden zu können. Jedem der schon einmal mit LDAP zu tun hatte, sollte hier zumindest die BaseDN ein Begriff sein.

Der Zugriff LDAP Objekte ist sowohl lesend als auch schreibend möglich. Dadurch geht z.B. auch das setzen von neuen AD-Attributen (z.B. Unix Attribute: UID, HomeDirectory usw.) deutlich schneller, als über die (versteckten?) Bordmittel von Microsoft. Auch das zurücksetzen von Usern Kennwörtern ist selbstverständlich möglich.

LDAPAdmin ist OpenSource und kann hier heruntergeladen werden.