Puppet — deklaratywne zarządzanie konfiguracją infrastruktury
Opublikowano: 10 kwietnia 2026 · Kategoria: VPS / Automatyzacja
Puppet to jeden z najstarszych i najbardziej dojrzałych narzędzi do zarządzania konfiguracją — istnieje od 2005 roku i jest powszechnie stosowany w dużych korporacyjnych środowiskach. Zamiast pisać procedury "co zrobić", opisujesz "jaki ma być stan" — Puppet sam decyduje jak do niego dojść. Model pull (agent odpytuje serwer) oznacza że konfiguracja jest automatycznie korygowana nawet gdy ktoś ją ręcznie zmieni. Ten artykuł pokazuje architekturę Puppet, Puppet DSL, Hiera i Puppet Bolt.
Instalacja Puppet Primary Server
# === Puppet Primary Server (Ubuntu 22.04) === # Dodaj repozytorium Puppet wget https://apt.puppet.com/puppet8-release-jammy.deb sudo dpkg -i puppet8-release-jammy.deb sudo apt update # Zainstaluj Puppet Server sudo apt install puppetserver -y # Konfiguracja pamięci (dostosuj do RAM VPS) # /etc/default/puppetserver # JAVA_ARGS="-Xms1g -Xmx1g ..." # Domyślnie 2GB, dla małego VPS: 512m-1g sudo systemctl enable --now puppetserver sudo systemctl status puppetserver # === Na każdym węźle (agent) === wget https://apt.puppet.com/puppet8-release-jammy.deb sudo dpkg -i puppet8-release-jammy.deb sudo apt update && sudo apt install puppet-agent -y # Konfiguracja agenta sudo tee -a /etc/puppetlabs/puppet/puppet.conf <<'EOF' [agent] server = puppet.moja-firma.pl environment = production EOF # Pierwsze połączenie — generuje certyfikat i wysyła CSR sudo /opt/puppetlabs/bin/puppet agent --test --server puppet.moja-firma.pl # === Na Primary Server — podpisz certyfikat agenta === sudo /opt/puppetlabs/bin/puppetserver ca list --all # Czekające CSR sudo /opt/puppetlabs/bin/puppetserver ca sign --certname web-prod-01 sudo /opt/puppetlabs/bin/puppetserver ca sign --all # Podpisz wszystkie
Puppet DSL — zasoby, klasy i moduły
Puppet DSL to deklaratywny język własny Puppet. Plik manifestu (.pp) zawiera
deklaracje zasobów (resources), klasy (reużywalne zestawy zasobów) i zależności między nimi:
# Podstawowe typy zasobów Puppet DSL
# Package — zarządzanie pakietami
package { 'nginx':
ensure => 'installed',
}
package { ['curl', 'wget', 'vim', 'htop']:
ensure => 'present',
}
# File — pliki i katalogi
file { '/etc/nginx/nginx.conf':
ensure => 'file',
owner => 'root',
group => 'root',
mode => '0644',
content => template('nginx/nginx.conf.erb'),
notify => Service['nginx'], # Restart nginx po zmianie
require => Package['nginx'], # Wymaga instalacji nginx
}
file { '/var/www/html':
ensure => 'directory',
owner => 'www-data',
group => 'www-data',
mode => '0755',
}
# Service — usługi systemowe
service { 'nginx':
ensure => 'running',
enable => true,
require => Package['nginx'],
}
# User — zarządzanie użytkownikami
user { 'deploy':
ensure => 'present',
uid => 1001,
gid => 'deploy',
home => '/home/deploy',
managehome => true,
shell => '/bin/bash',
groups => ['sudo'],
}
# Exec — jednorazowe komendy (używaj ostrożnie!)
exec { 'certbot-nginx':
command => '/usr/bin/certbot --nginx -d domena.pl --non-interactive --agree-tos -m [email protected]',
creates => '/etc/letsencrypt/live/domena.pl/fullchain.pem',
require => Package['certbot'],
} Klasy i moduły
# Definicja klasy (moduł nginx)
# /etc/puppetlabs/code/environments/production/modules/nginx/manifests/init.pp
class nginx (
Integer $port = 80,
String $server_name = $facts['networking']['fqdn'],
Boolean $manage_service = true,
) {
package { 'nginx':
ensure => 'installed',
}
file { '/etc/nginx/nginx.conf':
ensure => 'file',
content => template('nginx/nginx.conf.erb'),
require => Package['nginx'],
notify => Service['nginx'],
}
if $manage_service {
service { 'nginx':
ensure => 'running',
enable => true,
require => [Package['nginx'], File['/etc/nginx/nginx.conf']],
}
}
}
# Użycie klasy w manifeście węzła (site.pp)
# /etc/puppetlabs/code/environments/production/manifests/site.pp
node 'web-prod-01.firma.pl' {
class { 'nginx':
port => 80,
server_name => 'mojasrona.pl',
}
class { 'mysql':
root_password => lookup('mysql::root_password'),
}
}
# Lub przez include (z parametrami z Hiera)
node /^web-prod-\d+\.firma\.pl$/ {
include nginx
include php_fpm
} Puppet Forge — gotowe moduły ze społeczności
# Instalacja modułów z Puppet Forge puppet module install puppetlabs-nginx --version 4.3.0 puppet module install puppetlabs-mysql --version 14.0.0 puppet module install puppetlabs-firewall # Wylistuj zainstalowane moduły puppet module list # Plik Puppetfile (zarządzanie modułami przez r10k) # /etc/puppetlabs/r10k/Puppetfile forge "https://forgeapi.puppet.com" mod 'puppetlabs-nginx', '4.3.0' mod 'puppetlabs-mysql', '14.0.0' mod 'puppetlabs-firewall', '7.0.0' mod 'puppet-php', '9.0.0' # Własny moduł z Git repo mod 'my_company-deploy', :git => 'https://github.com/my-company/puppet-deploy.git', :branch => 'main' # Synchronizacja modułów przez r10k r10k puppetfile install
Hiera — hierarchia danych i sekrety
# Konfiguracja Hiera
# /etc/puppetlabs/puppet/hiera.yaml
version: 5
hierarchy:
- name: "Per-node data"
path: "nodes/%{trusted.certname}.yaml"
- name: "Per-environment data"
path: "environments/%{environment}.yaml"
- name: "Common data"
path: "common.yaml"
defaults:
datadir: /etc/puppetlabs/code/environments/production/data
# /etc/puppetlabs/code/environments/production/data/common.yaml
nginx::port: 80
php_fpm::php_version: "8.2"
mysql::root_password: "default-password" # Nadpisane per-node
# /etc/puppetlabs/code/environments/production/data/nodes/db-prod-01.firma.pl.yaml
mysql::root_password: "db-prod-superpassword!"
# W manifeście — lookup pobiera z Hiera
class { 'mysql':
root_password => lookup('mysql::root_password'),
}
# Lub w klasie przez automatic data binding (bez lookup):
# Puppet automatycznie szuka nginx::port w Hiera gdy klasa ma parametr $port
# class nginx (Integer $port = 80) — $port pochodzi z Hiera 'nginx::port' Puppet Bolt — zadania ad-hoc i orkiestracja
# Instalacja Bolt
wget https://apt.puppet.com/puppet-tools-release-jammy.deb
sudo dpkg -i puppet-tools-release-jammy.deb
sudo apt update && sudo apt install puppet-bolt -y
bolt --version
# inventory.yaml — lista hostów
targets:
- name: web-servers
uri: web-prod-01.firma.pl
config:
ssh:
user: ubuntu
private-key: ~/.ssh/id_ed25519
- name: db-servers
uri: db-prod-01.firma.pl
# Uruchomienie komendy na hostach
bolt command run 'uptime' --targets web-servers
bolt command run 'apt-get update' --targets all --run-as root
# Uruchomienie skryptu
bolt script run ./scripts/deploy.sh --targets web-servers
# Task z modułu Puppet Forge
bolt task run package name=nginx action=install --targets web-servers
# Plan — wielostopniowa orkiestracja
# plans/deploy.pp
plan deploy::app (
TargetSpec $targets,
String $version,
) {
$results = run_command("systemctl stop myapp", $targets)
upload_file("./dist/app-${version}.tar.gz", "/tmp/app.tar.gz", $targets)
run_command("tar -xzf /tmp/app.tar.gz -C /opt/myapp/", $targets)
run_command("systemctl start myapp", $targets)
}
bolt plan run deploy::app targets=web-servers version=1.2.3 Porównanie Puppet, Ansible i Chef
| Funkcja | Puppet | Ansible | Chef |
|---|---|---|---|
| Model wykonania | Pull (agent co 30 min) | Push (SSH na żądanie) | Pull (chef-client co N min) |
| Język | Puppet DSL (Ruby-like) | YAML | Ruby (Cookbooks/Recipes) |
| Agent wymagany | Tak | Nie | Tak |
| Krzywa uczenia | Wysoka | Niska | Bardzo wysoka |
| Dojrzałość | Bardzo wysoka (od 2005) | Wysoka (od 2012) | Wysoka (od 2009) |
| Raportowanie | PuppetDB + raporty | Ograniczone | Chef Infra Server |