Scaleway
You can use Scaleway instances as worker nodes in your CFKE cluster. The recommended approach combines the Cloudfleet Terraform provider with cloud-init automation. You deploy Scaleway instances with Terraform. The cloud-init configuration that Cloudfleet generates automatically then registers these instances with your CFKE cluster.
Prerequisites
- Terraform CLI installed on your local machine.
- Cloudfleet CLI configured with these setup instructions, or API token authentication configured per these guidelines.
- An active Scaleway account with API credentials (access key, secret key, and project ID). Generate these credentials in the Scaleway console.
- An existing CFKE cluster. This example uses a cluster with ID
CLUSTER_ID. You can also create a new cluster with Terraform by following the Terraform setup documentation.
Deploying Scaleway instances to your CFKE cluster
Deploy and connect Scaleway instances to your CFKE cluster using the following Terraform configuration. Update the variable values to match your environment.
variable "cfke_cluster_id" {
type = string
default = "CFKE Cluster ID"
}
variable "scaleway_access_key" {
type = string
description = "Scaleway Access Key"
}
variable "scaleway_secret_key" {
type = string
description = "Scaleway Secret Key"
}
variable "scaleway_project_id" {
type = string
description = "Scaleway Project ID"
}
terraform {
required_providers {
cloudfleet = {
source = "terraform.cloudfleet.ai/cloudfleet/cloudfleet"
}
scaleway = {
source = "scaleway/scaleway"
}
}
}
provider "scaleway" {
access_key = var.scaleway_access_key
secret_key = var.scaleway_secret_key
region = "fr-par"
project_id = var.scaleway_project_id
}
data "cloudfleet_cfke_cluster" "cluster" {
id = var.cfke_cluster_id
}
resource "cloudfleet_cfke_node_join_information" "scaleway" {
cluster_id = data.cloudfleet_cfke_cluster.cluster.id
region = "fr-par"
zone = "fr-par-1"
node_labels = {
"cfke.io/provider" = "scaleway"
}
# Scaleway requires uncompressed userdata
base64_encode = false
gzip = false
}
resource "scaleway_instance_server" "worker" {
count = 2
name = "cfke-worker-${count.index+1}"
type = "DEV1-M"
image = "ubuntu_jammy"
user_data = {
cloud-init = cloudfleet_cfke_node_join_information.scaleway.rendered
}
enable_dynamic_ip = true
}Run these commands to provision your Scaleway infrastructure and add the instances to your CFKE cluster:
terraform init
terraform applyAfter provisioning completes, check that your new nodes joined the cluster:
kubectl get nodesAdding a load balancer
To expose applications to the internet, deploy a Kubernetes Service of type NodePort. Then configure a Scaleway Load Balancer to route traffic to your nodes on that port. The following example shows a complete setup: an Nginx Deployment exposed on port 31001 and a matching Scaleway Load Balancer configuration.
locals {
node_port = 31001
}
// An example Kubernetes deployment using a Load Balancer
data "cloudfleet_client_config" "me" {}
provider "kubernetes" {
host = data.cloudfleet_cfke_cluster.cluster.endpoint
cluster_ca_certificate = data.cloudfleet_cfke_cluster.cluster.certificate_authority
token = data.cloudfleet_client_config.me.access_token
}
resource "kubernetes_namespace" "test" {
depends_on = [
data.cloudfleet_cfke_cluster.cluster
]
metadata {
name = "scaleway"
}
}
resource "kubernetes_deployment" "app" {
wait_for_rollout = false
metadata {
name = "nginx"
namespace = kubernetes_namespace.test.id
labels = {
app = "nginx"
}
}
spec {
replicas = 2
selector {
match_labels = {
app = "nginx"
}
}
template {
metadata {
labels = {
app = "nginx"
}
}
spec {
affinity {
node_affinity {
required_during_scheduling_ignored_during_execution {
node_selector_term {
match_expressions {
key = "cfke.io/provider"
operator = "In"
values = [
"scaleway"
]
}
}
}
}
}
container {
image = "nginx:latest"
name = "nginx"
port {
name = "http"
container_port = 80
}
}
}
}
}
}
resource "kubernetes_service" "app" {
depends_on = [
data.cloudfleet_cfke_cluster.cluster
]
metadata {
name = "nginx"
namespace = kubernetes_namespace.test.id
labels = {
app = "nginx"
}
}
spec {
selector = {
app = "nginx"
}
external_traffic_policy = "Local"
type = "NodePort"
port {
name = "http"
port = 80
target_port = 80
node_port = local.node_port
}
}
}
resource "scaleway_lb_ip" "cfke" {
zone = "fr-par-1"
}
resource "scaleway_lb" "cfke" {
ip_ids = [scaleway_lb_ip.cfke.id]
zone = scaleway_lb_ip.cfke.zone
type = "LB-S"
}
resource "scaleway_lb_backend" "cfke" {
lb_id = scaleway_lb.cfke.id
name = "nginx"
forward_protocol = "http"
forward_port = local.node_port
server_ips = [for ip in flatten(scaleway_instance_server.worker.*.public_ips) : ip.address]
health_check_http {
uri = "/"
}
}
resource "scaleway_lb_frontend" "cfke" {
lb_id = scaleway_lb.cfke.id
backend_id = scaleway_lb_backend.cfke.id
inbound_port = 80
}
output "load_balancer_ip" {
value = scaleway_lb_ip.cfke.ip_address
}For production deployments, consider an Ingress controller instead of this basic NodePort approach.
Firewall configuration
Configure Scaleway security groups to restrict network access to your cluster:
- Port 31001 (TCP): Allow access to the NodePort Service only from the Scaleway load balancer IP address. Do not expose this port to all sources (
0.0.0.0/0), because this creates unnecessary security exposure.
This configuration follows the principle of least privilege: only the load balancer can access the NodePort. All external traffic goes through the load balancer, which gives you one central point for access control and public exposure.
← OVH
Exoscale →