feat: add Scaleway BYOC provider#2105
Draft
simple-agent-manager[bot] wants to merge 39 commits into
Draft
Conversation
Add Scaleway as a new cloud provider with skeleton BYOC client: - Add SCALEWAY = 6 to Provider proto enum - Add ProviderScaleway constant, registration, and all switch cases - Add region config with default fr-par and SCW_DEFAULT_REGION env var - Create skeleton ByocScaleway client with stub implementations - Wire up provider factory in connect.go - Add test cases for provider ID and region Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add low-level Scaleway API wrappers in pkg/clouds/scaleway/ following the pattern established by pkg/clouds/aws/ and pkg/clouds/gcp/: - common.go: Base client with HTTP helpers, auth header, region/zone utils - auth.go: Credential validation via IAM API, env var loading - storage.go: S3-compatible object storage using AWS SDK with custom endpoint - secret.go: Secret Manager API (create, version, list, delete) - jobs.go: Serverless Jobs API for CD task execution - registry.go: Container Registry namespace and image management - dns.go: DNS zone management - errors.go: Structured error handling with IsNotFound/IsConflict helpers Includes unit tests for error detection, URL construction, and S3 endpoint generation. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Implement the Scaleway BYOC provider methods using the SDK wrappers from pkg/clouds/scaleway/: - Authenticate: validates credentials via IAM API, creates S3 client - Deploy/Preview: marshal compose to protobuf, upload payload, run CD job - GetProjectUpdate/GetServices/GetService: download state from S3 bucket - PutConfig/ListConfig/DeleteConfig: Scaleway Secret Manager operations - CreateUploadURL: presigned S3-compatible upload URLs - SetUpCD: create bucket, registry namespace, job definition - TearDownCD: basic cleanup with TODO for full implementation - CdCommand: run arbitrary CD commands via Serverless Jobs - CdList: list Pulumi stacks from S3 state bucket - GetDeploymentStatus: check Serverless Job run status QueryLogs, Subscribe, and PrepareDomainDelegation remain as stubs (ErrNotImplemented) as they require Scaleway-specific logging and DNS infrastructure not yet available. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- PrepareDomainDelegation: creates a DNS zone in Scaleway and returns NS records for parent zone delegation - Subscribe: polls Serverless Job run status to stream deployment events with state change detection - QueryLogs: queries Cockpit Loki API for container/job logs with support for both historical queries and follow/tail mode - Add Cockpit SDK wrapper (cockpit.go) for token management and Loki query_range integration Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Change CD command from `node lib/index.js` to `/app/cd` (Go CD binary) - Add DEFANG_PULUMI_DIR debug support for local CD testing - Add SCALEWAY_DEPLOY_LOG.md tracking deployment progress and fixes Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Scaleway S3 presigned URLs use HTTPS path-style format (https://s3.fr-par.scw.cloud/bucket/key) but Kaniko expects s3://bucket/key for S3 build contexts. Add convertScalewayS3URL() to perform this conversion, similar to the existing GCS URL conversion. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Pass S3_ENDPOINT to CD task environment for Scaleway S3-compatible storage - Fix secret name format: replace path separators with underscores to match Scaleway Secret Manager naming convention - Add early return in debug mode after DebugPulumiCD completes - Update work log with session 4 findings (blockers 6-10) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Document the eval$IFS$KANIKO_SCRIPT solution for running shell scripts in Scaleway Serverless Jobs, including failed approaches and verification experiments. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Session 5 resolved blockers 11-16: - AWS SDK v2 IMDS fallback (AWS_EC2_METADATA_DISABLED=true) - Kaniko chown in sandbox (patched binary ignoring EPERM) - Local storage limit (local_storage_capacity=10GB) - Staging directory permissions (MkdirAll 0644→0755) - apt-get setgroups in sandbox (apt config + user mgmt stubs) - Health check required fields (default threshold/interval) Deployment succeeded! App endpoint live on Scaleway. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add CDImage validation with actionable error message (like Azure) - Normalize Scaleway's 400 "same secret name" error to 409 so PutConfig correctly falls through to update existing secrets - Store raw API error body for detailed error matching Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The CD binary reads its command from os.Args, but the Scaleway job was only setting DEFANG_CD_CMD in env vars (which the CD binary ignores). Now pass the command string via the Scaleway start endpoint's command field, which is whitespace-split into an exec array by the API. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…r stubs Documents three new blockers fixed: - Blocker 17: USER appuser not in /etc/passwd (functional stubs instead of exit 0) - Blocker 18: addgroup symlink overwrites adduser (os.Remove before WriteFile) - Blocker 19: Kaniko cache reuses old broken layers (deleted cache tags) Full deployment now working: Next.js app + Postgres on Scaleway Serverless Containers. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Config → Up → Verify (HTTP 200 + Postgres data) → Down all working. Added known issue about Loki DNS not resolving in devcontainer. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add Scaleway provider case to configureAccessGateway in compose fixup: - Default chat model: llama-3.3-70b-instruct - Default embedding model: bge-multilingual-gemma2 - Uses LiteLLM's native scaleway/ prefix (SCW_SECRET_KEY for auth) Add sample chat app (samples/scaleway-llm-chat/) demonstrating the provider: type: model compose pattern with Scaleway Generative APIs. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Simplify compose.yaml to single service talking directly to Scaleway Generative APIs (OpenAI-compatible at api.scaleway.ai) - Remove LiteLLM intermediary (host-mode ports unsupported on Scaleway) - Add PULUMI_HOME env var for Scaleway CD jobs (non-root container) - Shorten project name to avoid 16-char resource name limit Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
For Scaleway deployments: - Model services use Scaleway Generative APIs directly (no LiteLLM sidecar needed). Dependent services get OPENAI_API_KEY (user-set), endpoint URL, and model name injected. - REDIS_PASSWORD env var is auto-injected for managed Redis services since Scaleway requires authentication. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
6 tasks
Image building section now reflects the Kaniko solution. LiteLLM "remaining work" section replaced with the final direct Generative API approach that was validated end-to-end. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
These files don't belong in the CLI repo: SCALEWAY_DEPLOY_LOG.md is an internal work log and samples/scaleway-llm-chat/ belongs in the samples repo. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…UpCD When CreateJobDefinition returns a conflict error, the code now calls ListJobDefinitions to find the existing job by name and stores its ID, preventing a nil jobDefID from being used in subsequent RunJob calls. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The Scaleway API does exact name matching, but ListSecrets documents prefix semantics. Now falls back to listing all secrets and filtering client-side by prefix when the exact match returns no results. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ication The function shares significant logic with wireDependentServices but the differences (no network wiring, nil OPENAI_API_KEY, dependency removal) are interleaved, making extraction non-trivial. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Only call the Scaleway S3 URL conversion when the URL actually contains a Scaleway domain, avoiding unnecessary processing for other providers. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The ProviderGCP and RegionDefaultGCP constants were reformatted only for alignment with the new Scaleway additions. Revert to original formatting to minimize diff noise. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Contributor
Author
Contributor
Author
|
Scaleway log validation update (2026-05-11) Pushed fixes through c96d540:
Validation performed against validation/scaleway/log-smoke with /tmp/defang-scaleway-pr:
Cleanup:
|
Contributor
Author
|
Adding concrete log command/output excerpts from the Scaleway validation run. Deployment-time logs from compose up: Post-deploy CD logs command: Runtime logs command after hitting the endpoint: Follow mode live request: Cleanup log excerpt: |
Scaleway Managed Database requires passwords with uppercase, lowercase, digit, and special character. CreateRandomConfigValue now accepts a ProviderID and generates Scaleway-compatible passwords for that provider. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.


Summary
Adds Scaleway as a BYOC provider in the Defang CLI.
defang --provider scaleway compose upnow deploys through a Scaleway Serverless Jobs CD task and integrates with the Pulumi provider in DefangLabs/pulumi-defang#234.Implemented
SCW_ACCESS_KEY,SCW_SECRET_KEY,SCW_DEFAULT_PROJECT_ID, and region env.v1alpha2.defang-cdjob definitions are removed before creating the current definition.project.pb.read_only_logsCockpit tokens.compose ps/ services readback from the CD-writtenproject.pbartifact.OPENAI_API_KEYis absent, the CLI creates the Defang config from the Scaleway secret key.Scaleway behavior and limitations
https://api.scaleway.ai/v1/; no LiteLLM sidecar is deployed.chat-default->llama-3.3-70b-instruct,embedding-default->bge-multilingual-gemma2).HTTP 403for the delegateddefang.appzone, while the native Scaleway container domain worked.compose logsnow reaches Cockpit without endpoint/auth failures. Log completeness still depends on Scaleway product log availability and labels.REDIS_PASSWORDconfig for this provider path;mastra-extendedexposed that requirement even though the sample README only calls outPOSTGRES_PASSWORD.Live validation
Validated on 2026-05-11 against the SAM-provided Scaleway account using the draft Pulumi provider branch and CD image
rg.fr-par.scw.cloud/defang-cd/cd:sam-20260511d.Small app validation:
compose upcompleted for a Python service with a Composemodels:entry./llmsuccessfully called Scaleway's OpenAI-compatible/modelsendpoint with auto-createdOPENAI_API_KEYconfig.compose psreturnedDEPLOYMENT_COMPLETEDandhealthyafter the Pulumi provider wroteproject.pb.compose logsreturned without Cockpit DNS/auth errors.compose downremoved the live Serverless Container and namespace.Mastra Extended validation:
projects/samples/samples/mastra-extendedsample on stackmastraextended.POSTGRES_PASSWORD,REDIS_PASSWORD, and auto-created ScalewayOPENAI_API_KEY.Generate sample items, verified 10 tasks, 10 events, and 20 classified items, waited 15 seconds, then asked the chat UI what to look at first.1 passed.compose downremoved the sample's Serverless Containers, namespace, managed Postgres, and managed Redis; native API checks confirmed cleanup.Test plan
go1.25.9 test ./pkg/clouds/scaleway ./pkg/cli/compose ./pkg/cli/client/byoc/scalewaygo1.25.9 test ./pkg/clouds/scaleway ./pkg/cli/client/byoc/scalewaycompose up/ endpoint checks /compose ps/compose logs/compose downon Scalewaymastra-extendedUIRelated PRs