# Veza V5 Ultra - Ansible Deployment

This directory contains Ansible playbooks and configuration for deploying Veza V5 Ultra using Incus/OVN + HAProxy-in-container + Let's Encrypt.

## Architecture

- **Single Debian host** (192.168.0.12) with Incus containers
- **HAProxy** running inside an Incus container as edge proxy
- **Let's Encrypt** ACME HTTP-01 validation handled in HAProxy container
- **OVN networking** for container communication
- **Applications** in separate containers:
  - `veza-backend` (Go API on port 8080)
  - `veza-chat` (Rust WebSocket on port 8081)
  - `veza-stream` (Rust HLS on port 8082)
  - `veza-web` (React + nginx on port 80)

## Prerequisites

### Control Node (Your Machine)
- Ansible ≥ 2.16
- SSH access to target host with key-based authentication
- Required collections:
  ```bash
  ansible-galaxy collection install community.general
  ansible-galaxy collection install community.docker
  ```

### Target Host (192.168.0.12)
- Debian 12 (Bookworm)
- SSH access for user `senke`
- Open ports: 22, 80, 443, 8080, 8081, 8082
- Sufficient resources for containers

## Quick Start

### 1. Full Deployment
```bash
cd ansible
./deploy-veza.sh
```

### 2. Custom Domain and Email
```bash
./deploy-veza.sh -d myapp.example.com -e admin@example.com
```

### 3. Step-by-Step Deployment
```bash
# Bootstrap host
./deploy-veza.sh --bootstrap-only

# Setup infrastructure
./deploy-veza.sh --infra-only

# Deploy applications
./deploy-veza.sh --apps-only

# Run tests
./deploy-veza.sh --test-only
```

## Manual Playbook Execution

```bash
# 1. Bootstrap remote host
ansible-playbook -i inventory/prod/hosts.yml playbooks/00-bootstrap-remote.yml

# 2. Install Incus + OVN
ansible-playbook -i inventory/prod/hosts.yml playbooks/10-incus-ovn.yml

# 3. Create containers
ansible-playbook -i inventory/prod/hosts.yml playbooks/20-incus-containers.yml

# 4. Configure HAProxy + ACME
ansible-playbook -i inventory/prod/hosts.yml playbooks/30-haproxy-in-container.yml \
  -e domain=veza.talas.fr -e acme_email=ops@talas.fr

# 5. Deploy applications
ansible-playbook -i inventory/prod/hosts.yml playbooks/40-veza-apps.yml

# 6. Run smoke tests
ansible-playbook -i inventory/prod/hosts.yml playbooks/50-smoke.yml
```

## Configuration

### Inventory
- `inventory/prod/hosts.yml` - Target host configuration
- `group_vars/all.yml` - Global variables (domain, ports, etc.)

### Key Variables
- `domain`: Target domain (default: veza.talas.fr)
- `acme_email`: Email for Let's Encrypt (default: ops@talas.fr)
- `veza_*_port`: Application ports
- `veza_database_url`: PostgreSQL connection string
- `veza_redis_url`: Redis connection string

## Post-Deployment

### 1. DNS Configuration
Point your domain's A record to the target host IP:
```
veza.talas.fr.    IN    A    192.168.0.12
```

### 2. Get Let's Encrypt Certificate
After DNS is configured, re-run the HAProxy playbook:
```bash
ansible-playbook -i inventory/prod/hosts.yml playbooks/30-haproxy-in-container.yml \
  -e domain=veza.talas.fr -e acme_email=ops@talas.fr
```

### 3. Verify Deployment
```bash
# Check container status
incus list

# Check services
incus exec veza-haproxy -- systemctl status haproxy
incus exec veza-backend -- systemctl status veza-backend
incus exec veza-chat -- systemctl status veza-chat
incus exec veza-stream -- systemctl status veza-stream
incus exec veza-web -- systemctl status nginx

# Test endpoints
curl -k https://192.168.0.12/
curl -k https://192.168.0.12/api/health
```

## Troubleshooting

### Container Issues
```bash
# Check container logs
incus exec <container-name> -- journalctl -u <service-name> -f

# Restart container
incus restart <container-name>

# Access container shell
incus exec <container-name> -- bash
```

### HAProxy Issues
```bash
# Check HAProxy config
incus exec veza-haproxy -- haproxy -c -f /etc/haproxy/haproxy.cfg

# Check HAProxy logs
incus exec veza-haproxy -- journalctl -u haproxy -f

# Reload HAProxy
incus exec veza-haproxy -- systemctl reload haproxy
```

### ACME Issues
```bash
# Check ACME webroot
incus exec veza-haproxy -- ls -la /var/www/acme-challenge/

# Test ACME challenge
curl http://192.168.0.12/.well-known/acme-challenge/test

# Manual certificate renewal
incus exec veza-haproxy -- /opt/dehydrated/dehydrated -c
```

## File Structure

```
ansible/
├── deploy-veza.sh              # Deployment script
├── inventory/
│   └── prod/
│       └── hosts.yml           # Target host inventory
├── group_vars/
│   └── all.yml                 # Global variables
├── playbooks/
│   ├── 00-bootstrap-remote.yml # Host bootstrap
│   ├── 10-incus-ovn.yml        # Incus + OVN setup
│   ├── 20-incus-containers.yml # Container creation
│   ├── 30-haproxy-in-container.yml # HAProxy + ACME
│   ├── 40-veza-apps.yml        # Application deployment
│   └── 50-smoke.yml            # Smoke tests
└── roles/                      # Existing Ansible roles
    ├── incus/
    ├── ovn/
    ├── haproxy/
    └── ...
```

## Security Notes

- All containers run with `security.nesting=true`
- HAProxy enforces HTTPS redirects
- Security headers are configured (HSTS, CSP, etc.)
- Let's Encrypt certificates are automatically renewed
- Firewall rules restrict access to necessary ports only

## Monitoring

The deployment includes basic health checks and logging. For production monitoring, consider:

- Prometheus + Grafana for metrics
- ELK stack for log aggregation
- Uptime monitoring for external services
- Container resource monitoring

## Support

For issues or questions:
1. Check container logs first
2. Verify network connectivity
3. Check HAProxy configuration
4. Review Ansible playbook output for errors
