103 lines
3.2 KiB
Nix
103 lines
3.2 KiB
Nix
|
{
|
||
|
name = "PostgreSQL";
|
||
|
description = ''
|
||
|
Runs a PostgreSQL database server on this host.
|
||
|
Other roles can use this role to create the required databases on this host through the
|
||
|
`postgres` attribute.
|
||
|
'';
|
||
|
|
||
|
nixosModule =
|
||
|
{
|
||
|
lib,
|
||
|
pkgs,
|
||
|
config,
|
||
|
...
|
||
|
}:
|
||
|
with lib;
|
||
|
{
|
||
|
options.postgres = {
|
||
|
databases = mkOption {
|
||
|
type = types.listOf types.str;
|
||
|
default = [ ];
|
||
|
};
|
||
|
};
|
||
|
config =
|
||
|
let
|
||
|
cfg = config.postgres;
|
||
|
in
|
||
|
{
|
||
|
# Create the postgresql service
|
||
|
services.postgresql = {
|
||
|
enable = true;
|
||
|
enableTCPIP = true;
|
||
|
ensureDatabases = map (db: db) cfg.databases;
|
||
|
ensureUsers = map (db: {
|
||
|
name = db;
|
||
|
ensureDBOwnership = true;
|
||
|
ensureClauses.login = true;
|
||
|
}) cfg.databases;
|
||
|
identMap = ''
|
||
|
# ArbitraryMapName systemUser DBUser
|
||
|
superuser_map root postgres
|
||
|
superuser_map postgres postgres
|
||
|
'';
|
||
|
|
||
|
authentication = pkgs.lib.mkOverride 10 ''
|
||
|
# Allow local users to log into the database user with the same name
|
||
|
local sameuser postgres peer map=superuser_map
|
||
|
# Allow "md5" (password) authentication
|
||
|
local all all md5
|
||
|
host all all 0.0.0.0/0 md5
|
||
|
host all all 127.0.0.1/32 md5
|
||
|
host all all ::1/128 md5
|
||
|
'';
|
||
|
};
|
||
|
|
||
|
networking.firewall.allowedTCPPorts = [
|
||
|
5432
|
||
|
];
|
||
|
|
||
|
# Persist the database contents across reboots
|
||
|
# TODO: This should be automatically backed up daily into the CEPH
|
||
|
# cluster storage. It can't be on the cluster all the time, since
|
||
|
# CEPH doesn't perform great with databases (according to people
|
||
|
# online).
|
||
|
environment.persistence."/persistent" = {
|
||
|
directories = [
|
||
|
{
|
||
|
directory = "/var/lib/postgresql";
|
||
|
user = "postgres";
|
||
|
mode = "0700";
|
||
|
}
|
||
|
];
|
||
|
};
|
||
|
|
||
|
# Create the required secret files
|
||
|
sops.secrets = listToAttrs (
|
||
|
map (db: {
|
||
|
name = "postgres/${db}";
|
||
|
value = {
|
||
|
owner = "postgres";
|
||
|
};
|
||
|
}) cfg.databases
|
||
|
);
|
||
|
|
||
|
# Use the secret files from sops to set database user passwords
|
||
|
systemd.services.postgresql.postStart = concatMapStrings (db: ''
|
||
|
$PSQL -tA <<'EOF'
|
||
|
DO $$
|
||
|
DECLARE username TEXT;
|
||
|
DECLARE password TEXT;
|
||
|
BEGIN
|
||
|
username := trim(both from replace('${db}', E'\n', '''));
|
||
|
password := trim(both from replace(pg_read_file('${
|
||
|
(attrsets.getAttrFromPath [ "postgres/${db}" ] config.sops.secrets).path
|
||
|
}'), E'\n', '''));
|
||
|
EXECUTE format('ALTER ROLE %s WITH PASSWORD '''%s''';', username, password);
|
||
|
END $$;
|
||
|
EOF
|
||
|
'') cfg.databases;
|
||
|
};
|
||
|
};
|
||
|
}
|