--- /dev/null
+class sudo (
+    Optional[String[1]] $sudogroup = undef,
+) {
+    $include_directory = '/etc/sudoers.d'
+    $file_defaults = {
+        owner        => "root",
+        group        => "root",
+        mode         => "0440",
+        validate_cmd => "sh -c 'if ! visudo --check --file=%; then cat %; exit 1; fi'",
+    }
+    $default_target = '00-defaults'
+
+    include sudo::install
+    include sudo::files
+    include sudo::defaults
+
+    define option (
+        Optional[String[1]] $parameter = undef,
+        Variant[String[1],Array[String[1]],Integer,Boolean] $value = true,
+        Enum['generic','host','user','cmnd','runas'] $context = 'generic',
+        Optional[Variant[Array[String[1]],String[1]]] $list = undef,
+        String[1] $target = $sudo::default_target,
+        Integer $order = 10,
+        Optional[String[1]] $comment = undef,
+        Boolean $newline_before = true,
+    ) {
+        $param = $parameter ? { undef => $name, default => $parameter }
+        $_list = type($list) ? { list => $list, default => [$list] }
+        sudo::internals::add_sudoers_fragment { "${name}":
+            target  => $target,
+            content => template("sudo/option_line.erb"),
+            order   => $order,
+            comment => $comment,
+        }
+    }
+
+    define alias (
+        Enum['host','user','cmnd','runas'] $type,
+        Optional[Variant[Array[String[1]],String[1]]] $list = undef,
+        String[1] $target = $sudo::default_target,
+        Integer $order = 10,
+        Optional[String[1]] $comment = undef,
+        Boolean $newline_before = true,
+    ) {
+        if $name !~ /^[[:upper:]][[:upper:]_[:digit:]]*$/ {
+            fail("sudoers alias definition '$name' can only contain uppercase letter, numbers, and the underscore")
+        }
+        $_list = type($list) ? { list => $list, default => [$list] }
+        sudo::internals::add_sudoers_fragment { "${name}":
+            target  => $target,
+            content => template("sudo/alias_line.erb"),
+            order   => $order,
+            comment => $comment,
+        }
+    }
+
+    define rule (
+        Variant[Array[String[1]],String[1]] $who,
+        Variant[Array[String[1]],String[1]] $where = 'ALL',
+        Optional[Variant[Array[String[1]],String[1]]] $as_whom = 'ALL',
+        Optional[Variant[Array[String[1]],String[1]]] $as_group = 'ALL',
+        Variant[Array[String[1]],String[1]] $what,
+        String[1] $target = $sudo::default_target,
+        Integer $order = 10,
+        Optional[String[1]] $comment = undef,
+        Boolean $newline_before = true,
+    )
+    {
+        $_comment = $comment ? { undef => $name, default => $comment }
+        sudo::internals::add_sudoers_fragment { "${name}":
+            target  => $target,
+            content => template("sudo/rule_line.erb"),
+            order   => $order,
+            comment => $comment,
+        }
+    }
+}
+
+class sudo::install {
+
+    package { "sudo":
+        ensure => latest,
+    }
+}
+
+class sudo::files (
+) {
+    $include_directory = $sudo::include_directory
+    file { default:
+             *              => $sudo::file_defaults
+           ;
+           "/etc/sudoers":
+               content      => template("sudo/sudoers.erb"),
+               validate_cmd => "visudo --check --strict --file=%",
+           ;
+           "$include_directory":
+               mode         => "0770",
+               recurse      => true,
+               purge        => true,
+               ignore       => ["*.local","*-local-*","local-*"],
+           ;
+           "$include_directory/README":
+               content      => @(EOT)
+                               # This directory is managed by Puppet
+                               #
+                               # Local files can be named any of:
+                               #   - local-*
+                               #   - *-local-*
+                               #   - *.local
+                               | EOT
+           ;
+    }
+}
+
+class sudo::defaults (
+    Optional[String[1]] $sudogroup = undef,
+    Boolean $root_may_sudo = true,
+    Optional[Hash] $generic = undef,
+    Optional[Hash] $user = undef,
+    Optional[Hash] $host = undef,
+    Optional[Hash] $runas = undef,
+    Optional[Hash] $cmnd = undef,
+) {
+    $netfacts = $facts[networking] ? { undef => $facts, default => $facts[networking] }
+    sudo::alias { "LOCALHOST":
+        type => host,
+        list => [ "localhost"
+                , $netfacts[hostname]
+                , $netfacts[fqdn]
+                ],
+    }
+
+    if $sudogroup {
+        $sudogroup_target = "00-sudogroup"
+
+        group { "$sudogroup":
+            ensure => present,
+            system => true
+        }->
+        sudo::rule { "sudogroup":
+            who     => "%$sudogroup",
+            where   => "LOCALHOST",
+            require => Sudo::Alias["LOCALHOST"],
+            what    => "PASSWD: ALL",
+            target  => "$sudogroup_target",
+            comment => "Members of the ${sudogroup} group can use sudo (with password)",
+        }
+    }
+
+    if $root_may_sudo {
+        $rootsudo_target = "00-root_may_sudo"
+
+        sudo::option { "syslog":
+            value   => false,
+            context => user,
+            list    => "root",
+            target  => "$rootsudo_target",
+            comment => "No need to log root usage of sudo",
+        }->
+        sudo::rule { "root_may_sudo":
+            who     => "root",
+            where   => "LOCALHOST",
+            require => Sudo::Alias["LOCALHOST"],
+            what    => "NOPASSWD: ALL",
+            target  => "$rootsudo_target",
+            comment => "root may inadvertedly run sudo, so let them:",
+        }
+    }
+
+    if $generic {
+        concat::fragment { "sudo::defaults::generic comment":
+            target  => "sudoers_file_$sudo::default_target",
+            order   => 14,
+            content => "\n# Generated from the sudo::defaults::generic class parameter:\n",
+        }
+        $generic.each | $param, $value | {
+            sudo::option { "$param":
+                value    => $value,
+                order    => 15,
+                newline_before => false,
+                require  => Concat::Fragment["sudo::defaults::generic comment"],
+            }
+        }
+        concat::fragment { "sudo::defaults::generic end":
+            target  => "sudoers_file_$sudo::default_target",
+            order   => 16,
+            content => "# End sudo::defaults::generic class parameters\n",
+        }
+    }
+
+    $context_hash = {"user"=>$user,"host"=>$host,"runas"=>$runas,"cmnd"=>$cmnd}
+    $context_hash.keys.each | $index, $context | {
+        $defaults = $context_hash[$context]
+        if $defaults {
+            concat::fragment { "sudo::defaults::${context} comment":
+                target  => "sudoers_$default_target",
+                order   => 17 + $index * 3,
+                content => "\n# Generated from the sudo::defaults::${context} class parameter:\n",
+            }
+            $defaults.each | $list, $items  | {
+                $items.each | $param, $value | {
+                    sudo::option { "${context}_${list}_${param}":
+                        parameter => $param,
+                        context   => $context,
+                        list      => $list,
+                        value     => $value,
+                        order     => 18 + $index * 3,
+                        newline_before => false,
+                    }
+                }
+            }
+            concat::fragment { "sudo::defaults::${context} end":
+                target  => "sudoers_$default_target",
+                order   => 19 + $index * 3,
+                content => "# End sudo::defaults::${context} class parameters\n",
+            }
+        }
+    }
+}
+
+class sudo::internals {
+
+    define add_sudoers_fragment (
+        String[1] $target,
+        String[1] $content,
+        Integer $order,
+        Optional[String[1]] $comment = undef,
+    ) {
+        sudo::internals::ensure_sudoers_file { "${name}":
+            target  => $target
+        }
+        $ts = strftime("%s.%N")
+        # include the timestamp to preserve order in the output if execution
+        # is ordered
+        concat::fragment { "${ts}_sudoers_fragment_${target}_${name}":
+            target  => "sudoers_file_${target}",
+            content => $content,
+            order   => $order,
+        }
+    }
+    define ensure_sudoers_file(
+        String[1] $target,
+    ) {
+        ensure_resource('concat', "sudoers_file_${target}", {
+                tag     => "${target}",
+                path    => "${sudo::include_directory}/$target",
+                warn    => "# THIS FILE IS MANAGED BY PUPPET; CHANGES WILL BE OVERWRITTEN\n",
+                require => File[$sudo::include_directory],
+            } + $sudo::file_defaults,
+        )
+    }
+}