// Consumer and management credentials are generated here, never injected by // the backend. The consumer password opens SSH on the head node only (the // single entry point); the management keypair opens every node. The Vault // layout follows the existing contract: // secret/{provider}/{cloud_account}/{requester_unique_id}/{username} password + head node access // secret/{provider}/{cloud_account}/{requester_unique_id}/admin ssh keypair + admin username // Only the Vault path of the consumer entry is exposed as an output. resource "random_bytes" "munge_key" { length = 128 } resource "tls_private_key" "admin" { algorithm = "ED25519" } // Regenerated whenever the rotation marker changes; the special set avoids // shell quoting issues in the password application command. resource "random_password" "consumer" { length = 24 special = true override_special = "-_=+" keepers = { rotation = var.credentials_version } } // Applies the consumer password on the head node, on day 0 and on every // rotation. The password never travels through user data, so a rotation // 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. // 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 = { rotation = var.credentials_version head_node = ovh_cloud_project_instance.head.id } connection { type = "ssh" host = local.head_public_ip user = var.admin_username private_key = tls_private_key.admin.private_key_openssh timeout = "15m" } provisioner "remote-exec" { inline = [ "cloud-init status --wait > /dev/null || true", "echo '${var.username}:${random_password.consumer.result}' | sudo chpasswd", ] } depends_on = [ovh_cloud_project_instance.head] } resource "vault_kv_secret_v2" "consumer" { mount = "secret" name = "ovh/${var.cloud_account}/${var.requester_unique_id}/${var.username}" data_json = jsonencode({ username = var.username password = random_password.consumer.result host = local.head_public_ip port = 22 }) depends_on = [null_resource.consumer_password] } resource "vault_kv_secret_v2" "admin" { mount = "secret" name = "ovh/${var.cloud_account}/${var.requester_unique_id}/admin" data_json = jsonencode({ username = var.admin_username ssh_private_key = tls_private_key.admin.private_key_openssh ssh_public_key = trimspace(tls_private_key.admin.public_key_openssh) }) }