Implement reproducible S1 handoff contracts
Assistant: codex Assistant-Model: gpt-5.6-sol Assistant-Session: 01a02994-7685-7940-bf34-3555b8256018
This commit is contained in:
parent
c8cb1c8edf
commit
b93af8cc78
44 changed files with 2035 additions and 342 deletions
53
terraform/hetzner/inventory_selection.tftest.hcl
Normal file
53
terraform/hetzner/inventory_selection.tftest.hcl
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
mock_provider "hcloud" {}
|
||||
mock_provider "template" {}
|
||||
|
||||
run "adopted_host_is_not_managed" {
|
||||
command = plan
|
||||
|
||||
variables {
|
||||
hcloud_token = "fixture-not-a-credential"
|
||||
inventory_yaml = <<-YAML
|
||||
schema_version: "1.0"
|
||||
servers:
|
||||
- name: adopted-host
|
||||
provider: hosteurope
|
||||
lifecycle_mode: adopted
|
||||
ip: 192.0.2.10
|
||||
ssh_user: admin
|
||||
baseline_profile: ufw-managed
|
||||
YAML
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = length(output.managed_server_names) == 0
|
||||
error_message = "adopted Host Europe records must not select Hetzner resources"
|
||||
}
|
||||
}
|
||||
|
||||
run "managed_hetzner_host_is_selected" {
|
||||
command = plan
|
||||
|
||||
variables {
|
||||
hcloud_token = "fixture-not-a-credential"
|
||||
inventory_yaml = <<-YAML
|
||||
schema_version: "1.0"
|
||||
servers:
|
||||
- name: fixture-hetzner-01
|
||||
provider: hetzner
|
||||
lifecycle_mode: provider-managed
|
||||
ssh_user: admin
|
||||
baseline_profile: ufw-managed
|
||||
provisioning:
|
||||
server_type: cpx21
|
||||
region: nbg1
|
||||
image: ubuntu-24.04
|
||||
role: fixture
|
||||
labels: [test]
|
||||
YAML
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = length(output.managed_server_names) == 1 && output.managed_server_names[0] == "fixture-hetzner-01"
|
||||
error_message = "provider-managed Hetzner records must be selected"
|
||||
}
|
||||
}
|
||||
|
|
@ -17,27 +17,32 @@ provider "hcloud" {
|
|||
}
|
||||
|
||||
locals {
|
||||
servers = yamldecode(file("${path.module}/../../inventory/servers.yaml")).servers
|
||||
inventory = yamldecode(var.inventory_yaml != null ? var.inventory_yaml : file("${path.module}/../../inventory/servers.yaml"))
|
||||
servers = {
|
||||
for server in local.inventory.servers : server.name => server
|
||||
if server.provider == "hetzner" && server.lifecycle_mode == "provider-managed"
|
||||
}
|
||||
cloud_init = file("${path.module}/cloud_init.yaml")
|
||||
}
|
||||
|
||||
resource "hcloud_ssh_key" "admin" {
|
||||
count = length(local.servers) > 0 ? 1 : 0
|
||||
name = "railliance-admin"
|
||||
public_key = file("${path.module}/../../keys/admin_ssh.pub")
|
||||
}
|
||||
|
||||
resource "hcloud_server" "srv" {
|
||||
for_each = { for s in local.servers : s.name => s }
|
||||
for_each = local.servers
|
||||
name = each.value.name
|
||||
image = coalesce(each.value.image, "ubuntu-24.04")
|
||||
server_type = each.value.type
|
||||
location = each.value.region
|
||||
ssh_keys = [hcloud_ssh_key.admin.id]
|
||||
image = each.value.provisioning.image
|
||||
server_type = each.value.provisioning.server_type
|
||||
location = each.value.provisioning.region
|
||||
ssh_keys = [hcloud_ssh_key.admin[0].id]
|
||||
user_data = local.cloud_init
|
||||
|
||||
labels = {
|
||||
role = each.value.role
|
||||
labels = join(",", try(each.value.labels, []))
|
||||
role = each.value.provisioning.role
|
||||
labels = join(",", try(each.value.provisioning.labels, []))
|
||||
env = "default"
|
||||
}
|
||||
}
|
||||
|
|
@ -45,3 +50,7 @@ resource "hcloud_server" "srv" {
|
|||
output "servers" {
|
||||
value = { for k, v in hcloud_server.srv : k => v.ipv4_address }
|
||||
}
|
||||
|
||||
output "managed_server_names" {
|
||||
value = sort(keys(local.servers))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,3 +3,9 @@ variable "hcloud_token" {
|
|||
type = string
|
||||
sensitive = true
|
||||
}
|
||||
|
||||
variable "inventory_yaml" {
|
||||
description = "Optional inventory YAML for isolated tests; normal runs use inventory/servers.yaml"
|
||||
type = string
|
||||
default = null
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue