1 class role::backup::postgresql inherits role::backup {
2 # This manifest is supposed to be part of the backup server
4 $password_seed = lookup("base_installation::puppet_pass_seed")
6 $user = lookup("role::backup::user")
7 $group = lookup("role::backup::group")
11 $ldap_cn = lookup("base_installation::ldap_cn")
12 $ldap_password = generate_password(24, $password_seed, "ldap")
13 $ldap_server = lookup("base_installation::ldap_server")
14 $ldap_base = lookup("base_installation::ldap_base")
15 $ldap_dn = lookup("base_installation::ldap_dn")
16 $pgbouncer_ldap_attribute = "uid"
18 $pg_slot = regsubst($ldap_cn, '-', "_", "G")
20 ensure_packages(["postgresql", "pgbouncer", "pam_ldap"])
22 $pg_backup_hosts = lookup("role::backup::postgresql::backup_hosts", { "default_value" => {} })
23 $ldap_filter = lookup("role::backup::postgresql::pgbouncer_access_filter", { "default_value" => undef })
25 unless empty($pg_backup_hosts) {
26 file { "/etc/systemd/system/postgresql_backup@.service":
30 content => template("role/backup/postgresql_backup@.service.erb"),
33 unless empty($ldap_filter) {
34 concat { "/etc/pgbouncer/pgbouncer.ini":
38 ensure_newline => true,
39 notify => Service["pgbouncer"],
42 concat::fragment { "pgbouncer_head":
43 target => "/etc/pgbouncer/pgbouncer.ini",
45 content => template("role/backup/pgbouncer.ini.erb"),
48 file { "/etc/systemd/system/pgbouncer.service.d":
49 ensure => "directory",
55 file { "/etc/systemd/system/pgbouncer.service.d/override.conf":
60 content => "[Service]\nUser=\nUser=$pg_user\n",
61 notify => Service["pgbouncer"],
64 service { "pgbouncer":
69 File["/etc/systemd/system/pgbouncer.service.d/override.conf"],
70 Concat["/etc/pgbouncer/pgbouncer.ini"]
74 file { "/etc/pam_ldap.d/pgbouncer.conf":
79 content => template("role/backup/pam_ldap_pgbouncer.conf.erb"),
80 require => File["/etc/pam_ldap.d"],
82 file { "/etc/pam.d/pgbouncer":
87 source => "puppet:///modules/role/backup/pam_pgbouncer"
92 $ldap_attribute = "cn"
94 file { "/etc/pam_ldap.d":
100 file { "/etc/pam_ldap.d/postgresql.conf":
105 content => template("profile/postgresql_master/pam_ldap_postgresql.conf.erb"),
107 file { "/etc/pam.d/postgresql":
112 source => "puppet:///modules/profile/postgresql_master/pam_postgresql"
115 $pg_backup_hosts.each |$backup_host_cn, $pg_infos| {
116 $host = find_host($facts["ldapvar"]["other"], $backup_host_cn)
118 $pg_backup_host = $backup_host_cn
119 } elsif has_key($host["vars"], "host") {
120 $pg_backup_host = $host["vars"]["host"][0]
122 $pg_backup_host = $host["vars"]["real_hostname"][0]
125 $pg_path = "$mountpoint/$pg_backup_host/postgresql"
126 $pg_backup_path = "$mountpoint/$pg_backup_host/postgresql_backup"
127 $pg_host = "$pg_backup_host"
128 $pg_port = $pg_infos["dbport"]
130 if has_key($host["vars"], "postgresql_backup_port") {
131 $pg_listen_port = $host["vars"]["postgresql_backup_port"][0]
132 file { "$pg_path/certs":
138 ssl::self_signed_certificate { $backup_host_cn:
139 common_name => $backup_host_cn,
142 organization => "Immae",
145 directory => "$pg_path/certs",
146 before => File["$pg_path/postgresql.conf"],
148 $ssl_key = "$pg_path/certs/$backup_host_cn.key"
149 $ssl_cert = "$pg_path/certs/$backup_host_cn.crt"
151 $pg_listen_port = undef
157 unless empty($host) {
158 $host["ipHostNumber"].each |$ip| {
159 $infos = split($ip, "/")
160 $ipaddress = $infos[0]
161 if (length($infos) == 1 and $ipaddress =~ /:/) {
163 } elsif (length($infos) == 1) {
169 postgresql::server::pg_hba_rule { "allow TCP access for initial replication from $ipaddress/$mask":
171 database => 'replication',
172 user => $backup_host_cn,
173 address => "$ipaddress/$mask",
174 auth_method => 'pam',
176 target => "$pg_path/pg_hba.conf",
177 postgresql_version => "10",
182 if !empty($ldap_filter) and ($pg_infos["pgbouncer"]) {
183 if empty($pg_listen_port) {
184 $pg_listen_port_key = ""
186 $pg_listen_port_key = "port=$pg_listen_port"
189 concat::fragment { "pgbouncer_$pg_backup_host":
190 target => "/etc/pgbouncer/pgbouncer.ini",
192 content => "${pg_infos[pgbouncer_dbname]} = host=$mountpoint/$pg_backup_host/postgresql $pg_listen_port_key user=${pg_infos[dbuser]} dbname=${pg_infos[dbname]}",
195 postgresql::server::pg_hba_rule { "$pg_backup_host - local access as ${pg_infos[dbuser]} user":
196 description => "Allow local access to ${pg_infos[dbuser]} user",
198 database => $pg_infos["dbname"],
199 user => $pg_infos["dbuser"],
200 auth_method => 'trust',
202 target => "$pg_path/pg_hba.conf",
203 postgresql_version => "10",
207 file { "$mountpoint/$pg_backup_host":
218 require => File["$mountpoint/$pg_backup_host"],
221 file { $pg_backup_path:
226 require => File["$mountpoint/$pg_backup_host"],
229 cron::job::multiple { "backup_psql_$pg_host":
231 require => [File[$pg_backup_path], File[$pg_path]],
234 command => "/usr/bin/pg_dumpall -h $pg_path -f $pg_backup_path/\$(date -Iseconds).sql",
236 hour => "22,4,10,16",
238 description => "Backup the database",
241 command => "/usr/bin/rm -f $(ls -1 $pg_backup_path/*.sql | grep -v 'T22:' | sort -r | sed -e '1,12d')",
245 description => "Cleanup the database backups",
248 command => "cd $pg_backup_path ; /usr/bin/rm -f $(ls -1 *T22*.sql | log2rotate --skip 7 --fuzz 7 --delete --format='%Y-%m-%dT%H:%M:%S+02:00.sql')",
252 description => "Cleanup the database backups exponentially",
257 exec { "pg_basebackup $pg_path":
260 creates => "$pg_path/PG_VERSION",
261 environment => ["PGPASSWORD=$ldap_password"],
262 command => "/usr/bin/pg_basebackup -w -h $pg_host -U $ldap_cn -D $pg_path -S $pg_slot",
264 Concat["$pg_path/pg_hba.conf"],
265 Concat["$pg_path/recovery.conf"],
266 File["$pg_path/postgresql.conf"],
270 concat { "$pg_path/pg_hba.conf":
276 postgresql::server::pg_hba_rule { "$pg_backup_host - local access as postgres user":
277 description => 'Allow local access to postgres user',
281 auth_method => 'ident',
283 target => "$pg_path/pg_hba.conf",
284 postgresql_version => "10",
286 postgresql::server::pg_hba_rule { "$pg_backup_host - localhost access as postgres user":
287 description => 'Allow localhost access to postgres user',
291 address => "127.0.0.1/32",
292 auth_method => 'md5',
294 target => "$pg_path/pg_hba.conf",
295 postgresql_version => "10",
297 postgresql::server::pg_hba_rule { "$pg_backup_host - localhost ip6 access as postgres user":
298 description => 'Allow localhost access to postgres user',
302 address => "::1/128",
303 auth_method => 'md5',
305 target => "$pg_path/pg_hba.conf",
306 postgresql_version => "10",
308 postgresql::server::pg_hba_rule { "$pg_backup_host - deny access to postgresql user":
309 description => 'Deny remote access to postgres user',
313 address => "0.0.0.0/0",
314 auth_method => 'reject',
316 target => "$pg_path/pg_hba.conf",
317 postgresql_version => "10",
320 postgresql::server::pg_hba_rule { "$pg_backup_host - local access":
321 description => 'Allow local access with password',
325 auth_method => 'md5',
327 target => "$pg_path/pg_hba.conf",
328 postgresql_version => "10",
331 postgresql::server::pg_hba_rule { "$pg_backup_host - local access with same name":
332 description => 'Allow local access with same name',
336 auth_method => 'ident',
338 target => "$pg_path/pg_hba.conf",
339 postgresql_version => "10",
342 $primary_conninfo = "host=$pg_host port=$pg_port user=$ldap_cn password=$ldap_password sslmode=require"
343 $primary_slot_name = regsubst($ldap_cn, '-', "_", "G")
346 concat { "$pg_path/recovery.conf":
352 concat::fragment { "$pg_path/recovery.conf":
353 target => "$pg_path/recovery.conf",
354 content => template('postgresql/recovery.conf.erb'),
357 file { "$pg_path/postgresql.conf":
361 content => template("role/backup/postgresql.conf.erb"),
364 service { "postgresql_backup@$pg_backup_host":
368 File["/etc/systemd/system/postgresql_backup@.service"],
369 Concat["$pg_path/pg_hba.conf"],
370 Concat["$pg_path/recovery.conf"],
371 File["$pg_path/postgresql.conf"],
374 Concat["$pg_path/pg_hba.conf"],
375 Concat["$pg_path/recovery.conf"],
376 File["$pg_path/postgresql.conf"],