Pages

Puppet

Puppet is a configuration management tool used to automate server and infrastructure management. Instead of manually installing software or changing configurations, Puppet ensures the desired state is automatically applied across all machines.

Puppet Server:
Stores Manifests/Modules: Keeps configuration files (.pp) and modules (organized sets of manifests, templates, files).
Signs Agent Certificates: Approves agent SSL requests for secure communication.
Compiles Catalogs: Generates a personalized set of instructions for each agent using manifests, modules, facts, and Hiera data.
Environment Management: Manages separate environments (production, staging, development) so configurations can differ per environment.
Node Classifications: Assigns classes/modules to nodes using an external node classifier (ENC) or PuppetDB.
PuppetDB Integration: Stores facts, catalogs, and reports for querying and analytics.

Puppet Agent:
Requests Catalogs: Contacts the server to get instructions.
Applies Configuration Changes: Updates the system to match the desired state.
Reports Back: Sends a summary of changes and status to the server.
Fact Collection: Gathers system info using Facter.
Idempotency: Ensures applying the same catalog multiple times won’t cause unintended changes.
No-Operation (noop) Mode: Can test changes without applying them.

Key Components:
Manifest: File in Puppet DSL defining desired state.
Module: Collection of manifests, templates, and files for reusable configuration.
Facter: Tool on the agent that provides system information.
PuppetDB: Stores node data, facts, catalogs, and reports.
Hiera: Hierarchical data lookup to separate data from code.
Resource Types: Built-in resource types (file, package, service, user, group, cron, etc.).
Defined Types: User-defined resources for reusable configuration blocks.
Functions: Custom Puppet or Ruby functions for reusable logic.
Tasks / Plans: Bolt-compatible tasks and orchestration plans.

1. Puppet Server Installation:
1.1: Add Puppet Repository
Puppet provides its own repository for installation.
On RHEL/CentOS:
$ sudo rpm -Uvh https://yum.puppet.com/puppet7-release-el-8.noarch.rpm
sudo dnf install puppetserver -y
On Ubuntu:
wget https://apt.puppet.com/puppet7-release-jammy.deb
sudo dpkg -i puppet7-release-jammy.deb
sudo apt-get update
sudo apt-get install puppetserver -y

1.2: Configure Puppet Server
By default, Puppet Server allocates 2 GB RAM for the JVM. You can adjust /etc/sysconfig/puppetserver (RHEL/CentOS) or /etc/default/puppetserver (Ubuntu):
JAVA_ARGS="-Xms512m -Xmx512m"

1.3: Start and Enable Puppet Server
sudo systemctl enable puppetserver
sudo systemctl start puppetserver
sudo systemctl status puppetserver

1.4: Open Firewall (if applicable)
Puppet Server listens on TCP port 8140:
sudo firewall-cmd --permanent --add-port=8140/tcp
sudo firewall-cmd --reload

2. Puppet Agent (Client) Installation:
2.1: Add Puppet Repository
Use the same repository as the server.
On RHEL/CentOS:
sudo rpm -Uvh https://yum.puppet.com/puppet7-release-el-8.noarch.rpm
sudo dnf install puppet-agent -y
On Ubuntu:
sudo apt-get install puppet-agent -y

2.2: Configure Puppet Agent
Edit /etc/puppetlabs/puppet/puppet.conf:
[main]
server = puppet.example.com
certname = agent1.example.com
environment = production
runinterval = 30m
Replace puppet.example.com with your Puppet Server hostname.
certname is the unique identity for this agent.

2.3: Start and Enable Puppet Agent
sudo systemctl enable puppet
sudo systemctl start puppet
sudo systemctl status puppet

2.4: Sign Agent Certificate on Server
On the Puppet Server:
sudo puppetserver ca list  # shows pending certificate requests
sudo puppetserver ca sign --certname agent1.example.com
On the agent, test the connection:
sudo puppet agent -t
It should now communicate with the server successfully.

Puppet Resource Parameters:
Parameter                 Description                                              Example
ensure               ---> Desired state 
                                         ---> ensure => present
owner                ---> File owner (user)                                     ---> owner => 'root'
group                ---> File group                                             ---> group => 'root'
mode                 ---> File permissions (numeric)                             ---> mode => '0644'
content              ---> Text content for a file                               ---> content => 'Hello Puppet!'
source               ---> Source file location from Puppet module               ---> source => 'puppet:///modules/my_module/file.txt'
require              ---> Dependency on another resource                         ---> require => Package['nginx']
recurse              ---> Apply resource to children (files/dirs)               ---> recurse => true
enable               ---> Enable service at boot                                 ---> enable => true
provider             ---> Package manager or resource provider (yum, apt, gem)  ---> provider => 'yum'
path                 ---> Full path to file or executable                       ---> path => '/usr/bin/custom'
shell                ---> Default shell for user accounts                       ---> shell => '/bin/bash'
home                 ---> Home directory for users                               ---> home => '/home/john'
managehome           ---> Whether to create/manage user home                     ---> managehome => true
uid                  ---> User ID number                                         ---> uid => 1050
gid                  ---> Group ID number or name                               ---> gid => 'users'
hasstatus            ---> Service supports status check                         ---> hasstatus => true
hasrestart           ---> Service supports restart                               ---> hasrestart => true
subscribe            ---> Trigger resource refresh when another resource changes ---> subscribe => File['/tmp/config.txt']
notify               ---> Notify another resource to take action after changes ---> notify => Service['nginx']
backup               ---> Backup original file before changes                   ---> backup => true
replace              ---> Whether to overwrite file content                     ---> replace => true
force                ---> Force overwrite (files, links)                         ---> force => true
target               ---> Target path for symlinks or files                     ---> target => '/etc/nginx/conf.d/default.conf'
links                ---> Behavior for managing symlinks (follow, manage)    ---> links => manage
source_permissions   ---> Preserve permissions from source files                 ---> source_permissions => use
creates              ---> Only run command if file does not exist               ---> creates => '/tmp/done.txt'
command              ---> Execute a shell command                               ---> command => '/usr/bin/touch /tmp/file.txt'
cwd                  ---> Working directory for command execution               ---> cwd => '/tmp'
environment          ---> Environment variables for command                     ---> environment => ['PATH=/usr/bin:/bin']
onlyif               ---> Run command only if condition is true                 ---> onlyif => 'test -f /tmp/file.txt'
unless               ---> Run command unless condition is true                   ---> unless => 'test -f /tmp/file.txt'
timeout              ---> Timeout for command execution                         ---> timeout => 60
path (exec)          ---> Paths for executables when running commands   ---> path => ['/usr/bin','/bin']
loglevel             ---> Logging level for resource                             ---> loglevel => 'notice'
tag                  ---> Assign a tag to resource                               ---> tag => 'webserver'
seltype              ---> SELinux file type                                     ---> seltype => 'httpd_sys_content_t'
selrole              ---> SELinux role                                           ---> selrole => 'object_r'
seluser              ---> SELinux user                                           ---> seluser => 'system_u'
acl                  ---> File access control lists (Linux/Solaris)             ---> acl => ['user::rwx','group::r-x']
dacl                 ---> File access control list (Windows)                     ---> dacl => 'BUILTIN\Administrators:F'
password             ---> User account password hash                             ---> password => 'hashed_password_here'
groups               ---> Additional groups for user                             ---> groups => ['sudo','adm']
refreshonly          ---> Run exec resource only on refresh                     ---> refreshonly => true
resource_name        ---> Name of the resource instance                         ---> resource_name => 'nginx_service'
ensure_packages      ---> Ensures multiple packages are present/absent ---> ensure_packages => ['nginx','git']
path (file)          ---> Search path for file sources                           ---> path => ['/etc/puppet/files','/usr/local/files']
replace (line)       ---> Whether to replace a line in a file                   ---> replace => true
match                ---> Used in file_line to match regex patterns             ---> match => '^Listen'
line                 ---> Used in file_line to define content                   ---> line => 'Listen 8080'
notify (exec)        ---> Notify an exec resource to run after change     ---> notify => Exec['restart_nginx']
tries / try_sleep    ---> Retry execution for commands                           ---> tries => 3, try_sleep => 5
audit                ---> Track specific attributes without enforcing changes  ---> audit => ['owner','mode']
purge                ---> Remove unmanaged files in directories               ---> purge => true
source_dir           ---> Specify source directory for copying files recursively  ---> source_dir => 'puppet:///modules/my_module/dir/'

Cloud / Virtualization Specific Parameters:
Parameter               Description                                                Example
region             ---> AWS region                            ---> region => 'us-east-1'
access_key         ---> AWS access key                        ---> access_key => 'AKIA...'
secret_key         ---> AWS secret key                        ---> secret_key => '...'
instance_type      ---> AWS EC2 instance type                 ---> instance_type => 't2.micro'
image_id           ---> AWS AMI ID                            ---> image_id => 'ami-123456'
state              ---> Desired state for cloud/VM resources  ---> state => 'running'
subnet_id          ---> AWS subnet ID                         ---> subnet_id => 'subnet-12345'
security_group_ids ---> AWS security groups                   ---> security_group_ids => ['sg-12345','sg-67890']
key_name           ---> SSH key for VM access                 ---> key_name => 'my-key'
tags               ---> Assign tags to cloud resources        ---> tags => {'env'=>'prod','role'=>'web'}
disk_size          ---> VM disk size in GB                    ---> disk_size => 50
os_type            ---> OS type for VM deployment             ---> os_type => 'Linux'
network_interface  ---> Network interface attachment          ---> network_interface => 'eth0'
zone               ---> GCP compute zone                      ---> zone => 'us-central1-a'
machine_type       ---> GCP instance type                     ---> machine_type => 'n1-standard-1'
image              ---> VM image / OS                         ---> image => 'debian-11'
project            ---> GCP project name                      ---> project => 'my-gcp-project'
image_project      ---> GCP image project                     ---> image_project => 'debian-cloud'
resource_group     ---> Azure resource group                  ---> resource_group => 'my-rg'
location           ---> Azure region                          ---> location => 'eastus'
vm_size            ---> Azure VM size                         ---> vm_size => 'Standard_B1s'
availability_set   ---> Azure availability set                ---> availability_set => 'my-avset'
datacenter         ---> VMware datacenter                     ---> datacenter => 'DC1'
cluster            ---> VMware cluster name                   ---> cluster => 'Cluster1'
guest_id           ---> VMware guest OS type                  ---> guest_id => 'ubuntu64Guest'
cpu                ---> Number of CPUs for VM                 ---> cpu => 2
memory             ---> VM memory in MB                       ---> memory => 2048

Puppet Modules:
Self-contained collection of manifests, files, templates, and other resources.
Helps structure Puppet code for easy maintenance, sharing, and scaling.
Location: Typically stored in /etc/puppetlabs/code/environments/production/modules/<module_name>/.

Module Structure:
my_module/
├── manifests/      # .pp files
├── files/          # Static files
├── templates/      # ERB templates
├── examples/       # Example manifests
├── tests/          # Unit/acceptance tests
├── data/           # Hiera data (optional)
├── lib/            # Custom Ruby functions/types
└── metadata.json   # Module metadata

Module Metadata (metadata.json) Parameters:
name ---> Module name ---> name => 'my_module'
version ---> Module version ---> version => '1.0.0'
author ---> Author/maintainer ---> author => 'John Doe'
summary ---> Short module description ---> summary => 'Installs and configures Nginx'
license ---> License type ---> license => 'Apache-2.0'
source ---> Module source URL ---> source => 'https://github.com/example/my_module'
dependencies ---> Module dependencies ---> dependencies => [{"name"=>"puppetlabs/stdlib","version_requirement"=>">= 4.25.0"}]
operatingsystem_support ---> Supported OS and versions ---> operatingsystem_support => [{"operatingsystem"=>"Ubuntu","operatingsystemrelease"=>["20.04","22.04"]}]
project_page ---> URL of project homepage ---> project_page => 'https://example.com/my_module'
issues_url ---> URL for bug reports/issues ---> issues_url => 'https://github.com/example/my_module/issues'
tags ---> Keywords for module categorization ---> tags => ['nginx','webserver','puppet']

Class Parameters & Data Types:
Example class:
class nginx (
  String $package_name = 'nginx',
  Boolean $service_enable = true,
  String $config_file_path = '/etc/nginx/nginx.conf',
  String $config_template = 'nginx/nginx.conf.erb',
  String $service_ensure = 'running',
  String $file_owner = 'root',
  String $file_group = 'root',
  String $file_mode = '0644',
) {
  package { $package_name: ensure => installed }
  service { $package_name: ensure => $service_ensure, enable => $service_enable }
  file { $config_file_path:
    ensure  => file,
    content => template($config_template),
    owner   => $file_owner,
    group   => $file_group,
    mode    => $file_mode,
  }
}
package_name ---> Name of package ---> package_name => 'nginx'
service_enable ---> Enable service at boot ---> service_enable => true
config_file_path ---> Path to config file ---> config_file_path => '/etc/nginx/nginx.conf'
config_template ---> ERB template file ---> config_template => 'nginx/nginx.conf.erb'
service_ensure ---> Desired service state ---> service_ensure => 'running'
file_owner ---> Owner of managed files ---> file_owner => 'root'
file_group ---> Group of managed files ---> file_group => 'root'
file_mode ---> File permissions ---> file_mode => '0644'

Supported Data Types:
String, Boolean, Integer, Array[String], Hash[String, Any]

Defined Types & Virtual Resources
Example:
define my_module::vhost (
  String $docroot,
  String $port = '80',
) {
  file { "/var/www/${title}":
    ensure => directory,
    owner  => 'www-data',
    group  => 'www-data',
  }
}
docroot ---> Root directory of vhost ---> docroot => '/var/www/example'
port ---> Port number ---> port => '80'
virtual_resource ---> Declare without applying ---> virtual_resource => true
resource_collector ---> Collect resources dynamically ---> resource_collector => File <<| title == '/tmp/test' |>>

Hiera Integration:
Example:
$package_name = lookup('my_module::package_name', String, 'first', 'nginx')
lookup_key ---> Key to fetch from Hiera ---> lookup_key => 'my_module::package_name'
default_value ---> Value if key is missing ---> default_value => 'nginx'
hiera_hierarchy ---> Lookup hierarchy ---> hiera_hierarchy => ['nodes/%{::fqdn}.yaml','common.yaml']

Module Testing
Unit Tests: puppetlabs_spec_helper, rspec-puppet
Acceptance Tests: Beaker
Directory convention:
tests/
├── init.pp       # Basic class test
├── webserver.pp  # Specific class test
test_file ---> Path to test manifest ---> test_file => '/etc/puppetlabs/code/environments/production/modules/my_module/tests/init.pp'

No comments:

Post a Comment