How to Manage sysctl.conf Parameters Efficiently with Puppet: A Practical Guide


2 views

System administrators transitioning from CFEngine to Puppet often encounter challenges when managing sysctl.conf parameters. While CFEngine provides straightforward file editing capabilities, Puppet requires a more structured approach. The key parameters like net.core.rmem_default and net.core.wmem_max demand careful handling to ensure system stability.

Many users initially try implementing solutions like:

class sysctl {
  sysctl::value {
    "net.core.rmem_default": value => "9000000";
    "net.core.wmem_default": value => "9000000";
  }
}

This often leads to errors such as:

err: Could not retrieve catalog from remote server: Error 400 on SERVER: 
Puppet::Parser::AST::Resource failed with error ArgumentError: 
Invalid resource type sysctl::value

A more reliable approach leverages Puppet's Augeas capabilities:

class sysctl {
  define conf ( $value ) {
    $key = $name
    $context = "/files/etc/sysctl.conf"
    
    augeas { "sysctl_conf/$key":
      context => "$context",
      onlyif  => "get $key != '$value'",
      changes => "set $key '$value'",
      notify  => Exec["sysctl"],
    }
  }

  file { "sysctl_conf":
    name => $operatingsystem ? {
      default => "/etc/sysctl.conf",
    },
  }

  exec { "/sbin/sysctl -p":
    alias => "sysctl",
    refreshonly => true,
    subscribe => File["sysctl_conf"],
  }
}

Here's how to apply specific sysctl settings:

class prod_sysctl {
  include sysctl
  
  sysctl::conf {
    "kernel.pid_max": value => "1048576";
    "net.core.rmem_default": value => "9000000";
    "net.core.wmem_max": value => "16777216";
  }
}

This solution provides several advantages:

  • Idempotent operations through Augeas
  • Automatic reloading of sysctl values when changed
  • Clean separation between the sysctl management framework and specific settings
  • Better error handling than direct file manipulation

For large-scale deployments, consider:

if $::virtual == 'kvm' {
  sysctl::conf { "vm.swappiness": value => "10" }
}

This demonstrates conditional application based on system facts.


While CFEngine made sysctl management straightforward with its file editing capabilities, Puppet requires a more structured approach. Many sysadmins transitioning to Puppet find themselves struggling with the paradigm shift - especially when dealing with kernel parameters like net.core.rmem_default or kernel.pid_max.

The initial approach many take is trying to replicate CFEngine's line-based editing in Puppet, which often leads to frustration. The error message:

err: Could not retrieve catalog from remote server: Error 400 on SERVER: 
Puppet::Parser::AST::Resource failed with error ArgumentError: 
Invalid resource type sysctl::value

typically occurs when trying to use undeclared resource types or when pluginsync isn't properly configured.

The most maintainable approach uses Puppet's Augeas provider, which understands the file structure and makes targeted changes. Here's a complete implementation:

class sysctl {
  define conf($value) {
    $key = $name
    $context = "/files/etc/sysctl.conf"

    augeas { "sysctl_conf/$key":
      context => $context,
      onlyif  => "get $key != '$value'",
      changes => "set $key '$value'",
      notify  => Exec["sysctl"],
    }
  }

  file { "sysctl_conf":
    name => $operatingsystem ? {
      default => "/etc/sysctl.conf",
    },
  }

  exec { "/sbin/sysctl -p":
    alias        => "sysctl",
    refreshonly  => true,
    subscribe    => File["sysctl_conf"],
  }
}

With the base module in place, you can declare specific parameters in separate classes:

class tcp_tuning {
  include sysctl

  sysctl::conf {
    "net.core.rmem_default": value => "9000000";
    "net.core.wmem_default": value => "9000000";
    "net.core.rmem_max":    value => "16777216";
    "net.core.wmem_max":    value => "16777216";
  }
}

class kernel_parameters {
  include sysctl

  sysctl::conf {
    "kernel.pid_max":      value => "1048576";
    "vm.swappiness":       value => "10";
    "fs.file-max":         value => "65536";
  }
}

For those preferring not to use Augeas, consider these methods:

1. File Line Management:

file_line { 'net.core.rmem_default':
  path  => '/etc/sysctl.conf',
  line  => 'net.core.rmem_default = 9000000',
  match => '^net\.core\.rmem_default',
}

2. Dedicated Modules:
The augeasproviders_sysctl module provides native types for sysctl management.

  • Always test changes in a non-production environment first
  • Consider using Hiera for environment-specific values
  • Monitor for sysctl parameter drift with Puppet reports
  • Combine with exec resources to load changes without reboot when needed