Add Valkey infrastructure role as Redis-compatible cache service

- Implemented complete Valkey infrastructure role following PostgreSQL patterns
- Provides 100% Redis-compatible high-performance data structure store
- Configured for multi-application support with database isolation
- Security-focused: localhost-only binding, password auth, systemd hardening
- Arch Linux compatible: uses native Valkey package with Redis compatibility
- Database allocation strategy: DB 0 reserved, DB 1+ for applications
- Full systemd integration with security overrides and proper service management
- Redis client compatibility maintained for seamless application integration
- Ready for Authentik and future container workloads requiring cache services
This commit is contained in:
2025-11-18 23:58:21 +01:00
parent ddbdefd27f
commit 3b062edeb6
10 changed files with 574 additions and 19 deletions

View File

@@ -24,17 +24,6 @@ caddy_acme_ca: "https://acme-v02.api.letsencrypt.org/directory"
caddy_api_enabled: true caddy_api_enabled: true
caddy_server_name: "main" 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 # Sigvild Gallery Configuration
# ================================================================= # =================================================================

View File

@@ -7,7 +7,7 @@
name: gitea name: gitea
state: present state: present
- name: Install Git (required for Gitea) - name: Install Git
pacman: pacman:
name: git name: git
state: present state: present
@@ -111,4 +111,4 @@
📦 Local HTTP: http://127.0.0.1:{{ gitea_http_port }} 📦 Local HTTP: http://127.0.0.1:{{ gitea_http_port }}
🗄️ Database: {{ gitea_db_name }} (self-managed) 🗄️ Database: {{ gitea_db_name }} (self-managed)
🏗️ Self-contained service ready for Git repositories! 🏗️ Self-contained service ready for Git repositories!

163
roles/valkey/README.md Normal file
View File

@@ -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.

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -8,14 +8,16 @@
gather_facts: yes gather_facts: yes
roles: roles:
# # Infrastructure services # Infrastructure services
# - role: postgresql # - role: postgresql
# tags: ['postgresql', 'infrastructure', 'database'] # tags: ['postgresql', 'infrastructure', 'database']
# # - role: caddy - role: valkey
# # tags: ['caddy', 'infrastructure', 'web'] tags: ['valkey', 'redis', 'infrastructure', 'cache']
# # - role: caddy
# tags: ['caddy', 'infrastructure', 'web']
# Application services # Application services
- role: gitea # - role: gitea
tags: ['gitea', 'git', 'development'] # tags: ['gitea', 'git', 'development']
# - role: sigvild-gallery # - role: sigvild-gallery
# tags: ['sigvild', 'gallery', 'wedding'] # tags: ['sigvild', 'gallery', 'wedding']