diff --git a/roles/podman/templates/containers.conf.j2 b/roles/podman/templates/containers.conf.j2 new file mode 100644 index 0000000..ffd4141 --- /dev/null +++ b/roles/podman/templates/containers.conf.j2 @@ -0,0 +1,29 @@ +# Podman containers configuration +# See: man containers.conf +# {{ ansible_managed }} + +[containers] +log_driver = "{{ podman_log_driver }}" + +{% if podman_log_driver == 'k8s-file' %} +# k8s-file driver options (JSON file logging with rotation) +log_size_max = {{ podman_log_max_size }} +log_tag = "{{ '{{.Name}}' }}" + +# Note: log rotation is handled by the k8s-file driver itself +# max_size triggers rotation, keeping log_max_files number of files +{% endif %} +# Default timezone for containers (use host timezone) +tz = "local" + +[engine] +events_logger = "journald" + +# Number of locks available for containers and pods +num_locks = 2048 + +# OCI runtime (crun or runc) +runtime = "{{ podman_runtime }}" + +# Default network backend +network_backend = "netavark" diff --git a/roles/postgres/templates/logrotate-postgresql.j2 b/roles/postgres/templates/logrotate-postgresql.j2 new file mode 100644 index 0000000..27da8f5 --- /dev/null +++ b/roles/postgres/templates/logrotate-postgresql.j2 @@ -0,0 +1,40 @@ +# Logrotate configuration for PostgreSQL +# Managed by Ansible - DO NOT EDIT MANUALLY + +{% if ansible_facts['os_family'] == 'Archlinux' %} +# Arch Linux: PostgreSQL logs to data directory +{{ postgres_data_dir }}/log/*.log { + {{ postgres_logrotate_frequency }} + missingok + rotate {{ postgres_logrotate_rotate }} + {% if postgres_logrotate_compress %} + compress + delaycompress + {% endif %} + notifempty + create 0600 postgres postgres + sharedscripts + postrotate + # Signal PostgreSQL to reopen log files + systemctl reload {{ postgres_service_name }} > /dev/null 2>&1 || true + endscript +} +{% else %} +# Debian/Ubuntu: PostgreSQL logs to /var/log/postgresql +/var/log/postgresql/*.log { + {{ postgres_logrotate_frequency }} + missingok + rotate {{ postgres_logrotate_rotate }} + {% if postgres_logrotate_compress %} + compress + delaycompress + {% endif %} + notifempty + create 0640 postgres postgres + sharedscripts + postrotate + # Signal PostgreSQL to reopen log files + systemctl reload {{ postgres_service_name }} > /dev/null 2>&1 || true + endscript +} +{% endif %} diff --git a/roles/systemd/README.md b/roles/systemd/README.md new file mode 100644 index 0000000..afeeedb --- /dev/null +++ b/roles/systemd/README.md @@ -0,0 +1,36 @@ +# Systemd Role + +Manages systemd-journald configuration for efficient log management and storage control. + +## Overview + +This role configures systemd's journal daemon (`systemd-journald`) to control log storage, retention, and rotation. It's designed to prevent excessive disk usage from system logs while maintaining sufficient logging for troubleshooting. + +## Hands-on commands + +```bash +# Disk usage +sudo journalctl --disk-usage + +# Current configuration +systemctl show systemd-journald + +# Verify configuration +sudo journalctl --verify + +# Manual cleanup by time +sudo journalctl --vacuum-time=2weeks + +# Manual cleanup by size +sudo journalctl --vacuum-size=500M + +# Manual cleanup by file count +sudo journalctl --vacuum-files=10 +``` + +## References + +- [journald.conf(5) man page](https://www.freedesktop.org/software/systemd/man/journald.conf.html) +- [systemd-journald.service(8)](https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html) +- [journalctl(1) man page](https://www.freedesktop.org/software/systemd/man/journalctl.html) +- [Arch Wiki: systemd/Journal](https://wiki.archlinux.org/title/Systemd/Journal) diff --git a/roles/systemd/defaults/main.yml b/roles/systemd/defaults/main.yml new file mode 100644 index 0000000..7ee2ea6 --- /dev/null +++ b/roles/systemd/defaults/main.yml @@ -0,0 +1,57 @@ +--- +# systemd-journald configuration +# See: man journald.conf + +# Storage mode +# - persistent: store in /var/log/journal (survives reboots) +# - volatile: store in /run/log/journal (cleared on reboot) +# - auto: use /var/log/journal if it exists, otherwise /run/log/journal +systemd_journald_storage: persistent + +# System journal size limits +systemd_journald_system_max_use: 500M # Max disk space for system logs +systemd_journald_system_keep_free: 1G # Keep this much disk space free +systemd_journald_system_max_file_size: 50M # Max size per journal file before rotation +systemd_journald_system_max_files: 10 # Max number of rotated files to keep + +# Runtime journal size limits (for volatile storage) +systemd_journald_runtime_max_use: 100M +systemd_journald_runtime_keep_free: 100M +systemd_journald_runtime_max_file_size: 10M +systemd_journald_runtime_max_files: 10 + +# Time-based retention (e.g., 1month, 1year, 0 for unlimited) +systemd_journald_max_retention_sec: 2weeks + +# Compression of journal files +systemd_journald_compress: "yes" + +# Rate limiting (prevent log flooding) +systemd_journald_rate_limit_interval_sec: 30s +systemd_journald_rate_limit_burst: 10000 + +# Forward to syslog (if you have rsyslog/syslog-ng) +systemd_journald_forward_to_syslog: "no" +systemd_journald_forward_to_kmsg: "no" +systemd_journald_forward_to_console: "no" +systemd_journald_forward_to_wall: "no" + +# Max level to store (debug, info, notice, warning, err, crit, alert, emerg) +systemd_journald_max_level_store: debug +systemd_journald_max_level_syslog: debug + +# Seal journals (requires systemd-journal-remote, adds forward-secure sealing) +systemd_journald_seal: "no" + +# Split mode - controls per-user journals +# - uid: one journal per user +# - none: single system journal only +systemd_journald_split_mode: uid + +# Sync to disk interval (performance vs losing logs on crash) +systemd_journald_sync_interval_sec: 5m + +# Whether to vacuum (clean) old logs on service start +systemd_journald_vacuum_on_deploy: true +systemd_journald_vacuum_time: "{{ systemd_journald_max_retention_sec }}" +systemd_journald_vacuum_size: "{{ systemd_journald_system_max_use }}" diff --git a/roles/systemd/handlers/main.yml b/roles/systemd/handlers/main.yml new file mode 100644 index 0000000..7305cdb --- /dev/null +++ b/roles/systemd/handlers/main.yml @@ -0,0 +1,6 @@ +--- +- name: Restart systemd-journald + ansible.builtin.systemd: + name: systemd-journald + state: restarted + daemon_reload: true diff --git a/roles/systemd/tasks/main.yml b/roles/systemd/tasks/main.yml new file mode 100644 index 0000000..3eada90 --- /dev/null +++ b/roles/systemd/tasks/main.yml @@ -0,0 +1,36 @@ +--- +# systemd role - manages systemd-journald configuration and log rotation + +- name: Deploy journald configuration + ansible.builtin.template: + src: journald.conf.j2 + dest: /etc/systemd/journald.conf + owner: root + group: root + mode: "0644" + notify: Restart systemd-journald + +- name: Ensure /var/log/journal directory exists (for persistent storage) + ansible.builtin.file: + path: /var/log/journal + state: directory + owner: root + group: systemd-journal + mode: "2755" + when: systemd_journald_storage in ['persistent', 'auto'] + +- name: Vacuum old journal logs (cleanup on deployment) + ansible.builtin.command: + cmd: > + journalctl --vacuum-time={{ systemd_journald_vacuum_time }} + --vacuum-size={{ systemd_journald_vacuum_size }} + when: systemd_journald_vacuum_on_deploy + changed_when: false + register: vacuum_result + +- name: Display vacuum results + ansible.builtin.debug: + msg: "{{ vacuum_result.stdout_lines }}" + when: + - systemd_journald_vacuum_on_deploy + - vacuum_result.stdout_lines is defined diff --git a/roles/systemd/templates/journald.conf.j2 b/roles/systemd/templates/journald.conf.j2 new file mode 100644 index 0000000..3529321 --- /dev/null +++ b/roles/systemd/templates/journald.conf.j2 @@ -0,0 +1,58 @@ +# This file is part of systemd. +# +# systemd is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 of the License, or +# (at your option) any later version. +# +# Entries in this file show the compile time defaults. +# You can change settings by editing this file. +# Defaults can be restored by simply deleting this file. +# +# See journald.conf(5) for details. +# Managed by Ansible - DO NOT EDIT MANUALLY + +[Journal] +# Storage mode: persistent|volatile|auto|none +Storage={{ systemd_journald_storage }} + +# Compress archived journal files +Compress={{ systemd_journald_compress }} + +# Seal journal files (requires systemd-journal-remote) +Seal={{ systemd_journald_seal }} + +# Split mode for per-user journals: uid|none +SplitMode={{ systemd_journald_split_mode }} + +# Sync interval - how often to flush to disk +SyncIntervalSec={{ systemd_journald_sync_interval_sec }} + +# Rate limiting to prevent log flooding +RateLimitIntervalSec={{ systemd_journald_rate_limit_interval_sec }} +RateLimitBurst={{ systemd_journald_rate_limit_burst }} + +# System journal size limits (persistent storage) +SystemMaxUse={{ systemd_journald_system_max_use }} +SystemKeepFree={{ systemd_journald_system_keep_free }} +SystemMaxFileSize={{ systemd_journald_system_max_file_size }} +SystemMaxFiles={{ systemd_journald_system_max_files }} + +# Runtime journal size limits (volatile storage in /run) +RuntimeMaxUse={{ systemd_journald_runtime_max_use }} +RuntimeKeepFree={{ systemd_journald_runtime_keep_free }} +RuntimeMaxFileSize={{ systemd_journald_runtime_max_file_size }} +RuntimeMaxFiles={{ systemd_journald_runtime_max_files }} + +# Time-based retention (e.g., 1week, 2months, 1year) +MaxRetentionSec={{ systemd_journald_max_retention_sec }} + +# Maximum log level to store +MaxLevelStore={{ systemd_journald_max_level_store }} +MaxLevelSyslog={{ systemd_journald_max_level_syslog }} + +# Forward messages to other targets +ForwardToSyslog={{ systemd_journald_forward_to_syslog }} +ForwardToKMsg={{ systemd_journald_forward_to_kmsg }} +ForwardToConsole={{ systemd_journald_forward_to_console }} +ForwardToWall={{ systemd_journald_forward_to_wall }}