diff --git a/host_vars/arch-vps/main.yml b/host_vars/arch-vps/main.yml index 313b892..0dcc515 100644 --- a/host_vars/arch-vps/main.yml +++ b/host_vars/arch-vps/main.yml @@ -24,17 +24,6 @@ caddy_acme_ca: "https://acme-v02.api.letsencrypt.org/directory" caddy_api_enabled: true caddy_server_name: "main" -# Static site configuration is deprecated - use API registration instead -# Services should use the registration handlers: -# -# Example service registration pattern: -# - name: Register my service -# set_fact: -# service_name: "myapi" -# service_domain: "api.jnss.me" -# service_backend: "localhost:8080" -# notify: register service with caddy - # ================================================================= # Sigvild Gallery Configuration # ================================================================= diff --git a/roles/gitea/tasks/main.yml b/roles/gitea/tasks/main.yml index b176a47..dd34469 100644 --- a/roles/gitea/tasks/main.yml +++ b/roles/gitea/tasks/main.yml @@ -7,7 +7,7 @@ name: gitea state: present -- name: Install Git (required for Gitea) +- name: Install Git pacman: name: git state: present @@ -111,4 +111,4 @@ 📦 Local HTTP: http://127.0.0.1:{{ gitea_http_port }} 🗄️ Database: {{ gitea_db_name }} (self-managed) - 🏗️ Self-contained service ready for Git repositories! \ No newline at end of file + 🏗️ Self-contained service ready for Git repositories! diff --git a/roles/valkey/README.md b/roles/valkey/README.md new file mode 100644 index 0000000..3e74b66 --- /dev/null +++ b/roles/valkey/README.md @@ -0,0 +1,163 @@ +# Valkey Infrastructure Role + +This role provides Valkey as shared infrastructure for the rick-infra project, following the same patterns established by the PostgreSQL role. + +## Overview + +**Valkey** is a high-performance data structure store used as a database, cache, and message broker. It's a Redis fork that maintains **100% Redis compatibility** while providing additional features and improvements. + +Valkey is deployed as a host-level service that multiple applications can use for caching, sessions, and data storage. Each application configures its own Valkey database number and connection parameters. + +## Why Valkey? + +- **Redis-compatible**: Drop-in replacement for Redis with identical API +- **Open source**: Truly open source alternative to Redis +- **Performance**: Enhanced performance optimizations +- **Arch Linux default**: Arch Linux provides Valkey instead of Redis in the `redis` package +- **Future-proof**: Active development and community support + +## Features + +- **Security-focused**: Localhost-only binding, password authentication, disabled dangerous commands +- **Systemd integration**: Native systemd service management with security hardening +- **Multi-application support**: 16 databases available for different services +- **Performance optimized**: Conservative memory limits and persistence settings +- **Infrastructure pattern**: Matches PostgreSQL role architecture +- **Redis compatibility**: Applications can use standard Redis clients and commands + +## Database Allocation + +Applications should use different Valkey database numbers: + +- **Database 0**: Reserved for system/testing use +- **Database 1**: Authentik (sessions, cache) +- **Database 2**: Nextcloud (sessions, file locking, cache) +- **Database 3+**: Available for additional services + +## Configuration + +### Required Variables + +```yaml +vault_valkey_password: "your-secure-valkey-password" +``` + +### Optional Overrides + +```yaml +# Service management +valkey_service_enabled: true +valkey_service_state: "started" + +# Network configuration +valkey_bind: "127.0.0.1" +valkey_port: 6379 + +# Memory management +valkey_maxmemory: "256mb" +valkey_maxmemory_policy: "allkeys-lru" + +# Security hardening +valkey_systemd_security: true +``` + +## Application Integration + +Applications can connect to Valkey using either Valkey-specific or Redis-compatible patterns: + +### Valkey Environment Variables (Recommended) +```yaml +VALKEY_HOST: "{{ ansible_default_ipv4.address }}" +VALKEY_PORT: "6379" +VALKEY_PASSWORD: "{{ vault_valkey_password }}" +VALKEY_DB: "1" # Unique database number per application +``` + +### Redis-Compatible Environment Variables (Also Supported) +```yaml +REDIS_HOST: "{{ ansible_default_ipv4.address }}" +REDIS_PORT: "6379" +REDIS_PASSWORD: "{{ vault_valkey_password }}" +REDIS_DB: "1" # Unique database number per application +``` + +### Connection Example +```bash +# Using redis-cli (Redis-compatible) +redis-cli -h 127.0.0.1 -p 6379 -a password -n 1 + +# Using valkey-cli (native Valkey client) +valkey-cli -h 127.0.0.1 -p 6379 -a password -n 1 +``` + +## Redis Compatibility + +Valkey maintains **100% Redis compatibility**: + +- **Same commands**: All Redis commands work identically +- **Same protocols**: RESP (Redis Serialization Protocol) supported +- **Same client libraries**: All Redis client libraries work without modification +- **Same configuration format**: Configuration syntax identical to Redis +- **Same data types**: All Redis data types supported + +## Security + +- **Network isolation**: Binds only to localhost +- **Authentication**: Password protection required +- **Command restrictions**: Dangerous commands disabled +- **Systemd hardening**: Full security restrictions applied +- **File permissions**: Restrictive access to configuration and data + +## Dependencies + +This is an infrastructure role with no dependencies. Applications that need Valkey should declare this role as a dependency: + +```yaml +# roles/your-app/meta/main.yml +dependencies: + - role: valkey +``` + +## Service Management + +```bash +# Service status +sudo systemctl status valkey + +# View logs +sudo journalctl -u valkey -f + +# Test connectivity +redis-cli -h 127.0.0.1 -p 6379 -a password ping +``` + +## Monitoring + +Valkey status is reported during deployment and can be monitored through: + +- **systemctl**: Service health and status +- **journald**: Centralized logging +- **Redis CLI**: Direct connectivity testing using standard Redis tools +- **Application logs**: Connection status from applications + +## File Locations + +- **Configuration**: `/etc/valkey/valkey.conf` +- **Data directory**: `/var/lib/valkey` +- **Systemd override**: `/etc/systemd/system/valkey.service.d/override.conf` +- **Logs**: `journalctl -u valkey` + +## Migration from Redis + +If migrating from Redis: + +1. **Data compatibility**: Valkey can read existing Redis data files +2. **Configuration**: Most Redis configurations work without changes +3. **Applications**: No application changes required due to protocol compatibility +4. **Monitoring**: Same Redis monitoring tools work with Valkey + +## Notes + +This role follows the rick-infra infrastructure pattern where foundational services (Valkey, PostgreSQL) are provided as host-level services, and applications configure their own usage patterns rather than managing separate instances. + +**Arch Linux Integration**: The role automatically works with Arch Linux's package system, which provides Valkey as the `redis` package with full Redis compatibility. \ No newline at end of file diff --git a/roles/valkey/defaults/main.yml b/roles/valkey/defaults/main.yml new file mode 100644 index 0000000..648b439 --- /dev/null +++ b/roles/valkey/defaults/main.yml @@ -0,0 +1,88 @@ +--- +# ================================================================= +# Valkey Infrastructure Role - Simplified Configuration +# ================================================================= +# Provides Valkey (Redis-compatible) as shared infrastructure for applications +# Applications manage their own Valkey database selections and usage + +# ================================================================= +# Essential Configuration +# ================================================================= + +# Service Management +valkey_service_enabled: true +valkey_service_state: "started" + +# Network Security (localhost only - matches PostgreSQL pattern) +valkey_bind: "127.0.0.1" +valkey_port: 6379 +valkey_protected_mode: true + +# Authentication +valkey_requirepass: "{{ vault_valkey_password }}" + +# ================================================================= +# Performance Settings (Conservative Defaults) +# ================================================================= + +# Memory Management +valkey_maxmemory: "256mb" +valkey_maxmemory_policy: "allkeys-lru" + +# Persistence (balanced approach) +valkey_save_enabled: true +valkey_save_intervals: + - "900 1" # Save if 1 key changed in 900s + - "300 10" # Save if 10 keys changed in 300s + - "60 10000" # Save if 10000 keys changed in 60s + +# RDB and AOF settings +valkey_rdbcompression: true +valkey_rdbchecksum: true +valkey_appendonly: false # RDB only for simplicity + +# ================================================================= +# Security Configuration +# ================================================================= + +# Systemd security hardening +valkey_systemd_security: true + +# Valkey security settings +valkey_timeout: 300 +valkey_tcp_keepalive: 300 +valkey_tcp_backlog: 511 + +# ================================================================= +# Database Configuration +# ================================================================= + +# Database allocation for applications +# Applications should use different database numbers: +# - authentik: database 1 +# - nextcloud: database 2 +# - future services: database 3, 4, etc. +valkey_databases: 16 + +# ================================================================= +# Logging Configuration +# ================================================================= + +valkey_loglevel: "notice" +valkey_syslog_enabled: true +valkey_syslog_ident: "valkey" + +# ================================================================= +# Infrastructure Notes +# ================================================================= +# This role provides minimal Valkey infrastructure +# Applications should configure their own Valkey usage: +# +# Environment variables in application configs: +# - VALKEY_HOST: "{{ ansible_default_ipv4.address }}" or "127.0.0.1" +# - VALKEY_PORT: "6379" +# - VALKEY_PASSWORD: "{{ vault_valkey_password }}" +# - VALKEY_DB: "1" (or 2, 3, etc. - unique per application) +# +# Note: Applications can also use REDIS_* environment variables +# for compatibility since Valkey is fully Redis-compatible \ No newline at end of file diff --git a/roles/valkey/handlers/main.yml b/roles/valkey/handlers/main.yml new file mode 100644 index 0000000..23d5dcd --- /dev/null +++ b/roles/valkey/handlers/main.yml @@ -0,0 +1,17 @@ +--- +# Valkey Infrastructure Role - Handlers +# Matches the handler pattern from PostgreSQL role + +- name: reload systemd + systemd: + daemon_reload: yes + +- name: restart valkey + systemd: + name: valkey + state: restarted + +- name: reload valkey + systemd: + name: valkey + state: reloaded \ No newline at end of file diff --git a/roles/valkey/meta/main.yml b/roles/valkey/meta/main.yml new file mode 100644 index 0000000..b480416 --- /dev/null +++ b/roles/valkey/meta/main.yml @@ -0,0 +1,23 @@ +--- +# Valkey Infrastructure Role - Meta Information + +galaxy_info: + author: rick-infra + description: Valkey (Redis-compatible) infrastructure role for rick-infra project + company: Personal Infrastructure + license: MIT + min_ansible_version: 2.9 + + platforms: + - name: ArchLinux + versions: + - all + + galaxy_tags: + - valkey + - redis + - cache + - infrastructure + - systemd + +# Role provides Valkey infrastructure for other services to consume diff --git a/roles/valkey/tasks/main.yml b/roles/valkey/tasks/main.yml new file mode 100644 index 0000000..9cf1d28 --- /dev/null +++ b/roles/valkey/tasks/main.yml @@ -0,0 +1,94 @@ +--- +# Valkey Infrastructure Role - Simplified Tasks + +- name: Install Valkey + pacman: + name: valkey + state: present + +# Note: Arch Linux's redis package (which provides Valkey) creates the 'valkey' user automatically +# We don't need to create users - just ensure data directory permissions + +- name: Create Valkey configuration directory + file: + path: /etc/valkey + state: directory + mode: '0755' + +- name: Check if Valkey data directory exists + stat: + path: "/var/lib/valkey" + register: valkey_data_dir + +- name: Ensure Valkey data directory permissions + file: + path: /var/lib/valkey + state: directory + owner: valkey + group: valkey + mode: '0750' + +- name: Deploy Valkey configuration file + template: + src: valkey.conf.j2 + dest: /etc/valkey/valkey.conf + owner: valkey + group: valkey + mode: '0640' + backup: yes + notify: restart valkey + +- name: Create systemd override directory for Valkey security + file: + path: /etc/systemd/system/valkey.service.d + state: directory + mode: '0755' + when: valkey_systemd_security + +- name: Deploy Valkey systemd security override + template: + src: systemd-override.conf.j2 + dest: /etc/systemd/system/valkey.service.d/override.conf + mode: '0644' + when: valkey_systemd_security + notify: + - reload systemd + - restart valkey + +- name: Enable and start Valkey service + systemd: + name: valkey + enabled: "{{ valkey_service_enabled }}" + state: "{{ valkey_service_state }}" + daemon_reload: yes + +- name: Wait for Valkey to be ready + wait_for: + port: "{{ valkey_port }}" + host: "{{ valkey_bind }}" + timeout: 30 + when: valkey_service_state == "started" + +- name: Test Valkey connectivity + command: redis-cli -h {{ valkey_bind }} -p {{ valkey_port }} -a {{ valkey_requirepass }} ping + register: valkey_ping_result + changed_when: false + failed_when: valkey_ping_result.stdout != "PONG" + when: valkey_service_state == "started" + +- name: Display Valkey infrastructure status + debug: + msg: | + ✅ Valkey infrastructure ready! + + 📡 Service: {{ valkey_bind }}:{{ valkey_port }} + 🔒 Auth: Password protected + 💾 Persistence: {{ 'RDB enabled' if valkey_save_enabled else 'Memory only' }} + 🗄️ Databases: {{ valkey_databases }} available (0-{{ valkey_databases - 1 }}) + + 🏗️ Ready for applications to configure Valkey usage + + 📋 Application Integration: + - Use database numbers 1-{{ valkey_databases - 1 }} for applications + - Database 0 reserved for system/testing + - Redis-compatible: applications can use REDIS_* or VALKEY_* env vars diff --git a/roles/valkey/templates/systemd-override.conf.j2 b/roles/valkey/templates/systemd-override.conf.j2 new file mode 100644 index 0000000..2d566fa --- /dev/null +++ b/roles/valkey/templates/systemd-override.conf.j2 @@ -0,0 +1,49 @@ +# Redis Systemd Security Override +# Generated by rick-infra Redis role +# +# This file provides additional security hardening for the Redis service +# following the same security patterns as the PostgreSQL role. + +[Service] +# Security hardening +NoNewPrivileges=yes +PrivateTmp=yes +PrivateDevices=yes +ProtectSystem=strict +ProtectHome=yes +ProtectKernelTunables=yes +ProtectKernelModules=yes +ProtectControlGroups=yes +RestrictRealtime=yes +RestrictSUIDSGID=yes + +# Network security +RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX + +# Filesystem permissions +ReadWritePaths=/var/lib/valkey +ReadOnlyPaths=/etc/valkey + +# System call filtering +SystemCallFilter=@system-service +SystemCallFilter=~@privileged @resources @obsolete + +# Memory and resource limits +MemoryDenyWriteExecute=yes +LockPersonality=yes + +# Capabilities +CapabilityBoundingSet= +AmbientCapabilities= + +# User and group isolation +DynamicUser=no +User=valkey +Group=valkey + +# Process isolation +PrivateUsers=yes +RemoveIPC=yes + +# Additional Redis-specific security +UMask=0027 \ No newline at end of file diff --git a/roles/valkey/templates/valkey.conf.j2 b/roles/valkey/templates/valkey.conf.j2 new file mode 100644 index 0000000..17cadcb --- /dev/null +++ b/roles/valkey/templates/valkey.conf.j2 @@ -0,0 +1,130 @@ +# Valkey Configuration - Generated by Ansible +# rick-infra Valkey Infrastructure Role +# +# This configuration provides a secure, performant Valkey instance +# for use by multiple applications on the same host. + +# ================================================================= +# Network Configuration +# ================================================================= + +# Bind to localhost only for security (like PostgreSQL) +bind {{ valkey_bind }} + +# Valkey port +port {{ valkey_port }} + +# Protected mode - requires authentication +protected-mode {{ 'yes' if valkey_protected_mode else 'no' }} + +# Connection timeout +timeout {{ valkey_timeout }} + +# TCP listen backlog +tcp-backlog {{ valkey_tcp_backlog }} + +# TCP keepalive +tcp-keepalive {{ valkey_tcp_keepalive }} + +# ================================================================= +# Authentication +# ================================================================= + +# Require password for all operations +requirepass {{ valkey_requirepass }} + +# ================================================================= +# Memory Management +# ================================================================= + +# Maximum memory usage +maxmemory {{ valkey_maxmemory }} + +# Eviction policy when max memory is reached +maxmemory-policy {{ valkey_maxmemory_policy }} + +# ================================================================= +# Persistence Configuration +# ================================================================= + +# Working directory for RDB files +dir /var/lib/valkey + +{% if valkey_save_enabled %} +# RDB persistence - save snapshots +{% for interval in valkey_save_intervals %} +save {{ interval }} +{% endfor %} + +# RDB file compression and checksums +rdbcompression {{ 'yes' if valkey_rdbcompression else 'no' }} +rdbchecksum {{ 'yes' if valkey_rdbchecksum else 'no' }} +{% else %} +# RDB persistence disabled +save "" +{% endif %} + +# AOF persistence +appendonly {{ 'yes' if valkey_appendonly else 'no' }} + +# ================================================================= +# Database Configuration +# ================================================================= + +# Number of databases (0 to databases-1) +databases {{ valkey_databases }} + +# ================================================================= +# Logging Configuration +# ================================================================= + +# Log level +loglevel {{ valkey_loglevel }} + +# Syslog integration +{% if valkey_syslog_enabled %} +syslog-enabled yes +syslog-ident {{ valkey_syslog_ident }} +{% endif %} + +# ================================================================= +# Security Settings +# ================================================================= + +# Disable dangerous commands +rename-command FLUSHDB "" +rename-command FLUSHALL "" +rename-command KEYS "" +rename-command CONFIG "" +rename-command SHUTDOWN VALKEY_SHUTDOWN +rename-command DEBUG "" +rename-command EVAL "" + +# ================================================================= +# Performance Tuning +# ================================================================= + +# Disable automatic rehashing for better performance +activerehashing yes + +# Client output buffer limits for normal clients +client-output-buffer-limit normal 0 0 0 + +# Client output buffer limits for replica clients +client-output-buffer-limit replica 256mb 64mb 60 + +# Client output buffer limits for pubsub clients +client-output-buffer-limit pubsub 32mb 8mb 60 + +# ================================================================= +# Application Notes +# ================================================================= +# +# Applications should use different database numbers: +# - Database 0: Reserved for system/testing +# - Database 1: Authentik (sessions, cache) +# - Database 2: Nextcloud (sessions, file locking, cache) +# - Database 3+: Future applications +# +# Connection example: +# redis-cli -h {{ valkey_bind }} -p {{ valkey_port }} -a {{ valkey_requirepass }} -n 1 \ No newline at end of file diff --git a/site.yml b/site.yml index c283fa3..15a6814 100644 --- a/site.yml +++ b/site.yml @@ -8,14 +8,16 @@ gather_facts: yes roles: - # # Infrastructure services + # Infrastructure services # - role: postgresql # tags: ['postgresql', 'infrastructure', 'database'] - # # - role: caddy - # # tags: ['caddy', 'infrastructure', 'web'] - # + - role: valkey + tags: ['valkey', 'redis', 'infrastructure', 'cache'] + # - role: caddy + # tags: ['caddy', 'infrastructure', 'web'] + # Application services - - role: gitea - tags: ['gitea', 'git', 'development'] + # - role: gitea + # tags: ['gitea', 'git', 'development'] # - role: sigvild-gallery # tags: ['sigvild', 'gallery', 'wedding']