Skip to content

Commit 88aefed

Browse files
committed
Define compute groups in terraform via mapping
1 parent 7c6f48d commit 88aefed

File tree

11 files changed

+227
-156
lines changed

11 files changed

+227
-156
lines changed

environments/.stackhpc/terraform/main.tf

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ variable "cluster_name" {
2222
variable "os_version" {
2323
type = string
2424
description = "RL8 or RL9"
25+
default = "RL9"
2526
}
2627

2728
variable "cluster_image" {
@@ -58,6 +59,11 @@ variable "volume_backed_instances" {
5859
default = false
5960
}
6061

62+
data "openstack_images_image_v2" "cluster" {
63+
name = var.cluster_image[var.os_version]
64+
most_recent = true
65+
}
66+
6167
module "cluster" {
6268
source = "../../skeleton/{{cookiecutter.environment}}/terraform/"
6369

@@ -66,33 +72,24 @@ module "cluster" {
6672
cluster_subnet = var.cluster_subnet
6773
vnic_type = var.vnic_type
6874
key_pair = "slurm-app-ci"
69-
control_node = {
70-
flavor: var.control_node_flavor
71-
image: var.cluster_image[var.os_version]
72-
}
75+
cluster_image_id = data.openstack_images_image_v2.cluster.id
76+
control_node_flavor = var.control_node_flavor
77+
7378
login_nodes = {
74-
login-0: {
75-
flavor: var.other_node_flavor
76-
image: var.cluster_image[var.os_version]
77-
}
79+
login-0: var.other_node_flavor
7880
}
79-
compute_types = {
81+
compute = {
8082
standard: { # NB: can't call this default!
83+
nodes: ["compute-0", "compute-1"]
8184
flavor: var.other_node_flavor
82-
image: var.cluster_image[var.os_version]
8385
}
8486
# Example of how to add another partition:
8587
# extra: {
88+
# nodes: ["compute-2", "compute-3"]
8689
# flavor: var.other_node_flavor
87-
# image: var.cluster_image[var.os_version]
8890
# }
8991
}
90-
compute_nodes = {
91-
compute-0: "standard"
92-
compute-1: "standard"
93-
# compute-2: "extra"
94-
# compute-3: "extra"
95-
}
92+
9693
volume_backed_instances = var.volume_backed_instances
9794

9895
environment_root = var.environment_root

environments/skeleton/{{cookiecutter.environment}}/terraform/.gitignore

Lines changed: 0 additions & 1 deletion
This file was deleted.
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
module "compute" {
2+
source = "./compute"
3+
4+
for_each = var.compute
5+
6+
nodes = each.value.nodes
7+
cluster_name = var.cluster_name
8+
cluster_domain_suffix = var.cluster_domain_suffix
9+
cluster_net_id = data.openstack_networking_network_v2.cluster_net.id
10+
cluster_subnet_id = data.openstack_networking_subnet_v2.cluster_subnet.id
11+
12+
flavor = each.value.flavor
13+
image_id = lookup(each.value, "image_id", var.cluster_image_id)
14+
vnic_type = lookup(each.value, "vnic_type", var.vnic_type)
15+
vnic_profile = lookup(each.value, "vnic_profile", var.vnic_profile)
16+
key_pair = var.key_pair
17+
environment_root = var.environment_root
18+
security_group_ids = [for o in data.openstack_networking_secgroup_v2.nonlogin: o.id]
19+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
resource "openstack_networking_port_v2" "compute" {
2+
3+
for_each = toset(var.nodes)
4+
5+
name = "${var.cluster_name}-${each.key}"
6+
network_id = var.cluster_net_id
7+
admin_state_up = "true"
8+
9+
fixed_ip {
10+
subnet_id = var.cluster_subnet_id
11+
}
12+
13+
security_group_ids = var.security_group_ids
14+
15+
binding {
16+
vnic_type = var.vnic_type
17+
profile = var.vnic_profile
18+
}
19+
}
20+
21+
resource "openstack_compute_instance_v2" "compute" {
22+
23+
for_each = toset(var.nodes)
24+
25+
name = "${var.cluster_name}-${each.key}"
26+
image_id = var.image_id
27+
flavor_name = var.flavor
28+
key_pair = var.key_pair
29+
30+
dynamic "block_device" {
31+
for_each = var.volume_backed_instances ? [1]: []
32+
content {
33+
uuid = var.image_id
34+
source_type = "image"
35+
destination_type = "volume"
36+
volume_size = var.root_volume_size
37+
boot_index = 0
38+
delete_on_termination = true
39+
}
40+
}
41+
42+
network {
43+
port = openstack_networking_port_v2.compute[each.key].id
44+
access_network = true
45+
}
46+
47+
metadata = {
48+
environment_root = var.environment_root
49+
}
50+
51+
user_data = <<-EOF
52+
#cloud-config
53+
fqdn: ${var.cluster_name}-${each.key}.${var.cluster_name}.${var.cluster_domain_suffix}
54+
EOF
55+
56+
}
57+
58+
output "compute_instances" {
59+
value = openstack_compute_instance_v2.compute
60+
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
variable "nodes" {
2+
type = list(string)
3+
description = "list of node names for partition"
4+
}
5+
6+
variable "flavor" {
7+
type = string
8+
description = "Name of flavor for partition"
9+
}
10+
11+
variable "cluster_name" {
12+
type = string
13+
}
14+
15+
variable "cluster_domain_suffix" {
16+
type = string
17+
default = "invalid"
18+
}
19+
20+
variable "cluster_net_id" {
21+
type = string
22+
}
23+
24+
variable "cluster_subnet_id" {
25+
type = string
26+
}
27+
28+
variable "key_pair" {
29+
type = string
30+
description = "Name of an existing keypair in OpenStack"
31+
}
32+
33+
variable "image_id" {
34+
type = string
35+
description = "ID of image for the partition"
36+
}
37+
38+
variable "environment_root" {
39+
type = string
40+
description = "Path to environment root, automatically set by activate script"
41+
}
42+
43+
variable "vnic_type" {
44+
type = string
45+
description = "VNIC type, see https://registry.terraform.io/providers/terraform-provider-openstack/openstack/latest/docs/resources/networking_port_v2#vnic_type"
46+
default = "normal"
47+
}
48+
49+
variable "vnic_profile" {
50+
type = string
51+
description = "VNIC binding profile as json string, see https://registry.terraform.io/providers/terraform-provider-openstack/openstack/latest/docs/resources/networking_port_v2#profile."
52+
default = "{}"
53+
}
54+
55+
variable "volume_backed_instances" {
56+
description = "Whether to use volumes for root disks"
57+
type = bool
58+
default = false
59+
}
60+
61+
variable "root_volume_size" {
62+
description = "Size of volume for root volumes if using volume backed instances, in Gb"
63+
type = number
64+
default = 40
65+
}
66+
67+
variable "security_group_ids" {
68+
type = list
69+
}

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

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,16 @@ resource "local_file" "hosts" {
55
"cluster_domain_suffix": var.cluster_domain_suffix,
66
"control_instances": openstack_compute_instance_v2.control
77
"login_instances": openstack_compute_instance_v2.login
8-
"compute_instances": openstack_compute_instance_v2.compute
9-
"state_dir": var.state_dir,
10-
"compute_types": var.compute_types,
11-
"compute_nodes": var.compute_nodes,
8+
"compute_groups": module.compute
129
},
1310
)
14-
filename = "../inventory/hosts"
11+
filename = "../inventory/hosts.yml"
1512
}
1613

1714
resource "local_file" "partitions" {
1815
content = templatefile("${path.module}/partitions.tpl",
1916
{
20-
"compute_types": var.compute_types,
17+
"compute_groups": module.compute,
2118
},
2219
)
2320
filename = "../inventory/group_vars/all/partitions.yml" # as all/ is created by skeleton
Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,36 @@
1-
[all:vars]
2-
openhpc_cluster_name=${cluster_name}
3-
cluster_domain_suffix=${cluster_domain_suffix}
1+
all:
2+
vars:
3+
openhpc_cluster_name: ${cluster_name}
4+
cluster_domain_suffix: ${cluster_domain_suffix}
45

5-
[control]
6+
control:
7+
hosts:
68
%{ for control in control_instances ~}
7-
${ control.name } ansible_host=${[for n in control.network: n.fixed_ip_v4 if n.access_network][0]} node_fqdn=${ control.name }.${cluster_name}.${cluster_domain_suffix}
9+
${ control.name }:
10+
ansible_host: ${[for n in control.network: n.fixed_ip_v4 if n.access_network][0]}
11+
instance_id: ${ control.id }
812
%{ endfor ~}
913

10-
[control:vars]
11-
# NB needs to be set on group not host otherwise it is ignored in packer build!
12-
appliances_state_dir=${state_dir}
13-
14-
[login]
14+
login:
15+
hosts:
1516
%{ for login in login_instances ~}
16-
${ login.name } ansible_host=${[for n in login.network: n.fixed_ip_v4 if n.access_network][0]} node_fqdn=${ login.name }.${cluster_name}.${cluster_domain_suffix}
17+
${ login.name }:
18+
ansible_host: ${[for n in login.network: n.fixed_ip_v4 if n.access_network][0]}
19+
instance_id: ${ login.id }
1720
%{ endfor ~}
1821

19-
[compute]
20-
%{ for compute in compute_instances ~}
21-
${ compute.name } ansible_host=${[for n in compute.network: n.fixed_ip_v4 if n.access_network][0]} node_fqdn=${ compute.name }.${cluster_name}.${cluster_domain_suffix}
22+
%{ for group_name in keys(compute_groups) ~}
23+
${cluster_name}_${group_name}:
24+
hosts:
25+
%{ for node in compute_groups[group_name]["compute_instances"] ~}
26+
${ node.name }:
27+
ansible_host: ${node.access_ip_v4}
28+
instance_id: ${ node.id }
29+
%{ endfor ~}
2230
%{ endfor ~}
2331

24-
# Define groups for slurm parititions:
25-
%{~ for type_name, type_descr in compute_types}
26-
[${cluster_name}_${type_name}]
27-
%{~ for node_name, node_type in compute_nodes ~}
28-
%{~ if node_type == type_name ~}
29-
${ compute_instances[node_name].name }
30-
%{~ endif ~}
31-
%{~ endfor ~}
32+
compute:
33+
children:
34+
%{ for group_name in keys(compute_groups) ~}
35+
${cluster_name}_${group_name}:
3236
%{ endfor ~}

0 commit comments

Comments
 (0)