In your Public Cloud project, click on Managed Kubernetes Service under Containers in the left-hand menu, then click Create a cluster. All the settings are on the Create a Kubernetes cluster page:
- Cluster name: enter a name for your cluster.
- Region: select a deployment mode (1-AZ or 3-AZ region) and a location for your new cluster.
- Plan: choose the
Free or Standard plan (Compare plans gives the details).
- Version and security policy: choose the minor version of Kubernetes and the automatic update policy.
Info
We recommend always using the latest stable version. Please read our End of life / end of support page to understand our version policy.
- Network settings: optionally, integrate your cluster into a private network using OVHcloud vRack by selecting an existing private network and subnet. For more information, read our guide Using the vRack.
- Node pools: click
Add node pool to configure a node pool. A node pool is a group of nodes sharing the same configuration. You can add a node pool now or skip this step to add one later. Read the Managing node pools guide for more information.
For each node pool, enter a Node pool name, select an instance model, and set the Number of nodes. Optionally, enable Autoscaling and define the minimum and maximum pool size. Choose the billing mode (Monthly or Hourly) and optionally enable Anti-affinity.
Info
Anti-affinity distributes nodes across different hypervisors for higher fault tolerance. Anti-affinity node pools are limited to 5 nodes. Monthly billing cannot be switched to hourly afterwards.
Review the summary and click Create Cluster.
The cluster is available within a few minutes.
Warning
After a cluster is created, the region and private network ID cannot be changed.
Create the cluster:
Call the following endpoint with this body:
{
"name": "my-cluster",
"region": "GRA7",
"version": "1.34"
}
Info
We recommend always using the latest stable version. Please read our End of life / end of support page to understand our version policy.
Tip
On the Standard plan, you can create a cluster that uses your own router or firewall as default gateway, with the public exposure of its nodes and workloads disabled, by adding plan, privateNetworkId, nodesSubnetId, disablePublicNetworking and privateNetworkConfiguration.useUserGateway to this body. See Using a custom gateway on an OVHcloud Managed Kubernetes cluster. To only disable the public exposure of the nodes and workloads while keeping the OVHcloud managed gateway of the nodes subnet, add plan, privateNetworkId, nodesSubnetId and disablePublicNetworking, without privateNetworkConfiguration.useUserGateway: see Understanding OVHcloud Managed Kubernetes architecture.
Note the id in the response — you will need it to create the node pool.
Create a node pool:
Call the following endpoint with this body:
{
"name": "my-pool",
"flavorName": "b2-7",
"desiredNodes": 3,
"minNodes": 3,
"maxNodes": 3
}
Warning
Node pool names only accept lowercase characters, digits and -. Underscores and dots are not supported.
Warning
After a cluster is created, the region, the private network ID, and the disablePublicNetworking and useUserGateway attributes cannot be changed.
Info
Install the OVHcloud CLI and configure your credentials before proceeding.
Create the cluster:
ovhcloud cloud managed-kubernetes create \
--cloud-project <serviceName> \
--name my-cluster \
--region GRA7 \
--version 1.34
Info
We recommend always using the latest stable version. Please read our End of life / end of support page to understand our version policy.
Note the id in the output — you will need it to create the node pool.
Create a node pool:
ovhcloud cloud managed-kubernetes nodepool create <kubeId> \
--cloud-project <serviceName> \
--name my-pool \
--flavor-name b2-7 \
--desired-nodes 3 \
--min-nodes 3 \
--max-nodes 3
Warning
Node pool names only accept lowercase characters, digits and -. Underscores and dots are not supported.
Warning
After a cluster is created, the region and private network ID cannot be changed.
Info
Install Terraform CLI (version 0.12.x minimum) before proceeding.
OVHcloud provides a Terraform provider available in the official Terraform registry.
Your Public Cloud project ID is the service_name. To copy it, click the project selector at the top of the left-hand menu of your Public Cloud project, then click the copy icon on the row of your project (it appears when you hover the row).
provider.tf:
terraform {
required_providers {
ovh = {
source = "ovh/ovh"
}
}
}
provider "ovh" {
endpoint = "ovh-eu"
application_key = "<your_access_key>"
application_secret = "<your_application_secret>"
consumer_key = "<your_consumer_key>"
}
Alternatively, use environment variables to avoid storing secrets in source code: OVH_ENDPOINT, OVH_APPLICATION_KEY, OVH_APPLICATION_SECRET, OVH_CONSUMER_KEY.
variables.tf:
variable service_name {
type = string
default = "<your_service_name>"
}
ovh_kube_cluster.tf:
resource "ovh_cloud_project_kube" "my_kube_cluster" {
service_name = "${var.service_name}"
name = "my_kube_cluster"
region = "GRA7"
version = "1.34"
}
resource "ovh_cloud_project_kube_nodepool" "node_pool" {
service_name = "${var.service_name}"
kube_id = ovh_cloud_project_kube.my_kube_cluster.id
name = "my-pool"
flavor_name = "b2-7"
desired_nodes = 3
max_nodes = 3
min_nodes = 3
}
output.tf:
output "kubeconfig" {
value = ovh_cloud_project_kube.my_kube_cluster.kubeconfig
sensitive = true
}
Warning
Node pool names only accept lowercase characters, digits and -. Underscores and dots cause a gzip: invalid header error.
Deploy:
terraform init && terraform apply

CDKTF translates Go code into Terraform HCL and uses the OVHcloud Terraform provider. Set the required credentials as environment variables:
export OVH_ENDPOINT="ovh-eu"
export OVH_APPLICATION_KEY="xxx"
export OVH_APPLICATION_SECRET="xxx"
export OVH_CONSUMER_KEY="xxx"
export OVH_CLOUD_PROJECT_SERVICE="xxx"
Initialize the project:
mkdir ovhcloud-kube && cd ovhcloud-kube
cdktf init --template=go --providers="ovh/ovh@~>0.37.0" "hashicorp/local" --providers-force-local --local --project-name=ovhcloud-kube
Edit main.go:
package main
import (
"os"
"path"
"cdk.tf/go/stack/generated/hashicorp/local/file"
local "cdk.tf/go/stack/generated/hashicorp/local/provider"
"cdk.tf/go/stack/generated/ovh/ovh/cloudprojectkube"
"cdk.tf/go/stack/generated/ovh/ovh/cloudprojectkubenodepool"
ovh "cdk.tf/go/stack/generated/ovh/ovh/provider"
"github.com/aws/constructs-go/constructs/v10"
"github.com/aws/jsii-runtime-go"
"github.com/hashicorp/terraform-cdk-go/cdktf"
)
func NewMyStack(scope constructs.Construct, id string) cdktf.TerraformStack {
stack := cdktf.NewTerraformStack(scope, &id)
ovh.NewOvhProvider(stack, jsii.String("ovh"), &ovh.OvhProviderConfig{
Endpoint: jsii.String("ovh-eu"),
})
local.NewLocalProvider(stack, jsii.String("local"), &local.LocalProviderConfig{})
serviceName := os.Getenv("OVH_CLOUD_PROJECT_SERVICE")
kube := cloudprojectkube.NewCloudProjectKube(stack, jsii.String("my_desired_cluster"), &cloudprojectkube.CloudProjectKubeConfig{
ServiceName: jsii.String(serviceName),
Name: jsii.String("my_desired_cluster"),
Region: jsii.String("GRA5"),
})
cdktf.NewTerraformOutput(stack, jsii.String("cluster_version"), &cdktf.TerraformOutputConfig{
Value: kube.Version(),
})
pwd, _ := os.Getwd()
file.NewFile(stack, jsii.String("kubeconfig"), &file.FileConfig{
Filename: jsii.String(path.Join(pwd, "kubeconfig.yaml")),
Content: kube.Kubeconfig(),
FilePermission: jsii.String("0644"),
})
nodePool := cloudprojectkubenodepool.NewCloudProjectKubeNodepool(stack, jsii.String("my-pool"), &cloudprojectkubenodepool.CloudProjectKubeNodepoolConfig{
ServiceName: kube.ServiceName(),
KubeId: kube.Id(),
Name: jsii.String("my-pool"),
DesiredNodes: jsii.Number(1),
MaxNodes: jsii.Number(3),
MinNodes: jsii.Number(1),
FlavorName: jsii.String("b2-7"),
})
cdktf.NewTerraformOutput(stack, jsii.String("nodePoolID"), &cdktf.TerraformOutputConfig{
Value: nodePool.Id(),
})
return stack
}
func main() {
app := cdktf.NewApp(nil)
NewMyStack(app, "ovhcloud")
app.Synth()
}
Deploy:

The OVH Pulumi provider supports Go, Python, Node.js/TypeScript, C# and Java. See examples.
Set credentials as environment variables:
export OVH_ENDPOINT="ovh-eu"
export OVH_APPLICATION_KEY="xxx"
export OVH_APPLICATION_SECRET="xxx"
export OVH_CONSUMER_KEY="xxx"
Create and initialize the project:
mkdir pulumi_ovh_kube && cd pulumi_ovh_kube
pulumi new go -y
go get github.com/ovh/pulumi-ovh/sdk/go/...
Edit Pulumi.yaml to add the service name:
config:
serviceName: <your-service-name>
Edit main.go:
package main
import (
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi/config"
"github.com/ovh/pulumi-ovh/sdk/go/ovh/cloudproject"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
serviceName := config.Require(ctx, "serviceName")
myKube, err := cloudproject.NewKube(ctx, "my_desired_cluster", &cloudproject.KubeArgs{
ServiceName: pulumi.String(serviceName),
Name: pulumi.String("my_desired_cluster"),
Region: pulumi.String("GRA5"),
})
if err != nil {
return err
}
ctx.Export("kubeconfig", pulumi.ToSecret(myKube.Kubeconfig))
nodePool, err := cloudproject.NewKubeNodePool(ctx, "my-desired-pool", &cloudproject.KubeNodePoolArgs{
ServiceName: pulumi.String(serviceName),
KubeId: myKube.ID(),
Name: pulumi.String("my-desired-pool"),
DesiredNodes: pulumi.Int(1),
MaxNodes: pulumi.Int(3),
MinNodes: pulumi.Int(1),
FlavorName: pulumi.String("b2-7"),
})
if err != nil {
return err
}
ctx.Export("nodePoolID", nodePool.ID())
return nil
})
}
Run go mod tidy then deploy: