Instalación y Configuración de Puppet
Puppet is an infrastructure automation platform that uses a client-server model with a declarative language for defining system state. Puppet enables centralized management of thousands of systems through reusable modules and manifests. This guide covers server and agent installation, writing manifests, creating modules, Hiera for data management, Facter for system discovery, and Puppet Forge for community modules.
Tabla de Contenidos
- Puppet Overview
- Server Installation
- Agent Installation
- Certificate Management
- Writing Manifests
- Creating Modules
- Hiera Data Management
- Facter for System Discovery
- Puppet Forge and Community Modules
- Conclusion
Descripción General de Puppet
Puppet is a declarative infrastructure automation tool that defines desired system state in Puppet language. The client-server model uses a central Puppet server managing agents on remote systems, enforcing desired configuration state automatically.
Key components:
- Puppet Server: Central authority managing system state
- Puppet Agent: Runs on managed nodes, pulls configuration from server
- Manifests: Files defining infrastructure state (Puppet language)
- Modules: Reusable collections of manifests and data
- Hiera: Hierarchical data management for flexibility
- Facter: System discovery, provides node information
- Catalog: Compiled configuration sent to agents
Architecture:
┌──────────────────────┐
│ Puppet Server │
│ (Master Authority) │
└──────────┬───────────┘
│ Compile catalogs
│
┌─────┴─────┬──────────┐
│ │ │
Agent Agent Agent
(Ubuntu) (CentOS) (Debian)
│ │ │
Pull config Pull config Pull config
│ │ │
Enforce Enforce Enforce
Instalación del Servidor
Install and configure the Puppet server.
Installation:
# Ubuntu/Debian
sudo apt-get update
sudo apt-get install -y puppetserver
# CentOS/RHEL
sudo yum install -y puppetserver
# macOS
brew install puppetserver
# Start server
sudo systemctl start puppetserver
sudo systemctl enable puppetserver
# Verify
sudo puppetserver ca list
Server configuration:
# /etc/puppet/puppet.conf
[master]
# Server certificate name
certname = puppet.example.com
# DNS names for certificate
dns_alt_names = puppet,puppet.example.com
# Manifest directory
manifest = /etc/puppet/manifests/site.pp
# Module path
modulepath = /etc/puppet/modules:/usr/share/puppet/modules
# SSL settings
ssl_protocols = TLSv1.2,TLSv1.3
# Memory settings
max_requests_per_instance = 1000
# Node definition
node_terminus = hiera
hiera_config = /etc/puppet/hiera.yaml
# Reporting
reports = foreman
[agent]
# Agent-side settings
runinterval = 1800 # 30 minutes
report = true
pluginsync = true
Create directory structure:
# Puppet directories
sudo mkdir -p /etc/puppet/manifests
sudo mkdir -p /etc/puppet/modules
sudo mkdir -p /etc/puppet/hieradata
# Set permissions
sudo chown -R puppet:puppet /etc/puppet
sudo chmod -R 755 /etc/puppet
Test server connectivity:
# List certificate requests
sudo puppetserver ca list
# Check server status
sudo systemctl status puppetserver
# View logs
sudo journalctl -u puppetserver -f
Instalación del Agente
Install Puppet agents on managed nodes.
Installation:
# Ubuntu/Debian
sudo apt-get update
sudo apt-get install -y puppet-agent
# CentOS/RHEL
sudo yum install -y puppet-agent
# macOS
brew install puppet-agent
# Start agent
sudo systemctl start puppet
sudo systemctl enable puppet
Agent configuration:
# /etc/puppet/puppet.conf
[agent]
# Puppet server address
server = puppet.example.com
# Agent certificate name (defaults to hostname)
certname = webserver-01
# Environment
environment = production
# Run interval
runinterval = 1800
# Report results
report = true
# Sync plugins from server
pluginsync = true
# Log level
loglevel = notice
# Log to syslog
use_syslog = true
Generate and sign certificates:
# On agent - generate certificate request
sudo puppet agent -t --waitforcert 60
# On server - list requests
sudo puppetserver ca list
# On server - sign certificate
sudo puppetserver ca sign webserver-01
# On server - sign all pending
sudo puppetserver ca sign --all
# View certificates
sudo puppetserver ca list --all
# Revoke certificate (if needed)
sudo puppetserver ca revoke webserver-01
sudo puppetserver ca clean webserver-01
Gestión de Certificados
Manage SSL certificates between server and agents.
Certificate operations:
# List all certificates
sudo puppetserver ca list --all
# List unsigned certificates
sudo puppetserver ca list
# List signed certificates
sudo puppetserver ca list --signed
# View certificate details
sudo puppetserver ca show webserver-01
# Verify certificate chain
sudo puppetserver ca verify webserver-01
# Delete certificate (remove node)
sudo puppetserver ca clean webserver-01
# Revoke certificate
sudo puppetserver ca revoke webserver-01
Automatic certificate signing:
# /etc/puppet/autosign.conf
# Enable autosign for specific pattern
*.example.com
webserver-*.prod.internal
# Or use autosign script
autosign = /usr/local/bin/autosign.sh
Custom autosign script:
#!/bin/bash
# /usr/local/bin/autosign.sh
# Automatically sign certificates from trusted networks
CERTNAME=$1
# Whitelist
if [[ "$CERTNAME" =~ ^(webserver|appserver)-[0-9]+\.prod\.internal$ ]]; then
exit 0
fi
exit 1
Escribiendo Manifiestos
Define system state using Puppet language.
Basic manifest:
# /etc/puppet/manifests/site.pp
# Apply to all nodes
node default {
# Include classes
include ::nginx
include ::ntp
include ::ssh
}
# Specific node
node 'webserver-01' {
include ::nginx
include ::php
# Resource examples
package { 'curl':
ensure => installed,
}
service { 'nginx':
ensure => running,
enable => true,
}
file { '/etc/nginx/nginx.conf':
ensure => file,
source => 'puppet:///modules/nginx/nginx.conf',
owner => 'root',
group => 'root',
mode => '0644',
require => Package['nginx'],
notify => Service['nginx'],
}
}
# Node pattern matching
node /^webserver-[0-9]+$/ {
include ::web_server
}
node /^db-(prod|staging)-[0-9]+$/ {
include ::database
}
Resource examples:
# Package installation
package { 'nginx':
ensure => '1.18.0-1ubuntu1',
before => Service['nginx'],
}
# Service management
service { 'nginx':
ensure => running,
enable => true,
provider => 'systemd',
subscribe => File['/etc/nginx/nginx.conf'],
}
# File management with template
file { '/etc/nginx/sites-available/default':
ensure => file,
content => template('nginx/vhost.erb'),
owner => 'www-data',
group => 'www-data',
mode => '0644',
require => Package['nginx'],
notify => Service['nginx'],
}
# Directory management
file { '/var/www/html':
ensure => directory,
owner => 'www-data',
group => 'www-data',
mode => '0755',
}
# Command execution
exec { 'configure-nginx':
command => '/usr/sbin/nginx -t',
unless => '/usr/sbin/nginx -t > /dev/null 2>&1',
require => Package['nginx'],
}
# Conditionals
if $::osfamily == 'Debian' {
package { 'apt-transport-https':
ensure => installed,
}
} elsif $::osfamily == 'RedHat' {
package { 'yum-plugin-fastestmirror':
ensure => installed,
}
}
Creando Módulos
Organize reusable Puppet code as modules.
Module structure:
nginx/
├── manifests/
│ ├── init.pp
│ ├── install.pp
│ ├── config.pp
│ └── service.pp
├── templates/
│ ├── nginx.conf.erb
│ └── vhost.erb
├── files/
│ └── mime.types
├── lib/
│ └── puppet/type/nginx_vhost.rb
└── README.md
Module creation:
# Generate module structure
puppet module generate company_name-nginx
# Install module
puppet module install puppetlabs-apache
# List installed modules
puppet module list
# Search Forge
puppet module search apache
Example module:
# nginx/manifests/init.pp
class nginx (
String $package_name = 'nginx',
String $service_name = 'nginx',
String $config_path = '/etc/nginx/nginx.conf',
String $user = 'www-data',
Integer $port = 80,
Boolean $enable_ssl = false,
) {
include nginx::install
include nginx::config
include nginx::service
Class['nginx::install']
-> Class['nginx::config']
-> Class['nginx::service']
}
# nginx/manifests/install.pp
class nginx::install (
String $package_name = $nginx::package_name,
) {
package { $package_name:
ensure => present,
}
}
# nginx/manifests/config.pp
class nginx::config (
String $config_path = $nginx::config_path,
String $user = $nginx::user,
Integer $port = $nginx::port,
) {
file { $config_path:
ensure => file,
content => template('nginx/nginx.conf.erb'),
owner => 'root',
group => 'root',
mode => '0644',
require => Class['nginx::install'],
notify => Class['nginx::service'],
}
}
# nginx/manifests/service.pp
class nginx::service (
String $service_name = $nginx::service_name,
) {
service { $service_name:
ensure => running,
enable => true,
require => Class['nginx::config'],
}
}
Use module in site.pp:
# /etc/puppet/manifests/site.pp
node 'webserver-01' {
class { 'nginx':
port => 8080,
user => 'www-data',
}
}
Gestión de Datos Hiera
Separate data from code using Hiera.
Hiera configuration:
# /etc/puppet/hiera.yaml
---
version: 5
defaults:
datadir: /etc/puppet/hieradata
data_hash: yaml_data
hierarchy:
- name: 'Per-node data'
path: 'nodes/%{::fqdn}.yaml'
- name: 'Per-environment data'
path: 'env/%{::environment}.yaml'
- name: 'Per-OS data'
path: 'os/%{::osfamily}.yaml'
- name: 'Common data'
path: 'common.yaml'
Hiera data files:
# /etc/puppet/hieradata/common.yaml
ntp::servers:
- 0.ubuntu.pool.ntp.org
- 1.ubuntu.pool.ntp.org
nginx::package_name: nginx
nginx::service_name: nginx
# /etc/puppet/hieradata/env/production.yaml
environment: production
nginx::port: 80
database::host: db.prod.internal
database::password: secure_password
# /etc/puppet/hieradata/nodes/webserver-01.example.com.yaml
role: webserver
nginx::port: 8080
app::name: myapp
Use Hiera in manifests:
# Access Hiera data
class web_server {
$app_name = lookup('app::name', String, 'first', 'default_app')
$db_host = lookup('database::host', String, 'first', 'localhost')
class { 'nginx':
port => lookup('nginx::port', Integer, 'first', 80),
}
}
Facter para Descubrimiento del Sistema
Leverage Facter for system information in manifests.
Built-in facts:
os
osrelease
osfamily
hostname
fqdn
ipaddress
ipaddress_eth0
netmask
gateway
memory
processorcount
timezone
Use facts in manifests:
# Use facts from Facter
if $::osfamily == 'Debian' {
package { 'apt-utils':
ensure => installed,
}
} elsif $::osfamily == 'RedHat' {
package { 'yum-utils':
ensure => installed,
}
}
# Memory-based configuration
if $::memorysize_mb > 4096 {
$max_workers = 8
} else {
$max_workers = 4
}
# Conditional based on hostname
if $::hostname =~ /^prod-/ {
include ::monitoring::agent
include ::logging::agent
}
Custom facts:
# /etc/puppet/modules/custom/lib/facter/app_version.rb
Facter.add(:app_version) do
confine :kernel => 'Linux'
setcode do
%x{/opt/app/bin/app --version 2>/dev/null}.chomp
end
end
View facts:
# List all facts
facter
# Get specific fact
facter hostname
facter osfamily
# JSON format
facter --json
Puppet Forge y Módulos Comunitarios
Leverage pre-built modules from Puppet Forge.
Install modules:
# Install specific module
puppet module install puppetlabs-apache
# Install specific version
puppet module install puppetlabs-apache -v 5.0.0
# List installed modules
puppet module list
# Update module
puppet module upgrade puppetlabs-apache
# Remove module
puppet module uninstall puppetlabs-apache
# Install from custom source
puppet module install git+https://github.com/example/module.git
Puppetfile for dependency management:
# Puppetfile
forge "https://forge.puppet.com"
# Specify versions
mod 'puppetlabs-apache', '5.0.0'
mod 'puppetlabs-mysql', '10.0.0'
mod 'puppetlabs-postgresql', '7.0.0'
# From GitHub
mod 'custom-module',
:git => 'https://github.com/myorg/puppet-module.git',
:branch => 'main'
# Install dependencies
# puppet install --puppetfile=./Puppetfile
Use Forge modules:
# /etc/puppet/manifests/site.pp
node 'database-01' {
class { 'postgresql::server':
postgres_password => 'secure_password',
}
postgresql::server::db { 'myapp':
user => 'appuser',
password => 'app_password',
}
}
Conclusión
Puppet provides powerful, declarative infrastructure automation through client-server architecture and reusable modules. By mastering manifest writing, module creation, Hiera for flexible data management, and leveraging Puppet Forge for community modules, you can automate configuration management at scale. The combination of declarative language, strong resource modeling, and extensive community support makes Puppet ideal for managing complex infrastructure consistently.


