Skip to content

Commit f276fb6

Browse files
authored
Support mapping compute & login instances to Ironic nodes (#573)
* WIP - fails on data source * swap to python baremetal node data
1 parent ea6e756 commit f276fb6

File tree

7 files changed

+81
-10
lines changed

7 files changed

+81
-10
lines changed
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#!/usr/bin/env python
2+
""" opentofu external data program to list baremetal nodes
3+
4+
Example usage:
5+
6+
data "external" "example" {
7+
program = [this_file]
8+
}
9+
10+
The external data resource's result attribute then contains a mapping of
11+
Ironic node names to their UUIDs.
12+
13+
An empty list is returned if:
14+
- There are no baremetal nodes
15+
- The listing fails for any reason, e.g.
16+
- there is no baremetal service
17+
- admin credentials are required and are not provided
18+
"""
19+
20+
import openstack
21+
import json
22+
23+
nodes = []
24+
proxy = None
25+
output = {}
26+
conn = openstack.connection.from_config()
27+
try:
28+
proxy = getattr(conn, 'baremetal', None)
29+
except Exception:
30+
pass
31+
if proxy is not None:
32+
nodes = proxy.nodes()
33+
for node in nodes:
34+
output[node.name] = node.id
35+
print(json.dumps(output))

environments/skeleton/{{cookiecutter.environment}}/tofu/compute.tf

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,19 @@ module "compute" {
2020
volume_backed_instances = lookup(each.value, "volume_backed_instances", var.volume_backed_instances)
2121
root_volume_size = lookup(each.value, "root_volume_size", var.root_volume_size)
2222

23-
# optionally set for group
23+
# optionally set for group:
2424
networks = concat(var.cluster_networks, lookup(each.value, "extra_networks", []))
2525
extra_volumes = lookup(each.value, "extra_volumes", {})
2626
compute_init_enable = lookup(each.value, "compute_init_enable", [])
2727
ignore_image_changes = lookup(each.value, "ignore_image_changes", false)
28+
match_ironic_node = lookup(each.value, "match_ironic_node", false)
29+
availability_zone = lookup(each.value, "availability_zone", "nova")
2830

2931
# computed
3032
k3s_token = local.k3s_token
3133
# not using openstack_compute_instance_v2.control.access_ip_v4 to avoid
3234
# updates to node metadata on deletion/recreation of the control node:
3335
control_address = openstack_networking_port_v2.control[var.cluster_networks[0].network].all_fixed_ips[0]
3436
security_group_ids = [for o in data.openstack_networking_secgroup_v2.nonlogin: o.id]
37+
baremetal_nodes = data.external.baremetal_nodes.result
3538
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
data "external" "inventory_secrets" {
2+
program = ["${path.module}/read-inventory-secrets.py"]
3+
4+
query = {
5+
path = var.inventory_secrets_path == "" ? "${path.module}/../inventory/group_vars/all/secrets.yml" : var.inventory_secrets_path
6+
}
7+
}
8+
9+
data "external" "baremetal_nodes" {
10+
# returns an empty map if cannot list baremetal nodes
11+
program = ["${path.module}/baremetal-node-list.py"]
12+
query = {}
13+
}

environments/skeleton/{{cookiecutter.environment}}/tofu/login.tf

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ module "login" {
2525
extra_volumes = lookup(each.value, "extra_volumes", {})
2626
fip_addresses = lookup(each.value, "fip_addresses", [])
2727
fip_network = lookup(each.value, "fip_network", "")
28+
match_ironic_node = lookup(each.value, "match_ironic_node", false)
29+
availability_zone = lookup(each.value, "availability_zone", "nova")
2830

2931
# can't be set for login
3032
compute_init_enable = []
@@ -36,4 +38,5 @@ module "login" {
3638
# updates to node metadata on deletion/recreation of the control node:
3739
control_address = openstack_networking_port_v2.control[var.cluster_networks[0].network].all_fixed_ips[0]
3840
security_group_ids = [for o in data.openstack_networking_secgroup_v2.login: o.id]
41+
baremetal_nodes = data.external.baremetal_nodes.result
3942
}

environments/skeleton/{{cookiecutter.environment}}/tofu/node_group/nodes.tf

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,8 @@ resource "openstack_compute_instance_v2" "compute_fixed_image" {
9797
fqdn: ${var.cluster_name}-${each.key}.${var.cluster_name}.${var.cluster_domain_suffix}
9898
EOF
9999

100+
availability_zone = var.match_ironic_node ? "${var.availability_zone}::${var.baremetal_nodes[each.key]}" : null
101+
100102
lifecycle {
101103
ignore_changes = [
102104
image_id,
@@ -140,7 +142,7 @@ resource "openstack_compute_instance_v2" "compute" {
140142
k3s_token = var.k3s_token
141143
control_address = var.control_address
142144
access_ip = openstack_networking_port_v2.compute["${each.key}-${var.networks[0].network}"].all_fixed_ips[0]
143-
},
145+
},
144146
{for e in var.compute_init_enable: e => true}
145147
)
146148

@@ -149,6 +151,8 @@ resource "openstack_compute_instance_v2" "compute" {
149151
fqdn: ${var.cluster_name}-${each.key}.${var.cluster_name}.${var.cluster_domain_suffix}
150152
EOF
151153

154+
availability_zone = var.match_ironic_node ? "${var.availability_zone}::${var.baremetal_nodes[each.key]}" : null
155+
152156
}
153157

154158
resource "openstack_networking_floatingip_associate_v2" "fip" {

environments/skeleton/{{cookiecutter.environment}}/tofu/node_group/variables.tf

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,3 +114,20 @@ variable "fip_network" {
114114
EOT
115115
default = ""
116116
}
117+
118+
variable "match_ironic_node" {
119+
type = bool
120+
description = "Whether to launch instances on the Ironic node of the same name as each cluster node"
121+
default = false
122+
}
123+
124+
variable "availability_zone" {
125+
type = string
126+
description = "Name of availability zone - ignored unless match_ironic_node is true"
127+
default = "nova"
128+
}
129+
130+
variable "baremetal_nodes" {
131+
type = map(string)
132+
default = {}
133+
}

environments/skeleton/{{cookiecutter.environment}}/tofu/variables.tf

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ variable "login" {
5959
fip_network: Name of network containing ports to attach FIPs to. Only
6060
required if multiple networks are defined.
6161
62+
match_ironic_node: Set true to launch instances on the Ironic node of the same name as each cluster node
63+
availability_zone: Name of availability zone - ignored unless match_ironic_node is true (default: "nova")
6264
EOF
6365
}
6466

@@ -93,6 +95,8 @@ variable "compute" {
9395
Values are a mapping with:
9496
size: Size of volume in GB
9597
**NB**: The order in /dev is not guaranteed to match the mapping
98+
match_ironic_node: Set true to launch instances on the Ironic node of the same name as each cluster node
99+
availability_zone: Name of availability zone - ignored unless match_ironic_node is true (default: "nova")
96100
EOF
97101
}
98102

@@ -186,14 +190,6 @@ variable "inventory_secrets_path" {
186190
default = ""
187191
}
188192

189-
data "external" "inventory_secrets" {
190-
program = ["${path.module}/read-inventory-secrets.py"]
191-
192-
query = {
193-
path = var.inventory_secrets_path == "" ? "${path.module}/../inventory/group_vars/all/secrets.yml" : var.inventory_secrets_path
194-
}
195-
}
196-
197193
locals {
198194
k3s_token = data.external.inventory_secrets.result["vault_k3s_token"]
199195
}

0 commit comments

Comments
 (0)