Skip to content

Commit 6569a37

Browse files
sjpbm-bull
andauthored
Define login nodes using an opentofu module (#547)
* define login nodes using tf module * Apply suggestions from code review Co-authored-by: Matt Anson <[email protected]> * tweak README to explain compute groups * try to clarify login/compute groups --------- Co-authored-by: Matt Anson <[email protected]>
1 parent 40665c0 commit 6569a37

File tree

11 files changed

+91
-76
lines changed

11 files changed

+91
-76
lines changed

README.md

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,14 +89,19 @@ Create an OpenTofu variables file to define the required infrastructure, e.g.:
8989
cluster_subnet = "some_subnet" # *
9090
key_pair = "my_key" # *
9191
control_node_flavor = "some_flavor_name"
92-
login_nodes = {
93-
login-0: "login_flavor_name"
92+
login = {
93+
# Arbitrary group name for these login nodes
94+
interactive = {
95+
nodes: ["login-0"]
96+
flavor: "login_flavor_name" # *
97+
}
9498
}
9599
cluster_image_id = "rocky_linux_9_image_uuid"
96100
compute = {
101+
# Group name used for compute node partition definition
97102
general = {
98103
nodes: ["compute-0", "compute-1"]
99-
flavor: "compute_flavor_name"
104+
flavor: "compute_flavor_name" # *
100105
}
101106
}
102107

environments/.stackhpc/tofu/main.tf

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,11 @@ module "cluster" {
7373
# are not in the same environment for stackhpc
7474
inventory_secrets_path = "${path.module}/../inventory/group_vars/all/secrets.yml"
7575

76-
login_nodes = {
77-
login-0: var.other_node_flavor
76+
login = {
77+
login: {
78+
nodes: ["login-0"]
79+
flavor: var.other_node_flavor
80+
}
7881
}
7982
compute = {
8083
standard: { # NB: can't call this default!

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
module "compute" {
2-
source = "./compute"
2+
source = "./node_group"
33

44
for_each = var.compute
55

environments/skeleton/{{cookiecutter.environment}}/tofu/nodes.tf renamed to environments/skeleton/{{cookiecutter.environment}}/tofu/control.tf

Lines changed: 0 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,6 @@ locals {
22
control_volumes = concat([openstack_blockstorage_volume_v3.state], var.home_volume_size > 0 ? [openstack_blockstorage_volume_v3.home][0] : [])
33
}
44

5-
resource "openstack_networking_port_v2" "login" {
6-
7-
for_each = var.login_nodes
8-
9-
name = "${var.cluster_name}-${each.key}"
10-
network_id = data.openstack_networking_network_v2.cluster_net.id
11-
admin_state_up = "true"
12-
13-
fixed_ip {
14-
subnet_id = data.openstack_networking_subnet_v2.cluster_subnet.id
15-
}
16-
17-
security_group_ids = [for o in data.openstack_networking_secgroup_v2.login: o.id]
18-
19-
binding {
20-
vnic_type = var.vnic_type
21-
profile = var.vnic_profile
22-
}
23-
}
24-
255
resource "openstack_networking_port_v2" "control" {
266

277
name = "${var.cluster_name}-control"
@@ -96,42 +76,3 @@ resource "openstack_compute_instance_v2" "control" {
9676
EOF
9777

9878
}
99-
100-
resource "openstack_compute_instance_v2" "login" {
101-
102-
for_each = var.login_nodes
103-
104-
name = "${var.cluster_name}-${each.key}"
105-
image_id = var.cluster_image_id
106-
flavor_name = each.value
107-
key_pair = var.key_pair
108-
109-
dynamic "block_device" {
110-
for_each = var.volume_backed_instances ? [1]: []
111-
content {
112-
uuid = var.cluster_image_id
113-
source_type = "image"
114-
destination_type = "volume"
115-
volume_size = var.root_volume_size
116-
boot_index = 0
117-
delete_on_termination = true
118-
}
119-
}
120-
121-
network {
122-
port = openstack_networking_port_v2.login[each.key].id
123-
access_network = true
124-
}
125-
126-
metadata = {
127-
environment_root = var.environment_root
128-
k3s_token = local.k3s_token
129-
control_address = [for n in openstack_compute_instance_v2.control["control"].network: n.fixed_ip_v4 if n.access_network][0]
130-
}
131-
132-
user_data = <<-EOF
133-
#cloud-config
134-
fqdn: ${var.cluster_name}-${each.key}.${var.cluster_name}.${var.cluster_domain_suffix}
135-
EOF
136-
137-
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ resource "local_file" "hosts" {
44
"cluster_name": var.cluster_name,
55
"cluster_domain_suffix": var.cluster_domain_suffix,
66
"control_instances": openstack_compute_instance_v2.control
7-
"login_instances": openstack_compute_instance_v2.login
7+
"login_groups": module.login
88
"compute_groups": module.compute
99
"state_dir": var.state_dir
1010
},

environments/skeleton/{{cookiecutter.environment}}/tofu/inventory.tpl

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,22 @@ control:
1313
vars:
1414
appliances_state_dir: ${state_dir} # NB needs to be set on group not host otherwise it is ignored in packer build!
1515

16-
login:
16+
17+
%{ for group_name in keys(login_groups) ~}
18+
${cluster_name}_${group_name}:
1719
hosts:
18-
%{ for login in login_instances ~}
19-
${ login.name }:
20-
ansible_host: ${[for n in login.network: n.fixed_ip_v4 if n.access_network][0]}
21-
instance_id: ${ login.id }
20+
%{ for node in login_groups[group_name]["compute_instances"] ~}
21+
${ node.name }:
22+
ansible_host: ${node.access_ip_v4}
23+
instance_id: ${ node.id }
24+
image_id: ${ node.image_id }
25+
%{ endfor ~}
26+
%{ endfor ~}
27+
28+
login:
29+
children:
30+
%{ for group_name in keys(login_groups) ~}
31+
${cluster_name}_${group_name}:
2232
%{ endfor ~}
2333

2434
%{ for group_name in keys(compute_groups) ~}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
module "login" {
2+
source = "./node_group"
3+
4+
for_each = var.login
5+
6+
# must be set for group:
7+
nodes = each.value.nodes
8+
flavor = each.value.flavor
9+
10+
cluster_name = var.cluster_name
11+
cluster_domain_suffix = var.cluster_domain_suffix
12+
cluster_net_id = data.openstack_networking_network_v2.cluster_net.id
13+
cluster_subnet_id = data.openstack_networking_subnet_v2.cluster_subnet.id
14+
15+
# can be set for group, defaults to top-level value:
16+
image_id = lookup(each.value, "image_id", var.cluster_image_id)
17+
vnic_type = lookup(each.value, "vnic_type", var.vnic_type)
18+
vnic_profile = lookup(each.value, "vnic_profile", var.vnic_profile)
19+
volume_backed_instances = lookup(each.value, "volume_backed_instances", var.volume_backed_instances)
20+
root_volume_size = lookup(each.value, "root_volume_size", var.root_volume_size)
21+
extra_volumes = lookup(each.value, "extra_volumes", {})
22+
23+
compute_init_enable = []
24+
ignore_image_changes = false
25+
26+
key_pair = var.key_pair
27+
environment_root = var.environment_root
28+
k3s_token = local.k3s_token
29+
control_address = [for n in openstack_compute_instance_v2.control["control"].network: n.fixed_ip_v4 if n.access_network][0]
30+
security_group_ids = [for o in data.openstack_networking_secgroup_v2.login: o.id]
31+
}

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

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,31 @@ variable "control_node_flavor" {
2929
description = "Flavor name for control name"
3030
}
3131

32-
variable "login_nodes" {
33-
type = map
34-
description = "Mapping defining login nodes: key -> (str) nodename suffix, value -> (str) flavor name"
32+
variable "login" {
33+
type = any
34+
description = <<-EOF
35+
Mapping defining homogenous groups of login nodes. Multiple groups may
36+
be useful for e.g. separating nodes for ssh and Open Ondemand usage, or
37+
to define login nodes with different capabilities such as high-memory.
38+
39+
Keys are names of groups.
40+
Values are a mapping as follows:
41+
42+
Required:
43+
nodes: List of node names
44+
flavor: String flavor name
45+
Optional:
46+
image_id: Overrides variable cluster_image_id
47+
vnic_type: Overrides variable vnic_type
48+
vnic_profile: Overrides variable vnic_profile
49+
volume_backed_instances: Overrides variable volume_backed_instances
50+
root_volume_size: Overrides variable root_volume_size
51+
extra_volumes: Mapping defining additional volumes to create and attach
52+
Keys are unique volume name.
53+
Values are a mapping with:
54+
size: Size of volume in GB
55+
**NB**: The order in /dev is not guaranteed to match the mapping
56+
EOF
3557
}
3658

3759
variable "cluster_image_id" {
@@ -42,8 +64,11 @@ variable "cluster_image_id" {
4264
variable "compute" {
4365
type = any
4466
description = <<-EOF
45-
Mapping defining compute infrastructure. Keys are names of groups. Values are a
46-
mapping as follows:
67+
Mapping defining homogenous groups of compute nodes. Groups are used
68+
in Slurm partition definitions.
69+
70+
Keys are names of groups.
71+
Values are a mapping as follows:
4772
4873
Required:
4974
nodes: List of node names

0 commit comments

Comments
 (0)