diff --git a/files/znc.conf b/files/znc.conf
index 14dc7426e86c2f4fa9daa3791b8735e69f17b647..ad2fcf92de0e16d9eed553b270dac6f77edbb9dc 100644
--- a/files/znc.conf
+++ b/files/znc.conf
@@ -24,7 +24,6 @@ SSLKeyFile = /etc/letsencrypt/live/verdigris.lysator.liu.se/privkey.pem
 	AllowWeb = false
 </Listener>
 
-
 <Listener httplistener>
 	Port = 443
 	IPv4 = true
@@ -55,5 +54,4 @@ SSLKeyFile = /etc/letsencrypt/live/verdigris.lysator.liu.se/privkey.pem
 		Method = SHA256
 		Salt = D?7uVG,WyJG+B+flUJ_j
 	</Pass>
-
 </User>
diff --git a/templates/znc.service.epp b/files/znc.service
similarity index 55%
rename from templates/znc.service.epp
rename to files/znc.service
index 6e3d6efa5f52c597fd958513d9d28973848d613a..1f90a9293b2be017249d9c49e2abaa0fef9ec9d1 100644
--- a/templates/znc.service.epp
+++ b/files/znc.service
@@ -1,5 +1,3 @@
-<%- | String $keyname
-| -%>
 [Unit]
 Description=ZNC, an advanced IRC bouncer
 After=network-online.target
@@ -9,8 +7,5 @@ ExecStart=/usr/bin/znc --foreground --datadir=/var/lib/znc
 AmbientCapabilities=CAP_NET_BIND_SERVICE
 User=znc
 
-# LoadCredential=fullchain.pem:/etc/letsencrypt/live/<%= $keyname %>/fullchain.pem
-# LoadCredential=privkey.pem:/etc/letsencrypt/live/<%= $keyname %>/privkey.pem
-
 [Install]
 WantedBy=multi-user.target
diff --git a/manifests/ident.pp b/manifests/ident.pp
index 7053fdd79c9da19766593ae3ef40089536292b8f..a020b83f611fae5b39089b6b78e6093990562200 100644
--- a/manifests/ident.pp
+++ b/manifests/ident.pp
@@ -4,8 +4,8 @@
 class irc_bouncer::ident {
   ensure_packages(['oidentd',], { ensure => installed, })
 
-  $oident_conf = @(EOF)
-    user "znc" {
+  $oident_conf = @("EOF")
+    user "${irc_bouncer::setup::user}" {
       default {
         allow spoof
         allow spoof_all
@@ -15,7 +15,7 @@ class irc_bouncer::ident {
 
   file { '/etc/oidentd.conf':
     ensure  => file,
-    group   => 'znc',
+    group   => $irc_bouncer::setup::user,
     mode    => '0664',
     content => $oident_conf,
   }
@@ -27,8 +27,14 @@ class irc_bouncer::ident {
 
   irc_bouncer::module { 'identfile': }
 
-  file { '/var/lib/znc/moddata/identfile/.registry':
+  file { "${irc_bouncer::setup::datadir}/moddata/identfile":
+    ensure => directory,
+    owner  => $irc_bouncer::setup::user,
+  }
+
+  file { "${irc_bouncer::setup::datadir}/moddata/identfile/.registry":
     ensure  => file,
+    owner   => $irc_bouncer::setup::user,
     content => [
       'File /etc/oidentd.conf',
       'Format global { reply "%user%" }',
diff --git a/manifests/init.pp b/manifests/init.pp
index f8526bbf0f83a5c679443ec48f44a9bf1422a8ca..acb1e53f629d3021aaffb9d583a7ecb5a5e72131 100644
--- a/manifests/init.pp
+++ b/manifests/init.pp
@@ -1,7 +1,6 @@
 # @summary
 class irc_bouncer {
   require irc_bouncer::setup
-  require irc_bouncer::ident
 
   service { 'znc':
     ensure => running,
diff --git a/manifests/sasl.pp b/manifests/sasl.pp
new file mode 100644
index 0000000000000000000000000000000000000000..a993e01dadb159eeb6e849d44d2289a69f9009ea
--- /dev/null
+++ b/manifests/sasl.pp
@@ -0,0 +1,46 @@
+# @summary Configures central authentication
+# 
+# Configures saslauthd to allow authentication through pam,
+#
+# Also loads the ZNC cyrusauth module and configures it to use
+# saslauth.
+#
+# @param package
+#   Name of the package providing saslauthd
+class irc_bouncer::sasl (
+  String $package = 'sasl2-bin',
+) {
+  ensure_packages([$package], { ensure => installed, })
+
+  file_line { 'saslauthd START=yes':
+    ensure  => present,
+    path    => '/etc/default/saslauthd',
+    line    => 'START=yes',
+    match   => '^START=',
+    require => Package[$package],
+    notify  => Service['saslauthd'],
+  }
+
+  file_line { 'saslauthd pam':
+    ensure  => present,
+    path    => '/etc/default/saslauthd',
+    line    => 'MECHANISMS="pam"',
+    match   => '^MECHANISMS=',
+    require => Package[$package],
+    notify  => Service['saslauthd'],
+  }
+
+  service { 'saslauthd':
+    ensure => running,
+    enable => true,
+  }
+
+  file { "${irc_bouncer::setup::datadir}/moddata/cyrusauth":
+    ensure => directory,
+    owner  => $irc_bouncer::setup::user,
+  }
+
+  irc_bouncer::module { 'cyrusauth':
+    args => ['saslauthd'],
+  }
+}
diff --git a/manifests/setup.pp b/manifests/setup.pp
index 41fdd3c2cc121aadc8945817390d8fc8b254d850..d46b6363e6baa047618ebcf4f59a9822048ccc56 100644
--- a/manifests/setup.pp
+++ b/manifests/setup.pp
@@ -1,61 +1,36 @@
 # @summary Initial configuration of ZNC
-class irc_bouncer::setup {
+# @api private
+class irc_bouncer::setup (
+  Stdlib::Absolutepath $datadir = '/var/lib/znc',
+  String $user                  = 'znc',
+  String $package               = 'znc',
+) {
   file { [
-      '/var/lib/znc',
-      '/var/lib/znc/configs',
-      '/var/lib/znc/mobdata',
-      '/var/lib/znc/moddata/cyrusauth',
-      '/var/lib/znc/moddata/identfile',
+      $datadir,
+      "${datadir}/configs",
+      "${datadir}/mobdata",
     ]:
       ensure => directory,
-      owner  => 'znc',
+      owner  => $user,
   }
 
-  # We use a self-packaged version of ZNC, whose package source is
-  # available at:
-  # https://git.lysator.liu.se/hugo/deb-znc
-  # It also comes bundled with a lysator module.
-
-  ensure_packages(['znc'], { ensure => latest, })
-
-  ensure_packages(['sasl2-bin'], { ensure => installed, })
-
-  file_line { 'saslauthd remove START=no':
-    ensure  => absent,
-    path    => '/etc/default/saslauthd',
-    line    => 'START=no',
-    require => Package['sasl2-bin'],
-  }
-
-  file_line { 'saslauthd START=yes':
-    ensure  => present,
-    path    => '/etc/default/saslauthd',
-    line    => 'START=yes',
-    require => Package['sasl2-bin'],
-  }
-
-  file_line { 'saslauthd pam':
-    ensure  => present,
-    path    => '/etc/default/saslauthd',
-    line    => 'MECHANISMS="pam"',
-    require => Package['sasl2-bin'],
-  }
+  ensure_packages([$package], { ensure => latest, })
 
   # restart saslauthd here?
 
-  user { 'znc':
+  user { $user:
     comment => 'ZNC Daemon runner',
-    home    => '/var/lib/znc',
+    home    => $datadir,
     system  => true,
     shell   => '/usr/sbin/nologin',
     groups  => ['sasl',],
   }
 
-  file { '/var/lib/znc/configs/znc.conf':
+  file { "${datadir}/configs/znc.conf":
     ensure  => file,
     replace => no,
-    source  => 'puppet:///modules/irc_bouncer/znc.conf',
-    owner   => 'znc',
+    source  => "puppet:///modules/${module_name}/znc.conf",
+    owner   => $user,
   }
 
   $certname = $facts['networking']['fqdn']
@@ -76,25 +51,13 @@ class irc_bouncer::setup {
     line  => "SSLKeyFile = /etc/letsencrypt/live/${certname}/privkey.pem",
   }
 
-  # lysconf module comes bundled with lysator-version of znc
-
   irc_bouncer::module { [
       'webadmin',
       'fail2ban',
       'chansaver',
-      'lysconf',
     ]:
   }
 
-  irc_bouncer::module { 'cyrusauth':
-    args => ['saslauthd'],
-  }
-
-  file { '/var/lib/znc/moddata/cyrusauth/.registry':
-    ensure  => file,
-    content => "CreateUser true\n",
-  }
-
   # Möjliga standarder för nya användare?
   # Gör så play-back ligger kvar även efter man sätt dem.
   # <user>
@@ -105,8 +68,7 @@ class irc_bouncer::setup {
   # Se möjligen även över loggar
 
   systemd::unit_file { 'znc.service':
-    content       => epp('irc_bouncer/znc.service.epp', {
-        'keyname' => $certname,
-    }),
+    source => "file:///modules/${module_name}/znc.service",
+    before => Service['znc'],
   }
 }