aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIsmaël Bouya <ismael.bouya@normalesup.org>2018-06-27 20:45:15 +0200
committerIsmaël Bouya <ismael.bouya@normalesup.org>2018-06-28 02:33:05 +0200
commitc53ac3f84852a42aa8b7341ee7fe0a629d2e3579 (patch)
tree694c4790a8382fe7c5ed5a2033042c377999760b
parentf1d583bfdaf881116e5f9ca9e050307e7acdc28e (diff)
downloadPuppet-c53ac3f84852a42aa8b7341ee7fe0a629d2e3579.tar.gz
Puppet-c53ac3f84852a42aa8b7341ee7fe0a629d2e3579.tar.zst
Puppet-c53ac3f84852a42aa8b7341ee7fe0a629d2e3579.zip
Refactor postgresql configuration
-rw-r--r--modules/profile/files/postgresql/pam_postgresql3
-rw-r--r--modules/profile/manifests/pam_ldap.pp13
-rw-r--r--modules/profile/manifests/postgresql/pam_ldap.pp28
-rw-r--r--modules/profile/manifests/postgresql/replication.pp60
-rw-r--r--modules/profile/manifests/postgresql/ssl.pp73
-rw-r--r--modules/profile/manifests/postgresql_master.pp119
-rw-r--r--modules/profile/templates/postgresql/pam_ldap_postgresql.conf.erb6
-rw-r--r--modules/role/manifests/backup/postgresql.pp2
8 files changed, 191 insertions, 113 deletions
diff --git a/modules/profile/files/postgresql/pam_postgresql b/modules/profile/files/postgresql/pam_postgresql
new file mode 100644
index 0000000..70a90ae
--- /dev/null
+++ b/modules/profile/files/postgresql/pam_postgresql
@@ -0,0 +1,3 @@
1auth required pam_ldap.so config=/etc/pam_ldap.d/postgresql.conf
2account required pam_ldap.so config=/etc/pam_ldap.d/postgresql.conf
3
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/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/replication.pp b/modules/profile/manifests/postgresql/replication.pp
new file mode 100644
index 0000000..33b147f
--- /dev/null
+++ b/modules/profile/manifests/postgresql/replication.pp
@@ -0,0 +1,60 @@
1define profile::postgresql::replication (
2 Boolean $handle_role = false,
3 Boolean $add_self_role = false,
4 Boolean $handle_slot = false,
5) {
6 include "profile::postgresql::pam_ldap"
7
8 $host_cn = $title
9 $host_infos = find_host($facts["ldapvar"]["other"], $host_cn)
10
11 if empty($host_infos) {
12 fail("Unable to find host for replication")
13 }
14
15 ensure_resource("postgresql::server::config_entry", "wal_level", {
16 value => "logical",
17 })
18
19 $host_infos["ipHostNumber"].each |$ip| {
20 $infos = split($ip, "/")
21 $ipaddress = $infos[0]
22 if (length($infos) == 1 and $ipaddress =~ /:/) {
23 $mask = "128"
24 } elsif (length($infos) == 1) {
25 $mask = "32"
26 } else {
27 $mask = $infos[1]
28 }
29
30 postgresql::server::pg_hba_rule { "allow TCP access for replication to user $host_cn from $ipaddress/$mask":
31 type => 'hostssl',
32 database => 'replication',
33 user => $host_cn,
34 address => "$ipaddress/$mask",
35 auth_method => 'pam',
36 order => "06-01",
37 }
38 }
39
40 if $handle_role {
41 postgresql::server::role { $host_cn:
42 replication => true,
43 }
44
45 if $add_self_role {
46 $ldap_cn = lookup("base_installation::ldap_cn")
47
48 # Needed to be replicated to the backup and be able to recover later
49 ensure_resource("postgresql::server::role", $ldap_cn, {
50 replication => true,
51 })
52 }
53 }
54
55 if $handle_slot {
56 postgresql_replication_slot { regsubst($host_cn, '-', "_", "G"):
57 ensure => present
58 }
59 }
60}
diff --git a/modules/profile/manifests/postgresql/ssl.pp b/modules/profile/manifests/postgresql/ssl.pp
new file mode 100644
index 0000000..e4da8af
--- /dev/null
+++ b/modules/profile/manifests/postgresql/ssl.pp
@@ -0,0 +1,73 @@
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[String] $pg_user = $profile::postgresql::pg_user,
7 Optional[String] $pg_group = $profile::postgresql::pg_user
8) {
9 $pg_dir = $title
10 $datadir = "$pg_dir/data"
11
12 file { "$datadir/certs":
13 ensure => directory,
14 mode => "0700",
15 owner => $pg_user,
16 group => $pg_group,
17 require => File[$pg_dir],
18 }
19
20 if empty($cert) or empty($key) {
21 if empty($certname) {
22 fail("A certificate name is necessary to generate ssl certificate")
23 }
24
25 ssl::self_signed_certificate { $certname:
26 common_name => $certname,
27 country => "FR",
28 days => "3650",
29 organization => "Immae",
30 owner => $pg_user,
31 group => $pg_group,
32 directory => "$datadir/certs",
33 }
34
35 $ssl_key = "$datadir/certs/$backup_host_cn.key"
36 $ssl_cert = "$datadir/certs/$backup_host_cn.crt"
37 } elsif $copy_keys {
38 $ssl_key = "$datadir/certs/privkey.pem"
39 $ssl_cert = "$datadir/certs/cert.pem"
40
41 file { $ssl_cert:
42 source => "file://$cert",
43 mode => "0600",
44 links => "follow",
45 owner => $pg_user,
46 group => $pg_group,
47 require => File["$datadir/certs"],
48 }
49 file { $ssl_key:
50 source => "file://$key",
51 mode => "0600",
52 links => "follow",
53 owner => $pg_user,
54 group => $pg_group,
55 require => File["$datadir/certs"],
56 }
57 } else {
58 $ssl_key = $key
59 $ssl_cert = $cert
60 }
61
62 postgresql::server::config_entry { "ssl":
63 value => "on",
64 }
65
66 postgresql::server::config_entry { "ssl_cert_file":
67 value => $ssl_cert,
68 }
69
70 postgresql::server::config_entry { "ssl_key_file":
71 value => $ssl_key,
72 }
73}
diff --git a/modules/profile/manifests/postgresql_master.pp b/modules/profile/manifests/postgresql_master.pp
index 067345a..e28c1b0 100644
--- a/modules/profile/manifests/postgresql_master.pp
+++ b/modules/profile/manifests/postgresql_master.pp
@@ -2,120 +2,17 @@ define profile::postgresql_master (
2 $letsencrypt_host = undef, 2 $letsencrypt_host = undef,
3 $backup_hosts = [], 3 $backup_hosts = [],
4) { 4) {
5 $password_seed = lookup("base_installation::puppet_pass_seed") 5 profile::postgresql::ssl { "/var/lib/postgres":
6 6 cert => "/etc/letsencrypt/live/$letsencrypt_host/cert.pem",
7 ensure_resource("file", "/var/lib/postgres/data/certs", { 7 key => "/etc/letsencrypt/live/$letsencrypt_host/privkey.pem",
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], 8 require => Letsencrypt::Certonly[$letsencrypt_host],
40 }) 9 }
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 10
52 $backup_hosts.each |$backup_host| { 11 $backup_hosts.each |$backup_host| {
53 ensure_packages(["pam_ldap"]) 12 profile::postgresql::replication { $backup_host:
54 13 handle_role => true,
55 $host = find_host($facts["ldapvar"]["other"], $backup_host) 14 handle_slot => true,
56 unless empty($host) { 15 add_self_role => true,
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 } 16 }
86 } 17 }
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} 18}
diff --git a/modules/profile/templates/postgresql/pam_ldap_postgresql.conf.erb b/modules/profile/templates/postgresql/pam_ldap_postgresql.conf.erb
new file mode 100644
index 0000000..f3d9674
--- /dev/null
+++ b/modules/profile/templates/postgresql/pam_ldap_postgresql.conf.erb
@@ -0,0 +1,6 @@
1host <%= @ldap_server %>
2
3base <%= @ldap_base %>
4binddn <%= @ldap_dn %>
5bindpw <%= @ldap_password %>
6pam_login_attribute <%= @ldap_attribute %>
diff --git a/modules/role/manifests/backup/postgresql.pp b/modules/role/manifests/backup/postgresql.pp
index ee62a00..8c7542b 100644
--- a/modules/role/manifests/backup/postgresql.pp
+++ b/modules/role/manifests/backup/postgresql.pp
@@ -1,6 +1,4 @@
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
3
4 $password_seed = lookup("base_installation::puppet_pass_seed") 2 $password_seed = lookup("base_installation::puppet_pass_seed")
5 3
6 $user = lookup("role::backup::user") 4 $user = lookup("role::backup::user")