+
+
+
+
matplotlib
asm
+
+
+
+
+
#
intellij
+
+
+
+
+
rails
influxdb
json
+
rocket
gentoo
elasticsearch
+
rollup
tf
gcp
aws
+
+
+
+
argocd
stimulus
...
+
+
grafana
<=
webpack
+
sqlite
+
+
+
git
svelte
grpc
graphql
+
+
+
+
oauth
+
+
prettier
macos
preact
rubymine
dask
+
+
+
surrealdb
k8s
fauna
+
rider
+
s3
bbedit
+
+
+
+
html
+
alpine
prometheus
pinecone
++
preact
+
Back to Blog
Managing Package Configuration Files 📄
alpine-linux configuration package-management

Managing Package Configuration Files 📄

Published Jun 3, 2025

Master Alpine Linux package configuration management with advanced techniques for backing up, tracking changes, and automating configuration deployments across environments.

5 min read
0 views
Table of Contents

Effective configuration file management is crucial for maintaining Alpine Linux systems, ensuring consistent deployments, and enabling reliable rollbacks. This comprehensive guide covers advanced techniques for tracking, versioning, and automating package configuration management across different environments.

🔍 Understanding Alpine Configuration Architecture

Alpine Linux follows the Unix philosophy of storing configuration in plain text files, making configuration management both powerful and accessible through standard tools.

Configuration File Hierarchy

  • System-wide configs - /etc/ directory 🌐
  • Service-specific configs - /etc/service-name/ 📋
  • User-specific configs - ~/.config/ and ~/ 👤
  • Runtime configs - /var/lib/, /var/run/

Package Configuration Categories

# Essential system configurations
/etc/passwd          # User accounts
/etc/group           # Group definitions
/etc/shadow          # Password hashes
/etc/fstab           # Filesystem table
/etc/hostname        # System hostname
/etc/hosts           # Host name resolution
/etc/resolv.conf     # DNS configuration

# Service configurations
/etc/nginx/          # Nginx web server
/etc/ssh/            # SSH daemon
/etc/mysql/          # MySQL/MariaDB
/etc/postgresql/     # PostgreSQL
/etc/redis/          # Redis
/etc/docker/         # Docker daemon

# Network configurations
/etc/network/        # Network interfaces
/etc/iptables/       # Firewall rules
/etc/wireguard/      # VPN configurations

🛠️ Configuration Management Strategies

Version Control with Git

# Initialize configuration repository
cd /etc
git init
git config user.name "System Administrator"
git config user.email "[email protected]"

# Create comprehensive .gitignore
cat > .gitignore << 'EOF'
# Sensitive files
shadow*
gshadow*
ssh/ssh_host_*
ssl/private/
*.key
*.pem

# Runtime files
mtab
resolv.conf.auto
*.pid
*.sock

# Backup files
*.bak
*.orig
*~
.#*

# Log files
*.log
*.log.*

# Temporary files
*.tmp
*.swp
*.cache
EOF

# Add initial configuration
git add .
git commit -m "Initial configuration snapshot"

# Create configuration tracking script
cat > /usr/local/bin/track-config-changes << 'EOF'
#!/bin/sh

# Configuration change tracking
cd /etc

# Check for changes
if git diff --quiet && git diff --cached --quiet; then
    echo "No configuration changes detected"
    exit 0
fi

# Show changes
echo "Configuration changes detected:"
git status --porcelain

# Interactive commit (for manual use)
if [ "$1" = "--interactive" ]; then
    git add -i
    git commit
else
    # Automatic commit with timestamp
    git add .
    git commit -m "Auto-commit: $(date '+%Y-%m-%d %H:%M:%S') - $(git status --porcelain | wc -l) files changed"
fi

echo "Configuration changes committed"
EOF

chmod +x /usr/local/bin/track-config-changes

Configuration Templates and Environment Management

# Create configuration template system
mkdir -p /etc/config-templates/{production,staging,development}

# Example: Nginx configuration template
cat > /etc/config-templates/nginx.conf.template << 'EOF'
user ${NGINX_USER:-nginx};
worker_processes ${NGINX_WORKERS:-auto};
error_log /var/log/nginx/error.log ${LOG_LEVEL:-warn};
pid /run/nginx.pid;

events {
    worker_connections ${WORKER_CONNECTIONS:-1024};
    use epoll;
    multi_accept on;
}

http {
    include /etc/nginx/mime.types;
    default_type application/octet-stream;
    
    # Security headers
    add_header X-Frame-Options "${X_FRAME_OPTIONS:-SAMEORIGIN}" always;
    add_header X-Content-Type-Options "${X_CONTENT_TYPE_OPTIONS:-nosniff}" always;
    
    # Performance settings
    sendfile ${SENDFILE:-on};
    tcp_nopush ${TCP_NOPUSH:-on};
    tcp_nodelay ${TCP_NODELAY:-on};
    keepalive_timeout ${KEEPALIVE_TIMEOUT:-65};
    
    # Gzip compression
    gzip ${GZIP_ENABLED:-on};
    gzip_vary on;
    gzip_min_length 1024;
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml;
    
    # Rate limiting
    limit_req_zone $binary_remote_addr zone=api:10m rate=${API_RATE_LIMIT:-10r/s};
    
    # Include additional configurations
    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;
}
EOF

# Environment-specific variable files
cat > /etc/config-templates/production/nginx.env << 'EOF'
NGINX_USER=nginx
NGINX_WORKERS=auto
LOG_LEVEL=error
WORKER_CONNECTIONS=2048
X_FRAME_OPTIONS=DENY
X_CONTENT_TYPE_OPTIONS=nosniff
SENDFILE=on
TCP_NOPUSH=on
TCP_NODELAY=on
KEEPALIVE_TIMEOUT=30
GZIP_ENABLED=on
API_RATE_LIMIT=5r/s
EOF

cat > /etc/config-templates/development/nginx.env << 'EOF'
NGINX_USER=nginx
NGINX_WORKERS=1
LOG_LEVEL=debug
WORKER_CONNECTIONS=1024
X_FRAME_OPTIONS=SAMEORIGIN
X_CONTENT_TYPE_OPTIONS=nosniff
SENDFILE=off
TCP_NOPUSH=off
TCP_NODELAY=on
KEEPALIVE_TIMEOUT=65
GZIP_ENABLED=off
API_RATE_LIMIT=100r/s
EOF

# Configuration deployment script
cat > /usr/local/bin/deploy-config << 'EOF'
#!/bin/sh

# Configuration deployment system
ENVIRONMENT="${1:-production}"
SERVICE="$2"
TEMPLATE_DIR="/etc/config-templates"
BACKUP_DIR="/var/backups/configs"

if [ -z "$SERVICE" ]; then
    echo "Usage: $0 <environment> <service>"
    echo "Environments: production, staging, development"
    echo "Services: nginx, ssh, mysql, postgresql, etc."
    exit 1
fi

# Load environment variables
ENV_FILE="$TEMPLATE_DIR/$ENVIRONMENT/$SERVICE.env"
if [ -f "$ENV_FILE" ]; then
    source "$ENV_FILE"
else
    echo "Warning: No environment file found at $ENV_FILE"
fi

# Template file
TEMPLATE_FILE="$TEMPLATE_DIR/$SERVICE.conf.template"
if [ ! -f "$TEMPLATE_FILE" ]; then
    echo "Error: Template file not found: $TEMPLATE_FILE"
    exit 1
fi

# Determine target configuration file
case "$SERVICE" in
    nginx)
        TARGET_FILE="/etc/nginx/nginx.conf"
        ;;
    ssh)
        TARGET_FILE="/etc/ssh/sshd_config"
        ;;
    mysql)
        TARGET_FILE="/etc/my.cnf"
        ;;
    postgresql)
        TARGET_FILE="/etc/postgresql/postgresql.conf"
        ;;
    *)
        TARGET_FILE="/etc/$SERVICE/$SERVICE.conf"
        ;;
esac

# Create backup
mkdir -p "$BACKUP_DIR/$(date +%Y%m%d)"
if [ -f "$TARGET_FILE" ]; then
    cp "$TARGET_FILE" "$BACKUP_DIR/$(date +%Y%m%d)/$(basename "$TARGET_FILE").$(date +%H%M%S)"
fi

# Process template
echo "Deploying $SERVICE configuration for $ENVIRONMENT environment"
envsubst < "$TEMPLATE_FILE" > "$TARGET_FILE"

# Validate configuration
case "$SERVICE" in
    nginx)
        if nginx -t 2>/dev/null; then
            echo "✅ Nginx configuration valid"
            rc-service nginx reload
        else
            echo "❌ Nginx configuration invalid, restoring backup"
            cp "$BACKUP_DIR/$(date +%Y%m%d)/$(basename "$TARGET_FILE")".* "$TARGET_FILE"
            exit 1
        fi
        ;;
    ssh)
        if sshd -t 2>/dev/null; then
            echo "✅ SSH configuration valid"
            rc-service sshd reload
        else
            echo "❌ SSH configuration invalid, restoring backup"
            cp "$BACKUP_DIR/$(date +%Y%m%d)/$(basename "$TARGET_FILE")".* "$TARGET_FILE"
            exit 1
        fi
        ;;
esac

echo "Configuration deployment completed"
EOF

chmod +x /usr/local/bin/deploy-config

# Deploy configurations
deploy-config production nginx
deploy-config development nginx

📊 Configuration Change Management

Automated Configuration Monitoring

# Create configuration monitoring system
cat > /usr/local/bin/monitor-config-changes << 'EOF'
#!/bin/sh

# Configuration change monitoring and alerting
CONFIG_DIR="/etc"
MONITOR_FILE="/var/lib/config-monitor/checksums"
ALERT_EMAIL="[email protected]"
LOG_FILE="/var/log/config-changes.log"

# Create monitoring directory
mkdir -p "$(dirname "$MONITOR_FILE")"

# Generate current checksums
generate_checksums() {
    find "$CONFIG_DIR" -type f \
         ! -path "*/.*" \
         ! -name "*.log" \
         ! -name "*.tmp" \
         ! -name "*.pid" \
         ! -name "*.sock" \
         ! -name "resolv.conf.auto" \
         -exec sha256sum {} \; 2>/dev/null | sort
}

# Load previous checksums
if [ -f "$MONITOR_FILE" ]; then
    PREVIOUS_CHECKSUMS=$(cat "$MONITOR_FILE")
else
    PREVIOUS_CHECKSUMS=""
fi

# Generate current checksums
CURRENT_CHECKSUMS=$(generate_checksums)

# Compare checksums
if [ "$PREVIOUS_CHECKSUMS" != "$CURRENT_CHECKSUMS" ]; then
    echo "$(date): Configuration changes detected" | tee -a "$LOG_FILE"
    
    # Find changed files
    echo "$PREVIOUS_CHECKSUMS" > /tmp/previous_checksums
    echo "$CURRENT_CHECKSUMS" > /tmp/current_checksums
    
    # Files that were modified
    MODIFIED_FILES=$(comm -13 /tmp/previous_checksums /tmp/current_checksums | awk '{print $2}')
    
    # Files that were deleted
    DELETED_FILES=$(comm -23 /tmp/previous_checksums /tmp/current_checksums | awk '{print $2}')
    
    # Log changes
    if [ -n "$MODIFIED_FILES" ]; then
        echo "Modified/Added files:" | tee -a "$LOG_FILE"
        echo "$MODIFIED_FILES" | while read file; do
            echo "  - $file" | tee -a "$LOG_FILE"
        done
    fi
    
    if [ -n "$DELETED_FILES" ]; then
        echo "Deleted files:" | tee -a "$LOG_FILE"
        echo "$DELETED_FILES" | while read file; do
            echo "  - $file" | tee -a "$LOG_FILE"
        done
    fi
    
    # Send alert email
    if [ -n "$ALERT_EMAIL" ]; then
        {
            echo "Configuration changes detected on $(hostname) at $(date)"
            echo ""
            echo "Modified/Added files:"
            echo "$MODIFIED_FILES"
            echo ""
            echo "Deleted files:"
            echo "$DELETED_FILES"
            echo ""
            echo "Please review these changes immediately."
        } | mail -s "Configuration Change Alert - $(hostname)" "$ALERT_EMAIL" 2>/dev/null || true
    fi
    
    # Update stored checksums
    echo "$CURRENT_CHECKSUMS" > "$MONITOR_FILE"
    
    # Track changes in git if available
    if [ -d "$CONFIG_DIR/.git" ]; then
        cd "$CONFIG_DIR"
        track-config-changes
    fi
else
    echo "$(date): No configuration changes detected" >> "$LOG_FILE"
fi

# Cleanup
rm -f /tmp/previous_checksums /tmp/current_checksums
EOF

chmod +x /usr/local/bin/monitor-config-changes

# Add to cron for regular monitoring
echo "*/15 * * * * /usr/local/bin/monitor-config-changes >/dev/null 2>&1" >> /etc/crontabs/root

Configuration Rollback System

# Create configuration rollback system
cat > /usr/local/bin/rollback-config << 'EOF'
#!/bin/sh

# Configuration rollback system
BACKUP_DIR="/var/backups/configs"
SERVICE="$1"
DATE="$2"

usage() {
    echo "Usage: $0 <service> [date]"
    echo ""
    echo "Available services:"
    ls -1 "$BACKUP_DIR" 2>/dev/null | head -5
    echo ""
    echo "Available dates:"
    ls -1 "$BACKUP_DIR/" 2>/dev/null | head -10
    echo ""
    echo "Examples:"
    echo "  $0 nginx                    # Rollback to latest backup"
    echo "  $0 nginx 20250603          # Rollback to specific date"
    echo "  $0 list                    # List available backups"
}

list_backups() {
    echo "Available configuration backups:"
    echo ""
    for date_dir in $(ls -1r "$BACKUP_DIR" 2>/dev/null | head -10); do
        echo "Date: $date_dir"
        ls -la "$BACKUP_DIR/$date_dir/" | while read line; do
            echo "  $line"
        done
        echo ""
    done
}

if [ "$1" = "list" ]; then
    list_backups
    exit 0
fi

if [ -z "$SERVICE" ]; then
    usage
    exit 1
fi

# Determine target configuration file
case "$SERVICE" in
    nginx)
        TARGET_FILE="/etc/nginx/nginx.conf"
        RESTART_CMD="rc-service nginx restart"
        TEST_CMD="nginx -t"
        ;;
    ssh)
        TARGET_FILE="/etc/ssh/sshd_config"
        RESTART_CMD="rc-service sshd restart"
        TEST_CMD="sshd -t"
        ;;
    mysql)
        TARGET_FILE="/etc/my.cnf"
        RESTART_CMD="rc-service mysql restart"
        TEST_CMD="mysqld --help --verbose > /dev/null"
        ;;
    apache2)
        TARGET_FILE="/etc/apache2/httpd.conf"
        RESTART_CMD="rc-service apache2 restart"
        TEST_CMD="httpd -t"
        ;;
    *)
        TARGET_FILE="/etc/$SERVICE/$SERVICE.conf"
        RESTART_CMD="rc-service $SERVICE restart"
        TEST_CMD="true"
        ;;
esac

# Find backup file
if [ -n "$DATE" ]; then
    BACKUP_FILE=$(find "$BACKUP_DIR/$DATE" -name "$(basename "$TARGET_FILE")*" | head -1)
else
    BACKUP_FILE=$(find "$BACKUP_DIR" -name "$(basename "$TARGET_FILE")*" | sort -r | head -1)
fi

if [ -z "$BACKUP_FILE" ] || [ ! -f "$BACKUP_FILE" ]; then
    echo "❌ No backup found for $SERVICE"
    list_backups
    exit 1
fi

echo "Rolling back $SERVICE configuration"
echo "Target: $TARGET_FILE"
echo "Backup: $BACKUP_FILE"
echo ""

# Create emergency backup of current config
EMERGENCY_BACKUP="/tmp/$(basename "$TARGET_FILE").emergency.$(date +%Y%m%d_%H%M%S)"
cp "$TARGET_FILE" "$EMERGENCY_BACKUP"
echo "Emergency backup created: $EMERGENCY_BACKUP"

# Restore configuration
cp "$BACKUP_FILE" "$TARGET_FILE"

# Test configuration
echo "Testing configuration..."
if eval "$TEST_CMD"; then
    echo "✅ Configuration test passed"
    
    # Restart service
    echo "Restarting $SERVICE..."
    if eval "$RESTART_CMD"; then
        echo "✅ Service restarted successfully"
        echo "Configuration rollback completed"
        
        # Remove emergency backup
        rm -f "$EMERGENCY_BACKUP"
    else
        echo "❌ Service restart failed, restoring emergency backup"
        cp "$EMERGENCY_BACKUP" "$TARGET_FILE"
        eval "$RESTART_CMD"
        exit 1
    fi
else
    echo "❌ Configuration test failed, restoring emergency backup"
    cp "$EMERGENCY_BACKUP" "$TARGET_FILE"
    exit 1
fi
EOF

chmod +x /usr/local/bin/rollback-config

# Example usage
# rollback-config nginx
# rollback-config nginx 20250603
# rollback-config list

🔧 Advanced Configuration Techniques

Configuration Validation Framework

# Create configuration validation framework
mkdir -p /etc/config-validators

# Nginx validator
cat > /etc/config-validators/nginx << 'EOF'
#!/bin/sh

# Nginx configuration validator
CONFIG_FILE="/etc/nginx/nginx.conf"

validate_nginx_config() {
    local errors=""
    
    # Basic syntax check
    if ! nginx -t 2>/dev/null; then
        errors="$errors\n- Nginx syntax check failed"
    fi
    
    # Security checks
    if grep -q "server_tokens on" "$CONFIG_FILE"; then
        errors="$errors\n- Security: server_tokens should be off"
    fi
    
    if ! grep -q "X-Frame-Options" "$CONFIG_FILE"; then
        errors="$errors\n- Security: Missing X-Frame-Options header"
    fi
    
    # Performance checks
    if ! grep -q "gzip on" "$CONFIG_FILE"; then
        errors="$errors\n- Performance: gzip compression not enabled"
    fi
    
    # Configuration completeness
    if ! grep -q "error_log" "$CONFIG_FILE"; then
        errors="$errors\n- Missing error_log directive"
    fi
    
    if [ -n "$errors" ]; then
        echo "❌ Nginx configuration validation failed:"
        echo "$errors"
        return 1
    else
        echo "✅ Nginx configuration validation passed"
        return 0
    fi
}

validate_nginx_config
EOF

# SSH validator
cat > /etc/config-validators/ssh << 'EOF'
#!/bin/sh

# SSH configuration validator
CONFIG_FILE="/etc/ssh/sshd_config"

validate_ssh_config() {
    local errors=""
    
    # Basic syntax check
    if ! sshd -t 2>/dev/null; then
        errors="$errors\n- SSH syntax check failed"
    fi
    
    # Security checks
    if grep -q "^PermitRootLogin yes" "$CONFIG_FILE"; then
        errors="$errors\n- Security: Root login should be disabled"
    fi
    
    if grep -q "^PasswordAuthentication yes" "$CONFIG_FILE"; then
        errors="$errors\n- Security: Password authentication should be disabled"
    fi
    
    if grep -q "^PermitEmptyPasswords yes" "$CONFIG_FILE"; then
        errors="$errors\n- Security: Empty passwords should not be permitted"
    fi
    
    # Protocol version check
    if grep -q "^Protocol 1" "$CONFIG_FILE"; then
        errors="$errors\n- Security: SSH Protocol 1 is deprecated"
    fi
    
    if [ -n "$errors" ]; then
        echo "❌ SSH configuration validation failed:"
        echo "$errors"
        return 1
    else
        echo "✅ SSH configuration validation passed"
        return 0
    fi
}

validate_ssh_config
EOF

# Make validators executable
chmod +x /etc/config-validators/*

# Configuration validation runner
cat > /usr/local/bin/validate-configs << 'EOF'
#!/bin/sh

# Run all configuration validators
VALIDATOR_DIR="/etc/config-validators"
FAILED_SERVICES=""

echo "Running configuration validation..."
echo "================================="

for validator in "$VALIDATOR_DIR"/*; do
    if [ -x "$validator" ]; then
        service_name=$(basename "$validator")
        echo ""
        echo "Validating $service_name:"
        
        if "$validator"; then
            echo "✅ $service_name validation passed"
        else
            echo "❌ $service_name validation failed"
            FAILED_SERVICES="$FAILED_SERVICES $service_name"
        fi
    fi
done

echo ""
echo "Validation Summary:"
echo "=================="

if [ -n "$FAILED_SERVICES" ]; then
    echo "❌ Failed services:$FAILED_SERVICES"
    exit 1
else
    echo "✅ All configuration validations passed"
    exit 0
fi
EOF

chmod +x /usr/local/bin/validate-configs

# Run validation
validate-configs

Configuration Automation with Ansible

# Create Ansible-compatible configuration management
mkdir -p /etc/ansible/{playbooks,roles,inventory}

# Ansible inventory
cat > /etc/ansible/inventory/hosts << 'EOF'
[alpine_servers]
server1 ansible_host=192.168.1.10
server2 ansible_host=192.168.1.11
server3 ansible_host=192.168.1.12

[alpine_servers:vars]
ansible_user=root
ansible_ssh_private_key_file=/root/.ssh/id_rsa
EOF

# Nginx configuration playbook
cat > /etc/ansible/playbooks/configure_nginx.yml << 'EOF'
---
- name: Configure Nginx on Alpine Linux
  hosts: alpine_servers
  vars:
    nginx_user: nginx
    nginx_workers: auto
    nginx_worker_connections: 1024
    
  tasks:
    - name: Install Nginx
      apk:
        name: nginx
        state: present
        
    - name: Create nginx user
      user:
        name: "{{ nginx_user }}"
        system: yes
        shell: /sbin/nologin
        
    - name: Deploy nginx configuration
      template:
        src: nginx.conf.j2
        dest: /etc/nginx/nginx.conf
        backup: yes
      notify: restart nginx
      
    - name: Validate nginx configuration
      command: nginx -t
      changed_when: false
      
    - name: Enable and start nginx
      service:
        name: nginx
        enabled: yes
        state: started
        
  handlers:
    - name: restart nginx
      service:
        name: nginx
        state: restarted
EOF

# Nginx Jinja2 template
cat > /etc/ansible/playbooks/templates/nginx.conf.j2 << 'EOF'
user {{ nginx_user }};
worker_processes {{ nginx_workers }};
error_log /var/log/nginx/error.log warn;
pid /run/nginx.pid;

events {
    worker_connections {{ nginx_worker_connections }};
    use epoll;
    multi_accept on;
}

http {
    include /etc/nginx/mime.types;
    default_type application/octet-stream;
    
    # Logging
    log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for"';
    
    access_log /var/log/nginx/access.log main;
    
    # Performance
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    
    # Security headers
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-XSS-Protection "1; mode=block" always;
    
    # Gzip compression
    gzip on;
    gzip_vary on;
    gzip_min_length 1024;
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml;
    
    # Hide nginx version
    server_tokens off;
    
    # Include additional configurations
    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;
}
EOF

# Configuration deployment script
cat > /usr/local/bin/deploy-ansible-config << 'EOF'
#!/bin/sh

# Deploy configurations using Ansible
PLAYBOOK="$1"
ENVIRONMENT="${2:-production}"

if [ -z "$PLAYBOOK" ]; then
    echo "Usage: $0 <playbook> [environment]"
    echo "Available playbooks:"
    ls -1 /etc/ansible/playbooks/*.yml | xargs basename -s .yml
    exit 1
fi

echo "Deploying $PLAYBOOK configuration to $ENVIRONMENT environment"

# Run ansible playbook
ansible-playbook \
    -i /etc/ansible/inventory/hosts \
    -l "$ENVIRONMENT" \
    --check \
    "/etc/ansible/playbooks/$PLAYBOOK.yml"

if [ $? -eq 0 ]; then
    echo "Dry run completed successfully. Deploy for real? (y/N)"
    read -r confirmation
    if [ "$confirmation" = "y" ] || [ "$confirmation" = "Y" ]; then
        ansible-playbook \
            -i /etc/ansible/inventory/hosts \
            -l "$ENVIRONMENT" \
            "/etc/ansible/playbooks/$PLAYBOOK.yml"
    fi
else
    echo "❌ Dry run failed. Please check the configuration."
    exit 1
fi
EOF

chmod +x /usr/local/bin/deploy-ansible-config

🔒 Security and Compliance

Configuration Security Scanning

# Create security scanner for configurations
cat > /usr/local/bin/scan-config-security << 'EOF'
#!/bin/sh

# Configuration security scanner
SCAN_RESULTS="/tmp/config-security-scan.txt"
CRITICAL_ISSUES=""
WARNING_ISSUES=""

scan_file_permissions() {
    echo "=== File Permission Security Scan ===" >> "$SCAN_RESULTS"
    
    # Check for world-writable config files
    find /etc -type f -perm -002 2>/dev/null | while read file; do
        echo "CRITICAL: World-writable config file: $file" >> "$SCAN_RESULTS"
        CRITICAL_ISSUES="$CRITICAL_ISSUES\n- World-writable: $file"
    done
    
    # Check for files with incorrect ownership
    find /etc -type f ! -user root 2>/dev/null | while read file; do
        owner=$(stat -c "%U" "$file")
        echo "WARNING: Non-root owned config file: $file (owner: $owner)" >> "$SCAN_RESULTS"
        WARNING_ISSUES="$WARNING_ISSUES\n- Non-root owned: $file"
    done
}

scan_ssh_security() {
    echo "=== SSH Security Scan ===" >> "$SCAN_RESULTS"
    
    if [ -f "/etc/ssh/sshd_config" ]; then
        # Check for dangerous SSH settings
        if grep -q "^PermitRootLogin yes" /etc/ssh/sshd_config; then
            echo "CRITICAL: SSH root login enabled" >> "$SCAN_RESULTS"
            CRITICAL_ISSUES="$CRITICAL_ISSUES\n- SSH root login enabled"
        fi
        
        if grep -q "^PasswordAuthentication yes" /etc/ssh/sshd_config; then
            echo "WARNING: SSH password authentication enabled" >> "$SCAN_RESULTS"
            WARNING_ISSUES="$WARNING_ISSUES\n- SSH password auth enabled"
        fi
        
        if grep -q "^PermitEmptyPasswords yes" /etc/ssh/sshd_config; then
            echo "CRITICAL: SSH empty passwords permitted" >> "$SCAN_RESULTS"
            CRITICAL_ISSUES="$CRITICAL_ISSUES\n- SSH empty passwords allowed"
        fi
    fi
}

scan_web_server_security() {
    echo "=== Web Server Security Scan ===" >> "$SCAN_RESULTS"
    
    # Nginx security
    if [ -f "/etc/nginx/nginx.conf" ]; then
        if grep -q "server_tokens on" /etc/nginx/nginx.conf; then
            echo "WARNING: Nginx server tokens enabled" >> "$SCAN_RESULTS"
            WARNING_ISSUES="$WARNING_ISSUES\n- Nginx server tokens exposed"
        fi
        
        if ! grep -q "X-Frame-Options" /etc/nginx/nginx.conf; then
            echo "WARNING: Nginx missing X-Frame-Options header" >> "$SCAN_RESULTS"
            WARNING_ISSUES="$WARNING_ISSUES\n- Missing X-Frame-Options"
        fi
    fi
    
    # Apache security
    if [ -f "/etc/apache2/httpd.conf" ]; then
        if grep -q "ServerTokens Full" /etc/apache2/httpd.conf; then
            echo "WARNING: Apache server tokens full" >> "$SCAN_RESULTS"
            WARNING_ISSUES="$WARNING_ISSUES\n- Apache server tokens exposed"
        fi
    fi
}

scan_database_security() {
    echo "=== Database Security Scan ===" >> "$SCAN_RESULTS"
    
    # MySQL security
    if [ -f "/etc/my.cnf" ]; then
        if grep -q "bind-address.*0.0.0.0" /etc/my.cnf; then
            echo "WARNING: MySQL bound to all interfaces" >> "$SCAN_RESULTS"
            WARNING_ISSUES="$WARNING_ISSUES\n- MySQL exposed to all interfaces"
        fi
    fi
    
    # PostgreSQL security
    if [ -f "/etc/postgresql/postgresql.conf" ]; then
        if grep -q "listen_addresses.*'\*'" /etc/postgresql/postgresql.conf; then
            echo "WARNING: PostgreSQL listening on all interfaces" >> "$SCAN_RESULTS"
            WARNING_ISSUES="$WARNING_ISSUES\n- PostgreSQL exposed to all interfaces"
        fi
    fi
}

# Run all scans
echo "Starting configuration security scan..."
echo "========================================"

> "$SCAN_RESULTS"  # Clear results file

scan_file_permissions
scan_ssh_security
scan_web_server_security
scan_database_security

# Generate report
echo ""
echo "Security Scan Results:"
echo "====================="
cat "$SCAN_RESULTS"

echo ""
echo "Summary:"
echo "========"

if [ -n "$CRITICAL_ISSUES" ]; then
    echo "🚨 CRITICAL ISSUES FOUND:"
    echo "$CRITICAL_ISSUES"
fi

if [ -n "$WARNING_ISSUES" ]; then
    echo "⚠️  WARNING ISSUES FOUND:"
    echo "$WARNING_ISSUES"
fi

if [ -z "$CRITICAL_ISSUES" ] && [ -z "$WARNING_ISSUES" ]; then
    echo "✅ No security issues found"
fi

# Cleanup
rm -f "$SCAN_RESULTS"
EOF

chmod +x /usr/local/bin/scan-config-security

# Run security scan
scan-config-security

🎯 Best Practices and Guidelines

Configuration Management Checklist

# Create configuration management checklist
cat > /usr/local/share/config-management-checklist.md << 'EOF'
# Configuration Management Checklist

## Before Making Changes
- [ ] Document the reason for configuration changes
- [ ] Create backup of current configuration
- [ ] Test changes in non-production environment
- [ ] Review security implications
- [ ] Check for dependencies and conflicts

## During Changes
- [ ] Use version control for tracking
- [ ] Apply principle of least privilege
- [ ] Validate configuration syntax
- [ ] Test configuration in isolated environment
- [ ] Document all modifications

## After Changes
- [ ] Verify service functionality
- [ ] Run security scans
- [ ] Update monitoring and alerts
- [ ] Document rollback procedures
- [ ] Commit changes to version control

## Regular Maintenance
- [ ] Review configuration changes monthly
- [ ] Audit file permissions quarterly
- [ ] Update configuration templates
- [ ] Test rollback procedures
- [ ] Clean up old backups
EOF

🎉 Conclusion

Effective package configuration management in Alpine Linux requires systematic approaches, proper tooling, and consistent practices. By implementing version control, automation, and monitoring, you can maintain reliable, secure, and scalable configuration management systems.

Key takeaways:

  • Use version control for all configuration changes 📝
  • Implement automated validation and testing
  • Create comprehensive backup and rollback procedures 🔄
  • Monitor configuration changes continuously 📊
  • Apply security best practices consistently 🔒

With proper configuration management, your Alpine Linux systems will be more reliable, secure, and maintainable! 🚀