# OVHcloud

Secondary cloud provider, used for the Brussels district. Hosts the WireGuard hub and hydraneckwebrtc relay for low-latency streaming to Belgian venues and bodies.

## CLI Setup

The `ovhcloud` CLI is installed on neoremote.

```bash
ovhcloud version    # v0.10.0
```

### Installation

```bash
curl -fsSL https://raw.githubusercontent.com/ovh/ovhcloud-cli/main/install.sh | sh
```

Installs to `~/.local/bin/ovhcloud`.

### Authentication

The CLI reads from `~/.ovh.conf`:

```ini
[default]
endpoint=ovh-eu

[ovh-eu]
application_key=<key>
application_secret=<secret>
consumer_key=<consumer_key>
```

**Create API credentials** at: https://eu.api.ovh.com/createToken/
- Set rights: `GET /*`, `POST /*`, `PUT /*`, `DELETE /*` for full access
- Validity: Unlimited

**Per-terminal project isolation** (no global context mutation):

```bash
export OVH_CLOUD_PROJECT_SERVICE=db254588bd8049bcb4ec8f0160754efe
```

There is no `hcloud context use` equivalent — `ovhcloud` uses profiles (`ovhcloud config profile`) but these modify global state. Always use environment variables for safe parallel work.

**Note**: `ovhcloud login` requires a TTY and does not work headless. Use `~/.ovh.conf` or env vars instead.

### Project ID

Get from the OVHcloud control panel: https://www.ovh.com/manager/#/public-cloud/ — the project ID is the hex string in the URL after `/projects/`.

Current project ID: `db254588bd8049bcb4ec8f0160754efe`

## Key Commands

```bash
# List instances
ovhcloud cloud instance list

# List available flavors (with regions)
ovhcloud cloud reference list-flavors -o json

# List available images
ovhcloud cloud reference list-images -o json

# Create instance
ovhcloud cloud instance create <region> \
  --name <name> \
  --flavor <flavor-id> \
  --boot-from.image <image-id> \
  --network.public \
  --ssh-key.name <key-name> \
  --billing-period hourly \
  --wait

# Register SSH key
ovhcloud cloud ssh-key create --name <name> --public-key "$(cat ~/.ssh/id_ed25519.pub)" --region <region>

# Delete instance
ovhcloud cloud instance delete <instance-id>
```

## Brussels Local Zone

Region code: `EU-WEST-LZ-BRU-A`

### Available flavors

| Flavor | vCPU | RAM | Disk | Hourly |
|--------|------|-----|------|--------|
| b3-8 | 2 | 8 GB | 50 GB | ~0.04/hr (~30/month) |
| b3-16 | 4 | 16 GB | 100 GB | ~0.08/hr |
| b3-32 | 8 | 32 GB | 200 GB | ~0.16/hr |
| b3-64 | 16 | 64 GB | 400 GB | ~0.32/hr |

Flex variants (b3-8-flex, etc.) have 50 GB fixed disk regardless of flavor.

### Local Zone Limitations

Brussels is a **Local Zone**, not a full region. Key restrictions:

- **No monthly billing** — hourly only
- **No Floating IP** — IP changes if instance is recreated
- **No vRack** — no private networking between instances
- **No Load Balancer**
- **Linux images only**
- Private networks limited to the same Local Zone

These limitations are acceptable for the current pilot (single instance).

### Available images

Ubuntu 22.04, 24.04, 24.10, 25.04 (standard and UEFI variants).

## Current Infrastructure

### Brussels District Instance

| Resource | Value |
|----------|-------|
| **Name** | `brussels-district` |
| **Instance ID** | `7fb01710-d9fd-4801-8b80-cf8e4ed85385` |
| **IP** | `141.227.136.12` |
| **Region** | `EU-WEST-LZ-BRU-A` |
| **Flavor** | b3-8 (2 vCPU, 8 GB RAM, 50 GB NVMe) |
| **OS** | Ubuntu 24.04 |
| **SSH** | `ubuntu@141.227.136.12` (key: `id_ed25519`) |
| **Billing** | Hourly (~30/month) |
| **Hydracluster node** | `node-338802b8` |

**Services running on this instance:**
- WireGuard hub (hydraguard) — port 51820/udp
- HydraGuard API — port 8081 (keep stopped when not enrolling)
- hydraneckwebrtc controller — port 443 (autocert)
- hydraneckwebrtc worker — port 47990
- coturn TURN server — port 3478
- hydranode agent — connects to hydracluster

**Firewall (ufw):**
- 22/tcp (SSH), 80/tcp (ACME), 443/tcp (HTTPS), 3478/udp+tcp (TURN)
- 8080-8095/tcp (sessions), 8081/tcp (hydraguard API)
- 49152-65535/udp+tcp (TURN relay — both protocols required, browsers use TCP relay for audio), 51820/udp (WireGuard)

## DNS

All DNS records are managed via **Hetzner DNS** (not OVHcloud), even for OVHcloud instances. See the [Hetzner runbook](hetzner.md) for DNS commands.

| Record | IP | Zone |
|--------|-----|------|
| hydraguard.experiencenet.com | 141.227.136.12 | experiencenet.com (788422) |
| hydraneckwebrtc.experiencenet.com | 141.227.136.12 | experiencenet.com (788422) |
| hydraguard-brussels.experiencenet.com | 141.227.136.12 | experiencenet.com (788422) |
| hydraneckwebrtc-brussels.experiencenet.com | 141.227.136.12 | experiencenet.com (788422) |
