/puppet-systemd

Puppet module to manage systemd

Primary LanguageRubyApache License 2.0Apache-2.0

Systemd

Puppet Forge Puppet Forge Downloads Build Status Puppet Forge Endorsement By Camptocamp

Overview

This module declares exec resources to create global sync points for reloading systemd.

Version 2 and newer of the module don't work with Hiera 3! You need to migrate your existing Hiera setup to Hiera 5

Usage and examples

There are two ways to use this module.

unit files

Let this module handle file creation.

systemd::unit_file { 'foo.service':
 source => "puppet:///modules/${module_name}/foo.service",
}
~> service {'foo':
  ensure => 'running',
}

This is equivalent to:

file { '/usr/lib/systemd/system/foo.service':
  ensure => file,
  owner  => 'root',
  group  => 'root',
  mode   => '0644',
  source => "puppet:///modules/${module_name}/foo.service",
}
~> service {'foo':
  ensure => 'running',
}

You can also use this module to more fully manage the new unit. This example deploys the unit, reloads systemd and then enables and starts it.

systemd::unit_file { 'foo.service':
 source => "puppet:///modules/${module_name}/foo.service",
 enable => true,
 active => true,
}

drop-in files

Drop-in files are used to add or alter settings of a unit without modifying the unit itself. As for the unit files, the module can handle the file and directory creation:

systemd::dropin_file { 'foo.conf':
  unit   => 'foo.service',
  source => "puppet:///modules/${module_name}/foo.conf",
}
~> service {'foo':
  ensure    => 'running',
}

This is equivalent to:

file { '/etc/systemd/system/foo.service.d':
  ensure => directory,
  owner  => 'root',
  group  => 'root',
}

file { '/etc/systemd/system/foo.service.d/foo.conf':
  ensure => file,
  owner  => 'root',
  group  => 'root',
  mode   => '0644',
  source => "puppet:///modules/${module_name}/foo.conf",
}
~> service {'foo':
  ensure => 'running',
}

dropin-files can also be generated via hiera:

systemd::dropin_files:
  my-foo.conf:
    unit: foo.service
    source: puppet:///modules/${module_name}/foo.conf

tmpfiles

Let this module handle file creation and systemd reloading

systemd::tmpfile { 'foo.conf':
  source => "puppet:///modules/${module_name}/foo.conf",
}

Or handle file creation yourself and trigger systemd.

include systemd::tmpfiles

file { '/etc/tmpfiles.d/foo.conf':
  ensure => file,
  owner  => 'root',
  group  => 'root',
  mode   => '0644',
  source => "puppet:///modules/${module_name}/foo.conf",
}
~> Class['systemd::tmpfiles']

timer units

Create a systemd timer unit and a systemd service unit to execute from that timer

The following will create a timer unit and a service unit file. When active and enable are set to true the puppet service runoften.timer will be declared, started and enabled.

systemd::timer{'runoften.timer':
  timer_source   => "puppet:///modules/${module_name}/runoften.timer",
  service_source => "puppet:///modules/${module_name}/runoften.service",
  active         => true,
  enable         => true,
}

A trivial daily run. In this case enable and active are both unset and so the service daily.timer is not declared by the systemd::timer type.

$_timer = @(EOT)
[Timer]
OnCalendar=daily
RandomizedDelaySec=1d
EOT

$_service = @(EOT)
[Service]
Type=oneshot
ExecStart=/usr/bin/touch /tmp/file
EOT

systemd::timer{'daily.timer':
  timer_content   => $_timer,
  service_content => $_service,
}

service{'daily.timer':
  ensure    => running,
  subscribe => Systemd::Timer['daily.timer'],
}

If neither service_content or service_source are specified then no service unit will be created.

The service unit name can also be specified.

$_timer = @(EOT)
[Timer]
OnCalendar=daily
RandomizedDelaySec=1d
Unit=touch-me-today.service
EOT

$_service = @(EOT)
[Service]
Type=oneshot
ExecStart=/usr/bin/touch /tmp/file
EOT


systemd::timer{'daily.timer':
  timer_content   => $_timer,
  service_unit    => 'touch-me-today.service',
  service_content => $_service,
  active          => true,
  enable          => true,
}

service limits

Manage soft and hard limits on various resources for executed processes.

systemd::service_limits { 'foo.service':
  limits => {
    'LimitNOFILE' => 8192,
    'LimitNPROC'  => 16384,
  }
}

Or provide the configuration file yourself. Systemd reloading and restarting of the service are handled by the module.

systemd::service_limits { 'foo.service':
  source => "puppet:///modules/${module_name}/foo.conf",
}

Daemon reloads

Systemd caches unit files and their relations. This means it needs to reload, typically done via systemctl daemon-reload. Since Puppet 6.1.0 (PUP-3483) takes care of this by calling systemctl show $SERVICE -- --property=NeedDaemonReload to determine if a reload is needed. Typically this works well and removes the need for systemd::systemctl::daemon_reload as provided prior to camptocamp/systemd 3.0.0. This avoids common circular dependencies.

It does contain a workaround for PUP-9473 but there's no guarantee that this works in every case.

network

systemd-networkd is able to manage your network configuration. We provide a defined resource which can write the interface configurations. systemd-networkd needs to be restarted to apply the configs. The defined resource can do this for you:

systemd::network{'eth0.network':
  source          => "puppet:///modules/${module_name}/eth0.network",
  restart_service => true,
}

Services

Systemd provides multiple services. Currently you can manage systemd-resolved, systemd-timesyncd, systemd-networkd, systemd-journald and systemd-logind via the main class:

class{'systemd':
  manage_resolved  => true,
  manage_networkd  => true,
  manage_timesyncd => true,
  manage_journald  => true,
  manage_udevd     => true,
  manage_logind    => true,
}

$manage_networkd is required if you want to reload it for new systemd::network resources. Setting $manage_resolved will also manage your /etc/resolv.conf.

When configuring systemd::resolved you could set dns_stub_resolver to false (default) to use a standard /etc/resolved.conf, or you could set it to true to use the local resolver provided by systemd-resolved.

Systemd has introduced DNS Over TLS in the release 239. Currently two states are supported no and opportunistic. When enabled with opportunistic systemd-resolved will start a TCP-session to a DNS server with DNS Over TLS support. Note that there will be no host checking for DNS Over TLS due to missing implementation in systemd-resolved.

It is possible to configure the default ntp servers in /etc/systemd/timesyncd.conf:

class{'systemd':
  manage_timesyncd    => true,
  ntp_server          => ['0.pool.ntp.org', '1.pool.ntp.org'],
  fallback_ntp_server => ['2.pool.ntp.org', '3.pool.ntp.org'],
}

This requires puppetlabs-inifile, which is only a soft dependency in this module (you need to explicitly install it). Both parameters accept a string or an array.

Resource Accounting

Systemd has support for different accounting option. It can track CPU/Memory/Network stats per process. This is explained in depth at systemd-system.conf. This defaults to off (default on most operating systems). You can enable this with the $manage_accounting parameter. The module provides a default set of working accounting options per operating system, but you can still modify them with $accounting:

class{'systemd':
  manage_accounting => true,
  accounting        => {
    'DefaultCPUAccounting'    => 'yes',
    'DefaultMemoryAccounting' => 'no',
  }
}

journald configuration

It also allows you to manage journald settings. You can manage journald settings through setting the journald_settings parameter. If you want a parameter to be removed, you can pass its value as params.

systemd::journald_settings:
  Storage: auto
  MaxRetentionSec: 5day
  MaxLevelStore:
    ensure: absent

udevd configuration

It allows you to manage the udevd configuration. You can set the udev.conf values via the udev_log, udev_children_max, udev_exec_delay, udev_event_timeout, udev_resolve_names, and udev_timeout_signal parameters.

Additionally you can set custom udev rules with the udev_rules parameter.

class { 'systemd':
  manage_udevd => true,
  udev_rules   => { 
      'example_raw.rules' => {
      'rules'             => [
        'ACTION=="add", KERNEL=="sda", RUN+="/bin/raw /dev/raw/raw1 %N"',
        'ACTION=="add", KERNEL=="sdb", RUN+="/bin/raw /dev/raw/raw2 %N"',
      ],
    },
  },
}

udev::rules configuration

Custom udev rules can be defined for specific events.

systemd::udev::rule:
  ensure: present
  path: /etc/udev/rules.d
  selinux_ignore_defaults: false
  notify: "Service[systemd-udevd']"
  rules:
    - 'ACTION=="add", KERNEL=="sda", RUN+="/bin/raw /dev/raw/raw1 %N"'
    - 'ACTION=="add", KERNEL=="sdb", RUN+="/bin/raw /dev/raw/raw2 %N"',

logind configuration

It also allows you to manage logind settings. You can manage logind settings through setting the logind_settings parameter. If you want a parameter to be removed, you can pass its value as params.

systemd::logind_settings:
  HandleSuspendKey: 'ignore'
  KillUserProcesses: 'no'
  RemoveIPC:
    ensure: absent
  UserTasksMax: 10000

User linger

A loginctl_user resource is available to manage user linger enablement:

loginctl_user { 'foo':
  linger => enabled,
}

or as a hash via the systemd::loginctl_users parameter.