{"id":29434380,"url":"https://github.com/opennebula/hosted-cloud-scaleway","last_synced_at":"2026-02-06T04:02:58.472Z","repository":{"id":303986806,"uuid":"1016804540","full_name":"OpenNebula/hosted-cloud-scaleway","owner":"OpenNebula","description":null,"archived":false,"fork":false,"pushed_at":"2025-11-29T09:36:14.000Z","size":4145,"stargazers_count":1,"open_issues_count":0,"forks_count":2,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-12-01T10:59:04.557Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/OpenNebula.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-07-09T14:48:58.000Z","updated_at":"2025-11-29T09:36:18.000Z","dependencies_parsed_at":"2025-07-30T16:25:13.649Z","dependency_job_id":"f249a091-586b-4794-a8e1-3e3ffb06f9b2","html_url":"https://github.com/OpenNebula/hosted-cloud-scaleway","commit_stats":null,"previous_names":["opennebula/hosted-cloud-scaleway"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/OpenNebula/hosted-cloud-scaleway","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenNebula%2Fhosted-cloud-scaleway","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenNebula%2Fhosted-cloud-scaleway/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenNebula%2Fhosted-cloud-scaleway/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenNebula%2Fhosted-cloud-scaleway/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/OpenNebula","download_url":"https://codeload.github.com/OpenNebula/hosted-cloud-scaleway/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenNebula%2Fhosted-cloud-scaleway/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29149594,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-06T02:39:25.012Z","status":"ssl_error","status_checked_at":"2026-02-06T02:37:22.784Z","response_time":59,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-07-13T02:16:00.294Z","updated_at":"2026-02-06T04:02:58.457Z","avatar_url":"https://github.com/OpenNebula.png","language":"HTML","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n# Deploying OpenNebula as a Hosted Cloud on Scaleway\n\nThis repository delivers the Terraform, Ansible, and driver customizations required to build an OpenNebula Hosted Cloud on **Scaleway Elastic Metal**. It extends the upstream [one-deploy](https://github.com/OpenNebula/one-deploy) and [one-deploy-validation](https://github.com/OpenNebula/one-deploy-validation) projects via git submodules and adds Scaleway-specific infrastructure modules, inventories, and Flexible IP (FIP) drivers.\n\nUse the in-repo [deployment guide](./deployment_guide.md) for a narrative, end-to-end walkthrough; the README below highlights the main entry points and recent platform changes.\n\n## Table of Contents\n\n- [Scaleway Hosted Cloud Overview](#scaleway-hosted-cloud-overview)\n- [Requirements](#requirements)\n- [Repository Setup](#repository-setup)\n- [Secrets and Environment Variables](#secrets-and-environment-variables)\n- [Infrastructure Provisioning](#infrastructure-provisioning)\n- [Inventory and Parameters](#inventory-and-parameters)\n- [Networking Configuration](#networking-configuration)\n- [OpenNebula Deployment Workflow](#opennebula-deployment-workflow)\n- [Validation Suite](#validation-suite)\n- [Troubleshooting \u0026 Known Issues](#troubleshooting--known-issues)\n- [CI/CD Roadmap](#cicd-roadmap)\n- [Extending the Cloud](#extending-the-cloud)\n\n## Scaleway Hosted Cloud Overview\n\n- Target architecture runs one OpenNebula frontend (also acting as a KVM node) and one or more KVM hypervisors on EM-A610R-NVMe servers connected through a private VPC and optional public Flexible IPs.\n- Terraform modules under `scw/` create networking (VPC, VLANs, Flexible IP routing), bare-metal instances, and dynamic inventories.\n- Ansible roles in `submodule-one-deploy` configure OpenNebula, while `roles/one-driver` provides a custom VNM bridge hook to allocate/detach Flexible IPs through Scaleway APIs (reworked in commits `967216f` and `a165376` to handle multi-NIC workloads).\n- `deployment_guide.md` documents the architecture diagrams, hardware SKUs, and provisioning prerequisites in detail.\n\n## Requirements\n\n| Component | Version / Notes |\n|-----------|-----------------|\n| OpenTofu  | ≥ 1.5.0 (used by the `scw/*` modules) |\n| Python / pip | Needed for [hatch](https://hatch.pypa.io) and Ansible tooling |\n| Hatch     | Used to manage the `scaleway-default` execution environment |\n| Ansible   | Driven by the `Makefile` targets |\n| Scaleway Credentials | API access key, secret key, organization/project IDs |\n\nManual prerequisites (before automation):\n\n- Create a Scaleway project (Console: Account \u003e Projects) and an API key with full admin or use a personnal access token (Console: IAM \u003e API Keys or use Scaleway CLI to have a PAT). No bare-metal server needs to be pre-created—the Terraform modules provision the Elastic Metal servers and also create the Flexible IP IAM application/token automatically in module `005`.\n\nInstall the local tooling:\n\n```bash\npip install hatch\nmake submodule-requirements     # installs collection dependencies via submodule-one-deploy\n```\n\n## Repository Setup\n\n```bash\ngit clone https://github.com/OpenNebula/hosted-cloud-scaleway.git\ncd hosted-cloud-scaleway\ngit submodule update --init --remote --merge\n```\n\nMakefile shortcuts (`deployment`, `validation`, `specifics`, `submodule-requirements`) proxy into the submodules with the Scaleway inventory pre-selected.\n\n## Secrets and Environment Variables\n\nSetup follows the template in `.secret.skel`:\n\n```bash\ncp .secret.skel .secret\nvim .secret               # fill TF_VAR_*, SCW_* values, Flexible IP token, OpenNebula password, etc.\nsource .secret\n```\n\nKey variables:\n\n- `TF_VAR_customer_name`, `TF_VAR_project_name`, `TF_VAR_project_fullname` — naming for resources/state (keep names as-is, only change values).\n- `TF_VAR_state_infrastructure_information` — object with `scw_infrastructure_project_name` (used to name the dedicated state project); `TF_VAR_tfstate` — bucket prefix for remote state. These two must be set or `tofu plan` will prompt.\n- `SCW_ACCESS_KEY` / `SCW_SECRET_KEY` plus `SCW_DEFAULT_ORGANIZATION_ID`, `SCW_DEFAULT_REGION`, and `SCW_DEFAULT_ZONE`. `SCW_DEFAULT_PROJECT_ID` is optional (not used by the modules).\n- `TF_VAR_scw_secret_key` — required input to module `005`, keep the name unchanged and set it to `$SCW_SECRET_KEY`.\n- Network inputs: `TF_VAR_private_subnet` (management subnet) and `TF_VAR_vmtovm_subnet` (VXLAN mesh subnet), plus `TF_VAR_worker_count` (number of hypervisors).\n- AWS-compatible aliases (`AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`) used by the state backend (keep the names as-is).\n- The Flexible IP IAM application, policy, and token are created for you in module `005` and injected into `inventory/scaleway.yml` (`scw_flexible_ip_token`). You do **not** need to pre-create or store this token in `.secret`.\n\nExample fill (replace with your IDs, zones, and secrets):\n\n```bash\nexport TF_VAR_customer_name='opennebula'\nexport TF_VAR_project_name='scw'\nexport SCW_ACCESS_KEY='\u003cscw-access-key\u003e'\nexport SCW_SECRET_KEY='\u003cscw-secret-key\u003e'\nexport TF_VAR_scw_secret_key=$SCW_SECRET_KEY   # required; name must stay as-is\nexport AWS_ACCESS_KEY_ID=$SCW_ACCESS_KEY\nexport AWS_SECRET_ACCESS_KEY=$SCW_SECRET_KEY\nexport SCW_DEFAULT_ORGANIZATION_ID='\u003corg-id\u003e'\nexport SCW_DEFAULT_REGION='fr-par'\nexport SCW_DEFAULT_ZONE='fr-par-2'\nexport TF_VAR_state_infrastructure_information='{ scw_infrastructure_project_name = \"infra\"}'\nexport TF_VAR_region=$SCW_DEFAULT_REGION\nexport TF_VAR_zone=$SCW_DEFAULT_ZONE\nexport TF_VAR_tfstate='opennebula-scw-infra-tfstates'\nexport TF_VAR_project_fullname='opennebula-scw-infra'\nexport TF_VAR_private_subnet=\"10.16.0.0/20\"\nexport TF_VAR_vmtovm_subnet=\"172.16.24.0/22\"\nexport TF_VAR_worker_count=\"1\"\nexport TF_VAR_one_password='\u003coneadmin-password\u003e'\n```\n\n\u003e `.secret` stays ignored; never commit credential material.\n\n## Infrastructure Provisioning\n\nModules under `scw/` are executed sequentially (OpenTofu CLI):\n\n| Order | Module | Purpose |\n|-------|--------|---------|\n| 001 | `terraform_state_management` | Bootstrap state bucket/project metadata |\n| 002 | `vpc` | Create VPC, subnets, VLAN assignments |\n| 003 | `opennebula_instances` | Provision frontend \u0026 hypervisors + cloud-init assets |\n| 004 | `opennebula_instances_net` | Configure networking (netplan, bridges, VLAN tags) |\n| 005 | `opennebula_inventories` | Render `inventory/scaleway.yml` from module outputs |\n\nExample run (after `source .secret`):\n\n```bash\ncd scw/002.vpc\ntofu init\ntofu plan -input=false   # surfaces any missing TF_VAR_* instead of prompting\ntofu apply\ncd ../..\n\n# run each module in order (no loops to keep debugging simple)\ncd scw/001.terraform_state_management \u0026\u0026 tofu init \u0026\u0026 tofu plan -input=false \u0026\u0026 tofu apply \u0026\u0026 cd ../..\ncd scw/002.vpc                      \u0026\u0026 tofu init \u0026\u0026 tofu plan -input=false \u0026\u0026 tofu apply \u0026\u0026 cd ../..\ncd scw/003.opennebula_instances     \u0026\u0026 tofu init \u0026\u0026 tofu plan -input=false \u0026\u0026 tofu apply \u0026\u0026 cd ../..\ncd scw/004.opennebula_instances_net \u0026\u0026 tofu init \u0026\u0026 tofu plan -input=false \u0026\u0026 tofu apply \u0026\u0026 cd ../..\ncd scw/005.opennebula_inventories   \u0026\u0026 tofu init \u0026\u0026 tofu plan -input=false \u0026\u0026 tofu apply \u0026\u0026 cd ../..\n```\n\nConsult `deployment_guide.md#4-infrastructure-deployment-tofu-modules` for module-specific inputs, expected outputs, and screenshots.\n\n## Inventory and Parameters\n\n`inventory/scaleway.yml` is auto-generated by module 005 but can be overridden for PoCs. Adapt these key parameters:\n\n| Description | Variable(s) | Files / Templates |\n|-------------|-------------|-------------------|\n| SSH user, key path | `ansible_user`, `ansible_ssh_private_key_file` | `inventory/group_vars/all.yml` |\n| Frontend + node metadata | `frontend.hosts.*`, `node.hosts.*` | `inventory/scaleway.yml` |\n| Scaleway project / Flexible IP identifiers | `scw_project_id`, `scw_server_id`, `scw_flexible_ip_token`, `scw_flexible_ip_zone` | `inventory/scaleway.yml`, `roles/one-driver/defaults/main.yaml` |\n| OpenNebula credentials | `one_pass`, `one_version` | `inventory/scaleway.yml`, `.secret` |\n| VNM templates | `vn.pubridge.template.*`, `vn.vxlan.template.*` | `inventory/scaleway.yml` |\n| Validation knobs | `validation.*` | `inventory/group_vars/all.yml` |\n\n`inventory/group_vars/all.yml` also defines which cloud validation tests will be executed (core services, storage/network benchmarks, connectivity matrix, marketplace VM instantiation, etc.).\n\n## Networking Configuration\n\n- Cloud-init assets under `scw/004.opennebula_instances_net/template/` apply a deterministic netplan layout: `br0` for public/FIP traffic, `brvmtovm` for host-to-host VXLAN (`vmtovm` altname), and VLAN subinterfaces for private routing.\n- `cloud_init_custom.tmpl` hard-codes `enp5s0` as the bare-metal NIC and wires in Tofu outputs such as `base_public_ip`, `gateway`, `private_network_vlan_assignment`, `vmtovm_vlan_assignment`, and IPAM settings.\n- After provisioning, run an Ansible ping to verify reachability:\n\n```bash\nansible -i inventory/scaleway.yml all -m ping -b\n```\n\nRefer to `deployment_guide.md#5-inventory-validation-ansible` for expected output and troubleshooting tips (missing SSH key, mismatch between generated PEM and inventory, etc.).\n\n## OpenNebula Deployment Workflow\n\n1. Review custom roles and hooks (`roles/one-driver`, `playbooks/scaleway.yml`).\n2. Deploy the base OpenNebula stack (frontend, KVM nodes, shared configs):\n\n   ```bash\n   make deployment\n   ```\n\n3. Apply Scaleway-specific driver hooks and Flexible IP sync (`specifics` target invokes the `one-driver` role on frontend + nodes using the Hatch environment):\n\n   ```bash\n   make specifics\n   ```\n\n4. Run the validation suite:\n\n   ```bash\n   make validation\n   ```\n\nEach step is re-runnable; Ansible plays are idempotent and the Flexible IP hooks now cope with multi-NIC VMs (commit `a165376`).\n\n## Validation Suite\n\nThe defaults in `inventory/group_vars/all.yml` enable:\n\n- Core service health checks (`oned`, `gate`, `flow`, `fireedge`).\n- Storage benchmark VM instantiation on `pub3`.\n- Network benchmark between all hypervisors (iperf, ping).\n- Connectivity matrix across hosts and `brvmtovm`.\n- Marketplace VM deploy \u0026 smoke tests (Alpine Linux 3.21 template, optional VNET creation).\n\nDisable tests by setting the corresponding `validation.run_*` flag to `false`. Validation output is saved under `/tmp/cloud_verification_report.html` (and other paths documented in the file).\n\n## Troubleshooting \u0026 Known Issues\n\n- **Flexible IP attach/detach:** `roles/one-driver/templates/vnm/bridge/{pre,clean}.d` hooks log verbosely to `/var/log/vnm/scw-flexip-pre.log` (attach) and `/var/log/vnm/scw-flexip-clean.log` (detach). Inspect those files when a driver action stalls—the logs capture every API call/response. Recent fixes (`4399aed`, `a165376`) ensure bridges are cleaned when VMs mix public \u0026 private NICs. Re-run `make specifics` after updating scripts so hosts download the latest hooks.\n- **Ubuntu gateway for Flexible IPs:** When a Flexible IP lives outside the VM gateway netmask, Ubuntu does not auto-create the route after attaching the public NIC, so outbound traffic stalls. To persist the fix, drop a small netplan file and apply it (the alternative `ip route add` command disappears after reboot):\n\n  ```yaml\n  # /etc/netplan/99-flexip-route.yaml\n  network:\n    version: 2\n    renderer: networkd\n    ethernets:\n      eth0:\n        routes:\n          - to: \"62.210.0.1/32\"\n            via: 0.0.0.0\n  ```\n\n  Apply it with `sudo netplan apply`. The `ETH0_ROUTES` context setting remains broken by [OpenNebula/one-apps#284](https://github.com/OpenNebula/one-apps/issues/284) (VNET-independent `ROUTES`) and [OpenNebula/one#7348](https://github.com/OpenNebula/one/issues/7348) (`ETHx_ROUTES`), so codifying the route via netplan is the only reliable workaround today.\n- **Host synchronization:** The role runs `onehost sync --force` for each registered host. Inspect Ansible output if Sync fails; hosts remain operational but may use outdated hooks.\n- **Networking drift:** Re-apply module `004.opennebula_instances_net` or netplan templates if manual edits break VLAN alt-names or `brvmtovm` routes.\n- **Credentials:** Missing Flexible IP token (`scw_flexible_ip_token`) or project ID causes the driver role to abort early via assertions.\n\n## CI/CD Roadmap\n\n`deployment_guide.md#7-cicd-pipeline-wip` outlines a GitHub Actions pipeline (WIP) that would:\n\n1. Validate inputs (tokens, CIDRs, host IPs).\n2. Run `tofu init/plan`.\n3. Require manual approval for `tofu apply`.\n4. Configure Ansible, then manually trigger `one-deploy-validation`, `one-deploy`, and eventual `tofu destroy`.\n\nA reference Mermaid diagram is provided in the guide for future automation work.\n\n## Extending the Cloud\n\nTo onboard a new hypervisor:\n\n1. Rerun the provisioning modules (especially `003` and `004`) with an increased `TF_VAR_worker_count`.\n2. Regenerate inventories (`005`) and verify SSH access.\n3. Apply `make deployment` followed by `make specifics` so hooks and Flexible IP metadata land on the new host.\n4. Re-run validation to ensure the additional capacity integrates cleanly.\n\nFor deeper background, diagrams, and step-by-step screenshots, consult [deployment_guide.md](./deployment_guide.md).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopennebula%2Fhosted-cloud-scaleway","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fopennebula%2Fhosted-cloud-scaleway","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopennebula%2Fhosted-cloud-scaleway/lists"}