]> git.immae.eu Git - perso/Immae/Projets/Puppet.git/commitdiff
Refactor postgresql configuration
authorIsmaël Bouya <ismael.bouya@normalesup.org>
Wed, 27 Jun 2018 18:45:15 +0000 (20:45 +0200)
committerIsmaël Bouya <ismael.bouya@normalesup.org>
Thu, 28 Jun 2018 00:33:05 +0000 (02:33 +0200)
modules/profile/files/postgresql/pam_postgresql [new file with mode: 0644]
modules/profile/manifests/pam_ldap.pp [new file with mode: 0644]
modules/profile/manifests/postgresql/pam_ldap.pp [new file with mode: 0644]
modules/profile/manifests/postgresql/replication.pp [new file with mode: 0644]
modules/profile/manifests/postgresql/ssl.pp [new file with mode: 0644]
modules/profile/manifests/postgresql_master.pp
modules/profile/templates/postgresql/pam_ldap_postgresql.conf.erb [new file with mode: 0644]
modules/role/manifests/backup/postgresql.pp

diff --git a/modules/profile/files/postgresql/pam_postgresql b/modules/profile/files/postgresql/pam_postgresql
new file mode 100644 (file)
index 0000000..70a90ae
--- /dev/null
@@ -0,0 +1,3 @@
+auth            required        pam_ldap.so config=/etc/pam_ldap.d/postgresql.conf
+account         required        pam_ldap.so config=/etc/pam_ldap.d/postgresql.conf
+
diff --git a/modules/profile/manifests/pam_ldap.pp b/modules/profile/manifests/pam_ldap.pp
new file mode 100644 (file)
index 0000000..956a7cd
--- /dev/null
@@ -0,0 +1,13 @@
+class profile::pam_ldap (
+) {
+  ensure_packages(["pam_ldap"])
+
+  file { "/etc/pam_ldap.d":
+    ensure  => directory,
+    mode    => "0755",
+    owner   => "root",
+    group   => "root",
+    require => Package["pam_ldap"],
+  }
+}
+
diff --git a/modules/profile/manifests/postgresql/pam_ldap.pp b/modules/profile/manifests/postgresql/pam_ldap.pp
new file mode 100644 (file)
index 0000000..f068245
--- /dev/null
@@ -0,0 +1,28 @@
+class profile::postgresql::pam_ldap (
+  String $pg_user = "postgres"
+) {
+  include "profile::pam_ldap"
+
+  $password_seed = lookup("base_installation::puppet_pass_seed")
+  $ldap_server = lookup("base_installation::ldap_server")
+  $ldap_base   = lookup("base_installation::ldap_base")
+  $ldap_dn     = lookup("base_installation::ldap_dn")
+  $ldap_password = generate_password(24, $password_seed, "ldap")
+  $ldap_attribute = "cn"
+
+  file { "/etc/pam_ldap.d/postgresql.conf":
+    ensure  => "present",
+    mode    => "0400",
+    owner   => $pg_user,
+    group   => "root",
+    content => template("profile/postgresql/pam_ldap_postgresql.conf.erb"),
+    require => File["/etc/pam_ldap.d"],
+  } ->
+  file { "/etc/pam.d/postgresql":
+    ensure => "present",
+    mode   => "0644",
+    owner  => "root",
+    group  => "root",
+    source => "puppet:///modules/profile/postgresql/pam_postgresql"
+  }
+}
diff --git a/modules/profile/manifests/postgresql/replication.pp b/modules/profile/manifests/postgresql/replication.pp
new file mode 100644 (file)
index 0000000..33b147f
--- /dev/null
@@ -0,0 +1,60 @@
+define profile::postgresql::replication (
+  Boolean $handle_role = false,
+  Boolean $add_self_role = false,
+  Boolean $handle_slot = false,
+) {
+  include "profile::postgresql::pam_ldap"
+
+  $host_cn = $title
+  $host_infos = find_host($facts["ldapvar"]["other"], $host_cn)
+
+  if empty($host_infos) {
+    fail("Unable to find host for replication")
+  }
+
+  ensure_resource("postgresql::server::config_entry", "wal_level", {
+    value => "logical",
+  })
+
+  $host_infos["ipHostNumber"].each |$ip| {
+    $infos = split($ip, "/")
+    $ipaddress = $infos[0]
+    if (length($infos) == 1 and $ipaddress =~ /:/) {
+      $mask = "128"
+    } elsif (length($infos) == 1) {
+      $mask = "32"
+    } else {
+      $mask = $infos[1]
+    }
+
+    postgresql::server::pg_hba_rule { "allow TCP access for replication to user $host_cn from $ipaddress/$mask":
+      type        => 'hostssl',
+      database    => 'replication',
+      user        => $host_cn,
+      address     => "$ipaddress/$mask",
+      auth_method => 'pam',
+      order       => "06-01",
+    }
+  }
+
+  if $handle_role {
+    postgresql::server::role { $host_cn:
+      replication => true,
+    }
+
+    if $add_self_role {
+      $ldap_cn = lookup("base_installation::ldap_cn")
+
+      # Needed to be replicated to the backup and be able to recover later
+      ensure_resource("postgresql::server::role", $ldap_cn, {
+        replication => true,
+      })
+    }
+  }
+
+  if $handle_slot {
+    postgresql_replication_slot { regsubst($host_cn, '-', "_", "G"):
+      ensure => present
+    }
+  }
+}
diff --git a/modules/profile/manifests/postgresql/ssl.pp b/modules/profile/manifests/postgresql/ssl.pp
new file mode 100644 (file)
index 0000000..e4da8af
--- /dev/null
@@ -0,0 +1,73 @@
+define profile::postgresql::ssl (
+  Optional[String] $cert       = undef,
+  Optional[String] $key        = undef,
+  Optional[String] $certname   = undef,
+  Optional[Boolean] $copy_keys = true,
+  Optional[String] $pg_user    = $profile::postgresql::pg_user,
+  Optional[String] $pg_group   = $profile::postgresql::pg_user
+) {
+  $pg_dir  = $title
+  $datadir = "$pg_dir/data"
+
+  file { "$datadir/certs":
+    ensure  => directory,
+    mode    => "0700",
+    owner   => $pg_user,
+    group   => $pg_group,
+    require => File[$pg_dir],
+  }
+
+  if empty($cert) or empty($key) {
+    if empty($certname) {
+      fail("A certificate name is necessary to generate ssl certificate")
+    }
+
+    ssl::self_signed_certificate { $certname:
+      common_name  => $certname,
+      country      => "FR",
+      days         => "3650",
+      organization => "Immae",
+      owner        => $pg_user,
+      group        => $pg_group,
+      directory    => "$datadir/certs",
+    }
+
+    $ssl_key  = "$datadir/certs/$backup_host_cn.key"
+    $ssl_cert = "$datadir/certs/$backup_host_cn.crt"
+  } elsif $copy_keys {
+    $ssl_key  = "$datadir/certs/privkey.pem"
+    $ssl_cert = "$datadir/certs/cert.pem"
+
+    file { $ssl_cert:
+      source  => "file://$cert",
+      mode    => "0600",
+      links   => "follow",
+      owner   => $pg_user,
+      group   => $pg_group,
+      require => File["$datadir/certs"],
+    }
+    file { $ssl_key:
+      source  => "file://$key",
+      mode    => "0600",
+      links   => "follow",
+      owner   => $pg_user,
+      group   => $pg_group,
+      require => File["$datadir/certs"],
+    }
+  } else {
+    $ssl_key  = $key
+    $ssl_cert = $cert
+  }
+
+  postgresql::server::config_entry { "ssl":
+    value => "on",
+  }
+
+  postgresql::server::config_entry { "ssl_cert_file":
+    value => $ssl_cert,
+  }
+
+  postgresql::server::config_entry { "ssl_key_file":
+    value => $ssl_key,
+  }
+}
index 067345afe282892c16bbf5c4613208375f780761..e28c1b0add6567f79e0dc8feced8c86fe835d176 100644 (file)
@@ -2,120 +2,17 @@ define profile::postgresql_master (
   $letsencrypt_host = undef,
   $backup_hosts     = [],
 ) {
-  $password_seed = lookup("base_installation::puppet_pass_seed")
-
-  ensure_resource("file", "/var/lib/postgres/data/certs", {
-    ensure  => directory,
-    mode    => "0700",
-    owner   => $::profile::postgresql::pg_user,
-    group   => $::profile::postgresql::pg_user,
-    require => File["/var/lib/postgres"],
-  })
-
-  ensure_resource("file", "/var/lib/postgres/data/certs/cert.pem", {
-    source  => "file:///etc/letsencrypt/live/$letsencrypt_host/cert.pem",
-    mode    => "0600",
-    links   => "follow",
-    owner   => $::profile::postgresql::pg_user,
-    group   => $::profile::postgresql::pg_user,
-    require => [Letsencrypt::Certonly[$letsencrypt_host], File["/var/lib/postgres/data/certs"]]
-  })
-
-  ensure_resource("file", "/var/lib/postgres/data/certs/privkey.pem", {
-    source  => "file:///etc/letsencrypt/live/$letsencrypt_host/privkey.pem",
-    mode    => "0600",
-    links   => "follow",
-    owner   => $::profile::postgresql::pg_user,
-    group   => $::profile::postgresql::pg_user,
-    require => [Letsencrypt::Certonly[$letsencrypt_host], File["/var/lib/postgres/data/certs"]]
-  })
-
-  ensure_resource("postgresql::server::config_entry", "wal_level", {
-    value => "logical",
-  })
-
-  ensure_resource("postgresql::server::config_entry", "ssl", {
-    value   => "on",
+  profile::postgresql::ssl { "/var/lib/postgres":
+    cert    => "/etc/letsencrypt/live/$letsencrypt_host/cert.pem",
+    key     => "/etc/letsencrypt/live/$letsencrypt_host/privkey.pem",
     require => Letsencrypt::Certonly[$letsencrypt_host],
-  })
-
-  ensure_resource("postgresql::server::config_entry", "ssl_cert_file", {
-    value   => "/var/lib/postgres/data/certs/cert.pem",
-    require => Letsencrypt::Certonly[$letsencrypt_host],
-  })
-
-  ensure_resource("postgresql::server::config_entry", "ssl_key_file", {
-    value   => "/var/lib/postgres/data/certs/privkey.pem",
-    require => Letsencrypt::Certonly[$letsencrypt_host],
-  })
+  }
 
   $backup_hosts.each |$backup_host| {
-    ensure_packages(["pam_ldap"])
-
-    $host = find_host($facts["ldapvar"]["other"], $backup_host)
-    unless empty($host) {
-      $host["ipHostNumber"].each |$ip| {
-        $infos = split($ip, "/")
-        $ipaddress = $infos[0]
-        if (length($infos) == 1 and $ipaddress =~ /:/) {
-          $mask = "128"
-        } elsif (length($infos) == 1) {
-          $mask = "32"
-        } else {
-          $mask = $infos[1]
-        }
-
-        postgresql::server::pg_hba_rule { "allow TCP access to replication user from backup for replication from $ipaddress/$mask":
-          type        => 'hostssl',
-          database    => 'replication',
-          user        => $backup_host,
-          address     => "$ipaddress/$mask",
-          auth_method => 'pam',
-          order       => "06-01",
-        }
-      }
-
-      postgresql::server::role { $backup_host:
-        replication => true,
-      }
-
-      postgresql_replication_slot { regsubst($backup_host, '-', "_", "G"):
-        ensure => present
-      }
+    profile::postgresql::replication { $backup_host:
+      handle_role   => true,
+      handle_slot   => true,
+      add_self_role => true,
     }
   }
-
-  $ldap_server = lookup("base_installation::ldap_server")
-  $ldap_base   = lookup("base_installation::ldap_base")
-  $ldap_dn     = lookup("base_installation::ldap_dn")
-  $ldap_cn     = lookup("base_installation::ldap_cn")
-  $ldap_password = generate_password(24, $password_seed, "ldap")
-  $ldap_attribute = "cn"
-
-  # This is to be replicated to the backup
-  postgresql::server::role { $ldap_cn:
-    replication => true,
-  }
-
-  file { "/etc/pam_ldap.d":
-    ensure => directory,
-    mode   => "0755",
-    owner  => "root",
-    group  => "root",
-  } ->
-  file { "/etc/pam_ldap.d/postgresql.conf":
-    ensure  => "present",
-    mode    => "0600",
-    owner   => $::profile::postgresql::pg_user,
-    group   => "root",
-    content => template("profile/postgresql_master/pam_ldap_postgresql.conf.erb"),
-  } ->
-  file { "/etc/pam.d/postgresql":
-    ensure => "present",
-    mode   => "0644",
-    owner  => "root",
-    group  => "root",
-    source => "puppet:///modules/profile/postgresql_master/pam_postgresql"
-  }
-
 }
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 (file)
index 0000000..f3d9674
--- /dev/null
@@ -0,0 +1,6 @@
+host <%= @ldap_server %>
+
+base <%= @ldap_base %>
+binddn <%= @ldap_dn %>
+bindpw <%= @ldap_password %>
+pam_login_attribute <%= @ldap_attribute %>
index ee62a0022ed2fb3efdacd480f8d734780904ed18..8c7542b4d91b817061f9c7e33e5a5070f0efddd1 100644 (file)
@@ -1,6 +1,4 @@
 class role::backup::postgresql inherits role::backup {
-  # This manifest is supposed to be part of the backup server
-
   $password_seed = lookup("base_installation::puppet_pass_seed")
 
   $user = lookup("role::backup::user")