Sovra Sovra

Exoscale Deployment

Deploy Sovra on Exoscale, a Swiss cloud provider ideal for European data sovereignty requirements.

Overview

Exoscale offers:

Prerequisites

Architecture

┌────────────────────────────────────────┐
│              Exoscale Zone             │
│                                        │
│  ┌─────────────────────────────────┐   │
│  │      Network Load Balancer      │   │
│  │         (vault-nlb)             │   │
│  └──────────────┬──────────────────┘   │
│                 │ :8200                │
│  ┌──────────────┼──────────────────┐   │
│  │              ▼                  │   │
│  │  ┌─────┐  ┌─────┐  ┌─────┐      │   │
│  │  │Vault│  │Vault│  │Vault│      │   │
│  │  │  0  │──│  1  │──│  2  │      │   │
│  │  └─────┘  └─────┘  └─────┘      │   │
│  │         Raft Cluster            │   │
│  └─────────────────────────────────┘   │
│                                        │
│  Security Group: vault-sg              │
│  - 8200/tcp (API)                      │
│  - 8201/tcp (cluster - internal)       │
│  - 22/tcp (SSH)                        │
└────────────────────────────────────────┘

Deployment Steps

1. Configure Exoscale Provider

Set your Exoscale API credentials:

export EXOSCALE_API_KEY="your-api-key"
export EXOSCALE_API_SECRET="your-api-secret"

Or create a ~/.exoscale/exoscale.toml:

defaultaccount = "myaccount"

[[accounts]]
name = "myaccount"
endpoint = "https://api.exoscale.com/v1"
key = "your-api-key"
secret = "your-api-secret"

2. Initialize Terraform

cd infrastructure/terraform/exoscale
terraform init

3. Configure Variables

Create terraform.tfvars:

# Required
cluster_name = "sovra-prod"
ssh_key_name = "your-ssh-key-name"

# Optional - defaults shown
zone          = "ch-gva-2"        # Geneva zone
instance_type = "standard.medium" # 4 vCPU, 8GB RAM
node_count    = 3                 # 3 or 5 for Raft
vault_version = "1.18.3"

4. Deploy

terraform plan
terraform apply

5. Initialize Vault

SSH to one of the instances:

# Get instance IPs
terraform output instance_ips

# SSH to first node
ssh ubuntu@<instance-ip>

# Initialize Vault
vault operator init -key-shares=5 -key-threshold=3

Store the unseal keys and root token securely!

6. Unseal Vault

Unseal each node with 3 of the 5 keys:

vault operator unseal <key-1>
vault operator unseal <key-2>
vault operator unseal <key-3>

Repeat on all nodes.

Available Zones

Zone Location
ch-gva-2 Geneva, Switzerland
ch-dk-2 Zurich, Switzerland
at-vie-1 Vienna, Austria
de-muc-1 Munich, Germany
de-fra-1 Frankfurt, Germany
bg-sof-1 Sofia, Bulgaria

Instance Types

Type vCPU RAM Recommended Use
standard.small 2 4GB Development
standard.medium 4 8GB Production (default)
standard.large 8 16GB High-load production
standard.extra-large 16 32GB Enterprise

Network Configuration

Security Group Rules

The Terraform module creates these rules:

Port Protocol Source Purpose
8200 TCP 0.0.0.0/0 Vault API
8201 TCP Self (SG) Raft cluster
22 TCP 0.0.0.0/0 SSH access

For production, restrict SSH to your IP ranges.

Private Network (Optional)

For additional isolation:

# Create private network
resource "exoscale_private_network" "vault" {
  zone = var.zone
  name = "${var.cluster_name}-network"
}

# Attach to instances
# (Modify compute instance resource)

High Availability

Multi-Zone Deployment

For cross-zone HA, deploy separate clusters and configure federation:

# Geneva cluster
module "vault_gva" {
  source       = "./modules/vault-cluster"
  zone         = "ch-gva-2"
  cluster_name = "sovra-gva"
  # ...
}

# Zurich cluster (DR)
module "vault_zrh" {
  source       = "./modules/vault-cluster"
  zone         = "ch-dk-2"
  cluster_name = "sovra-zrh"
  # ...
}

Monitoring

Prometheus Metrics

Vault exposes Prometheus metrics at /v1/sys/metrics:

scrape_configs:
  - job_name: 'vault'
    metrics_path: '/v1/sys/metrics'
    params:
      format: ['prometheus']
    static_configs:
      - targets:
          - 'vault-0:8200'
          - 'vault-1:8200'
          - 'vault-2:8200'
    # Add auth header if required

Exoscale Observability

Use Exoscale’s built-in monitoring for:

Backup and Recovery

Raft Snapshots

Configure automated snapshots:

# Create snapshot
vault operator raft snapshot save /opt/vault/snapshots/$(date +%Y%m%d).snap

# Restore snapshot
vault operator raft snapshot restore /opt/vault/snapshots/backup.snap

Exoscale Instance Snapshots

Create instance snapshots for quick recovery:

exo compute instance snapshot create vault-0 --name "vault-0-backup-$(date +%Y%m%d)"

Troubleshooting

Cannot Connect to Vault

  1. Check security group allows port 8200
  2. Verify NLB is healthy
  3. Check Vault service status: systemctl status vault

Raft Cluster Not Forming

  1. Check nodes can communicate on port 8201
  2. Verify security group self-reference rule
  3. Check Vault logs: journalctl -u vault -f

Instance Not Starting

  1. Check cloud-init logs: cat /var/log/cloud-init-output.log
  2. Verify Vault binary downloaded correctly
  3. Check disk space and permissions

Cleanup

terraform destroy

Warning: This deletes all data. Ensure you have backups!