Skip to content

lejeunen/ovh-starter-kit

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

14 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

OVH Starter Kit

An infrastructure starter kit for OVHcloud, built with Terragrunt and OpenTofu. A learning tool and starting point for deploying a secure, sovereign cloud platform on a European provider.

This is the OVH counterpart of the Scaleway Starter Kit. Same philosophy, different provider - compare the two to understand the trade-offs between European cloud platforms.

Architecture

                         Internet
                            │
                       ┌────┴────┐
                       │ Octavia │
                       │   LB    │
                       └────┬────┘
                            │
              ┌─────────────┼─────────────┐
              │   vRack Private Network   │
              │             │             │
              │   ┌─────────┴─────────┐   │
              │   │       MKS         │   │
              │   │   (Kubernetes)    │   │
              │   │                   │   │
              │   │  Envoy Gateway    │   │
              │   │  cert-manager     │   │
              │   └───────────────────┘   │
              │                           │
              │   ┌───────────────────┐   │
              │   │    PostgreSQL     │   │
              │   │   (Managed DB)    │   │
              │   └───────────────────┘   │
              └───────────────────────────┘

              Container Registry
              (Harbor-based)

The Load Balancer is not managed by Terraform. Instead, the OVH Cloud Controller Manager (CCM), pre-installed in MKS, automatically provisions an Octavia LB when it detects the Envoy Gateway Service of type LoadBalancer. PROXY protocol is enabled so Envoy can recover real client IPs. This avoids the hardcoded backend IP problem — node upgrades and autoscaling just work.

Components

Component OVH Service Scaleway Equivalent Notes
Private Network vRack + VLAN VPC + Private Network OVH's vRack is a free L2 backbone spanning all products. Simpler model — no VPC wrapper needed.
Kubernetes MKS (Managed Kubernetes Service) Kapsule Free control plane on both. OVH requires OpenStack network IDs (Neutron under the hood). No CNI choice on OVH.
Container Registry Managed Private Registry (Harbor) Container Registry OVH runs full Harbor instances with web UI. Plan-based pricing (SMALL €17/mo). Scaleway is pay-per-storage.
Database Managed PostgreSQL Managed PostgreSQL OVH auto-generates the DB password. Requires explicit IP whitelisting (even on private network) and enforces TLS. Uses Aiven-based avnadmin user.
Load Balancer Octavia LB (CCM-managed) Scaleway LB (CCM-managed) Not Terraform-managed. Provisioned automatically by the K8s Cloud Controller Manager via Envoy Gateway.
Gateway Envoy Gateway (Gateway API) Envoy Gateway (Gateway API) Kubernetes Gateway API with PROXY protocol. Replaces ingress-nginx.
TLS cert-manager (Let's Encrypt) cert-manager (Let's Encrypt) HTTP-01 challenge for subdomains. DNS-01 for apex domain available via cert-manager-webhook-ovh.
Secret Manager OKMS Secret Manager (beta) + ESO Secret Manager + ESO OKMS exposes a Vault-compatible KV2 API. Terraform creates the OKMS instance; secret values are pushed via scripts/push-secrets.sh (kept out of TF state). ESO uses the Vault provider with a PAT for auth.
Observability Coming soon Cockpit (Grafana)

Dependency Graph

network
 ├── kube
 └── database

okms        (independent)
registry    (independent)

Project Structure

infrastructure/
├── root.hcl                       # Shared Terragrunt config (S3 backend, provider)
├── modules/                       # Reusable Terraform modules
│   ├── network/                   # vRack private network + subnet
│   ├── kube/                      # MKS cluster + node pool
│   ├── database/                  # Managed PostgreSQL
│   ├── registry/                  # Managed Private Registry (Harbor)
│   └── okms/                      # OKMS instance (shell only, no secret values)
└── dev/                           # Dev environment
    ├── env.hcl                    # Environment-specific variables
    ├── network/terragrunt.hcl
    ├── kube/terragrunt.hcl
    ├── database/terragrunt.hcl
    ├── registry/terragrunt.hcl
    └── okms/terragrunt.hcl

k8s/                               # Kubernetes manifests (deployed via deploy.sh)
├── namespace.yaml                 # sovereign-wisdom namespace
├── gateway/
│   ├── envoyproxy.yaml            # Envoy data-plane config (Octavia LB annotations)
│   ├── gatewayclass.yaml          # Links to Envoy Gateway controller
│   ├── gateway.yaml               # HTTP/HTTPS listeners with TLS termination
│   ├── clienttrafficpolicy.yaml   # PROXY protocol support for real client IPs
│   ├── httproute-redirect.yaml    # HTTP → HTTPS redirect (301)
│   └── cluster-issuer.yaml        # cert-manager ClusterIssuer (Let's Encrypt)
├── external-secrets/
│   ├── cluster-secret-store.yaml  # ESO ClusterSecretStore (Vault provider → OKMS)
│   └── external-secret.yaml       # Syncs DB password from OKMS to K8s Secret
└── app/
    ├── deployment.yaml            # Sovereign Cloud Wisdom app
    ├── service.yaml               # ClusterIP Service
    └── httproute.yaml             # HTTPRoute (ovh.sovereigncloudwisdom.eu)

scripts/
├── deploy.sh                      # Deploy app to MKS (Helm installs + K8s manifests)
├── push-secrets.sh                # Push secret values to OKMS (bypasses TF state)
└── validate.sh                    # Validate IaC (format, tflint, trivy security scan)

The root Terragrunt config (root.hcl) is environment-agnostic — all environment-specific values live in env.hcl. To add a new environment (staging, prod), just create a new directory with its own env.hcl.

Prerequisites

Getting Started

1. Create the state bucket

In the OVH console, go to Public Cloud → Object Storage and create an S3-compatible bucket:

  • Name: ovh-starter-kit-tfstate
  • Region: GRA
  • Type: Standard (S3)

Then create an S3 user under Object Storage → S3 users for Terraform state access.

2. Create API credentials

Generate OVH API credentials at https://api.ovh.com/createToken/ with GET, POST, PUT, DELETE rights on /*.

3. Create the .env file

cp .env.example .env

Edit .env with your credentials:

# OVH API credentials
export OVH_ENDPOINT="ovh-eu"
export OVH_APPLICATION_KEY=<your-application-key>
export OVH_APPLICATION_SECRET=<your-application-secret>
export OVH_CONSUMER_KEY=<your-consumer-key>

# Public Cloud project ID
export OVH_CLOUD_PROJECT_SERVICE_NAME=<your-project-id>

# S3 credentials for Terraform state backend
export AWS_ACCESS_KEY_ID=<your-s3-access-key>
export AWS_SECRET_ACCESS_KEY=<your-s3-secret-key>

# OKMS Personal Access Token for External Secrets Operator
# Create in OVH Console → IAM → Users → Personal Access Tokens
export OVH_OKMS_TOKEN=<your-okms-pat>

export KUBECONFIG="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/infrastructure/dev/.kubeconfig"

Then load it:

source .env

4. Deploy the infrastructure

cd infrastructure/dev
terragrunt run --all apply

Terragrunt will deploy in order: network -> kube + database (parallel). OKMS and the container registry are independent and deploy in parallel with the rest.

5. Push secret values

Terraform creates the OKMS instance but not the secret data. Push the DB password via the Vault-compatible KV2 API (keeps it out of Terraform state):

./scripts/push-secrets.sh

Use --dry-run to preview what would be pushed:

./scripts/push-secrets.sh --dry-run

6. Generate the kubeconfig

After the MKS cluster is deployed:

cd infrastructure/dev/kube
terragrunt output -raw kubeconfig > ../.kubeconfig
chmod 600 ../.kubeconfig

Then connect to the cluster:

kubectl get nodes

7. Log in to the container registry

cd infrastructure/dev/registry
REGISTRY_URL=$(terragrunt output -raw registry_url)
REGISTRY_PASSWORD=$(terragrunt output -raw registry_password)
docker login "$REGISTRY_URL" -u deployer -p "$REGISTRY_PASSWORD"

8. Push the app image

Build and push the sovereign-cloud-wisdom image to the Harbor registry:

# Strip https:// — Docker image references don't include the protocol
REGISTRY_HOST="${REGISTRY_URL#https://}"
docker tag sovereign-cloud-wisdom:latest "$REGISTRY_HOST/library/sovereign-cloud-wisdom:latest"
docker push "$REGISTRY_HOST/library/sovereign-cloud-wisdom:latest"

Note: OVH Harbor uses a default library project. You can create additional projects in the Harbor web UI.

9. Deploy the app

./scripts/deploy.sh

The script will:

  1. Install Envoy Gateway (triggers Octavia LB provisioning via PROXY protocol)
  2. Apply Gateway API resources (GatewayClass, Gateway, HTTPRoutes, ClientTrafficPolicy)
  3. Install cert-manager with Gateway API support for automated TLS
  4. Install External Secrets Operator and sync DB password from OKMS
  5. Create K8s ConfigMaps from Terraform outputs
  6. Deploy the app (Deployment, Service, HTTPRoute)
  7. Print the Load Balancer IP for DNS configuration

Then create a DNS A record:

ovh.sovereigncloudwisdom.eu → <LB IP>

OVH vs Scaleway — Key Differences

Aspect OVH Scaleway
Authentication 3 API keys (app key, app secret, consumer key) 2 keys (access key, secret key)
Networking vRack (free L2 backbone) + VLANs. No VPC abstraction. VPC + Private Network. More AWS-like model.
Regions GRA9 = compute, GRA = storage. Same datacenter (Gravelines), different service scopes. fr-par / nl-ams / pl-waw. Unified region naming.
Kubernetes MKS. No CNI choice. OpenStack IDs required for private network. Kapsule. Cilium or Calico CNI. Scaleway IDs directly.
Container Registry Harbor-based. Plan-based pricing (from €17/mo). Web UI included. Namespace-based. Pay-per-storage (~€0.01/GB). No UI.
IaC provider ovh/ovh. Resources follow ovh_cloud_project_* naming. scaleway/scaleway. Resources follow scaleway_* naming.
Database Aiven-based. Enforces TLS. Requires explicit ip_restrictions even on private network. avnadmin is the admin user. Built-in. TLS optional. Private network attachment is sufficient. User-defined credentials.
Secret Manager OKMS Secret Manager (beta). Vault-compatible KV2 API. PAT auth. Native Secret Manager. ESO has a built-in Scaleway provider.
State backend S3 on OVH Object Storage (s3.gra.io.cloud.ovh.net). Needs separate S3 user. S3 on Scaleway Object Storage (s3.fr-par.scw.cloud). Uses same API keys.

Tear Down

cd infrastructure/dev
terragrunt run --all destroy

Note: Container registry deletion may take a few minutes. If destroy times out, retry.

Compliance & Sovereignty

All resources are deployed exclusively in France (Gravelines datacenter), using OVHcloud — a French cloud provider not subject to US extraterritorial surveillance laws (CLOUD Act, FISA Section 702). OVHcloud is a founding member of the Gaia-X initiative and has achieved SecNumCloud 3.2 qualification (ANSSI) for its Bare Metal Pod and Hosted Private Cloud offerings. Public Cloud SecNumCloud qualification is in progress.

About

Infrastructure starter kit for OVHcloud — Terragrunt, OpenTofu, MKS, PostgreSQL, Harbor, cert-manager

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors