Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Server Instance Feature #1450

Merged
merged 8 commits into from Oct 10, 2023
181 changes: 180 additions & 1 deletion README.md
Expand Up @@ -8,6 +8,7 @@
* [Getting started with postgresql](#getting-started-with-postgresql)
3. [Usage - Configuration options and additional functionality](#usage)
* [Configure a server](#configure-a-server)
* [Configure an instance](#configure-an-instance)
* [Create a database](#create-a-database)
* [Manage users, roles, and permissions](#manage-users-roles-and-permissions)
* [Manage ownership of DB objects](#manage-ownership-of-db-objects)
Expand Down Expand Up @@ -72,6 +73,184 @@ If you get an error message from these commands, your permission settings restri

For more details about server configuration parameters, consult the [PostgreSQL Runtime Configuration documentation](http://www.postgresql.org/docs/current/static/runtime-config.html).

### Configure an instance
SimonHoenscheid marked this conversation as resolved.
Show resolved Hide resolved

This module supports managing multiple instances (the default instance is referred to as 'main' and managed via including the server.pp class)

**NOTE:** This feature is currently tested on Centos 8 Streams/RHEL8 with DNF Modules enabled. Different Linux plattforms and/or the Postgresql.org
packages distribute different Systemd service files or use wrapper scripts with Systemd to start Postgres. Additional adjustmentments are needed to get this working on these plattforms.

#### Working Plattforms

* Centos 8 Streams
* RHEL 8

#### Background and example

creating a new instance has the following advantages:
* files are owned by the postgres user
* instance is running under a different user, if the instance is hacked, the hacker has no access to the file system
* the instance user can be an LDAP user, higher security because of central login monitoring, password policies, password rotation policies
* main instance can be disabled


Here is a profile which can be used to create instaces

```puppet
class profiles::postgres (
Hash $instances = {},
String $postgresql_version = '13',
) {
class { 'postgresql::globals':
encoding => 'UTF-8',
locale => 'en_US.UTF-8',
manage_package_repo => false,
manage_dnf_module => true,
needs_initdb => true,
version => $postgresql_version,
}
include postgresql::server

$instances.each |String $instance, Hash $instance_settings| {
postgresql::server_instance { $instance:
* => $instance_settings,
}
}
}
```

And here is data to create an instance called test1:

```yaml
# stop default main instance
postgresql::server::service_ensure: "stopped"
postgresql::server::service_enable: false
Comment on lines +125 to +127
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should go in the above profile rather than in Hiera.


#define an instance
profiles::postgres::instances:
test1:
instance_user: "ins_test1"
instance_group: "ins_test1"
instance_directories:
"/opt/pgsql":
ensure: directory
"/opt/pgsql/backup":
ensure: directory
"/opt/pgsql/data":
ensure: directory
"/opt/pgsql/data/13":
ensure: directory
"/opt/pgsql/data/home":
ensure: directory
"/opt/pgsql/wal":
ensure: directory
"/opt/pgsql/log":
ensure: directory
"/opt/pgsql/log/13":
ensure: directory
"/opt/pgsql/log/13/test1":
ensure: directory
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we place the directory names in an array? This would reduce the number of lines.

Another option would be to make use of the dirtree module and the dirtree type/provider inside the instance defined type.
Using dirtree option should be done in a different PR as this will raise different discussion.

config_settings:
pg_hba_conf_path: "/opt/pgsql/data/13/test1/pg_hba.conf"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here we have to replicate the version in many occasions.
Maybe version should become a hiera data, so it can be reused where needed.
Hardcoding version might make sense, if one is able to install multiple postgresql versions in parallel.

postgresql_conf_path: "/opt/pgsql/data/13/test1/postgresql.conf"
pg_ident_conf_path: "/opt/pgsql/data/13/test1/pg_ident.conf"
datadir: "/opt/pgsql/data/13/test1"
service_name: "postgresql@13-test1"
port: 5433
pg_hba_conf_defaults: false
service_settings:
service_name: "postgresql@13-test1"
service_status: "systemctl status postgresql@13-test1.service"
service_ensure: "running"
service_enable: true
initdb_settings:
auth_local: "peer"
auth_host: "md5"
needs_initdb: true
datadir: "/opt/pgsql/data/13/test1"
encoding: "UTF-8"
lc_messages: "en_US.UTF8"
locale: "en_US.UTF8"
data_checksums: false
group: "postgres"
user: "postgres"
username: "ins_test1"
config_entries:
authentication_timeout:
value: "1min"
comment: "a test"
log_statement_stats:
value: "off"
autovacuum_vacuum_scale_factor:
value: 0.3
databases:
testdb1:
encoding: "UTF8"
locale: "en_US.UTF8"
owner: "dba_test1"
testdb2:
encoding: "UTF8"
locale: "en_US.UTF8"
owner: "dba_test1"
roles:
"ins_test1":
superuser: true
login: true
"dba_test1":
createdb: true
login: true
"app_test1":
login: true
"rep_test1":
replication: true
login: true
"rou_test1":
login: true
pg_hba_rules:
"local all INSTANCE user":
type: "local"
database: "all"
user: "ins_test1"
auth_method: "peer"
order: 1
"local all DB user":
type: "local"
database: "all"
user: "dba_test1"
auth_method: "peer"
order: 2
"local all APP user":
type: "local"
database: "all"
user: "app_test1"
auth_method: "peer"
order: 3
"local all READONLY user":
type: "local"
database: "all"
user: "rou_test1"
auth_method: "peer"
order: 4
"remote all INSTANCE user PGADMIN server":
type: "host"
database: "all"
user: "ins_test1"
address: "192.168.22.131/32"
auth_method: "md5"
order: 5
"local replication INSTANCE user":
type: "local"
database: "replication"
user: "ins_test1"
auth_method: "peer"
order: 6
"local replication REPLICATION user":
type: "local"
database: "replication"
user: "rep_test1"
auth_method: "peer"
order: 7
Comment on lines +132 to +252
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These 120 lines of boilerplate are scary 😱

I guess that if it was trivial it would have been done, but just to be sure, we have no way to skip some parameters that feel redundant (e.g. pass a datadir and infer the path to config files, generate the service name based on the instance name, etc)? That would require to change a lot of parameter default values and use the value of previous parameters instead of taking a value directly from params.pp?

```
### Create a database

You can set up a variety of PostgreSQL databases with the `postgresql::server::db` defined type. For instance, to set up a database for PuppetDB:
Expand Down Expand Up @@ -359,7 +538,7 @@ For information on the classes and types, see the [REFERENCE.md](https://github.

## Limitations

Works with versions of PostgreSQL on supported OSes.
Works with versions of PostgreSQL on supported OSes.

For an extensive list of supported operating systems, see [metadata.json](https://github.com/puppetlabs/puppetlabs-postgresql/blob/main/metadata.json)

Expand Down