From 09cc7b38e06bce38842dfd949e6bf40fc8dbe00c Mon Sep 17 00:00:00 2001 From: gitops_test Date: Thu, 8 Oct 2026 16:15:41 +0000 Subject: [PATCH] sync-modules: mirrored modules of release 3.3.0-F-feature-simpl-33565.773.825d7dcb +++ hpc/README.md +++ hpc/ovh/credentials.tf +++ hpc/ovh/main.tf +++ hpc/ovh/versions.tf --- hpc/README.md | 2 +- hpc/ovh/credentials.tf | 11 ++++++++--- hpc/ovh/main.tf | 33 +++++++++++++++++++++++---------- hpc/ovh/versions.tf | 4 ++++ 4 files changed, 36 insertions(+), 14 deletions(-) diff --git a/hpc/README.md b/hpc/README.md index 9afbcc8..9be97dc 100644 --- a/hpc/README.md +++ b/hpc/README.md @@ -16,7 +16,7 @@ Provisions an HPC cluster and generates the consumer access credentials. One sub | `credentials_version` | Opaque rotation marker for the consumer credential, defaults to `1`. Changing the value regenerates the consumer password, applies it on the head node over SSH and republishes the fresh credential to Vault in the same apply, without touching any instance. Managed by the credential renewal workflow, not by the deployment script author | | `name_prefix` | Prefix for resource names, defaults to `simpl` | | `region` | OVH region for the instances and the private network, for example SBG5 | -| `project_id` | Optional override of the OVH project; by default the provider resolves it from the `OVH_CLOUD_PROJECT_SERVICE` variable of the runner environment, which the provisioner derives from the `OVH_PROJECT_ID` key of the cloud account configuration | +| `project_id` | OVH project id. Unlike the other catalog modules this one effectively needs it: its flavors/images/floatingips data sources require an explicit service_name (no `OVH_CLOUD_PROJECT_SERVICE` fallback for an explicit null). When omitted, the module falls back to resolving the project from the credential (`ovh_cloud_projects`), which only works if the account API key is granted `GET /cloud/project`; the current platform account keys are not, so either pass the value in the deployment script or add that read grant when creating account keys | | `compute_node_count` | Number of compute nodes, defaults to 2 | | `head_flavor`, `compute_flavor` | Instance flavors per role, default `b3-8` | | `compute_cpus` | Schedulable CPUs per compute node declared to the Slurm controller, must not exceed the vCPUs of `compute_flavor`, defaults to 2 | diff --git a/hpc/ovh/credentials.tf b/hpc/ovh/credentials.tf index 09d2206..3de9fce 100644 --- a/hpc/ovh/credentials.tf +++ b/hpc/ovh/credentials.tf @@ -31,11 +31,16 @@ resource "random_password" "consumer" { // never touches the instances: this resource is replaced (triggered by the // rotation marker), re-runs chpasswd over SSH with the management key, and // the Vault entry below is updated in the same apply. -resource "terraform_data" "consumer_password" { +// null_resource instead of terraform_data: the tofu-controller runner ships a +// Terraform older than 1.4, which has no terraform_data built-in. +resource "null_resource" "consumer_password" { // Re-applied on rotation AND whenever the head node is recreated: a fresh // instance boots without the consumer password (it never travels through // user data). - triggers_replace = [var.credentials_version, ovh_cloud_project_instance.head.id] + triggers = { + rotation = var.credentials_version + head_node = ovh_cloud_project_instance.head.id + } connection { type = "ssh" @@ -65,7 +70,7 @@ resource "vault_kv_secret_v2" "consumer" { port = 22 }) - depends_on = [terraform_data.consumer_password] + depends_on = [null_resource.consumer_password] } resource "vault_kv_secret_v2" "admin" { diff --git a/hpc/ovh/main.tf b/hpc/ovh/main.tf index 08ad93a..e3f37ca 100644 --- a/hpc/ovh/main.tf +++ b/hpc/ovh/main.tf @@ -4,20 +4,33 @@ // credentials and the project (OVH_CLOUD_PROJECT_SERVICE) reach the provider // from the runner environment, never from module inputs. +// The flavors/images data sources require an explicit service_name (unlike +// the resources, they do not fall back to the OVH_CLOUD_PROJECT_SERVICE +// runner variable when the attribute is an explicit null), so the project is +// resolved from the credential itself when no override is given: the +// per-account API keys of the platform are scoped to a single project. +data "ovh_cloud_projects" "all" { + count = var.project_id == null ? 1 : 0 +} + +locals { + service_name = var.project_id != null ? var.project_id : one(data.ovh_cloud_projects.all[0].projects[*].project_id) +} + data "ovh_cloud_project_flavors" "head" { - service_name = var.project_id + service_name = local.service_name name_filter = var.head_flavor region = var.region } data "ovh_cloud_project_flavors" "compute" { - service_name = var.project_id + service_name = local.service_name name_filter = var.compute_flavor region = var.region } data "ovh_cloud_project_images" "all" { - service_name = var.project_id + service_name = local.service_name region = var.region } @@ -37,14 +50,14 @@ locals { // assigned outside the DHCP pool; DHCP stays enabled so the instances // configure their private interface from the OpenStack metadata. resource "ovh_cloud_project_network_private" "cluster" { - service_name = var.project_id + service_name = local.service_name name = "${var.name_prefix}-hpc-${var.deployment_id}" regions = [var.region] vlan_id = var.vlan_id } resource "ovh_cloud_project_network_private_subnet" "cluster" { - service_name = var.project_id + service_name = local.service_name network_id = ovh_cloud_project_network_private.cluster.id region = var.region network = var.cluster_cidr @@ -69,7 +82,7 @@ locals { // through a dual-homed head node is not an option: the cloud's port // anti-spoofing silently drops the forwarded return traffic. resource "ovh_cloud_project_gateway" "egress" { - service_name = var.project_id + service_name = local.service_name name = "${var.name_prefix}-hpc-gw-${var.deployment_id}" model = var.gateway_model region = var.region @@ -81,13 +94,13 @@ resource "ovh_cloud_project_gateway" "egress" { // on destroy. The instance level ssh_key_create is avoided on purpose: keys it // creates outlive the instance and collide on the next deployment. resource "ovh_cloud_project_ssh_key" "admin" { - service_name = var.project_id + service_name = local.service_name name = "${var.name_prefix}-${var.deployment_id}-key" public_key = trimspace(tls_private_key.admin.public_key_openssh) } resource "ovh_cloud_project_instance" "head" { - service_name = var.project_id + service_name = local.service_name region = var.region billing_period = "hourly" name = local.head_hostname @@ -133,7 +146,7 @@ resource "ovh_cloud_project_instance" "head" { // addresses only carry the fixed private ip, the floating ip is matched // through the port it is associated with. data "ovh_cloud_project_floatingips" "all" { - service_name = var.project_id + service_name = local.service_name region_name = var.region depends_on = [ovh_cloud_project_instance.head] @@ -141,7 +154,7 @@ data "ovh_cloud_project_floatingips" "all" { resource "ovh_cloud_project_instance" "compute" { count = var.compute_node_count - service_name = var.project_id + service_name = local.service_name region = var.region billing_period = "hourly" name = local.compute_hostnames[count.index] diff --git a/hpc/ovh/versions.tf b/hpc/ovh/versions.tf index 7b1ad18..46bdbe7 100644 --- a/hpc/ovh/versions.tf +++ b/hpc/ovh/versions.tf @@ -16,6 +16,10 @@ terraform { source = "hashicorp/tls" version = "4.0.6" } + null = { + source = "hashicorp/null" + version = "3.2.4" + } cloudinit = { source = "hashicorp/cloudinit" version = "2.3.7"