]> git.madduck.net Git - puppet/acmessl.git/blob - manifests/init.pp

madduck's git repository

Every one of the projects in this repository is available at the canonical URL git://git.madduck.net/madduck/pub/<projectpath> — see each project's metadata for the exact URL.

All patches and comments are welcome. Please squash your changes to logical commits before using git-format-patch and git-send-email to patches@git.madduck.net. If you'd read over the Git project's submission guidelines and adhered to them, I'd be especially grateful.

SSH access, as well as push access can be individually arranged.

If you use my repositories frequently, consider adding the following snippet to ~/.gitconfig and using the third clone URL listed for each project:

[url "git://git.madduck.net/madduck/"]
  insteadOf = madduck:

initial checkin
[puppet/acmessl.git] / manifests / init.pp
1 class acmessl (
2     String[1] $username = 'acmecert',
3     String[1] $homedir = '/var/lib/acmecert',
4     String[1] $nsupdate_key,
5     String[1] $dnszone,
6     String[1] $dnsserver,
7     Optional[String[1]] $emailaddress = undef,
8 ) {
9     $certsdir = "$homedir/certs"
10
11     include acmessl::tools
12     include acmessl::rehash
13
14     class { "acmessl::user":
15         user    => $username,
16         homedir => $homedir,
17     }->
18     class { "acmessl::pullconfig":
19         user         => $username,
20         homedir      => $homedir,
21         dnsserver    => $dnsserver,
22         dnszone      => $dnszone,
23         nsupdate_key => $nsupdate_key,
24         certsdir     => $certsdir,
25         emailaddress => $emailaddress,
26     }->
27     class { "acmessl::sslfiles":
28         certsdir     => $certsdir,
29     }
30 }
31
32 class acmessl::sslfiles (
33     Stdlib::Absolutepath $certsdir,
34 ) {
35
36     $netfacts = $facts[networking] ? { undef => $facts, default => $facts[networking] }
37     $fqdn = $netfacts[fqdn]
38     file { "/etc/ssl/certs/${fqdn}.pem":
39         ensure => present,
40         owner  => root,
41         group  => root,
42         mode   => "0444",
43         source => "${certsdir}/cert.pem",
44         notify => Exec["update-ca-certificates"],
45     }
46     file { "/etc/ssl/certs/Lets_Encrypt_Authority_X3.pem":
47         ensure => present,
48         owner  => root,
49         group  => root,
50         mode   => "0444",
51         source => "${certsdir}/chain.pem",
52         notify => Exec["update-ca-certificates"],
53     }
54     file { "/etc/ssl/private/${fqdn}.pem":
55         ensure => present,
56         owner  => root,
57         group  => "ssl-cert",
58         mode   => "0440",
59         source => "${certsdir}/privkey.pem",
60     }
61
62 }
63
64 class acmessl::pullconfig (
65     String[1] $user,
66     Stdlib::Absolutepath $homedir,
67     Stdlib::Absolutepath $certsdir,
68     String[1] $dnsserver,
69     String[1] $dnszone,
70     String[1] $nsupdate_key,
71     Optional[Array[String[1]]] $dns_alt_names = undef,
72     Optional[String[1]] $emailaddress = undef,
73 ) {
74     $confdir = "$homedir/dehydrated"
75     $basedir = "$confdir/spool"
76     $logsdir = "$homedir/logs"
77     $_keyparts = $nsupdate_key.split(' ')
78     $key = "${_keyparts[0]}:$dnszone:${_keyparts[1]}"
79     $netfacts = $facts[networking] ? { undef => $facts, default => $facts[networking] }
80     $fqdn = $netfacts[fqdn]
81     $_dns_alt_names = $dns_alt_names ? {
82         undef => "",
83         default => $dns_alt_names.join(' '),
84     }
85     $_emailaddress = $emailaddress ? {
86         undef    => undef,
87         /.+@.+/  => $emailaddress,
88         default  => "${emailaddress}@${netfacts[fqdn]}",
89     }
90
91     file { default:
92             ensure  => present,
93             owner   => $user,
94             group   => $user,
95         ;
96         "$confdir":
97             ensure  => directory,
98             mode    => "2770",
99         ;
100         "$basedir":
101             ensure  => directory,
102             mode    => "2770",
103         ;
104         "$confdir/dehydrated.conf":
105             mode    => "0440",
106             content => epp("acmessl/dehydrated.conf.epp", {
107                             basedir => $basedir,
108                             emailaddress => $_emailaddress,
109                             }),
110         ;
111         "$confdir/domains.txt":
112             mode    => "0440",
113             content => "$fqdn $_dns_alt_names\n",
114         ;
115         "$confdir/dehydrated-wrapper":
116             mode    => "0550",
117             content => epp("acmessl/dehydrated-wrapper.epp", {
118                             logsdir => $logsdir,
119                             }),
120         ;
121         "$confdir/dehydrated-hook":
122             mode    => "0550",
123             content => epp("acmessl/dehydrated-hook.epp", {
124                             dnsserver => $dnsserver,
125                             dnszone   => $dnszone,
126                             deploydir => $certsdir,
127                             }),
128         ;
129         "$confdir/nsupdate-wrapper":
130             mode    => "0550",
131             content => epp("acmessl/nsupdate-wrapper.epp", {
132                             nsupdate_key => $key,
133                             })
134         ;
135         "$certsdir":
136             ensure  => directory,
137             mode    => "2770",
138         ;
139     }
140
141     class { "acmessl::register":
142         user    => $user,
143         confdir => $confdir,
144         basedir => $basedir,
145     }
146
147     class { "acmessl::schedule":
148         user    => $user,
149         confdir => $confdir,
150     }
151 }
152
153 class acmessl::schedule (
154     String[1] $user,
155     Stdlib::Absolutepath $confdir,
156 ) {
157     schedule { "Try to renew ACME certificates once a day":
158         period => daily,
159     }->
160     exec { "$confdir/dehydrated-wrapper --cron":
161         require   => [ Class["acmessl::tools"]
162                      , Class["acmessl::pullconfig"]
163                      , Class["acmessl::register"]
164                      ],
165         user      => $user,
166         umask     => "0007",
167         logoutput => true,
168         schedule  => "Try to renew ACME certificates once a day",
169     }
170 }
171
172 class acmessl::tools {
173     ensure_packages( [ 'dehydrated', 'dnsutils', 'ssl-cert', 'gnutls-bin' ], {
174                         ensure => latest
175                     })
176
177     file { [ "/etc/ssl/certs/ssl-cert-snakeoil.pem"
178            , "/etc/ssl/private/ssl-cert-snakeoil.key" ]:
179                ensure => absent,
180     }
181 }
182
183 class acmessl::register (
184     String[1] $user,
185     Stdlib::Absolutepath $confdir,
186     Stdlib::Absolutepath $basedir,
187 ) {
188     exec { "Register with Letsencrypt":
189         require   => [ Class["acmessl::tools"]
190                      , Class["acmessl::pullconfig"]
191                      ],
192         creates   => "$basedir/accounts",
193         command   => "$confdir/dehydrated-wrapper --register --accept-terms",
194         logoutput => true,
195         user      => $user,
196         umask     => "0007",
197     }
198 }
199
200 class acmessl::user (
201     String[1] $user,
202     Stdlib::Absolutepath $homedir,
203 )
204 {
205     group { $user:
206         ensure => present,
207         system => true,
208     }->
209     user { $user:
210         ensure         => present,
211         comment        => "ACME certificate manager,,,",
212         home           => $homedir,
213         gid            => $user,
214         system         => true,
215         shell          => "/usr/sbin/nologin",
216         purge_ssh_keys => true,
217     }->
218     file { "$homedir":
219         ensure  => directory,
220         owner   => $user,
221         group   => $user,
222         mode    => "2770",
223         recurse => true,
224         purge   => true,
225         force   => true,
226     }
227 }
228
229 class acmessl::rehash {
230     ensure_resource("exec", "update-ca-certificates", {
231         command     => "update-ca-certificates --fresh",
232         path        => "/usr/sbin:/usr/bin:/sbin:/bin",
233         cwd         => "/etc/ssl/certs",
234         logoutput   => true,
235         refreshonly => true,
236     })
237 }