aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIsmaël Bouya <ismael.bouya@normalesup.org>2018-06-28 12:17:40 +0200
committerIsmaël Bouya <ismael.bouya@normalesup.org>2018-06-28 12:17:40 +0200
commit0a145a25c0a8cbcd50d515d2a828bd6665836ddb (patch)
treec6e3832098d19917b0ba0bcbe119103c632c7d29
parentf1d583bfdaf881116e5f9ca9e050307e7acdc28e (diff)
parent3925777d9715d271c0643faef9f520e7816dba89 (diff)
downloadPuppet-0a145a25c0a8cbcd50d515d2a828bd6665836ddb.tar.gz
Puppet-0a145a25c0a8cbcd50d515d2a828bd6665836ddb.tar.zst
Puppet-0a145a25c0a8cbcd50d515d2a828bd6665836ddb.zip
Merge branch 'refactoring' into dev
-rw-r--r--modules/profile/files/postgresql/pam_pgbouncer (renamed from modules/role/files/backup/pam_pgbouncer)0
-rw-r--r--modules/profile/files/postgresql/pam_postgresql (renamed from modules/profile/files/postgresql_master/pam_postgresql)0
-rw-r--r--modules/profile/files/postgresql/pgbouncer_head.ini (renamed from modules/role/templates/backup/pgbouncer.ini.erb)0
-rw-r--r--modules/profile/manifests/pam_ldap.pp13
-rw-r--r--modules/profile/manifests/postgresql.pp64
-rw-r--r--modules/profile/manifests/postgresql/backup_dump.pp53
-rw-r--r--modules/profile/manifests/postgresql/backup_pgbouncer.pp92
-rw-r--r--modules/profile/manifests/postgresql/backup_replication.pp135
-rw-r--r--modules/profile/manifests/postgresql/base_pg_hba_rules.pp74
-rw-r--r--modules/profile/manifests/postgresql/master.pp20
-rw-r--r--modules/profile/manifests/postgresql/pam_ldap.pp28
-rw-r--r--modules/profile/manifests/postgresql/pam_ldap_pgbouncer.pp33
-rw-r--r--modules/profile/manifests/postgresql/replication.pp72
-rw-r--r--modules/profile/manifests/postgresql/ssl.pp82
-rw-r--r--modules/profile/manifests/postgresql_master.pp121
-rw-r--r--modules/profile/templates/postgresql/pam_ldap_pgbouncer.conf.erb (renamed from modules/role/templates/backup/pam_ldap_pgbouncer.conf.erb)2
-rw-r--r--modules/profile/templates/postgresql/pam_ldap_postgresql.conf.erb (renamed from modules/profile/templates/postgresql_master/pam_ldap_postgresql.conf.erb)0
-rw-r--r--modules/profile/templates/postgresql/postgresql_backup@.service.erb (renamed from modules/role/templates/backup/postgresql_backup@.service.erb)4
-rw-r--r--modules/role/manifests/backup.pp8
-rw-r--r--modules/role/manifests/backup/postgresql.pp376
-rw-r--r--modules/role/manifests/cryptoportfolio/postgresql.pp194
-rw-r--r--modules/role/manifests/etherpad.pp2
22 files changed, 640 insertions, 733 deletions
diff --git a/modules/role/files/backup/pam_pgbouncer b/modules/profile/files/postgresql/pam_pgbouncer
index 13f0d3d..13f0d3d 100644
--- a/modules/role/files/backup/pam_pgbouncer
+++ b/modules/profile/files/postgresql/pam_pgbouncer
diff --git a/modules/profile/files/postgresql_master/pam_postgresql b/modules/profile/files/postgresql/pam_postgresql
index 70a90ae..70a90ae 100644
--- a/modules/profile/files/postgresql_master/pam_postgresql
+++ b/modules/profile/files/postgresql/pam_postgresql
diff --git a/modules/role/templates/backup/pgbouncer.ini.erb b/modules/profile/files/postgresql/pgbouncer_head.ini
index 3ba8728..3ba8728 100644
--- a/modules/role/templates/backup/pgbouncer.ini.erb
+++ b/modules/profile/files/postgresql/pgbouncer_head.ini
diff --git a/modules/profile/manifests/pam_ldap.pp b/modules/profile/manifests/pam_ldap.pp
new file mode 100644
index 0000000..956a7cd
--- /dev/null
+++ b/modules/profile/manifests/pam_ldap.pp
@@ -0,0 +1,13 @@
1class profile::pam_ldap (
2) {
3 ensure_packages(["pam_ldap"])
4
5 file { "/etc/pam_ldap.d":
6 ensure => directory,
7 mode => "0755",
8 owner => "root",
9 group => "root",
10 require => Package["pam_ldap"],
11 }
12}
13
diff --git a/modules/profile/manifests/postgresql.pp b/modules/profile/manifests/postgresql.pp
index 2cd1bcc..97ce572 100644
--- a/modules/profile/manifests/postgresql.pp
+++ b/modules/profile/manifests/postgresql.pp
@@ -1,4 +1,7 @@
1class profile::postgresql { 1class profile::postgresql (
2 Optional[String] $pg_user = "postgres",
3 Optional[String] $pg_group = "postgres",
4) {
2 $password_seed = lookup("base_installation::puppet_pass_seed") 5 $password_seed = lookup("base_installation::puppet_pass_seed")
3 6
4 class { '::postgresql::globals': 7 class { '::postgresql::globals':
@@ -7,16 +10,13 @@ class profile::postgresql {
7 pg_hba_conf_defaults => false, 10 pg_hba_conf_defaults => false,
8 } 11 }
9 12
10 # FIXME: get it from the postgresql module?
11 $pg_user = "postgres"
12
13 class { '::postgresql::client': } 13 class { '::postgresql::client': }
14 14
15 # FIXME: postgresql module is buggy and doesn't create dir? 15 # FIXME: postgresql module is buggy and doesn't create dir?
16 file { "/var/lib/postgres": 16 file { "/var/lib/postgres":
17 ensure => directory, 17 ensure => directory,
18 owner => $pg_user, 18 owner => $pg_user,
19 group => $pg_user, 19 group => $pg_group,
20 before => File["/var/lib/postgres/data"], 20 before => File["/var/lib/postgres/data"],
21 require => Package["postgresql-server"], 21 require => Package["postgresql-server"],
22 } 22 }
@@ -26,59 +26,7 @@ class profile::postgresql {
26 listen_addresses => "*", 26 listen_addresses => "*",
27 } 27 }
28 28
29 postgresql::server::pg_hba_rule { 'local access as postgres user': 29 profile::postgresql::base_pg_hba_rules { "default": }
30 description => 'Allow local access to postgres user',
31 type => 'local',
32 database => 'all',
33 user => $pg_user,
34 auth_method => 'ident',
35 order => "00-01",
36 }
37 postgresql::server::pg_hba_rule { 'localhost access as postgres user':
38 description => 'Allow localhost access to postgres user',
39 type => 'host',
40 database => 'all',
41 user => $pg_user,
42 address => "127.0.0.1/32",
43 auth_method => 'md5',
44 order => "00-02",
45 }
46 postgresql::server::pg_hba_rule { 'localhost ip6 access as postgres user':
47 description => 'Allow localhost access to postgres user',
48 type => 'host',
49 database => 'all',
50 user => $pg_user,
51 address => "::1/128",
52 auth_method => 'md5',
53 order => "00-03",
54 }
55 postgresql::server::pg_hba_rule { 'deny access to postgresql user':
56 description => 'Deny remote access to postgres user',
57 type => 'host',
58 database => 'all',
59 user => $pg_user,
60 address => "0.0.0.0/0",
61 auth_method => 'reject',
62 order => "00-04",
63 }
64
65 postgresql::server::pg_hba_rule { 'local access':
66 description => 'Allow local access with password',
67 type => 'local',
68 database => 'all',
69 user => 'all',
70 auth_method => 'md5',
71 order => "10-01",
72 }
73
74 postgresql::server::pg_hba_rule { 'local access with same name':
75 description => 'Allow local access with same name',
76 type => 'local',
77 database => 'all',
78 user => 'all',
79 auth_method => 'ident',
80 order => "10-02",
81 }
82 30
83} 31}
84 32
diff --git a/modules/profile/manifests/postgresql/backup_dump.pp b/modules/profile/manifests/postgresql/backup_dump.pp
new file mode 100644
index 0000000..10e349a
--- /dev/null
+++ b/modules/profile/manifests/postgresql/backup_dump.pp
@@ -0,0 +1,53 @@
1define profile::postgresql::backup_dump (
2 String $pg_user = "postgres",
3 String $pg_group = "postgres",
4) {
5 $base_path = $title
6 $pg_path = "$base_path/postgresql"
7 $pg_backup_path = "$base_path/postgresql_backup"
8 $pg_host = split($base_path, "/")[-1]
9
10 ensure_packages(["python", "python-pip"])
11 ensure_resource("package", "pylog2rotate", {
12 source => "git+https://github.com/avian2/pylog2rotate",
13 ensure => present,
14 provider => "pip3",
15 require => Package["python-pip"],
16 })
17
18 file { $pg_backup_path:
19 ensure => directory,
20 owner => $pg_user,
21 group => $pg_group,
22 mode => "0700",
23 require => File[$base_path],
24 }
25
26 cron::job::multiple { "backup_psql_$pg_host":
27 ensure => "present",
28 require => [File[$pg_backup_path], File[$pg_path]],
29 jobs => [
30 {
31 command => "/usr/bin/pg_dumpall -h $pg_path -f $pg_backup_path/\$(date -Iseconds).sql",
32 user => $pg_user,
33 hour => "22,4,10,16",
34 minute => 0,
35 description => "Backup the database",
36 },
37 {
38 command => "/usr/bin/rm -f $(ls -1 $pg_backup_path/*.sql | grep -v 'T22:' | sort -r | sed -e '1,12d')",
39 user => $pg_user,
40 hour => 3,
41 minute => 0,
42 description => "Cleanup the database backups",
43 },
44 {
45 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')",
46 user => $pg_user,
47 hour => 3,
48 minute => 1,
49 description => "Cleanup the database backups exponentially",
50 },
51 ]
52 }
53}
diff --git a/modules/profile/manifests/postgresql/backup_pgbouncer.pp b/modules/profile/manifests/postgresql/backup_pgbouncer.pp
new file mode 100644
index 0000000..45b8ed5
--- /dev/null
+++ b/modules/profile/manifests/postgresql/backup_pgbouncer.pp
@@ -0,0 +1,92 @@
1define profile::postgresql::backup_pgbouncer (
2 String $base_path,
3 Hash $pg_infos,
4 String $pg_user = "postgres",
5 String $pg_group = "postgres",
6) {
7 include "profile::postgresql::pam_ldap_pgbouncer"
8 ensure_packages(["pgbouncer"])
9
10 $host_cn = $title
11
12 $host = find_host($facts["ldapvar"]["other"], $host_cn)
13 if empty($host) {
14 fail("No host found for pgbouncer")
15 } elsif has_key($host["vars"], "host") {
16 $pg_backup_host = $host["vars"]["host"][0]
17 } else {
18 $pg_backup_host = $host["vars"]["real_hostname"][0]
19 }
20
21 $pg_path = "$base_path/$pg_backup_host/postgresql"
22
23 if has_key($host["vars"], "postgresql_backup_port") {
24 $pg_port = " port=${host[vars][postgresql_backup_port][0]}"
25 } else {
26 $pg_port = ""
27 }
28
29 # Config
30 ensure_resource("concat", "/etc/pgbouncer/pgbouncer.ini", {
31 mode => "0644",
32 owner => "root",
33 group => "root",
34 ensure_newline => true,
35 notify => Service["pgbouncer"],
36 before => Service["pgbouncer"],
37 })
38
39 ensure_resource("concat::fragment", "pgbouncer_head", {
40 target => "/etc/pgbouncer/pgbouncer.ini",
41 order => 01,
42 source => "puppet:///modules/profile/postgresql/pgbouncer_head.ini",
43 })
44
45 concat::fragment { "pgbouncer_$pg_backup_host":
46 target => "/etc/pgbouncer/pgbouncer.ini",
47 order => 02,
48 content => "${pg_infos[pgbouncer_dbname]} = host=$pg_path$pg_port user=${pg_infos[dbuser]} dbname=${pg_infos[dbname]}",
49 }
50
51 # pg_hba for accessed cluster
52 postgresql::server::pg_hba_rule { "$pg_backup_host - local access as ${pg_infos[dbuser]} user":
53 description => "Allow local access to ${pg_infos[dbuser]} user",
54 type => 'local',
55 database => $pg_infos["dbname"],
56 user => $pg_infos["dbuser"],
57 auth_method => 'trust',
58 order => "01-00",
59 target => "$pg_path/pg_hba.conf",
60 postgresql_version => "10",
61 }
62
63 # service
64 ensure_resource("file", "/etc/systemd/system/pgbouncer.service.d", {
65 ensure => "directory",
66 mode => "0644",
67 owner => "root",
68 group => "root",
69 })
70
71 ensure_resource("file", "/etc/systemd/system/pgbouncer.service.d/override.conf", {
72 ensure => "present",
73 mode => "0644",
74 owner => "root",
75 group => "root",
76 content => "[Service]\nUser=\nUser=$pg_user\n",
77 notify => Service["pgbouncer"],
78 before => Service["pgbouncer"],
79 })
80
81 ensure_resource("service", "pgbouncer", {
82 ensure => "running",
83 enable => true,
84 require => [
85 Package["pgbouncer"],
86 File["/etc/systemd/system/pgbouncer.service.d/override.conf"],
87 Concat["/etc/pgbouncer/pgbouncer.ini"]
88 ],
89 })
90
91
92}
diff --git a/modules/profile/manifests/postgresql/backup_replication.pp b/modules/profile/manifests/postgresql/backup_replication.pp
new file mode 100644
index 0000000..a4edb8f
--- /dev/null
+++ b/modules/profile/manifests/postgresql/backup_replication.pp
@@ -0,0 +1,135 @@
1define profile::postgresql::backup_replication (
2 String $base_path,
3 Hash $pg_infos,
4 String $pg_user = "postgres",
5 String $pg_group = "postgres",
6) {
7 $host_cn = $title
8
9 $host = find_host($facts["ldapvar"]["other"], $host_cn)
10 if empty($host) {
11 $pg_backup_host = $host_cn
12 } elsif has_key($host["vars"], "host") {
13 $pg_backup_host = $host["vars"]["host"][0]
14 } else {
15 $pg_backup_host = $host["vars"]["real_hostname"][0]
16 }
17
18 $pg_path = "$base_path/$pg_backup_host/postgresql"
19
20 # Replication folder
21 ensure_resource("file", "$base_path/$pg_backup_host", {
22 ensure => directory,
23 })
24
25 file { $pg_path:
26 ensure => directory,
27 owner => $pg_user,
28 group => $pg_group,
29 mode => "0700",
30 require => File["$base_path/$pg_backup_host"],
31 }
32
33 # pg_hba.conf
34 profile::postgresql::base_pg_hba_rules { $pg_backup_host:
35 pg_path => $pg_path
36 }
37
38 # postgresql.conf file and ssl
39 concat { "$pg_path/postgresql.conf":
40 owner => $pg_user,
41 group => $pg_group,
42 mode => '0640',
43 warn => true,
44 }
45
46 if !empty($host) and has_key($host["vars"], "postgresql_backup_port") {
47 $pg_listen_port = $host["vars"]["postgresql_backup_port"][0]
48
49 profile::postgresql::ssl { $pg_path:
50 certname => $host_cn,
51 handle_concat_config => true,
52 before => Service["postgresql_backup@$pg_backup_host"]
53 }
54
55 concat::fragment { "$pg_path/postgresql.conf listen":
56 target => "$pg_path/postgresql.conf",
57 content => "listen_addresses = '*'\nport = $pg_listen_port\n",
58 }
59
60 profile::postgresql::replication { $host_cn:
61 target => "$pg_path/pg_hba.conf",
62 }
63 } else {
64 concat::fragment { "$pg_path/postgresql.conf listen":
65 target => "$pg_path/postgresql.conf",
66 content => "listen_addresses = ''\n",
67 }
68 }
69
70 concat::fragment { "$pg_path/postgresql.conf paths":
71 target => "$pg_path/postgresql.conf",
72 content => "unix_socket_directories = '$pg_path'\ndata_directory = '$pg_path'\nwal_level = logical\n",
73 }
74
75 $password_seed = lookup("base_installation::puppet_pass_seed")
76 $pg_host = $pg_backup_host
77 $pg_port = $pg_infos["dbport"]
78 $ldap_cn = lookup("base_installation::ldap_cn")
79 $ldap_password = generate_password(24, $password_seed, "ldap")
80 $pg_slot = regsubst($ldap_cn, '-', "_", "G")
81
82 # recovery.conf file
83 $primary_conninfo = "host=$pg_host port=$pg_port user=$ldap_cn password=$ldap_password sslmode=require"
84 $primary_slot_name = $pg_slot
85 $standby_mode = "on"
86
87 file { "$pg_path/recovery.conf":
88 owner => $pg_user,
89 group => $pg_group,
90 mode => '0640',
91 content => template('postgresql/recovery.conf.erb'),
92 }
93
94 # Initial replication
95 exec { "pg_basebackup $pg_path":
96 cwd => $pg_path,
97 user => $pg_user,
98 creates => "$pg_path/PG_VERSION",
99 environment => ["PGPASSWORD=$ldap_password"],
100 command => "/usr/bin/pg_basebackup -w -h $pg_host -p $pg_port -U $ldap_cn -D $pg_path -S $pg_slot",
101 before => [
102 Concat["$pg_path/pg_hba.conf"],
103 File["$pg_path/recovery.conf"],
104 Concat["$pg_path/postgresql.conf"],
105 ]
106 }
107
108 # Service
109 ensure_resource("file", "/etc/systemd/system/postgresql_backup@.service", {
110 mode => "0644",
111 owner => "root",
112 group => "root",
113 content => template("profile/postgresql/postgresql_backup@.service.erb"),
114 })
115
116 service { "postgresql_backup@$pg_backup_host":
117 enable => true,
118 ensure => "running",
119 require => [
120 File["/etc/systemd/system/postgresql_backup@.service"],
121 Concat["$pg_path/pg_hba.conf"],
122 File["$pg_path/recovery.conf"],
123 Concat["$pg_path/postgresql.conf"],
124 ],
125 subscribe => [
126 Concat["$pg_path/pg_hba.conf"],
127 File["$pg_path/recovery.conf"],
128 Concat["$pg_path/postgresql.conf"],
129 ]
130 }
131
132 # Dumps
133 profile::postgresql::backup_dump { "$base_path/$pg_backup_host": }
134
135}
diff --git a/modules/profile/manifests/postgresql/base_pg_hba_rules.pp b/modules/profile/manifests/postgresql/base_pg_hba_rules.pp
new file mode 100644
index 0000000..07c4bb6
--- /dev/null
+++ b/modules/profile/manifests/postgresql/base_pg_hba_rules.pp
@@ -0,0 +1,74 @@
1define profile::postgresql::base_pg_hba_rules (
2 Optional[String] $pg_path = undef,
3 String $pg_user = "postgres",
4 String $pg_group = "postgres",
5) {
6 unless empty($pg_path) {
7 concat { "$pg_path/pg_hba.conf":
8 owner => $pg_user,
9 group => $pg_group,
10 mode => '0640',
11 warn => true,
12 require => File[$pg_path],
13 }
14
15 Postgresql::Server::Pg_hba_rule {
16 target => "$pg_path/pg_hba.conf",
17 postgresql_version => "10",
18 }
19 }
20
21 postgresql::server::pg_hba_rule { "$title - local access as postgres user":
22 description => 'Allow local access to postgres user',
23 type => 'local',
24 database => 'all',
25 user => $pg_user,
26 auth_method => 'ident',
27 order => "00-01",
28 }
29 postgresql::server::pg_hba_rule { "$title - localhost access as postgres user":
30 description => 'Allow localhost access to postgres user',
31 type => 'host',
32 database => 'all',
33 user => $pg_user,
34 address => "127.0.0.1/32",
35 auth_method => 'md5',
36 order => "00-02",
37 }
38 postgresql::server::pg_hba_rule { "$title - localhost ip6 access as postgres user":
39 description => 'Allow localhost access to postgres user',
40 type => 'host',
41 database => 'all',
42 user => $pg_user,
43 address => "::1/128",
44 auth_method => 'md5',
45 order => "00-03",
46 }
47 postgresql::server::pg_hba_rule { "$title - deny access to postgresql user":
48 description => 'Deny remote access to postgres user',
49 type => 'host',
50 database => 'all',
51 user => $pg_user,
52 address => "0.0.0.0/0",
53 auth_method => 'reject',
54 order => "00-04",
55 }
56 postgresql::server::pg_hba_rule { "$title - local access":
57 description => 'Allow local access with password',
58 type => 'local',
59 database => 'all',
60 user => 'all',
61 auth_method => 'md5',
62 order => "10-01",
63 }
64
65 postgresql::server::pg_hba_rule { "$title - local access with same name":
66 description => 'Allow local access with same name',
67 type => 'local',
68 database => 'all',
69 user => 'all',
70 auth_method => 'ident',
71 order => "10-02",
72 }
73
74}
diff --git a/modules/profile/manifests/postgresql/master.pp b/modules/profile/manifests/postgresql/master.pp
new file mode 100644
index 0000000..969905f
--- /dev/null
+++ b/modules/profile/manifests/postgresql/master.pp
@@ -0,0 +1,20 @@
1define profile::postgresql::master (
2 $letsencrypt_host = undef,
3 $backup_hosts = [],
4) {
5 profile::postgresql::ssl { "/var/lib/postgres/data":
6 cert => "/etc/letsencrypt/live/$letsencrypt_host/cert.pem",
7 key => "/etc/letsencrypt/live/$letsencrypt_host/privkey.pem",
8 require => Letsencrypt::Certonly[$letsencrypt_host],
9 handle_config_entry => true,
10 }
11
12 $backup_hosts.each |$backup_host| {
13 profile::postgresql::replication { $backup_host:
14 handle_config => true,
15 handle_role => true,
16 handle_slot => true,
17 add_self_role => true,
18 }
19 }
20}
diff --git a/modules/profile/manifests/postgresql/pam_ldap.pp b/modules/profile/manifests/postgresql/pam_ldap.pp
new file mode 100644
index 0000000..f068245
--- /dev/null
+++ b/modules/profile/manifests/postgresql/pam_ldap.pp
@@ -0,0 +1,28 @@
1class profile::postgresql::pam_ldap (
2 String $pg_user = "postgres"
3) {
4 include "profile::pam_ldap"
5
6 $password_seed = lookup("base_installation::puppet_pass_seed")
7 $ldap_server = lookup("base_installation::ldap_server")
8 $ldap_base = lookup("base_installation::ldap_base")
9 $ldap_dn = lookup("base_installation::ldap_dn")
10 $ldap_password = generate_password(24, $password_seed, "ldap")
11 $ldap_attribute = "cn"
12
13 file { "/etc/pam_ldap.d/postgresql.conf":
14 ensure => "present",
15 mode => "0400",
16 owner => $pg_user,
17 group => "root",
18 content => template("profile/postgresql/pam_ldap_postgresql.conf.erb"),
19 require => File["/etc/pam_ldap.d"],
20 } ->
21 file { "/etc/pam.d/postgresql":
22 ensure => "present",
23 mode => "0644",
24 owner => "root",
25 group => "root",
26 source => "puppet:///modules/profile/postgresql/pam_postgresql"
27 }
28}
diff --git a/modules/profile/manifests/postgresql/pam_ldap_pgbouncer.pp b/modules/profile/manifests/postgresql/pam_ldap_pgbouncer.pp
new file mode 100644
index 0000000..67714f2
--- /dev/null
+++ b/modules/profile/manifests/postgresql/pam_ldap_pgbouncer.pp
@@ -0,0 +1,33 @@
1class profile::postgresql::pam_ldap_pgbouncer (
2 String $pg_user = "postgres"
3) {
4 include "profile::pam_ldap"
5
6 $password_seed = lookup("base_installation::puppet_pass_seed")
7 $ldap_server = lookup("base_installation::ldap_server")
8 $ldap_base = lookup("base_installation::ldap_base")
9 $ldap_dn = lookup("base_installation::ldap_dn")
10 $ldap_password = generate_password(24, $password_seed, "ldap")
11 $ldap_attribute = "uid"
12 $ldap_filter = lookup("role::backup::postgresql::pgbouncer_access_filter", { "default_value" => undef })
13
14 if empty($ldap_filter) {
15 fail("need ldap filter for pgbouncer")
16 }
17
18 file { "/etc/pam_ldap.d/pgbouncer.conf":
19 ensure => "present",
20 mode => "0600",
21 owner => $pg_user,
22 group => "root",
23 content => template("profile/postgresql/pam_ldap_pgbouncer.conf.erb"),
24 require => File["/etc/pam_ldap.d"],
25 } ->
26 file { "/etc/pam.d/pgbouncer":
27 ensure => "present",
28 mode => "0644",
29 owner => "root",
30 group => "root",
31 source => "puppet:///modules/profile/postgresql/pam_pgbouncer"
32 }
33}
diff --git a/modules/profile/manifests/postgresql/replication.pp b/modules/profile/manifests/postgresql/replication.pp
new file mode 100644
index 0000000..2fcb71c
--- /dev/null
+++ b/modules/profile/manifests/postgresql/replication.pp
@@ -0,0 +1,72 @@
1define profile::postgresql::replication (
2 Boolean $handle_role = false,
3 Boolean $handle_config = false,
4 Boolean $add_self_role = false,
5 Boolean $handle_slot = false,
6 Optional[String] $target = undef,
7) {
8 include "profile::postgresql::pam_ldap"
9
10 $host_cn = $title
11 $host_infos = find_host($facts["ldapvar"]["other"], $host_cn)
12
13 if empty($host_infos) {
14 fail("Unable to find host for replication")
15 }
16
17 if empty($target) {
18 $pg_version = undef
19 } else {
20 $pg_version = "10"
21 }
22
23 $host_infos["ipHostNumber"].each |$ip| {
24 $infos = split($ip, "/")
25 $ipaddress = $infos[0]
26 if (length($infos) == 1 and $ipaddress =~ /:/) {
27 $mask = "128"
28 } elsif (length($infos) == 1) {
29 $mask = "32"
30 } else {
31 $mask = $infos[1]
32 }
33
34 postgresql::server::pg_hba_rule { "allow TCP access for replication to user $host_cn from $ipaddress/$mask":
35 type => 'hostssl',
36 database => 'replication',
37 user => $host_cn,
38 address => "$ipaddress/$mask",
39 auth_method => 'pam',
40 order => "06-01",
41 target => $target,
42 postgresql_version => $pg_version,
43 }
44 }
45
46 if $handle_config {
47 ensure_resource("postgresql::server::config_entry", "wal_level", {
48 value => "logical",
49 })
50 }
51
52 if $handle_role {
53 postgresql::server::role { $host_cn:
54 replication => true,
55 }
56
57 if $add_self_role {
58 $ldap_cn = lookup("base_installation::ldap_cn")
59
60 # Needed to be replicated to the backup and be able to recover later
61 ensure_resource("postgresql::server::role", $ldap_cn, {
62 replication => true,
63 })
64 }
65 }
66
67 if $handle_slot {
68 postgresql_replication_slot { regsubst($host_cn, '-', "_", "G"):
69 ensure => present
70 }
71 }
72}
diff --git a/modules/profile/manifests/postgresql/ssl.pp b/modules/profile/manifests/postgresql/ssl.pp
new file mode 100644
index 0000000..dc56c0b
--- /dev/null
+++ b/modules/profile/manifests/postgresql/ssl.pp
@@ -0,0 +1,82 @@
1define profile::postgresql::ssl (
2 Optional[String] $cert = undef,
3 Optional[String] $key = undef,
4 Optional[String] $certname = undef,
5 Optional[Boolean] $copy_keys = true,
6 Optional[Boolean] $handle_config_entry = false,
7 Optional[Boolean] $handle_concat_config = false,
8 Optional[String] $pg_user = "postgres",
9 Optional[String] $pg_group = "postgres",
10) {
11 $datadir = $title
12
13 file { "$datadir/certs":
14 ensure => directory,
15 mode => "0700",
16 owner => $pg_user,
17 group => $pg_group,
18 require => File[$datadir],
19 }
20
21 if empty($cert) or empty($key) {
22 if empty($certname) {
23 fail("A certificate name is necessary to generate ssl certificate")
24 }
25
26 ssl::self_signed_certificate { $certname:
27 common_name => $certname,
28 country => "FR",
29 days => "3650",
30 organization => "Immae",
31 owner => $pg_user,
32 group => $pg_group,
33 directory => "$datadir/certs",
34 }
35
36 $ssl_key = "$datadir/certs/$certname.key"
37 $ssl_cert = "$datadir/certs/$certname.crt"
38 } elsif $copy_keys {
39 $ssl_key = "$datadir/certs/privkey.pem"
40 $ssl_cert = "$datadir/certs/cert.pem"
41
42 file { $ssl_cert:
43 source => "file://$cert",
44 mode => "0600",
45 links => "follow",
46 owner => $pg_user,
47 group => $pg_group,
48 require => File["$datadir/certs"],
49 }
50 file { $ssl_key:
51 source => "file://$key",
52 mode => "0600",
53 links => "follow",
54 owner => $pg_user,
55 group => $pg_group,
56 require => File["$datadir/certs"],
57 }
58 } else {
59 $ssl_key = $key
60 $ssl_cert = $cert
61 }
62
63 if $handle_config_entry {
64 postgresql::server::config_entry { "ssl":
65 value => "on",
66 }
67
68 postgresql::server::config_entry { "ssl_cert_file":
69 value => $ssl_cert,
70 }
71
72 postgresql::server::config_entry { "ssl_key_file":
73 value => $ssl_key,
74 }
75 } elsif $handle_concat_config {
76 concat::fragment { "$datadir/postgresql.conf ssl config":
77 target => "$datadir/postgresql.conf",
78 content => "ssl = on\nssl_key_file = '$ssl_key'\nssl_cert_file = '$ssl_cert'\n"
79 }
80 }
81
82}
diff --git a/modules/profile/manifests/postgresql_master.pp b/modules/profile/manifests/postgresql_master.pp
deleted file mode 100644
index 067345a..0000000
--- a/modules/profile/manifests/postgresql_master.pp
+++ /dev/null
@@ -1,121 +0,0 @@
1define profile::postgresql_master (
2 $letsencrypt_host = undef,
3 $backup_hosts = [],
4) {
5 $password_seed = lookup("base_installation::puppet_pass_seed")
6
7 ensure_resource("file", "/var/lib/postgres/data/certs", {
8 ensure => directory,
9 mode => "0700",
10 owner => $::profile::postgresql::pg_user,
11 group => $::profile::postgresql::pg_user,
12 require => File["/var/lib/postgres"],
13 })
14
15 ensure_resource("file", "/var/lib/postgres/data/certs/cert.pem", {
16 source => "file:///etc/letsencrypt/live/$letsencrypt_host/cert.pem",
17 mode => "0600",
18 links => "follow",
19 owner => $::profile::postgresql::pg_user,
20 group => $::profile::postgresql::pg_user,
21 require => [Letsencrypt::Certonly[$letsencrypt_host], File["/var/lib/postgres/data/certs"]]
22 })
23
24 ensure_resource("file", "/var/lib/postgres/data/certs/privkey.pem", {
25 source => "file:///etc/letsencrypt/live/$letsencrypt_host/privkey.pem",
26 mode => "0600",
27 links => "follow",
28 owner => $::profile::postgresql::pg_user,
29 group => $::profile::postgresql::pg_user,
30 require => [Letsencrypt::Certonly[$letsencrypt_host], File["/var/lib/postgres/data/certs"]]
31 })
32
33 ensure_resource("postgresql::server::config_entry", "wal_level", {
34 value => "logical",
35 })
36
37 ensure_resource("postgresql::server::config_entry", "ssl", {
38 value => "on",
39 require => Letsencrypt::Certonly[$letsencrypt_host],
40 })
41
42 ensure_resource("postgresql::server::config_entry", "ssl_cert_file", {
43 value => "/var/lib/postgres/data/certs/cert.pem",
44 require => Letsencrypt::Certonly[$letsencrypt_host],
45 })
46
47 ensure_resource("postgresql::server::config_entry", "ssl_key_file", {
48 value => "/var/lib/postgres/data/certs/privkey.pem",
49 require => Letsencrypt::Certonly[$letsencrypt_host],
50 })
51
52 $backup_hosts.each |$backup_host| {
53 ensure_packages(["pam_ldap"])
54
55 $host = find_host($facts["ldapvar"]["other"], $backup_host)
56 unless empty($host) {
57 $host["ipHostNumber"].each |$ip| {
58 $infos = split($ip, "/")
59 $ipaddress = $infos[0]
60 if (length($infos) == 1 and $ipaddress =~ /:/) {
61 $mask = "128"
62 } elsif (length($infos) == 1) {
63 $mask = "32"
64 } else {
65 $mask = $infos[1]
66 }
67
68 postgresql::server::pg_hba_rule { "allow TCP access to replication user from backup for replication from $ipaddress/$mask":
69 type => 'hostssl',
70 database => 'replication',
71 user => $backup_host,
72 address => "$ipaddress/$mask",
73 auth_method => 'pam',
74 order => "06-01",
75 }
76 }
77
78 postgresql::server::role { $backup_host:
79 replication => true,
80 }
81
82 postgresql_replication_slot { regsubst($backup_host, '-', "_", "G"):
83 ensure => present
84 }
85 }
86 }
87
88 $ldap_server = lookup("base_installation::ldap_server")
89 $ldap_base = lookup("base_installation::ldap_base")
90 $ldap_dn = lookup("base_installation::ldap_dn")
91 $ldap_cn = lookup("base_installation::ldap_cn")
92 $ldap_password = generate_password(24, $password_seed, "ldap")
93 $ldap_attribute = "cn"
94
95 # This is to be replicated to the backup
96 postgresql::server::role { $ldap_cn:
97 replication => true,
98 }
99
100 file { "/etc/pam_ldap.d":
101 ensure => directory,
102 mode => "0755",
103 owner => "root",
104 group => "root",
105 } ->
106 file { "/etc/pam_ldap.d/postgresql.conf":
107 ensure => "present",
108 mode => "0600",
109 owner => $::profile::postgresql::pg_user,
110 group => "root",
111 content => template("profile/postgresql_master/pam_ldap_postgresql.conf.erb"),
112 } ->
113 file { "/etc/pam.d/postgresql":
114 ensure => "present",
115 mode => "0644",
116 owner => "root",
117 group => "root",
118 source => "puppet:///modules/profile/postgresql_master/pam_postgresql"
119 }
120
121}
diff --git a/modules/role/templates/backup/pam_ldap_pgbouncer.conf.erb b/modules/profile/templates/postgresql/pam_ldap_pgbouncer.conf.erb
index 384a418..12fa9bb 100644
--- a/modules/role/templates/backup/pam_ldap_pgbouncer.conf.erb
+++ b/modules/profile/templates/postgresql/pam_ldap_pgbouncer.conf.erb
@@ -3,5 +3,5 @@ host <%= @ldap_server %>
3base <%= @ldap_base %> 3base <%= @ldap_base %>
4binddn <%= @ldap_dn %> 4binddn <%= @ldap_dn %>
5bindpw <%= @ldap_password %> 5bindpw <%= @ldap_password %>
6pam_login_attribute <%= @pgbouncer_ldap_attribute %> 6pam_login_attribute <%= @ldap_attribute %>
7pam_filter <%= @ldap_filter %> 7pam_filter <%= @ldap_filter %>
diff --git a/modules/profile/templates/postgresql_master/pam_ldap_postgresql.conf.erb b/modules/profile/templates/postgresql/pam_ldap_postgresql.conf.erb
index f3d9674..f3d9674 100644
--- a/modules/profile/templates/postgresql_master/pam_ldap_postgresql.conf.erb
+++ b/modules/profile/templates/postgresql/pam_ldap_postgresql.conf.erb
diff --git a/modules/role/templates/backup/postgresql_backup@.service.erb b/modules/profile/templates/postgresql/postgresql_backup@.service.erb
index 245a1cb..74f5a98 100644
--- a/modules/role/templates/backup/postgresql_backup@.service.erb
+++ b/modules/profile/templates/postgresql/postgresql_backup@.service.erb
@@ -8,10 +8,10 @@ TimeoutSec=120
8User=postgres 8User=postgres
9Group=postgres 9Group=postgres
10 10
11Environment=PGROOT=<%= @mountpoint %>/%i/postgresql 11Environment=PGROOT=<%= @base_path %>/%i/postgresql
12 12
13SyslogIdentifier=postgres 13SyslogIdentifier=postgres
14PIDFile=<%= @mountpoint %>/%i/postgresql/postmaster.pid 14PIDFile=<%= @base_path %>/%i/postgresql/postmaster.pid
15RuntimeDirectory=postgresql 15RuntimeDirectory=postgresql
16RuntimeDirectoryMode=755 16RuntimeDirectoryMode=755
17 17
diff --git a/modules/role/manifests/backup.pp b/modules/role/manifests/backup.pp
index 51b689d..b35c542 100644
--- a/modules/role/manifests/backup.pp
+++ b/modules/role/manifests/backup.pp
@@ -17,14 +17,6 @@ class role::backup (
17 17
18 include "role::backup::postgresql" 18 include "role::backup::postgresql"
19 19
20 ensure_packages(["python", "python-pip"])
21 package { "pylog2rotate":
22 source => "git+https://github.com/avian2/pylog2rotate",
23 ensure => present,
24 provider => "pip3",
25 require => Package["python-pip"],
26 }
27
28 ensure_packages(["rsync"]) 20 ensure_packages(["rsync"])
29 21
30 ssh_keygen { $user: 22 ssh_keygen { $user:
diff --git a/modules/role/manifests/backup/postgresql.pp b/modules/role/manifests/backup/postgresql.pp
index ee62a00..8a65dec 100644
--- a/modules/role/manifests/backup/postgresql.pp
+++ b/modules/role/manifests/backup/postgresql.pp
@@ -1,381 +1,21 @@
1class role::backup::postgresql inherits role::backup { 1class role::backup::postgresql inherits role::backup {
2 # This manifest is supposed to be part of the backup server 2 ensure_packages(["postgresql"])
3
4 $password_seed = lookup("base_installation::puppet_pass_seed")
5
6 $user = lookup("role::backup::user")
7 $group = lookup("role::backup::group")
8 $pg_user = "postgres"
9 $pg_group = "postgres"
10
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"
17
18 $pg_slot = regsubst($ldap_cn, '-', "_", "G")
19
20 ensure_packages(["postgresql", "pgbouncer", "pam_ldap"])
21 3
22 $pg_backup_hosts = lookup("role::backup::postgresql::backup_hosts", { "default_value" => {} }) 4 $pg_backup_hosts = lookup("role::backup::postgresql::backup_hosts", { "default_value" => {} })
23 $ldap_filter = lookup("role::backup::postgresql::pgbouncer_access_filter", { "default_value" => undef })
24
25 unless empty($pg_backup_hosts) {
26 file { "/etc/systemd/system/postgresql_backup@.service":
27 mode => "0644",
28 owner => "root",
29 group => "root",
30 content => template("role/backup/postgresql_backup@.service.erb"),
31 }
32
33 unless empty($ldap_filter) {
34 concat { "/etc/pgbouncer/pgbouncer.ini":
35 mode => "0644",
36 owner => "root",
37 group => "root",
38 ensure_newline => true,
39 notify => Service["pgbouncer"],
40 }
41
42 concat::fragment { "pgbouncer_head":
43 target => "/etc/pgbouncer/pgbouncer.ini",
44 order => "01",
45 content => template("role/backup/pgbouncer.ini.erb"),
46 }
47
48 file { "/etc/systemd/system/pgbouncer.service.d":
49 ensure => "directory",
50 mode => "0644",
51 owner => "root",
52 group => "root",
53 }
54
55 file { "/etc/systemd/system/pgbouncer.service.d/override.conf":
56 ensure => "present",
57 mode => "0644",
58 owner => "root",
59 group => "root",
60 content => "[Service]\nUser=\nUser=$pg_user\n",
61 notify => Service["pgbouncer"],
62 }
63
64 service { "pgbouncer":
65 ensure => "running",
66 enable => true,
67 require => [
68 Package["pgbouncer"],
69 File["/etc/systemd/system/pgbouncer.service.d/override.conf"],
70 Concat["/etc/pgbouncer/pgbouncer.ini"]
71 ],
72 }
73
74 file { "/etc/pam_ldap.d/pgbouncer.conf":
75 ensure => "present",
76 mode => "0600",
77 owner => $pg_user,
78 group => "root",
79 content => template("role/backup/pam_ldap_pgbouncer.conf.erb"),
80 require => File["/etc/pam_ldap.d"],
81 } ->
82 file { "/etc/pam.d/pgbouncer":
83 ensure => "present",
84 mode => "0644",
85 owner => "root",
86 group => "root",
87 source => "puppet:///modules/role/backup/pam_pgbouncer"
88 }
89 }
90 }
91
92 $ldap_attribute = "cn"
93
94 file { "/etc/pam_ldap.d":
95 ensure => directory,
96 mode => "0755",
97 owner => "root",
98 group => "root",
99 } ->
100 file { "/etc/pam_ldap.d/postgresql.conf":
101 ensure => "present",
102 mode => "0600",
103 owner => $pg_user,
104 group => "root",
105 content => template("profile/postgresql_master/pam_ldap_postgresql.conf.erb"),
106 } ->
107 file { "/etc/pam.d/postgresql":
108 ensure => "present",
109 mode => "0644",
110 owner => "root",
111 group => "root",
112 source => "puppet:///modules/profile/postgresql_master/pam_postgresql"
113 }
114 5
115 $pg_backup_hosts.each |$backup_host_cn, $pg_infos| { 6 $pg_backup_hosts.each |$backup_host_cn, $pg_infos| {
116 $host = find_host($facts["ldapvar"]["other"], $backup_host_cn) 7 profile::postgresql::backup_replication { $backup_host_cn:
117 if empty($host) { 8 base_path => $mountpoint,
118 $pg_backup_host = $backup_host_cn 9 pg_infos => $pg_infos,
119 } elsif has_key($host["vars"], "host") {
120 $pg_backup_host = $host["vars"]["host"][0]
121 } else {
122 $pg_backup_host = $host["vars"]["real_hostname"][0]
123 }
124
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"]
129
130 if has_key($host["vars"], "postgresql_backup_port") {
131 $pg_listen_port = $host["vars"]["postgresql_backup_port"][0]
132 file { "$pg_path/certs":
133 ensure => directory,
134 mode => "0700",
135 owner => $pg_user,
136 group => $pg_group,
137 } ->
138 ssl::self_signed_certificate { $backup_host_cn:
139 common_name => $backup_host_cn,
140 country => "FR",
141 days => "3650",
142 organization => "Immae",
143 owner => $pg_user,
144 group => $pg_group,
145 directory => "$pg_path/certs",
146 before => File["$pg_path/postgresql.conf"],
147 }
148 $ssl_key = "$pg_path/certs/$backup_host_cn.key"
149 $ssl_cert = "$pg_path/certs/$backup_host_cn.crt"
150 } else {
151 $pg_listen_port = undef
152 $ssl_key = undef
153 $ssl_cert = undef
154 }
155
156
157 unless empty($host) {
158 $host["ipHostNumber"].each |$ip| {
159 $infos = split($ip, "/")
160 $ipaddress = $infos[0]
161 if (length($infos) == 1 and $ipaddress =~ /:/) {
162 $mask = "128"
163 } elsif (length($infos) == 1) {
164 $mask = "32"
165 } else {
166 $mask = $infos[1]
167 }
168
169 postgresql::server::pg_hba_rule { "allow TCP access for initial replication from $ipaddress/$mask":
170 type => 'hostssl',
171 database => 'replication',
172 user => $backup_host_cn,
173 address => "$ipaddress/$mask",
174 auth_method => 'pam',
175 order => "06-01",
176 target => "$pg_path/pg_hba.conf",
177 postgresql_version => "10",
178 }
179 }
180 } 10 }
181 11
182 if !empty($ldap_filter) and ($pg_infos["pgbouncer"]) { 12 if $pg_infos["pgbouncer"] {
183 if empty($pg_listen_port) { 13 profile::postgresql::backup_pgbouncer { $backup_host_cn:
184 $pg_listen_port_key = "" 14 base_path => $mountpoint,
185 } else { 15 pg_infos => $pg_infos,
186 $pg_listen_port_key = "port=$pg_listen_port"
187 }
188
189 concat::fragment { "pgbouncer_$pg_backup_host":
190 target => "/etc/pgbouncer/pgbouncer.ini",
191 order => 02,
192 content => "${pg_infos[pgbouncer_dbname]} = host=$mountpoint/$pg_backup_host/postgresql $pg_listen_port_key user=${pg_infos[dbuser]} dbname=${pg_infos[dbname]}",
193 }
194
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",
197 type => 'local',
198 database => $pg_infos["dbname"],
199 user => $pg_infos["dbuser"],
200 auth_method => 'trust',
201 order => "01-00",
202 target => "$pg_path/pg_hba.conf",
203 postgresql_version => "10",
204 } 16 }
205 } 17 }
206 18
207 file { "$mountpoint/$pg_backup_host":
208 ensure => directory,
209 owner => $user,
210 group => $group,
211 }
212
213 file { $pg_path:
214 ensure => directory,
215 owner => $pg_user,
216 group => $pg_group,
217 mode => "0700",
218 require => File["$mountpoint/$pg_backup_host"],
219 }
220
221 file { $pg_backup_path:
222 ensure => directory,
223 owner => $pg_user,
224 group => $pg_group,
225 mode => "0700",
226 require => File["$mountpoint/$pg_backup_host"],
227 }
228
229 cron::job::multiple { "backup_psql_$pg_host":
230 ensure => "present",
231 require => [File[$pg_backup_path], File[$pg_path]],
232 jobs => [
233 {
234 command => "/usr/bin/pg_dumpall -h $pg_path -f $pg_backup_path/\$(date -Iseconds).sql",
235 user => $pg_user,
236 hour => "22,4,10,16",
237 minute => 0,
238 description => "Backup the database",
239 },
240 {
241 command => "/usr/bin/rm -f $(ls -1 $pg_backup_path/*.sql | grep -v 'T22:' | sort -r | sed -e '1,12d')",
242 user => $pg_user,
243 hour => 3,
244 minute => 0,
245 description => "Cleanup the database backups",
246 },
247 {
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')",
249 user => $pg_user,
250 hour => 3,
251 minute => 1,
252 description => "Cleanup the database backups exponentially",
253 },
254 ]
255 }
256
257 exec { "pg_basebackup $pg_path":
258 cwd => $pg_path,
259 user => $pg_user,
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",
263 before => [
264 Concat["$pg_path/pg_hba.conf"],
265 Concat["$pg_path/recovery.conf"],
266 File["$pg_path/postgresql.conf"],
267 ]
268 }
269
270 concat { "$pg_path/pg_hba.conf":
271 owner => $pg_user,
272 group => $pg_group,
273 mode => '0640',
274 warn => true,
275 }
276 postgresql::server::pg_hba_rule { "$pg_backup_host - local access as postgres user":
277 description => 'Allow local access to postgres user',
278 type => 'local',
279 database => 'all',
280 user => $pg_user,
281 auth_method => 'ident',
282 order => "00-01",
283 target => "$pg_path/pg_hba.conf",
284 postgresql_version => "10",
285 }
286 postgresql::server::pg_hba_rule { "$pg_backup_host - localhost access as postgres user":
287 description => 'Allow localhost access to postgres user',
288 type => 'host',
289 database => 'all',
290 user => $pg_user,
291 address => "127.0.0.1/32",
292 auth_method => 'md5',
293 order => "00-02",
294 target => "$pg_path/pg_hba.conf",
295 postgresql_version => "10",
296 }
297 postgresql::server::pg_hba_rule { "$pg_backup_host - localhost ip6 access as postgres user":
298 description => 'Allow localhost access to postgres user',
299 type => 'host',
300 database => 'all',
301 user => $pg_user,
302 address => "::1/128",
303 auth_method => 'md5',
304 order => "00-03",
305 target => "$pg_path/pg_hba.conf",
306 postgresql_version => "10",
307 }
308 postgresql::server::pg_hba_rule { "$pg_backup_host - deny access to postgresql user":
309 description => 'Deny remote access to postgres user',
310 type => 'host',
311 database => 'all',
312 user => $pg_user,
313 address => "0.0.0.0/0",
314 auth_method => 'reject',
315 order => "00-04",
316 target => "$pg_path/pg_hba.conf",
317 postgresql_version => "10",
318 }
319
320 postgresql::server::pg_hba_rule { "$pg_backup_host - local access":
321 description => 'Allow local access with password',
322 type => 'local',
323 database => 'all',
324 user => 'all',
325 auth_method => 'md5',
326 order => "10-01",
327 target => "$pg_path/pg_hba.conf",
328 postgresql_version => "10",
329 }
330
331 postgresql::server::pg_hba_rule { "$pg_backup_host - local access with same name":
332 description => 'Allow local access with same name',
333 type => 'local',
334 database => 'all',
335 user => 'all',
336 auth_method => 'ident',
337 order => "10-02",
338 target => "$pg_path/pg_hba.conf",
339 postgresql_version => "10",
340 }
341
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")
344 $standby_mode = "on"
345
346 concat { "$pg_path/recovery.conf":
347 owner => $pg_user,
348 group => $pg_group,
349 mode => '0640',
350 warn => true,
351 }
352 concat::fragment { "$pg_path/recovery.conf":
353 target => "$pg_path/recovery.conf",
354 content => template('postgresql/recovery.conf.erb'),
355 }
356
357 file { "$pg_path/postgresql.conf":
358 owner => $pg_user,
359 group => $pg_group,
360 mode => '0640',
361 content => template("role/backup/postgresql.conf.erb"),
362 }
363
364 service { "postgresql_backup@$pg_backup_host":
365 enable => true,
366 ensure => "running",
367 require => [
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"],
372 ],
373 subscribe => [
374 Concat["$pg_path/pg_hba.conf"],
375 Concat["$pg_path/recovery.conf"],
376 File["$pg_path/postgresql.conf"],
377 ]
378 }
379 } 19 }
380 20
381} 21}
diff --git a/modules/role/manifests/cryptoportfolio/postgresql.pp b/modules/role/manifests/cryptoportfolio/postgresql.pp
index 776b30f..addad67 100644
--- a/modules/role/manifests/cryptoportfolio/postgresql.pp
+++ b/modules/role/manifests/cryptoportfolio/postgresql.pp
@@ -2,194 +2,40 @@ class role::cryptoportfolio::postgresql inherits role::cryptoportfolio {
2 $password_seed = lookup("base_installation::puppet_pass_seed") 2 $password_seed = lookup("base_installation::puppet_pass_seed")
3 3
4 $pg_password = generate_password(24, $password_seed, "postgres_cryptoportfolio") 4 $pg_password = generate_password(24, $password_seed, "postgres_cryptoportfolio")
5 $pg_replication_password = generate_password(24, $password_seed, "postgres_cryptoportfolio_replication")
6 5
7 file { "/var/lib/postgres/data/certs": 6 profile::postgresql::master { "postgresql master for cryptoportfolio":
8 ensure => directory, 7 letsencrypt_host => $web_host,
9 mode => "0700", 8 backup_hosts => ["backup-1"],
10 owner => $::profile::postgresql::pg_user,
11 group => $::profile::postgresql::pg_user,
12 require => File["/var/lib/postgres"],
13 }
14
15 file { "/var/lib/postgres/data/certs/cert.pem":
16 source => "file:///etc/letsencrypt/live/$web_host/cert.pem",
17 mode => "0600",
18 links => "follow",
19 owner => $::profile::postgresql::pg_user,
20 group => $::profile::postgresql::pg_user,
21 require => [Letsencrypt::Certonly[$web_host], File["/var/lib/postgres/data/certs"]]
22 }
23
24 file { "/var/lib/postgres/data/certs/privkey.pem":
25 source => "file:///etc/letsencrypt/live/$web_host/privkey.pem",
26 mode => "0600",
27 links => "follow",
28 owner => $::profile::postgresql::pg_user,
29 group => $::profile::postgresql::pg_user,
30 require => [Letsencrypt::Certonly[$web_host], File["/var/lib/postgres/data/certs"]]
31 }
32
33 postgresql_replication_slot { $pg_user_replication:
34 ensure => present
35 }
36
37 postgresql::server::config_entry { "wal_level":
38 value => "logical",
39 }
40
41 postgresql::server::config_entry { "ssl":
42 value => "on",
43 require => Letsencrypt::Certonly[$web_host],
44 }
45
46 postgresql::server::config_entry { "ssl_cert_file":
47 value => "/var/lib/postgres/data/certs/cert.pem",
48 require => Letsencrypt::Certonly[$web_host],
49 }
50
51 postgresql::server::config_entry { "ssl_key_file":
52 value => "/var/lib/postgres/data/certs/privkey.pem",
53 require => Letsencrypt::Certonly[$web_host],
54 } 9 }
55 10
56 postgresql::server::db { $pg_db: 11 postgresql::server::db { $pg_db:
57 user => $pg_user, 12 user => $pg_user,
58 password => postgresql_password($pg_user, $pg_password), 13 password => postgresql_password($pg_user, $pg_password),
59 } 14 }
60 ->
61 postgresql_psql { "CREATE PUBLICATION ${pg_db}_publication FOR ALL TABLES":
62 db => $pg_db,
63 unless => "SELECT 1 FROM pg_catalog.pg_publication WHERE pubname = '${pg_db}_publication'",
64 }
65 ->
66 postgresql::server::role { $pg_user_replication:
67 db => $pg_db,
68 replication => true,
69 password_hash => postgresql_password($pg_user_replication, $pg_replication_password),
70 }
71 ->
72 postgresql::server::database_grant { $pg_user_replication:
73 db => $pg_db,
74 privilege => "CONNECT",
75 role => $pg_user_replication,
76 }
77 ->
78 postgresql::server::grant { "all tables in schema:public:$pg_user_replication":
79 db => $pg_db,
80 role => $pg_user_replication,
81 privilege => "SELECT",
82 object_type => "ALL TABLES IN SCHEMA",
83 object_name => "public",
84 }
85 ->
86 postgresql::server::grant { "all sequences in schema:public:$pg_user_replication":
87 db => $pg_db,
88 role => $pg_user_replication,
89 privilege => "SELECT",
90 object_type => "ALL SEQUENCES IN SCHEMA",
91 object_name => "public",
92 }
93 15
94 postgresql::server::pg_hba_rule { 'allow localhost TCP access to cryptoportfolio user': 16 postgresql::server::pg_hba_rule { 'allow localhost TCP access to cryptoportfolio user':
95 type => 'host', 17 type => 'local',
96 database => $pg_db, 18 database => $pg_db,
97 user => $pg_user, 19 user => $pg_user,
98 address => '127.0.0.1/32', 20 auth_method => 'ident',
99 auth_method => 'md5',
100 order => "05-01", 21 order => "05-01",
101 } 22 }
102 postgresql::server::pg_hba_rule { 'allow localhost ip6 TCP access to cryptoportfolio user':
103 type => 'host',
104 database => $pg_db,
105 user => $pg_user,
106 address => '::1/128',
107 auth_method => 'md5',
108 order => "05-01",
109 }
110
111 postgresql::server::pg_hba_rule { 'allow TCP access to replication user from immae.eu for replication':
112 type => 'hostssl',
113 database => 'replication',
114 user => $pg_user_replication,
115 address => 'immae.eu',
116 auth_method => 'md5',
117 order => "05-01",
118 }
119
120 postgresql::server::pg_hba_rule { 'allow TCP access to replication user from immae.eu':
121 type => 'hostssl',
122 database => $pg_db,
123 user => $pg_user_replication,
124 address => 'immae.eu',
125 auth_method => 'md5',
126 order => "05-02",
127 }
128
129 $backup_host = "backup-1"
130 23
131 unless empty($backup_host) { 24 # cleanup
132 ensure_packages(["pam_ldap"]) 25 postgresql_psql { "DROP PUBLICATION ${pg_db}_publication":
133 26 db => $pg_db,
134 $facts["ldapvar"]["other"].each |$host| { 27 onlyif => "SELECT 1 FROM pg_catalog.pg_publication WHERE pubname = '${pg_db}_publication'",
135 if ($host["cn"][0] == $backup_host) { 28 } ->
136 $host["ipHostNumber"].each |$ip| { 29 postgresql_replication_slot { $pg_user_replication:
137 $infos = split($ip, "/") 30 ensure => absent
138 $ipaddress = $infos[0] 31 } ->
139 if (length($infos) == 1 and $ipaddress =~ /:/) { 32 postgresql_psql { "DROP OWNED BY $pg_user_replication":
140 $mask = "128" 33 db => $pg_db,
141 } elsif (length($infos) == 1) { 34 onlyif => "SELECT 1 FROM pg_user WHERE usename='$pg_user_replication'"
142 $mask = "32" 35 } ->
143 } else { 36 postgresql::server::role { $pg_user_replication:
144 $mask = $infos[1] 37 ensure => absent,
145 }
146
147 postgresql::server::pg_hba_rule { "allow TCP access to replication user from backup for replication from $ipaddress/$mask":
148 type => 'hostssl',
149 database => 'replication',
150 user => 'all',
151 address => "$ipaddress/$mask",
152 auth_method => 'pam',
153 order => "06-01",
154 }
155 }
156
157 postgresql::server::role { $backup_host:
158 replication => true,
159 }
160
161 postgresql_replication_slot { regsubst($backup_host, '-', "_", "G"):
162 ensure => present
163 }
164 }
165 }
166
167 $ldap_server = lookup("base_installation::ldap_server")
168 $ldap_base = lookup("base_installation::ldap_base")
169 $ldap_dn = lookup("base_installation::ldap_dn")
170 $ldap_password = generate_password(24, $password_seed, "ldap")
171 $ldap_attribute = "cn"
172
173 file { "/etc/pam_ldap.d":
174 ensure => directory,
175 mode => "0755",
176 owner => "root",
177 group => "root",
178 } ->
179 file { "/etc/pam_ldap.d/postgresql.conf":
180 ensure => "present",
181 mode => "0600",
182 owner => $::profile::postgresql::pg_user,
183 group => "root",
184 content => template("role/cryptoportfolio/pam_ldap_postgresql.conf.erb"),
185 } ->
186 file { "/etc/pam.d/postgresql":
187 ensure => "present",
188 mode => "0644",
189 owner => "root",
190 group => "root",
191 source => "puppet:///modules/role/cryptoportfolio/pam_postgresql"
192 }
193 } 38 }
39 # /cleanup
194 40
195} 41}
diff --git a/modules/role/manifests/etherpad.pp b/modules/role/manifests/etherpad.pp
index 109da96..28b9eb6 100644
--- a/modules/role/manifests/etherpad.pp
+++ b/modules/role/manifests/etherpad.pp
@@ -87,7 +87,7 @@ class role::etherpad (
87 subscribe => Aur::Package["etherpad-lite"], 87 subscribe => Aur::Package["etherpad-lite"],
88 } 88 }
89 89
90 profile::postgresql_master { "postgresql master for etherpad": 90 profile::postgresql::master { "postgresql master for etherpad":
91 letsencrypt_host => $web_host, 91 letsencrypt_host => $web_host,
92 backup_hosts => ["backup-1"], 92 backup_hosts => ["backup-1"],
93 } 93 }