Files
rick-infra/roles/postgresql

PostgreSQL Infrastructure Role

This role provides PostgreSQL as shared database infrastructure for rick-infra applications. It follows the self-contained service architecture where this role provides the database server, and applications manage their own databases and users.

Architecture

PostgreSQL serves as database infrastructure (similar to how Caddy provides web infrastructure):

  • PostgreSQL Role: Installs and configures PostgreSQL server
  • Application Roles: Create their own databases/users via dependency

Features

  • Native Arch Linux installation via pacman
  • Secure configuration with scram-sha-256 authentication
  • SystemD security hardening
  • Data integrity with checksums enabled by default
  • Performance-tuned defaults
  • Comprehensive logging configuration
  • UTF-8 encoding with C.UTF-8 locale

Usage

In Application Roles

Add PostgreSQL as a dependency in your application's meta/main.yml:

dependencies:
  - role: postgresql
    tags: ['postgresql', 'infrastructure']

Then create your application's database and user in your tasks:

- name: Create application database user
  postgresql_user:
    name: "{{ myapp_db_user }}"
    password: "{{ myapp_db_password }}"
    encrypted: yes
  become: yes
  become_user: postgres

- name: Create application database
  postgresql_db:
    name: "{{ myapp_db_name }}"
    owner: "{{ myapp_db_user }}"
    encoding: UTF8
    template: template0
  become: yes
  become_user: postgres

In site.yml

- name: Deploy Infrastructure
  hosts: arch-vps
  become: yes
  
  roles:
    - role: postgresql
      tags: ['postgresql', 'infrastructure', 'database']
    - role: myapp  # Will use PostgreSQL infrastructure
      tags: ['myapp']

Configuration Variables

Basic Configuration

Variable Default Description
postgresql_service_enabled true Enable PostgreSQL service
postgresql_service_state "started" Service state
postgresql_port 5432 PostgreSQL port
postgresql_listen_addresses "localhost" Listen addresses

Security Configuration

Variable Default Description
postgresql_auth_method "scram-sha-256" Authentication method
postgresql_systemd_security true Enable systemd security hardening
postgresql_data_checksums true Enable data checksums
postgresql_ssl false Enable SSL/TLS

Performance Configuration

Variable Default Description
postgresql_max_connections 100 Maximum connections
postgresql_shared_buffers "128MB" Shared buffer size
postgresql_effective_cache_size "1GB" Effective cache size

See defaults/main.yml for all available configuration options.

Security Features

SystemD Hardening

The role implements comprehensive systemd security restrictions:

  • NoNewPrivileges=true
  • PrivateTmp=true
  • ProtectHome=true
  • ProtectSystem=strict
  • Memory execution protection
  • System call filtering

Authentication

  • Secure scram-sha-256 password authentication
  • peer authentication for postgres superuser
  • Local connections only by default
  • Encrypted password storage

File System Security

  • Proper ownership and permissions
  • Protected configuration files (mode 0600)
  • Separate log directory with appropriate access

Directory Structure

/var/lib/postgres/data/     # PostgreSQL data directory
/var/lib/postgres/          # PostgreSQL home directory  
/var/log/postgresql/        # PostgreSQL logs
/etc/systemd/system/postgresql.service.d/  # SystemD overrides

Database Administration

Connect as postgres superuser:

sudo -u postgres psql

Create application database and user:

CREATE ROLE myapp WITH LOGIN PASSWORD 'secure_password';
CREATE DATABASE myapp WITH OWNER myapp TEMPLATE template0 ENCODING 'UTF8';

List databases:

\l

List users:

\du

Performance Tuning

The role provides conservative performance defaults suitable for most applications. For production workloads, consider adjusting:

  • postgresql_shared_buffers: 25% of system RAM
  • postgresql_effective_cache_size: 75% of system RAM
  • postgresql_max_connections: Based on application needs
  • postgresql_maintenance_work_mem: For large datasets

Monitoring

Service Status

systemctl status postgresql

Logs

journalctl -u postgresql
# or
sudo -u postgres tail -f /var/log/postgresql/postgresql-*.log

Connection Test

sudo -u postgres psql -c "SELECT version();"

Troubleshooting

Common Issues

  1. Permission Denied: Ensure postgres user owns data directory
  2. Connection Refused: Check service status and listen_addresses
  3. Authentication Failed: Verify pg_hba.conf configuration

Debug Mode

Enable detailed logging:

postgresql_log_statement: "all"
postgresql_log_connections: true
postgresql_log_disconnections: true

Examples

Development Setup

postgresql_log_statement: "all"  # Log all statements
postgresql_max_connections: 50   # Lower for development

Production Setup

postgresql_shared_buffers: "256MB"
postgresql_effective_cache_size: "2GB" 
postgresql_log_min_duration_statement: 1000  # Log slow queries
postgresql_log_connections: true  # Audit trail

High Security Setup

postgresql_ssl: true
postgresql_log_connections: true
postgresql_log_disconnections: true
postgresql_log_statement: "ddl"  # Log schema changes

Dependencies

  • Arch Linux PostgreSQL package
  • python-psycopg2 (for Ansible modules)

Compatibility

  • OS: Arch Linux
  • PostgreSQL: Latest stable version from Arch repositories
  • Ansible: >= 2.9

Contributing

When modifying this role:

  1. Update this README for any new features
  2. Test with example applications
  3. Ensure security configurations remain intact
  4. Follow rick-infra coding standards

Integration Examples

See roles that use this infrastructure:

  • gitea: Git repository management
  • nextcloud (planned): File sharing and collaboration

Rick-Infra PostgreSQL Infrastructure Role
Provides secure, performant PostgreSQL database infrastructure for rick-infra applications.