From 0c9d7224537b8e4fcdfccfeafafca9ecfa022054 Mon Sep 17 00:00:00 2001
From: David Visscher <d.j.visscher@rug.nl>
Date: Tue, 25 Mar 2025 08:47:12 +0100
Subject: [PATCH 01/43] Move local_libvirt terraform to its own directory

---
 terraform/{ => local_libvirt}/cephmon.tf                      | 0
 terraform/{ => local_libvirt}/cephosd.tf                      | 0
 terraform/{ => local_libvirt}/cloud_init/meta_data.tftpl      | 0
 terraform/{ => local_libvirt}/cloud_init/network_config.tftpl | 0
 terraform/{ => local_libvirt}/cloud_init/user_data.tftpl      | 0
 terraform/{ => local_libvirt}/cloudinit.tf                    | 0
 terraform/{ => local_libvirt}/compute.tf                      | 0
 terraform/{ => local_libvirt}/controller.tf                   | 0
 terraform/{ => local_libvirt}/database.tf                     | 0
 terraform/{ => local_libvirt}/graph.svg                       | 0
 terraform/{ => local_libvirt}/monitor.tf                      | 0
 terraform/{ => local_libvirt}/network.tf                      | 0
 terraform/{ => local_libvirt}/networker.tf                    | 0
 terraform/{ => local_libvirt}/salt.tf                         | 0
 terraform/{ => local_libvirt}/scripts/.gitkeep                | 0
 terraform/{ => local_libvirt}/serviceproxy.tf                 | 0
 terraform/{ => local_libvirt}/terraform.tf                    | 0
 17 files changed, 0 insertions(+), 0 deletions(-)
 rename terraform/{ => local_libvirt}/cephmon.tf (100%)
 rename terraform/{ => local_libvirt}/cephosd.tf (100%)
 rename terraform/{ => local_libvirt}/cloud_init/meta_data.tftpl (100%)
 rename terraform/{ => local_libvirt}/cloud_init/network_config.tftpl (100%)
 rename terraform/{ => local_libvirt}/cloud_init/user_data.tftpl (100%)
 rename terraform/{ => local_libvirt}/cloudinit.tf (100%)
 rename terraform/{ => local_libvirt}/compute.tf (100%)
 rename terraform/{ => local_libvirt}/controller.tf (100%)
 rename terraform/{ => local_libvirt}/database.tf (100%)
 rename terraform/{ => local_libvirt}/graph.svg (100%)
 rename terraform/{ => local_libvirt}/monitor.tf (100%)
 rename terraform/{ => local_libvirt}/network.tf (100%)
 rename terraform/{ => local_libvirt}/networker.tf (100%)
 rename terraform/{ => local_libvirt}/salt.tf (100%)
 rename terraform/{ => local_libvirt}/scripts/.gitkeep (100%)
 rename terraform/{ => local_libvirt}/serviceproxy.tf (100%)
 rename terraform/{ => local_libvirt}/terraform.tf (100%)

diff --git a/terraform/cephmon.tf b/terraform/local_libvirt/cephmon.tf
similarity index 100%
rename from terraform/cephmon.tf
rename to terraform/local_libvirt/cephmon.tf
diff --git a/terraform/cephosd.tf b/terraform/local_libvirt/cephosd.tf
similarity index 100%
rename from terraform/cephosd.tf
rename to terraform/local_libvirt/cephosd.tf
diff --git a/terraform/cloud_init/meta_data.tftpl b/terraform/local_libvirt/cloud_init/meta_data.tftpl
similarity index 100%
rename from terraform/cloud_init/meta_data.tftpl
rename to terraform/local_libvirt/cloud_init/meta_data.tftpl
diff --git a/terraform/cloud_init/network_config.tftpl b/terraform/local_libvirt/cloud_init/network_config.tftpl
similarity index 100%
rename from terraform/cloud_init/network_config.tftpl
rename to terraform/local_libvirt/cloud_init/network_config.tftpl
diff --git a/terraform/cloud_init/user_data.tftpl b/terraform/local_libvirt/cloud_init/user_data.tftpl
similarity index 100%
rename from terraform/cloud_init/user_data.tftpl
rename to terraform/local_libvirt/cloud_init/user_data.tftpl
diff --git a/terraform/cloudinit.tf b/terraform/local_libvirt/cloudinit.tf
similarity index 100%
rename from terraform/cloudinit.tf
rename to terraform/local_libvirt/cloudinit.tf
diff --git a/terraform/compute.tf b/terraform/local_libvirt/compute.tf
similarity index 100%
rename from terraform/compute.tf
rename to terraform/local_libvirt/compute.tf
diff --git a/terraform/controller.tf b/terraform/local_libvirt/controller.tf
similarity index 100%
rename from terraform/controller.tf
rename to terraform/local_libvirt/controller.tf
diff --git a/terraform/database.tf b/terraform/local_libvirt/database.tf
similarity index 100%
rename from terraform/database.tf
rename to terraform/local_libvirt/database.tf
diff --git a/terraform/graph.svg b/terraform/local_libvirt/graph.svg
similarity index 100%
rename from terraform/graph.svg
rename to terraform/local_libvirt/graph.svg
diff --git a/terraform/monitor.tf b/terraform/local_libvirt/monitor.tf
similarity index 100%
rename from terraform/monitor.tf
rename to terraform/local_libvirt/monitor.tf
diff --git a/terraform/network.tf b/terraform/local_libvirt/network.tf
similarity index 100%
rename from terraform/network.tf
rename to terraform/local_libvirt/network.tf
diff --git a/terraform/networker.tf b/terraform/local_libvirt/networker.tf
similarity index 100%
rename from terraform/networker.tf
rename to terraform/local_libvirt/networker.tf
diff --git a/terraform/salt.tf b/terraform/local_libvirt/salt.tf
similarity index 100%
rename from terraform/salt.tf
rename to terraform/local_libvirt/salt.tf
diff --git a/terraform/scripts/.gitkeep b/terraform/local_libvirt/scripts/.gitkeep
similarity index 100%
rename from terraform/scripts/.gitkeep
rename to terraform/local_libvirt/scripts/.gitkeep
diff --git a/terraform/serviceproxy.tf b/terraform/local_libvirt/serviceproxy.tf
similarity index 100%
rename from terraform/serviceproxy.tf
rename to terraform/local_libvirt/serviceproxy.tf
diff --git a/terraform/terraform.tf b/terraform/local_libvirt/terraform.tf
similarity index 100%
rename from terraform/terraform.tf
rename to terraform/local_libvirt/terraform.tf
-- 
GitLab


From 1e1b593898dc055b25c444e5a2d95ea9de4c6d7c Mon Sep 17 00:00:00 2001
From: David Visscher <d.j.visscher@rug.nl>
Date: Tue, 25 Mar 2025 15:56:19 +0100
Subject: [PATCH 02/43] Init Terraform for openstack

---
 .gitignore                                    |   1 +
 salt/pillar/defaults.sls                      |   3 +-
 salt/salt/core/init.sls                       |   2 +
 .../core/{packages.sls => packages-rocky.sls} |   0
 .../local_libvirt/cloud_init/user_data.tftpl  |   2 +-
 terraform/local_libvirt/cloudinit.tf          |   3 +
 terraform/openstack/ceph_monitor.tf           |  72 +++++++
 terraform/openstack/ceph_osd.tf               |  81 +++++++
 terraform/openstack/cloud_init                |   1 +
 terraform/openstack/flavor.tf                 |   3 +
 terraform/openstack/image.tf                  |   3 +
 terraform/openstack/monitor.tf                |  86 ++++++++
 terraform/openstack/networking.tf             |  47 ++++
 terraform/openstack/openstack_compute.tf      |  72 +++++++
 terraform/openstack/openstack_controller.tf   |  71 +++++++
 terraform/openstack/openstack_database.tf     |  71 +++++++
 terraform/openstack/openstack_networker.tf    |  81 +++++++
 terraform/openstack/openstack_serviceproxy.tf |  81 +++++++
 terraform/openstack/salt.tf                   | 200 ++++++++++++++++++
 terraform/openstack/terraform.tf              |  51 +++++
 20 files changed, 928 insertions(+), 3 deletions(-)
 rename salt/salt/core/{packages.sls => packages-rocky.sls} (100%)
 create mode 100644 terraform/openstack/ceph_monitor.tf
 create mode 100644 terraform/openstack/ceph_osd.tf
 create mode 120000 terraform/openstack/cloud_init
 create mode 100644 terraform/openstack/flavor.tf
 create mode 100644 terraform/openstack/image.tf
 create mode 100644 terraform/openstack/monitor.tf
 create mode 100644 terraform/openstack/networking.tf
 create mode 100644 terraform/openstack/openstack_compute.tf
 create mode 100644 terraform/openstack/openstack_controller.tf
 create mode 100644 terraform/openstack/openstack_database.tf
 create mode 100644 terraform/openstack/openstack_networker.tf
 create mode 100644 terraform/openstack/openstack_serviceproxy.tf
 create mode 100644 terraform/openstack/salt.tf
 create mode 100644 terraform/openstack/terraform.tf

diff --git a/.gitignore b/.gitignore
index 8c6f14d..008b006 100644
--- a/.gitignore
+++ b/.gitignore
@@ -384,6 +384,7 @@ scrubfile.json
 .terraform*
 **/.terraform
 **/terraform.tfstate
+**/terraform.tfvars
 
 # VS Code
 .vscode/
diff --git a/salt/pillar/defaults.sls b/salt/pillar/defaults.sls
index 268b27f..65267ff 100644
--- a/salt/pillar/defaults.sls
+++ b/salt/pillar/defaults.sls
@@ -41,8 +41,7 @@ cloud4:
 
 
 mine_functions:
-  network.ip_addrs:
-    cidr: 10.10.0.0/24
+  network.ip_addrs: []
 
 mysql.host: openstack-database-0
 mysql.port: 3306
diff --git a/salt/salt/core/init.sls b/salt/salt/core/init.sls
index 126fe53..31c4677 100644
--- a/salt/salt/core/init.sls
+++ b/salt/salt/core/init.sls
@@ -13,7 +13,9 @@ include:
  - {{ slspath }}/sshd
  - {{ slspath }}/hosts
  - {{ slspath }}/crb
+ {% if grains['os'] == "Rocky" %}
  - {{ slspath }}/packages
+ {% endif %}
  - {{ slspath }}/minion
  - {{ slspath }}/users
  - {{ slspath }}/disable_selinux
diff --git a/salt/salt/core/packages.sls b/salt/salt/core/packages-rocky.sls
similarity index 100%
rename from salt/salt/core/packages.sls
rename to salt/salt/core/packages-rocky.sls
diff --git a/terraform/local_libvirt/cloud_init/user_data.tftpl b/terraform/local_libvirt/cloud_init/user_data.tftpl
index b21a80a..09de27c 100644
--- a/terraform/local_libvirt/cloud_init/user_data.tftpl
+++ b/terraform/local_libvirt/cloud_init/user_data.tftpl
@@ -12,7 +12,7 @@ ssh_authorized_keys:
 runcmd:
   - "set -x"
 %{ if host_type != "salt-master" ~}
-  - "echo '10.10.0.2 salt' >> /etc/hosts"
+  - "echo '${salt_master_ip} salt' >> /etc/hosts"
 %{ endif ~}
   - 'sudo dnf install --assumeyes --refresh epel-release'
   - 'sudo dnf clean all'
diff --git a/terraform/local_libvirt/cloudinit.tf b/terraform/local_libvirt/cloudinit.tf
index 5692479..9fc61cb 100644
--- a/terraform/local_libvirt/cloudinit.tf
+++ b/terraform/local_libvirt/cloudinit.tf
@@ -20,6 +20,7 @@ data "template_file" "salt_user_data" {
     host_type               = "salt-master"
     salt_version            = var.salt_version
     ssh_public_key          = file(var.ssh_public_key_file)
+    salt_master_ip          = "10.10.0.2"
   }
 }
 
@@ -31,6 +32,7 @@ data "template_file" "salt_minion_user_data" {
     host_type               = "salt-minion"
     salt_version            = var.salt_version
     ssh_public_key          = file(var.ssh_public_key_file)
+    salt_master_ip          = libvirt_domain.salt.network_interface.0.addresses.0
   }
 }
 
@@ -42,6 +44,7 @@ data "template_file" "salt_minion_openstack_user_data" {
     host_type               = "salt-minion-openstack"
     salt_version            = var.salt_version
     ssh_public_key          = file(var.ssh_public_key_file)
+    salt_master_ip          = libvirt_domain.salt.network_interface.0.addresses.0
   }
 }
 
diff --git a/terraform/openstack/ceph_monitor.tf b/terraform/openstack/ceph_monitor.tf
new file mode 100644
index 0000000..1bae190
--- /dev/null
+++ b/terraform/openstack/ceph_monitor.tf
@@ -0,0 +1,72 @@
+variable "ceph_mon_count" {
+    type = number
+    default = 3
+}
+
+variable "ceph_mon_size" {
+    type = number
+    default = 50
+}
+
+resource "openstack_networking_port_v2" "ceph_monitor_private" {
+    count = var.ceph_mon_count
+    network_id = openstack_networking_network_v2.private.id
+    admin_state_up = true
+
+    fixed_ip {
+        subnet_id = openstack_networking_subnet_v2.private.id
+        ip_address = cidrhost(openstack_networking_subnet_v2.private.cidr, count.index + 80)
+    }
+}
+
+resource "openstack_blockstorage_volume_v3" "ceph_monitor_persistent_volume" {
+    count = var.ceph_mon_count
+    size = 50
+    image_id = data.openstack_images_image_v2.base_image.id
+    enable_online_resize = true
+}
+
+resource "openstack_compute_instance_v2" "ceph_monitor" {
+    count = var.ceph_mon_count
+    name = "ceph-monitor-${count.index}"
+
+    flavor_id = data.openstack_compute_flavor_v2.small.id
+
+    user_data = templatefile("${path.module}/cloud_init/user_data.tftpl", {
+        deploy_environment_name = var.deploy_environment_name
+        deploy_username         = var.deploy_username
+        host_type               = "ceph-monitor"
+        salt_version            = var.salt_version
+        ssh_public_key          = file(var.ssh_public_key_file)
+        salt_master_ip          = openstack_networking_port_v2.salt_private.fixed_ip
+    })
+
+    connection {
+        type = "ssh"
+        user = var.deploy_username
+        host = self.access_ip_v6
+        private_key = file(var.ssh_private_key_file)
+
+        bastion_host = openstack_compute_instance_v2.salt.access_ip_v4
+        bastion_user = var.deploy_username
+        bastion_private_key = file(var.ssh_private_key_file)
+    }
+
+    provisioner "remote-exec" {
+        inline = [
+            "until [ -f /run/cloud-init-done ]; do sleep 5; done"
+        ]
+    }
+
+    network {
+        port = element(openstack_networking_port_v2.ceph_monitor_private.*.id, count.index)
+    }
+
+    block_device {
+        source_type = "volume"
+        uuid = element(openstack_blockstorage_volume_v3.ceph_monitor_persistent_volume.*.id, count.index)
+    }
+}
+
+
+
diff --git a/terraform/openstack/ceph_osd.tf b/terraform/openstack/ceph_osd.tf
new file mode 100644
index 0000000..55584ea
--- /dev/null
+++ b/terraform/openstack/ceph_osd.tf
@@ -0,0 +1,81 @@
+variable "ceph_osd_count" {
+    type = number
+    default = 3
+}
+
+variable "ceph_osd_size" {
+    type = number
+    default = 100
+}
+
+resource "openstack_networking_port_v2" "ceph_osd_private" {
+    count = var.ceph_osd_count
+    network_id = openstack_networking_network_v2.private.id
+    admin_state_up = true
+
+    fixed_ip {
+        subnet_id = openstack_networking_subnet_v2.private.id
+        ip_address = cidrhost(openstack_networking_subnet_v2.private.cidr, count.index + 70)
+    }
+}
+
+resource "openstack_blockstorage_volume_v3" "ceph_osd_persistent_volume" {
+    count = var.ceph_osd_count
+    size = var.ceph_osd_size
+    image_id = data.openstack_images_image_v2.base_image.id
+}
+
+resource "openstack_blockstorage_volume_v3" "ceph_osd_data_disk" {
+    size = 100
+    count = var.ceph_osd_count
+}
+
+resource "openstack_compute_instance_v2" "ceph_osd" {
+    count = var.ceph_osd_count
+    name = "ceph-osd-${count.index}"
+
+    flavor_id = data.openstack_compute_flavor_v2.small.id
+
+    user_data = templatefile("${path.module}/cloud_init/user_data.tftpl", {
+        deploy_environment_name = var.deploy_environment_name
+        deploy_username         = var.deploy_username
+        host_type               = "ceph-osd"
+        salt_version            = var.salt_version
+        ssh_public_key          = file(var.ssh_public_key_file)
+        salt_master_ip          = openstack_networking_port_v2.salt_private.fixed_ip
+    })
+
+    connection {
+        type = "ssh"
+        user = var.deploy_username
+        host = self.access_ip_v6
+        private_key = file(var.ssh_private_key_file)
+
+        bastion_host = openstack_compute_instance_v2.salt.access_ip_v4
+        bastion_user = var.deploy_username
+        bastion_private_key = file(var.ssh_private_key_file)
+    }
+
+    provisioner "remote-exec" {
+        inline = [
+            "until [ -f /run/cloud-init-done ]; do sleep 5; done"
+        ]
+    }
+
+    network {
+        port = element(openstack_networking_port_v2.ceph_osd_private.*.id, count.index)
+    }
+
+    block_device {
+        source_type = "volume"
+        uuid = element(openstack_blockstorage_volume_v3.ceph_osd_persistent_volume.*.id, count.index)
+    }
+
+    block_device {
+        source_type = "volume"
+        uuid = element(openstack_blockstorage_volume_v3.ceph_osd_data_disk.*.id, count.index)
+    }
+}
+
+
+
diff --git a/terraform/openstack/cloud_init b/terraform/openstack/cloud_init
new file mode 120000
index 0000000..53fa83e
--- /dev/null
+++ b/terraform/openstack/cloud_init
@@ -0,0 +1 @@
+../local_libvirt/cloud_init
\ No newline at end of file
diff --git a/terraform/openstack/flavor.tf b/terraform/openstack/flavor.tf
new file mode 100644
index 0000000..f7d9b01
--- /dev/null
+++ b/terraform/openstack/flavor.tf
@@ -0,0 +1,3 @@
+data openstack_compute_flavor_v2 "small" {
+  name = var.default_small_flavor_name
+}
\ No newline at end of file
diff --git a/terraform/openstack/image.tf b/terraform/openstack/image.tf
new file mode 100644
index 0000000..365fd48
--- /dev/null
+++ b/terraform/openstack/image.tf
@@ -0,0 +1,3 @@
+data openstack_images_image_v2 "base_image" {
+  name = var.base_image_name
+}
\ No newline at end of file
diff --git a/terraform/openstack/monitor.tf b/terraform/openstack/monitor.tf
new file mode 100644
index 0000000..96d671e
--- /dev/null
+++ b/terraform/openstack/monitor.tf
@@ -0,0 +1,86 @@
+variable "monitor_count" {
+    type = number
+    default = 1
+}
+
+variable "monitor_size" {
+    type = number
+    default = 50
+}
+
+resource "openstack_networking_port_v2" "monitor_private" {
+    count = var.monitor_count
+    network_id = openstack_networking_network_v2.private.id
+    admin_state_up = true
+
+    fixed_ip {
+        subnet_id = openstack_networking_subnet_v2.private.id
+        ip_address = cidrhost(openstack_networking_subnet_v2.private.cidr, count.index + 5)
+    }
+}
+
+resource "openstack_networking_port_v2" "monitor_public" {
+    count = var.monitor_count
+    network_id = openstack_networking_network_v2.public.id
+    admin_state_up = true
+
+    fixed_ip {
+        subnet_id = openstack_networking_subnet_v2.public.id
+        ip_address = cidrhost(openstack_networking_subnet_v2.public.cidr, count.index + 5)
+    }
+}
+
+
+resource "openstack_blockstorage_volume_v3" "monitor_persistent_volume" {
+    count = var.monitor_count
+    size = var.monitor_size
+}
+
+resource "openstack_compute_instance_v2" "monitor" {
+    count = var.monitor_count
+    name = "openstack-serviceproxy-${count.index}"
+
+    flavor_id = data.openstack_compute_flavor_v2.small.id
+
+    user_data = templatefile("${path.module}/cloud_init/user_data.tftpl", {
+        deploy_environment_name = var.deploy_environment_name
+        deploy_username         = var.deploy_username
+        host_type               = "openstack-serviceproxy"
+        salt_version            = var.salt_version
+        ssh_public_key          = file(var.ssh_public_key_file)
+        salt_master_ip          = openstack_networking_port_v2.salt_private.fixed_ip
+    })
+
+    connection {
+        type = "ssh"
+        user = var.deploy_username
+        host = self.access_ip_v6
+        private_key = file(var.ssh_private_key_file)
+
+        bastion_host = openstack_compute_instance_v2.salt.access_ip_v4
+        bastion_user = var.deploy_username
+        bastion_private_key = file(var.ssh_private_key_file)
+    }
+
+    provisioner "remote-exec" {
+        inline = [
+            "until [ -f /run/cloud-init-done ]; do sleep 5; done"
+        ]
+    }
+
+    network {
+        port = element(openstack_networking_port_v2.monitor_public.*.id, count.index)
+    }
+
+    network {
+        port = element(openstack_networking_port_v2.monitor_private.*.id, count.index)
+    }
+
+    block_device {
+        source_type = "volume"
+        uuid = element(openstack_blockstorage_volume_v3.monitor_persistent_volume.*.id, count.index)
+    }
+}
+
+
+
diff --git a/terraform/openstack/networking.tf b/terraform/openstack/networking.tf
new file mode 100644
index 0000000..0687a02
--- /dev/null
+++ b/terraform/openstack/networking.tf
@@ -0,0 +1,47 @@
+data "openstack_networking_network_v2" "external" {
+    name = var.external_network_name
+}
+resource "openstack_networking_network_v2" "public" {
+    name           = "cloud4_public_network"
+    admin_state_up = "true"
+    mtu            = 1450
+}
+resource "openstack_networking_subnet_v2" "public" {
+    name       = "cloud4_public_subnet"
+    network_id = openstack_networking_network_v2.public.id
+    cidr       = "10.10.0.0/16"
+    ip_version = 4
+    dns_nameservers     = ["1.1.1.1", "1.0.0.1"]
+}
+resource "openstack_networking_router_v2" "public" {
+    name                = "cloud4_public_router"
+    admin_state_up      = true
+    external_network_id = data.openstack_networking_network_v2.external.id
+}
+resource "openstack_networking_router_interface_v2" "public_subnet_interface" {
+    router_id = openstack_networking_router_v2.public.id
+    subnet_id = openstack_networking_subnet_v2.public.id
+}
+resource "openstack_networking_network_v2" "private" {
+    name           = "cloud4_private_network"
+    admin_state_up = "true"
+    mtu            = 1450
+}
+resource "openstack_networking_subnet_v2" "private" {
+    name       = "cloud4_private_subnet"
+    network_id = openstack_networking_network_v2.private.id
+    cidr       = "fd80:c4c4::0/64"
+    ip_version = 6
+
+    enable_dhcp = true
+    ipv6_address_mode = "dhcpv6-stateful"
+    ipv6_ra_mode = "dhcpv6-stateful"
+}
+resource "openstack_networking_floatingip_v2" "reserved" {
+    count = 2
+    pool  = var.external_network_name
+    lifecycle {
+        # Set this to true to keep hold of the floating IPs when the environment is destroyed
+        prevent_destroy = false
+    }
+}
\ No newline at end of file
diff --git a/terraform/openstack/openstack_compute.tf b/terraform/openstack/openstack_compute.tf
new file mode 100644
index 0000000..1e120f8
--- /dev/null
+++ b/terraform/openstack/openstack_compute.tf
@@ -0,0 +1,72 @@
+variable "openstack_compute_count" {
+    type = number
+    default = 3
+}
+
+variable "openstack_compute_size" {
+    type = number
+    default = 100
+}
+
+resource "openstack_networking_port_v2" "openstack_compute_private" {
+    count = var.openstack_compute_count
+    network_id = openstack_networking_network_v2.private.id
+    admin_state_up = true
+
+    fixed_ip {
+        subnet_id = openstack_networking_subnet_v2.private.id
+        ip_address = cidrhost(openstack_networking_subnet_v2.private.cidr, count.index + 20)
+    }
+}
+
+resource "openstack_blockstorage_volume_v3" "openstack_compute_persistent_volume" {
+    count = var.openstack_compute_count
+    size = var.openstack_compute_size
+    image_id = data.openstack_images_image_v2.base_image.id
+}
+
+resource "openstack_compute_instance_v2" "openstack_compute" {
+    count = var.openstack_compute_count
+    name = "openstack-compute-${count.index}"
+
+    flavor_id = data.openstack_compute_flavor_v2.small.id
+
+    user_data = templatefile("${path.module}/cloud_init/user_data.tftpl", {
+        deploy_environment_name = var.deploy_environment_name
+        deploy_username         = var.deploy_username
+        host_type               = "salt-minion-openstack"
+        salt_version            = var.salt_version
+        ssh_public_key          = file(var.ssh_public_key_file)
+        salt_master_ip          = openstack_networking_port_v2.salt_private.fixed_ip
+    })
+
+    connection {
+        type = "ssh"
+        user = var.deploy_username
+        host = self.access_ip_v6
+        private_key = file(var.ssh_private_key_file)
+
+        bastion_host = openstack_compute_instance_v2.salt.access_ip_v4
+        bastion_user = var.deploy_username
+        bastion_private_key = file(var.ssh_private_key_file)
+    }
+
+    provisioner "remote-exec" {
+        inline = [
+            "until [ -f /run/cloud-init-done ]; do sleep 5; done"
+        ]
+    }
+
+    network {
+        port = element(openstack_networking_port_v2.openstack_compute_private.*.id, count.index)
+    }
+
+    block_device {
+        source_type = "volume"
+        uuid = element(openstack_blockstorage_volume_v3.openstack_compute_persistent_volume.*.id, count.index)
+        boot_index = 0
+    }
+}
+
+
+
diff --git a/terraform/openstack/openstack_controller.tf b/terraform/openstack/openstack_controller.tf
new file mode 100644
index 0000000..4b3eaf0
--- /dev/null
+++ b/terraform/openstack/openstack_controller.tf
@@ -0,0 +1,71 @@
+variable "openstack_controller_count" {
+    type = number
+    default = 3
+}
+
+variable "openstack_controller_size" {
+    type = number
+    default = 20
+}
+
+resource "openstack_networking_port_v2" "openstack_controller_private" {
+    count = var.openstack_controller_count
+    network_id = openstack_networking_network_v2.private.id
+    admin_state_up = true
+
+    fixed_ip {
+        subnet_id = openstack_networking_subnet_v2.private.id
+        ip_address = cidrhost(openstack_networking_subnet_v2.private.cidr, count.index + 10)
+    }
+}
+
+resource "openstack_blockstorage_volume_v3" "openstack_controller_persistent_volume" {
+    count = var.openstack_controller_count
+    size = var.openstack_controller_size
+    image_id = data.openstack_images_image_v2.base_image.id
+}
+
+resource "openstack_compute_instance_v2" "openstack_controller" {
+    count = var.openstack_controller_count
+    name = "openstack-controller-${count.index}"
+
+    flavor_id = data.openstack_compute_flavor_v2.small.id
+
+    user_data = templatefile("${path.module}/cloud_init/user_data.tftpl", {
+        deploy_environment_name = var.deploy_environment_name
+        deploy_username         = var.deploy_username
+        host_type               = "salt-minion-openstack"
+        salt_version            = var.salt_version
+        ssh_public_key          = file(var.ssh_public_key_file)
+        salt_master_ip          = openstack_networking_port_v2.salt_private.fixed_ip
+    })
+
+    connection {
+        type = "ssh"
+        user = var.deploy_username
+        host = self.access_ip_v6
+        private_key = file(var.ssh_private_key_file)
+
+        bastion_host = openstack_compute_instance_v2.salt.access_ip_v4
+        bastion_user = var.deploy_username
+        bastion_private_key = file(var.ssh_private_key_file)
+    }
+
+    provisioner "remote-exec" {
+        inline = [
+            "until [ -f /run/cloud-init-done ]; do sleep 5; done"
+        ]
+    }
+
+    network {
+        port = element(openstack_networking_port_v2.openstack_controller_private.*.id, count.index)
+    }
+
+    block_device {
+        source_type = "volume"
+        uuid = element(openstack_blockstorage_volume_v3.openstack_controller_persistent_volume.*.id, count.index)
+    }
+}
+
+
+
diff --git a/terraform/openstack/openstack_database.tf b/terraform/openstack/openstack_database.tf
new file mode 100644
index 0000000..710683a
--- /dev/null
+++ b/terraform/openstack/openstack_database.tf
@@ -0,0 +1,71 @@
+variable "openstack_database_count" {
+    type = number
+    default = 2
+}
+
+variable "openstack_database_size" {
+    type = number
+    default = 20
+}
+
+resource "openstack_networking_port_v2" "openstack_database_private" {
+    count = var.openstack_database_count
+    network_id = openstack_networking_network_v2.private.id
+    admin_state_up = true
+
+    fixed_ip {
+        subnet_id = openstack_networking_subnet_v2.private.id
+        ip_address = cidrhost(openstack_networking_subnet_v2.private.cidr, count.index + 30)
+    }
+}
+
+resource "openstack_blockstorage_volume_v3" "openstack_database_persistent_volume" {
+    count = var.openstack_database_count
+    size = var.openstack_database_size
+    image_id = data.openstack_images_image_v2.base_image.id
+}
+
+resource "openstack_compute_instance_v2" "openstack_database" {
+    count = var.openstack_database_count
+    name = "openstack-database-${count.index}"
+
+    flavor_id = data.openstack_compute_flavor_v2.small.id
+
+    user_data = templatefile("${path.module}/cloud_init/user_data.tftpl", {
+        deploy_environment_name = var.deploy_environment_name
+        deploy_username         = var.deploy_username
+        host_type               = "salt-minion-openstack"
+        salt_version            = var.salt_version
+        ssh_public_key          = file(var.ssh_public_key_file)
+        salt_master_ip          = openstack_networking_port_v2.salt_private.fixed_ip
+    })
+
+    connection {
+        type = "ssh"
+        user = var.deploy_username
+        host = self.access_ip_v6
+        private_key = file(var.ssh_private_key_file)
+
+        bastion_host = openstack_compute_instance_v2.salt.access_ip_v4
+        bastion_user = var.deploy_username
+        bastion_private_key = file(var.ssh_private_key_file)
+    }
+
+    provisioner "remote-exec" {
+        inline = [
+            "until [ -f /run/cloud-init-done ]; do sleep 5; done"
+        ]
+    }
+
+    network {
+        port = element(openstack_networking_port_v2.openstack_database_private.*.id, count.index)
+    }
+
+    block_device {
+        source_type = "volume"
+        uuid = element(openstack_blockstorage_volume_v3.openstack_database_persistent_volume.*.id, count.index)
+    }
+}
+
+
+
diff --git a/terraform/openstack/openstack_networker.tf b/terraform/openstack/openstack_networker.tf
new file mode 100644
index 0000000..e920d1a
--- /dev/null
+++ b/terraform/openstack/openstack_networker.tf
@@ -0,0 +1,81 @@
+variable "openstack_networker_count" {
+    type = number
+    default = 2
+}
+
+resource "openstack_networking_port_v2" "openstack_networker_private" {
+    count = var.openstack_networker_count
+    network_id = openstack_networking_network_v2.private.id
+    admin_state_up = true
+
+    fixed_ip {
+        subnet_id = openstack_networking_subnet_v2.private.id
+        ip_address = cidrhost(openstack_networking_subnet_v2.private.cidr, count.index + 40)
+    }
+}
+
+resource "openstack_networking_port_v2" "openstack_networker_public" {
+    count = var.openstack_networker_count
+    network_id = openstack_networking_network_v2.public.id
+    admin_state_up = true
+
+    fixed_ip {
+        subnet_id = openstack_networking_subnet_v2.public.id
+        ip_address = cidrhost(openstack_networking_subnet_v2.public.cidr, count.index + 40)
+    }
+}
+
+resource "openstack_blockstorage_volume_v3" "networker_persistent_volume" {
+    count = var.openstack_networker_count
+    size = 30
+    image_id = data.openstack_images_image_v2.base_image.id
+}
+
+resource "openstack_compute_instance_v2" "openstack_networker" {
+    count = var.openstack_networker_count
+    name = "openstack-networker-${count.index}"
+
+    flavor_id = data.openstack_compute_flavor_v2.small.id
+
+    user_data = templatefile("${path.module}/cloud_init/user_data.tftpl", {
+        deploy_environment_name = var.deploy_environment_name
+        deploy_username         = var.deploy_username
+        host_type               = "salt-minion-openstack"
+        salt_version            = var.salt_version
+        ssh_public_key          = file(var.ssh_public_key_file)
+        salt_master_ip          = openstack_networking_port_v2.salt_private.fixed_ip
+    })
+
+    connection {
+        type = "ssh"
+        user = var.deploy_username
+        host = self.access_ip_v6
+        private_key = file(var.ssh_private_key_file)
+
+        bastion_host = openstack_compute_instance_v2.salt.access_ip_v4
+        bastion_user = var.deploy_username
+        bastion_private_key = file(var.ssh_private_key_file)
+    }
+
+    provisioner "remote-exec" {
+        inline = [
+            "until [ -f /run/cloud-init-done ]; do sleep 5; done"
+        ]
+    }
+
+    network {
+        port = element(openstack_networking_port_v2.openstack_networker_public.*.id, count.index)
+    }
+
+    network {
+        port = element(openstack_networking_port_v2.openstack_networker_private.*.id, count.index)
+    }
+
+    block_device {
+        source_type = "volume"
+        uuid = element(openstack_blockstorage_volume_v3.networker_persistent_volume.*.id, count.index)
+    }
+}
+
+
+
diff --git a/terraform/openstack/openstack_serviceproxy.tf b/terraform/openstack/openstack_serviceproxy.tf
new file mode 100644
index 0000000..2d607f9
--- /dev/null
+++ b/terraform/openstack/openstack_serviceproxy.tf
@@ -0,0 +1,81 @@
+variable "openstack_serviceproxy_count" {
+    type = number
+    default = 1
+}
+
+resource "openstack_networking_port_v2" "openstack_serviceproxy_private" {
+    count = var.openstack_serviceproxy_count
+    network_id = openstack_networking_network_v2.private.id
+    admin_state_up = true
+
+    fixed_ip {
+        subnet_id = openstack_networking_subnet_v2.private.id
+        ip_address = cidrhost(openstack_networking_subnet_v2.private.cidr, count.index + 40)
+    }
+}
+
+resource "openstack_networking_port_v2" "openstack_serviceproxy_public" {
+    count = var.openstack_serviceproxy_count
+    network_id = openstack_networking_network_v2.public.id
+    admin_state_up = true
+
+    fixed_ip {
+        subnet_id = openstack_networking_subnet_v2.public.id
+        ip_address = cidrhost(openstack_networking_subnet_v2.public.cidr, count.index + 40)
+    }
+}
+
+resource "openstack_blockstorage_volume_v3" "openstack_serviceproxy_persistent_volume" {
+    count = var.openstack_serviceproxy_count
+    size = 40
+    image_id = data.openstack_images_image_v2.base_image.id
+}
+
+resource "openstack_compute_instance_v2" "openstack_serviceproxy" {
+    count = var.openstack_serviceproxy_count
+    name = "openstack-serviceproxy-${count.index}"
+
+    flavor_id = data.openstack_compute_flavor_v2.small.id
+
+    user_data = templatefile("${path.module}/cloud_init/user_data.tftpl", {
+        deploy_environment_name = var.deploy_environment_name
+        deploy_username         = var.deploy_username
+        host_type               = "salt-minion-openstack"
+        salt_version            = var.salt_version
+        ssh_public_key          = file(var.ssh_public_key_file)
+        salt_master_ip          = openstack_networking_port_v2.salt_private.fixed_ip
+    })
+
+    connection {
+        type = "ssh"
+        user = var.deploy_username
+        host = self.access_ip_v6
+        private_key = file(var.ssh_private_key_file)
+
+        bastion_host = openstack_compute_instance_v2.salt.access_ip_v4
+        bastion_user = var.deploy_username
+        bastion_private_key = file(var.ssh_private_key_file)
+    }
+
+    provisioner "remote-exec" {
+        inline = [
+            "until [ -f /run/cloud-init-done ]; do sleep 5; done"
+        ]
+    }
+
+    network {
+        port = element(openstack_networking_port_v2.openstack_serviceproxy_public.*.id, count.index)
+    }
+
+    network {
+        port = element(openstack_networking_port_v2.openstack_serviceproxy_private.*.id, count.index)
+    }
+
+    block_device {
+        source_type = "volume"
+        uuid = element(openstack_blockstorage_volume_v3.openstack_serviceproxy_persistent_volume.*.id, count.index)
+    }
+}
+
+
+
diff --git a/terraform/openstack/salt.tf b/terraform/openstack/salt.tf
new file mode 100644
index 0000000..a95ea4b
--- /dev/null
+++ b/terraform/openstack/salt.tf
@@ -0,0 +1,200 @@
+resource "openstack_networking_port_v2" "salt_private" {
+    name           = "salt_private"
+    network_id     = openstack_networking_network_v2.private.id
+    admin_state_up = true
+
+    fixed_ip {
+        subnet_id  = openstack_networking_subnet_v2.private.id
+        ip_address = cidrhost(openstack_networking_subnet_v2.private.cidr, 2)
+    }
+}
+
+resource "openstack_networking_port_v2" "salt_public" {
+    name           = "salt_public"
+    network_id     = openstack_networking_network_v2.public.id
+    admin_state_up = true
+
+    fixed_ip {
+        subnet_id  = openstack_networking_subnet_v2.public.id
+        ip_address = cidrhost(openstack_networking_subnet_v2.public.cidr, 2)
+    }
+}
+
+resource "openstack_blockstorage_volume_v3" "salt_persistent_volume" {
+    name                 = "salt_persistent_volume"
+    description          = "Stores persistent state for the salt master."
+    size                 = 20
+    enable_online_resize = true
+    image_id = data.openstack_images_image_v2.base_image.id
+}
+
+resource "openstack_networking_secgroup_v2" "salt" {
+    name = "salt security group"
+}
+
+resource "openstack_networking_secgroup_rule_v2" "salt_ssh_in" {
+    direction         = "ingress"
+    security_group_id = openstack_networking_secgroup_v2.salt.id
+    port_range_min    = 22
+    port_range_max    = 22
+    protocol          = "tcp"
+    ethertype         = "IPv4"
+}
+
+resource "openstack_compute_instance_v2" "salt" {
+    name = "salt"
+    security_groups = [
+        "default",
+        openstack_networking_secgroup_v2.salt.id
+    ]
+
+    flavor_id = data.openstack_compute_flavor_v2.small.id
+
+    block_device {
+        source_type = "volume"
+        uuid   = openstack_blockstorage_volume_v3.salt_persistent_volume.id
+        boot_index  = 0
+    }
+
+    user_data = templatefile("${path.module}/cloud_init/user_data.tftpl", {
+        deploy_environment_name = var.deploy_environment_name
+        deploy_username         = var.deploy_username
+        host_type               = "salt-master"
+        salt_version            = var.salt_version
+        ssh_public_key          = file(var.ssh_public_key_file)
+        salt_master_ip          = openstack_networking_port_v2.salt_private.fixed_ip
+    })
+
+    connection {
+        type = "ssh"
+        user = var.deploy_username
+        host = self.access_ip_v4
+        private_key = file(var.ssh_private_key_file)
+    }
+
+    provisioner "remote-exec" {
+        inline = [
+            "until [ -f /run/cloud-init-done ]; do sleep 5; done"
+        ]
+    }
+
+    network {
+        port = openstack_networking_port_v2.salt_public.id
+    }
+    network {
+        port = openstack_networking_port_v2.salt_private.id
+    }
+
+}
+
+resource "null_resource" "sync_salt_states" {
+    depends_on = [
+        openstack_compute_instance_v2.salt,
+        openstack_compute_instance_v2.ceph_monitor,
+        openstack_compute_instance_v2.ceph_osd,
+        openstack_compute_instance_v2.openstack_controller,
+        openstack_compute_instance_v2.openstack_compute,
+        openstack_compute_instance_v2.openstack_networker,
+        openstack_compute_instance_v2.openstack_serviceproxy,
+        openstack_compute_instance_v2.openstack_database,
+        openstack_compute_instance_v2.monitor,
+    ]
+
+    triggers = {
+        # Easy way to watch for changes in all files in a directory
+        # Creates a long string of all file hashes concatenated together, and then hashes that again.
+        # If one file changes, the end hash also changes, triggering resync of states.
+        dir_hash = sha256(join("", [
+            for filename in fileset("${path.cwd}/../salt/", "**") :
+            filesha256("../salt/${filename}")
+        ]))
+    }
+
+    connection {
+        type = "ssh"
+        user = var.deploy_username
+        host = openstack_compute_instance_v2.salt.access_ip_v4
+        private_key = file(var.ssh_private_key_file)
+    }
+
+    provisioner "file" {
+        source      = "${path.module}/../salt"
+        destination = "/tmp/"
+    }
+
+    provisioner "remote-exec" {
+        inline = [
+            "set -x",
+            "sudo rm -rf /srv/{salt,pillar,reactor,files}",
+            "sudo mv /tmp/salt/{salt,pillar,reactor,files} /srv/",
+            "sudo rm -rf /tmp/salt",
+            "sudo chown root: -R /srv/{salt,reactor,pillar,files}",
+            "sleep 5",
+            "sudo salt \\* test.ping",
+            "sudo salt-call --output-diff state.apply monitoring.prometheus.node_exporter.master_fetch_archive",
+            "sudo salt-call --output-diff state.highstate",
+            "sudo systemctl restart salt-master",
+            "sleep 5",
+        ]
+    }
+}
+
+resource "null_resource" "monitoring_orchestrate" {
+    depends_on = [
+        null_resource.sync_salt_states
+    ]
+
+    connection {
+        type = "ssh"
+        user = var.deploy_username
+        host = openstack_compute_instance_v2.salt.access_ip_v4
+        private_key = file(var.ssh_private_key_file)
+    }
+
+    provisioner "remote-exec" {
+        inline = [
+            "sudo salt-run manage.status",
+            "sudo salt-run --state-output mixed state.orchestrate orch.bootstrap_monitoring",
+        ]
+    }
+}
+
+resource "null_resource" "ceph_orchestrate" {
+    depends_on = [
+        null_resource.monitoring_orchestrate
+    ]
+
+    connection {
+        type = "ssh"
+        user = var.deploy_username
+        host = openstack_compute_instance_v2.salt.access_ip_v4
+        private_key = file(var.ssh_private_key_file)
+    }
+
+    provisioner "remote-exec" {
+        inline = [
+            "sudo salt-run manage.status",
+            "sudo salt-run --state-output mixed state.orchestrate orch.bootstrap_ceph",
+        ]
+    }
+}
+
+resource "null_resource" "openstack_orchestrate" {
+    depends_on = [
+        null_resource.ceph_orchestrate
+    ]
+
+    connection {
+        type = "ssh"
+        user = var.deploy_username
+        host = openstack_compute_instance_v2.salt.access_ip_v4
+        private_key = file(var.ssh_private_key_file)
+    }
+
+    provisioner "remote-exec" {
+        inline = [
+            "sudo salt-run manage.status",
+            "sudo salt-run --state-output mixed state.orchestrate orch.bootstrap_openstack",
+        ]
+    }
+}
diff --git a/terraform/openstack/terraform.tf b/terraform/openstack/terraform.tf
new file mode 100644
index 0000000..45a8f72
--- /dev/null
+++ b/terraform/openstack/terraform.tf
@@ -0,0 +1,51 @@
+variable "external_network_name" {
+    type        = string
+    description = "The name of the external network to use"
+}
+variable "base_image_name" {
+    type        = string
+    description = "The base image to use when creating instance volumes"
+}
+variable "default_small_flavor_name" {
+    type = string
+    description = "The name of the default flavor to use for small instances"
+    default = "m1.small"
+}
+variable "deploy_environment_name" {
+    type        = string
+    description = "Domain to affix to instance names, used for env-specific variables."
+    default     = "local.cloud4"
+}
+variable "deploy_username" {
+    type        = string
+    description = "Default user to use when deploying over ssh. Change when using a different OS."
+    default     = "rocky"
+}
+variable "salt_version" {
+    type = string
+    description = "The version of salt to install on the salt master and minions"
+    default = "3007.1"
+}
+variable "ssh_public_key_file" {
+    type = string
+    description = "The path to the public key file to use for ssh access"
+    default = "~/.ssh/id_rsa.pub"
+}
+variable "ssh_private_key_file" {
+    type = string
+    description = "The path to the private key file to use for ssh access"
+    default = "~/.ssh/id_rsa"
+}
+
+terraform {
+    backend "http" {
+    }
+    required_providers {
+        openstack = {
+            source  = "terraform-provider-openstack/openstack"
+            version = "1.53.0"
+        }
+    }
+}
+provider "openstack" {
+}
\ No newline at end of file
-- 
GitLab


From afcefc45c4a9fbb70c8d8a7e95f51933051582cf Mon Sep 17 00:00:00 2001
From: David Visscher <d.j.visscher@rug.nl>
Date: Mon, 31 Mar 2025 12:08:31 +0200
Subject: [PATCH 03/43] Set private networking to V4, our metadata services in
 hb don't work properly over v6

---
 terraform/openstack/ceph_monitor.tf           |  7 +--
 terraform/openstack/ceph_osd.tf               |  6 ++-
 terraform/openstack/monitor.tf                |  4 +-
 terraform/openstack/networking.tf             | 24 +++++----
 terraform/openstack/openstack_compute.tf      |  7 +--
 terraform/openstack/openstack_controller.tf   |  7 +--
 terraform/openstack/openstack_database.tf     |  7 +--
 terraform/openstack/openstack_networker.tf    |  7 +--
 terraform/openstack/openstack_serviceproxy.tf |  9 ++--
 terraform/openstack/salt.tf                   | 50 +++++++++++--------
 10 files changed, 75 insertions(+), 53 deletions(-)

diff --git a/terraform/openstack/ceph_monitor.tf b/terraform/openstack/ceph_monitor.tf
index 1bae190..7621209 100644
--- a/terraform/openstack/ceph_monitor.tf
+++ b/terraform/openstack/ceph_monitor.tf
@@ -1,6 +1,6 @@
 variable "ceph_mon_count" {
     type = number
-    default = 3
+    default = 1
 }
 
 variable "ceph_mon_size" {
@@ -38,7 +38,7 @@ resource "openstack_compute_instance_v2" "ceph_monitor" {
         host_type               = "ceph-monitor"
         salt_version            = var.salt_version
         ssh_public_key          = file(var.ssh_public_key_file)
-        salt_master_ip          = openstack_networking_port_v2.salt_private.fixed_ip
+        salt_master_ip          = openstack_networking_port_v2.salt_private.fixed_ip[0].ip_address
     })
 
     connection {
@@ -47,7 +47,7 @@ resource "openstack_compute_instance_v2" "ceph_monitor" {
         host = self.access_ip_v6
         private_key = file(var.ssh_private_key_file)
 
-        bastion_host = openstack_compute_instance_v2.salt.access_ip_v4
+        bastion_host = openstack_compute_floatingip_v2.salt.address
         bastion_user = var.deploy_username
         bastion_private_key = file(var.ssh_private_key_file)
     }
@@ -64,6 +64,7 @@ resource "openstack_compute_instance_v2" "ceph_monitor" {
 
     block_device {
         source_type = "volume"
+        destination_type = "volume"
         uuid = element(openstack_blockstorage_volume_v3.ceph_monitor_persistent_volume.*.id, count.index)
     }
 }
diff --git a/terraform/openstack/ceph_osd.tf b/terraform/openstack/ceph_osd.tf
index 55584ea..e285bbb 100644
--- a/terraform/openstack/ceph_osd.tf
+++ b/terraform/openstack/ceph_osd.tf
@@ -42,7 +42,7 @@ resource "openstack_compute_instance_v2" "ceph_osd" {
         host_type               = "ceph-osd"
         salt_version            = var.salt_version
         ssh_public_key          = file(var.ssh_public_key_file)
-        salt_master_ip          = openstack_networking_port_v2.salt_private.fixed_ip
+        salt_master_ip          = openstack_networking_port_v2.salt_private.fixed_ip[0].ip_address
     })
 
     connection {
@@ -51,7 +51,7 @@ resource "openstack_compute_instance_v2" "ceph_osd" {
         host = self.access_ip_v6
         private_key = file(var.ssh_private_key_file)
 
-        bastion_host = openstack_compute_instance_v2.salt.access_ip_v4
+        bastion_host = openstack_compute_floatingip_v2.salt.address
         bastion_user = var.deploy_username
         bastion_private_key = file(var.ssh_private_key_file)
     }
@@ -68,11 +68,13 @@ resource "openstack_compute_instance_v2" "ceph_osd" {
 
     block_device {
         source_type = "volume"
+        destination_type = "volume"
         uuid = element(openstack_blockstorage_volume_v3.ceph_osd_persistent_volume.*.id, count.index)
     }
 
     block_device {
         source_type = "volume"
+        destination_type = "volume"
         uuid = element(openstack_blockstorage_volume_v3.ceph_osd_data_disk.*.id, count.index)
     }
 }
diff --git a/terraform/openstack/monitor.tf b/terraform/openstack/monitor.tf
index 96d671e..99e0c20 100644
--- a/terraform/openstack/monitor.tf
+++ b/terraform/openstack/monitor.tf
@@ -48,7 +48,7 @@ resource "openstack_compute_instance_v2" "monitor" {
         host_type               = "openstack-serviceproxy"
         salt_version            = var.salt_version
         ssh_public_key          = file(var.ssh_public_key_file)
-        salt_master_ip          = openstack_networking_port_v2.salt_private.fixed_ip
+        salt_master_ip          = openstack_networking_port_v2.salt_private.fixed_ip[0].ip_address
     })
 
     connection {
@@ -57,7 +57,7 @@ resource "openstack_compute_instance_v2" "monitor" {
         host = self.access_ip_v6
         private_key = file(var.ssh_private_key_file)
 
-        bastion_host = openstack_compute_instance_v2.salt.access_ip_v4
+        bastion_host = openstack_compute_floatingip_v2.salt.address
         bastion_user = var.deploy_username
         bastion_private_key = file(var.ssh_private_key_file)
     }
diff --git a/terraform/openstack/networking.tf b/terraform/openstack/networking.tf
index 0687a02..40418dc 100644
--- a/terraform/openstack/networking.tf
+++ b/terraform/openstack/networking.tf
@@ -11,31 +11,35 @@ resource "openstack_networking_subnet_v2" "public" {
     network_id = openstack_networking_network_v2.public.id
     cidr       = "10.10.0.0/16"
     ip_version = 4
-    dns_nameservers     = ["1.1.1.1", "1.0.0.1"]
+    dns_nameservers = ["1.1.1.1", "1.0.0.1"]
 }
-resource "openstack_networking_router_v2" "public" {
+resource "openstack_networking_router_v2" "os_router" {
     name                = "cloud4_public_router"
     admin_state_up      = true
     external_network_id = data.openstack_networking_network_v2.external.id
 }
 resource "openstack_networking_router_interface_v2" "public_subnet_interface" {
-    router_id = openstack_networking_router_v2.public.id
+    router_id = openstack_networking_router_v2.os_router.id
     subnet_id = openstack_networking_subnet_v2.public.id
 }
+
+resource "openstack_networking_router_interface_v2" "private_subnet_interface" {
+    router_id = openstack_networking_router_v2.os_router.id
+    subnet_id = openstack_networking_subnet_v2.private.id
+}
+
 resource "openstack_networking_network_v2" "private" {
     name           = "cloud4_private_network"
     admin_state_up = "true"
     mtu            = 1450
 }
 resource "openstack_networking_subnet_v2" "private" {
-    name       = "cloud4_private_subnet"
-    network_id = openstack_networking_network_v2.private.id
-    cidr       = "fd80:c4c4::0/64"
-    ip_version = 6
+    name          = "cloud4_private_subnet"
+    network_id    = openstack_networking_network_v2.private.id
+    cidr          = "10.11.0.0/24"
+    ip_version    = 4
 
-    enable_dhcp = true
-    ipv6_address_mode = "dhcpv6-stateful"
-    ipv6_ra_mode = "dhcpv6-stateful"
+    enable_dhcp       = true
 }
 resource "openstack_networking_floatingip_v2" "reserved" {
     count = 2
diff --git a/terraform/openstack/openstack_compute.tf b/terraform/openstack/openstack_compute.tf
index 1e120f8..fdb96b3 100644
--- a/terraform/openstack/openstack_compute.tf
+++ b/terraform/openstack/openstack_compute.tf
@@ -1,6 +1,6 @@
 variable "openstack_compute_count" {
     type = number
-    default = 3
+    default = 1
 }
 
 variable "openstack_compute_size" {
@@ -37,7 +37,7 @@ resource "openstack_compute_instance_v2" "openstack_compute" {
         host_type               = "salt-minion-openstack"
         salt_version            = var.salt_version
         ssh_public_key          = file(var.ssh_public_key_file)
-        salt_master_ip          = openstack_networking_port_v2.salt_private.fixed_ip
+        salt_master_ip          = openstack_networking_port_v2.salt_private.fixed_ip[0].ip_address
     })
 
     connection {
@@ -46,7 +46,7 @@ resource "openstack_compute_instance_v2" "openstack_compute" {
         host = self.access_ip_v6
         private_key = file(var.ssh_private_key_file)
 
-        bastion_host = openstack_compute_instance_v2.salt.access_ip_v4
+        bastion_host = openstack_compute_floatingip_v2.salt.address
         bastion_user = var.deploy_username
         bastion_private_key = file(var.ssh_private_key_file)
     }
@@ -63,6 +63,7 @@ resource "openstack_compute_instance_v2" "openstack_compute" {
 
     block_device {
         source_type = "volume"
+        destination_type = "volume"
         uuid = element(openstack_blockstorage_volume_v3.openstack_compute_persistent_volume.*.id, count.index)
         boot_index = 0
     }
diff --git a/terraform/openstack/openstack_controller.tf b/terraform/openstack/openstack_controller.tf
index 4b3eaf0..a30dc6e 100644
--- a/terraform/openstack/openstack_controller.tf
+++ b/terraform/openstack/openstack_controller.tf
@@ -1,6 +1,6 @@
 variable "openstack_controller_count" {
     type = number
-    default = 3
+    default = 1
 }
 
 variable "openstack_controller_size" {
@@ -37,7 +37,7 @@ resource "openstack_compute_instance_v2" "openstack_controller" {
         host_type               = "salt-minion-openstack"
         salt_version            = var.salt_version
         ssh_public_key          = file(var.ssh_public_key_file)
-        salt_master_ip          = openstack_networking_port_v2.salt_private.fixed_ip
+        salt_master_ip          = openstack_networking_port_v2.salt_private.fixed_ip[0].ip_address
     })
 
     connection {
@@ -46,7 +46,7 @@ resource "openstack_compute_instance_v2" "openstack_controller" {
         host = self.access_ip_v6
         private_key = file(var.ssh_private_key_file)
 
-        bastion_host = openstack_compute_instance_v2.salt.access_ip_v4
+        bastion_host = openstack_compute_floatingip_v2.salt.address
         bastion_user = var.deploy_username
         bastion_private_key = file(var.ssh_private_key_file)
     }
@@ -63,6 +63,7 @@ resource "openstack_compute_instance_v2" "openstack_controller" {
 
     block_device {
         source_type = "volume"
+        destination_type = "volume"
         uuid = element(openstack_blockstorage_volume_v3.openstack_controller_persistent_volume.*.id, count.index)
     }
 }
diff --git a/terraform/openstack/openstack_database.tf b/terraform/openstack/openstack_database.tf
index 710683a..723109c 100644
--- a/terraform/openstack/openstack_database.tf
+++ b/terraform/openstack/openstack_database.tf
@@ -1,6 +1,6 @@
 variable "openstack_database_count" {
     type = number
-    default = 2
+    default = 1
 }
 
 variable "openstack_database_size" {
@@ -37,7 +37,7 @@ resource "openstack_compute_instance_v2" "openstack_database" {
         host_type               = "salt-minion-openstack"
         salt_version            = var.salt_version
         ssh_public_key          = file(var.ssh_public_key_file)
-        salt_master_ip          = openstack_networking_port_v2.salt_private.fixed_ip
+        salt_master_ip          = openstack_networking_port_v2.salt_private.fixed_ip[0].ip_address
     })
 
     connection {
@@ -46,7 +46,7 @@ resource "openstack_compute_instance_v2" "openstack_database" {
         host = self.access_ip_v6
         private_key = file(var.ssh_private_key_file)
 
-        bastion_host = openstack_compute_instance_v2.salt.access_ip_v4
+        bastion_host = openstack_compute_floatingip_v2.salt.address
         bastion_user = var.deploy_username
         bastion_private_key = file(var.ssh_private_key_file)
     }
@@ -63,6 +63,7 @@ resource "openstack_compute_instance_v2" "openstack_database" {
 
     block_device {
         source_type = "volume"
+        destination_type = "volume"
         uuid = element(openstack_blockstorage_volume_v3.openstack_database_persistent_volume.*.id, count.index)
     }
 }
diff --git a/terraform/openstack/openstack_networker.tf b/terraform/openstack/openstack_networker.tf
index e920d1a..16465d8 100644
--- a/terraform/openstack/openstack_networker.tf
+++ b/terraform/openstack/openstack_networker.tf
@@ -1,6 +1,6 @@
 variable "openstack_networker_count" {
     type = number
-    default = 2
+    default = 1
 }
 
 resource "openstack_networking_port_v2" "openstack_networker_private" {
@@ -43,7 +43,7 @@ resource "openstack_compute_instance_v2" "openstack_networker" {
         host_type               = "salt-minion-openstack"
         salt_version            = var.salt_version
         ssh_public_key          = file(var.ssh_public_key_file)
-        salt_master_ip          = openstack_networking_port_v2.salt_private.fixed_ip
+        salt_master_ip          = openstack_networking_port_v2.salt_private.fixed_ip[0].ip_address
     })
 
     connection {
@@ -52,7 +52,7 @@ resource "openstack_compute_instance_v2" "openstack_networker" {
         host = self.access_ip_v6
         private_key = file(var.ssh_private_key_file)
 
-        bastion_host = openstack_compute_instance_v2.salt.access_ip_v4
+        bastion_host = openstack_compute_floatingip_v2.salt.address
         bastion_user = var.deploy_username
         bastion_private_key = file(var.ssh_private_key_file)
     }
@@ -73,6 +73,7 @@ resource "openstack_compute_instance_v2" "openstack_networker" {
 
     block_device {
         source_type = "volume"
+        destination_type = "volume"
         uuid = element(openstack_blockstorage_volume_v3.networker_persistent_volume.*.id, count.index)
     }
 }
diff --git a/terraform/openstack/openstack_serviceproxy.tf b/terraform/openstack/openstack_serviceproxy.tf
index 2d607f9..e331c3e 100644
--- a/terraform/openstack/openstack_serviceproxy.tf
+++ b/terraform/openstack/openstack_serviceproxy.tf
@@ -10,7 +10,7 @@ resource "openstack_networking_port_v2" "openstack_serviceproxy_private" {
 
     fixed_ip {
         subnet_id = openstack_networking_subnet_v2.private.id
-        ip_address = cidrhost(openstack_networking_subnet_v2.private.cidr, count.index + 40)
+        ip_address = cidrhost(openstack_networking_subnet_v2.private.cidr, count.index + 100)
     }
 }
 
@@ -21,7 +21,7 @@ resource "openstack_networking_port_v2" "openstack_serviceproxy_public" {
 
     fixed_ip {
         subnet_id = openstack_networking_subnet_v2.public.id
-        ip_address = cidrhost(openstack_networking_subnet_v2.public.cidr, count.index + 40)
+        ip_address = cidrhost(openstack_networking_subnet_v2.public.cidr, count.index + 100)
     }
 }
 
@@ -43,7 +43,7 @@ resource "openstack_compute_instance_v2" "openstack_serviceproxy" {
         host_type               = "salt-minion-openstack"
         salt_version            = var.salt_version
         ssh_public_key          = file(var.ssh_public_key_file)
-        salt_master_ip          = openstack_networking_port_v2.salt_private.fixed_ip
+        salt_master_ip          = openstack_networking_port_v2.salt_private.fixed_ip[0].ip_address
     })
 
     connection {
@@ -52,7 +52,7 @@ resource "openstack_compute_instance_v2" "openstack_serviceproxy" {
         host = self.access_ip_v6
         private_key = file(var.ssh_private_key_file)
 
-        bastion_host = openstack_compute_instance_v2.salt.access_ip_v4
+        bastion_host = openstack_compute_floatingip_v2.salt.address
         bastion_user = var.deploy_username
         bastion_private_key = file(var.ssh_private_key_file)
     }
@@ -73,6 +73,7 @@ resource "openstack_compute_instance_v2" "openstack_serviceproxy" {
 
     block_device {
         source_type = "volume"
+        destination_type = "volume"
         uuid = element(openstack_blockstorage_volume_v3.openstack_serviceproxy_persistent_volume.*.id, count.index)
     }
 }
diff --git a/terraform/openstack/salt.tf b/terraform/openstack/salt.tf
index a95ea4b..ea5bf1c 100644
--- a/terraform/openstack/salt.tf
+++ b/terraform/openstack/salt.tf
@@ -5,7 +5,7 @@ resource "openstack_networking_port_v2" "salt_private" {
 
     fixed_ip {
         subnet_id  = openstack_networking_subnet_v2.private.id
-        ip_address = cidrhost(openstack_networking_subnet_v2.private.cidr, 2)
+        ip_address = cidrhost(openstack_networking_subnet_v2.private.cidr, 3)
     }
 }
 
@@ -16,7 +16,7 @@ resource "openstack_networking_port_v2" "salt_public" {
 
     fixed_ip {
         subnet_id  = openstack_networking_subnet_v2.public.id
-        ip_address = cidrhost(openstack_networking_subnet_v2.public.cidr, 2)
+        ip_address = cidrhost(openstack_networking_subnet_v2.public.cidr, 3)
     }
 }
 
@@ -28,30 +28,34 @@ resource "openstack_blockstorage_volume_v3" "salt_persistent_volume" {
     image_id = data.openstack_images_image_v2.base_image.id
 }
 
-resource "openstack_networking_secgroup_v2" "salt" {
-    name = "salt security group"
+data "openstack_networking_secgroup_v2" "default" {
+    name = "default"
 }
 
 resource "openstack_networking_secgroup_rule_v2" "salt_ssh_in" {
     direction         = "ingress"
-    security_group_id = openstack_networking_secgroup_v2.salt.id
+    security_group_id =  data.openstack_networking_secgroup_v2.default.id
     port_range_min    = 22
     port_range_max    = 22
     protocol          = "tcp"
     ethertype         = "IPv4"
 }
 
+resource "openstack_compute_floatingip_v2" "salt" {
+    pool = var.external_network_name
+}
+
 resource "openstack_compute_instance_v2" "salt" {
     name = "salt"
     security_groups = [
         "default",
-        openstack_networking_secgroup_v2.salt.id
     ]
 
     flavor_id = data.openstack_compute_flavor_v2.small.id
 
     block_device {
         source_type = "volume"
+        destination_type = "volume"
         uuid   = openstack_blockstorage_volume_v3.salt_persistent_volume.id
         boot_index  = 0
     }
@@ -62,29 +66,35 @@ resource "openstack_compute_instance_v2" "salt" {
         host_type               = "salt-master"
         salt_version            = var.salt_version
         ssh_public_key          = file(var.ssh_public_key_file)
-        salt_master_ip          = openstack_networking_port_v2.salt_private.fixed_ip
+        salt_master_ip          = openstack_networking_port_v2.salt_private.fixed_ip[0]
     })
 
+    network {
+        port = openstack_networking_port_v2.salt_public.id
+    }
+    network {
+        port = openstack_networking_port_v2.salt_private.id
+    }
+
+}
+
+resource "openstack_compute_floatingip_associate_v2" "salt" {
+    floating_ip = openstack_compute_floatingip_v2.salt.address
+    instance_id = openstack_compute_instance_v2.salt.id
+
     connection {
         type = "ssh"
         user = var.deploy_username
-        host = self.access_ip_v4
+        host = openstack_compute_floatingip_v2.salt.address
         private_key = file(var.ssh_private_key_file)
     }
 
     provisioner "remote-exec" {
         inline = [
+            "echo 'auto_accept: True' > /etc/salt/master.d/auto_accept.conf",
             "until [ -f /run/cloud-init-done ]; do sleep 5; done"
         ]
     }
-
-    network {
-        port = openstack_networking_port_v2.salt_public.id
-    }
-    network {
-        port = openstack_networking_port_v2.salt_private.id
-    }
-
 }
 
 resource "null_resource" "sync_salt_states" {
@@ -113,7 +123,7 @@ resource "null_resource" "sync_salt_states" {
     connection {
         type = "ssh"
         user = var.deploy_username
-        host = openstack_compute_instance_v2.salt.access_ip_v4
+        host = openstack_compute_floatingip_v2.salt.address
         private_key = file(var.ssh_private_key_file)
     }
 
@@ -147,7 +157,7 @@ resource "null_resource" "monitoring_orchestrate" {
     connection {
         type = "ssh"
         user = var.deploy_username
-        host = openstack_compute_instance_v2.salt.access_ip_v4
+        host = openstack_compute_floatingip_v2.salt.address
         private_key = file(var.ssh_private_key_file)
     }
 
@@ -167,7 +177,7 @@ resource "null_resource" "ceph_orchestrate" {
     connection {
         type = "ssh"
         user = var.deploy_username
-        host = openstack_compute_instance_v2.salt.access_ip_v4
+        host = openstack_compute_floatingip_v2.salt.address
         private_key = file(var.ssh_private_key_file)
     }
 
@@ -187,7 +197,7 @@ resource "null_resource" "openstack_orchestrate" {
     connection {
         type = "ssh"
         user = var.deploy_username
-        host = openstack_compute_instance_v2.salt.access_ip_v4
+        host = openstack_compute_floatingip_v2.salt.address
         private_key = file(var.ssh_private_key_file)
     }
 
-- 
GitLab


From bf4a789a8c5650b41068f0b1e3e35765112e98a6 Mon Sep 17 00:00:00 2001
From: David Visscher <d.j.visscher@rug.nl>
Date: Mon, 31 Mar 2025 12:17:10 +0200
Subject: [PATCH 04/43] Set access_ips to v4

---
 terraform/openstack/ceph_monitor.tf           | 2 +-
 terraform/openstack/ceph_osd.tf               | 4 +++-
 terraform/openstack/monitor.tf                | 3 ++-
 terraform/openstack/openstack_compute.tf      | 2 +-
 terraform/openstack/openstack_controller.tf   | 2 +-
 terraform/openstack/openstack_database.tf     | 2 +-
 terraform/openstack/openstack_networker.tf    | 2 +-
 terraform/openstack/openstack_serviceproxy.tf | 2 +-
 8 files changed, 11 insertions(+), 8 deletions(-)

diff --git a/terraform/openstack/ceph_monitor.tf b/terraform/openstack/ceph_monitor.tf
index 7621209..958f0a4 100644
--- a/terraform/openstack/ceph_monitor.tf
+++ b/terraform/openstack/ceph_monitor.tf
@@ -44,7 +44,7 @@ resource "openstack_compute_instance_v2" "ceph_monitor" {
     connection {
         type = "ssh"
         user = var.deploy_username
-        host = self.access_ip_v6
+        host = self.access_ip_v4
         private_key = file(var.ssh_private_key_file)
 
         bastion_host = openstack_compute_floatingip_v2.salt.address
diff --git a/terraform/openstack/ceph_osd.tf b/terraform/openstack/ceph_osd.tf
index e285bbb..79d6e22 100644
--- a/terraform/openstack/ceph_osd.tf
+++ b/terraform/openstack/ceph_osd.tf
@@ -48,7 +48,7 @@ resource "openstack_compute_instance_v2" "ceph_osd" {
     connection {
         type = "ssh"
         user = var.deploy_username
-        host = self.access_ip_v6
+        host = self.access_ip_v4
         private_key = file(var.ssh_private_key_file)
 
         bastion_host = openstack_compute_floatingip_v2.salt.address
@@ -70,12 +70,14 @@ resource "openstack_compute_instance_v2" "ceph_osd" {
         source_type = "volume"
         destination_type = "volume"
         uuid = element(openstack_blockstorage_volume_v3.ceph_osd_persistent_volume.*.id, count.index)
+        boot_index = 0
     }
 
     block_device {
         source_type = "volume"
         destination_type = "volume"
         uuid = element(openstack_blockstorage_volume_v3.ceph_osd_data_disk.*.id, count.index)
+        boot_index = 1
     }
 }
 
diff --git a/terraform/openstack/monitor.tf b/terraform/openstack/monitor.tf
index 99e0c20..774b24e 100644
--- a/terraform/openstack/monitor.tf
+++ b/terraform/openstack/monitor.tf
@@ -54,7 +54,7 @@ resource "openstack_compute_instance_v2" "monitor" {
     connection {
         type = "ssh"
         user = var.deploy_username
-        host = self.access_ip_v6
+        host = self.access_ip_v4
         private_key = file(var.ssh_private_key_file)
 
         bastion_host = openstack_compute_floatingip_v2.salt.address
@@ -78,6 +78,7 @@ resource "openstack_compute_instance_v2" "monitor" {
 
     block_device {
         source_type = "volume"
+        destination_type = "volume"
         uuid = element(openstack_blockstorage_volume_v3.monitor_persistent_volume.*.id, count.index)
     }
 }
diff --git a/terraform/openstack/openstack_compute.tf b/terraform/openstack/openstack_compute.tf
index fdb96b3..38af91d 100644
--- a/terraform/openstack/openstack_compute.tf
+++ b/terraform/openstack/openstack_compute.tf
@@ -43,7 +43,7 @@ resource "openstack_compute_instance_v2" "openstack_compute" {
     connection {
         type = "ssh"
         user = var.deploy_username
-        host = self.access_ip_v6
+        host = self.access_ip_v4
         private_key = file(var.ssh_private_key_file)
 
         bastion_host = openstack_compute_floatingip_v2.salt.address
diff --git a/terraform/openstack/openstack_controller.tf b/terraform/openstack/openstack_controller.tf
index a30dc6e..01c80f7 100644
--- a/terraform/openstack/openstack_controller.tf
+++ b/terraform/openstack/openstack_controller.tf
@@ -43,7 +43,7 @@ resource "openstack_compute_instance_v2" "openstack_controller" {
     connection {
         type = "ssh"
         user = var.deploy_username
-        host = self.access_ip_v6
+        host = self.access_ip_v4
         private_key = file(var.ssh_private_key_file)
 
         bastion_host = openstack_compute_floatingip_v2.salt.address
diff --git a/terraform/openstack/openstack_database.tf b/terraform/openstack/openstack_database.tf
index 723109c..1b7cca2 100644
--- a/terraform/openstack/openstack_database.tf
+++ b/terraform/openstack/openstack_database.tf
@@ -43,7 +43,7 @@ resource "openstack_compute_instance_v2" "openstack_database" {
     connection {
         type = "ssh"
         user = var.deploy_username
-        host = self.access_ip_v6
+        host = self.access_ip_v4
         private_key = file(var.ssh_private_key_file)
 
         bastion_host = openstack_compute_floatingip_v2.salt.address
diff --git a/terraform/openstack/openstack_networker.tf b/terraform/openstack/openstack_networker.tf
index 16465d8..d02cc20 100644
--- a/terraform/openstack/openstack_networker.tf
+++ b/terraform/openstack/openstack_networker.tf
@@ -49,7 +49,7 @@ resource "openstack_compute_instance_v2" "openstack_networker" {
     connection {
         type = "ssh"
         user = var.deploy_username
-        host = self.access_ip_v6
+        host = self.access_ip_v4
         private_key = file(var.ssh_private_key_file)
 
         bastion_host = openstack_compute_floatingip_v2.salt.address
diff --git a/terraform/openstack/openstack_serviceproxy.tf b/terraform/openstack/openstack_serviceproxy.tf
index e331c3e..8b5c42b 100644
--- a/terraform/openstack/openstack_serviceproxy.tf
+++ b/terraform/openstack/openstack_serviceproxy.tf
@@ -49,7 +49,7 @@ resource "openstack_compute_instance_v2" "openstack_serviceproxy" {
     connection {
         type = "ssh"
         user = var.deploy_username
-        host = self.access_ip_v6
+        host = self.access_ip_v4
         private_key = file(var.ssh_private_key_file)
 
         bastion_host = openstack_compute_floatingip_v2.salt.address
-- 
GitLab


From 6d50de0b2f422f043d08a0a9fa13b804e279565b Mon Sep 17 00:00:00 2001
From: Max Roeleveld <m.g.roeleveld@rug.nl>
Date: Mon, 31 Mar 2025 10:29:43 +0000
Subject: [PATCH 05/43] Force HTTPS for RUG mirror.

Using HTTP seems to result in connection reset by peer errors.
---
 terraform/local_libvirt/cloud_init/user_data.tftpl | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/terraform/local_libvirt/cloud_init/user_data.tftpl b/terraform/local_libvirt/cloud_init/user_data.tftpl
index 09de27c..43f2742 100644
--- a/terraform/local_libvirt/cloud_init/user_data.tftpl
+++ b/terraform/local_libvirt/cloud_init/user_data.tftpl
@@ -16,8 +16,9 @@ runcmd:
 %{ endif ~}
   - 'sudo dnf install --assumeyes --refresh epel-release'
   - 'sudo dnf clean all'
+  - 'sudo rm -Rf /var/cache/dnf/'
   - 'sudo echo "rocky" > "/etc/yum/vars/contentdir"'
-  - "sudo sed -i -e '/baseurl=/s/dl.rockylinux.org/osmirror.rug.nl/g' -e '/baseurl=/s/^#//g' -e '/mirrorlist/s/^mirror/#mirror/g' /etc/yum.repos.d/rocky*.repo"
+  - "sudo sed -i -e '/baseurl=/s/dl.rockylinux.org/osmirror.rug.nl/g' -e '/baseurl=/s/^#baseurl=http:/baseurl=https:/g' -e '/mirrorlist/s/^mirror/#mirror/g' /etc/yum.repos.d/rocky*.repo"
   - 'curl -fsSL https://github.com/saltstack/salt-install-guide/releases/latest/download/salt.repo | sudo tee /etc/yum.repos.d/salt.repo'
   - 'sudo dnf config-manager --set-disable salt-repo-*'
   - 'sudo dnf config-manager --set-enabled salt-repo-${salt_version}-sts'
-- 
GitLab


From 6eeb0e18cd1c53e699fdaf0113d238ea71fd2fce Mon Sep 17 00:00:00 2001
From: David Visscher <d.j.visscher@rug.nl>
Date: Mon, 31 Mar 2025 12:56:32 +0200
Subject: [PATCH 06/43] Misc fixes

---
 terraform/openstack/monitor.tf | 2 ++
 terraform/openstack/salt.tf    | 5 +++--
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/terraform/openstack/monitor.tf b/terraform/openstack/monitor.tf
index 774b24e..30e4598 100644
--- a/terraform/openstack/monitor.tf
+++ b/terraform/openstack/monitor.tf
@@ -32,6 +32,7 @@ resource "openstack_networking_port_v2" "monitor_public" {
 
 
 resource "openstack_blockstorage_volume_v3" "monitor_persistent_volume" {
+    image_id = data.openstack_images_image_v2.base_image.id
     count = var.monitor_count
     size = var.monitor_size
 }
@@ -80,6 +81,7 @@ resource "openstack_compute_instance_v2" "monitor" {
         source_type = "volume"
         destination_type = "volume"
         uuid = element(openstack_blockstorage_volume_v3.monitor_persistent_volume.*.id, count.index)
+        boot_index = 0
     }
 }
 
diff --git a/terraform/openstack/salt.tf b/terraform/openstack/salt.tf
index ea5bf1c..c2b5c35 100644
--- a/terraform/openstack/salt.tf
+++ b/terraform/openstack/salt.tf
@@ -91,8 +91,9 @@ resource "openstack_compute_floatingip_associate_v2" "salt" {
 
     provisioner "remote-exec" {
         inline = [
-            "echo 'auto_accept: True' > /etc/salt/master.d/auto_accept.conf",
-            "until [ -f /run/cloud-init-done ]; do sleep 5; done"
+            "until [ -f /run/cloud-init-done ]; do sleep 5; done",
+            "sudo bash -c 'echo \"auto_accept: True\" > /etc/salt/master.d/auto_accept.conf'",
+            "sudo systemctl restart salt-master"
         ]
     }
 }
-- 
GitLab


From 03e2f53070a42c07c73008a86aa60856572fc87d Mon Sep 17 00:00:00 2001
From: David Visscher <d.j.visscher@rug.nl>
Date: Mon, 31 Mar 2025 14:13:17 +0200
Subject: [PATCH 07/43] Set hostnames in user_data

---
 terraform/local_libvirt/cloud_init/user_data.tftpl | 5 +++++
 terraform/local_libvirt/cloudinit.tf               | 6 ++++++
 terraform/openstack/ceph_monitor.tf                | 4 +++-
 terraform/openstack/ceph_osd.tf                    | 4 +++-
 terraform/openstack/monitor.tf                     | 4 +++-
 terraform/openstack/openstack_compute.tf           | 4 +++-
 terraform/openstack/openstack_controller.tf        | 4 +++-
 terraform/openstack/openstack_database.tf          | 4 +++-
 terraform/openstack/openstack_networker.tf         | 4 +++-
 terraform/openstack/openstack_serviceproxy.tf      | 4 +++-
 terraform/openstack/salt.tf                        | 4 +++-
 11 files changed, 38 insertions(+), 9 deletions(-)

diff --git a/terraform/local_libvirt/cloud_init/user_data.tftpl b/terraform/local_libvirt/cloud_init/user_data.tftpl
index 43f2742..382dc36 100644
--- a/terraform/local_libvirt/cloud_init/user_data.tftpl
+++ b/terraform/local_libvirt/cloud_init/user_data.tftpl
@@ -2,6 +2,11 @@
 
 #host_type=${host_type}
 
+%{ if set_hostname ~}
+hostname: ${hostname}
+fqdn: ${hostname}.${deploy_environment_name}
+%{ endif ~}
+
 password: banaan
 chpasswd:
   expire: False
diff --git a/terraform/local_libvirt/cloudinit.tf b/terraform/local_libvirt/cloudinit.tf
index 9fc61cb..612a0d1 100644
--- a/terraform/local_libvirt/cloudinit.tf
+++ b/terraform/local_libvirt/cloudinit.tf
@@ -21,6 +21,8 @@ data "template_file" "salt_user_data" {
     salt_version            = var.salt_version
     ssh_public_key          = file(var.ssh_public_key_file)
     salt_master_ip          = "10.10.0.2"
+    set_hostname            = false
+    hostname                = ""
   }
 }
 
@@ -33,6 +35,8 @@ data "template_file" "salt_minion_user_data" {
     salt_version            = var.salt_version
     ssh_public_key          = file(var.ssh_public_key_file)
     salt_master_ip          = libvirt_domain.salt.network_interface.0.addresses.0
+    set_hostname            = false
+    hostname                = ""
   }
 }
 
@@ -45,6 +49,8 @@ data "template_file" "salt_minion_openstack_user_data" {
     salt_version            = var.salt_version
     ssh_public_key          = file(var.ssh_public_key_file)
     salt_master_ip          = libvirt_domain.salt.network_interface.0.addresses.0
+    set_hostname            = false
+    hostname                = ""
   }
 }
 
diff --git a/terraform/openstack/ceph_monitor.tf b/terraform/openstack/ceph_monitor.tf
index 958f0a4..edb99ff 100644
--- a/terraform/openstack/ceph_monitor.tf
+++ b/terraform/openstack/ceph_monitor.tf
@@ -28,7 +28,7 @@ resource "openstack_blockstorage_volume_v3" "ceph_monitor_persistent_volume" {
 
 resource "openstack_compute_instance_v2" "ceph_monitor" {
     count = var.ceph_mon_count
-    name = "ceph-monitor-${count.index}"
+    name = "ceph-monitor-${count.index}.${var.deploy_environment_name}"
 
     flavor_id = data.openstack_compute_flavor_v2.small.id
 
@@ -39,6 +39,8 @@ resource "openstack_compute_instance_v2" "ceph_monitor" {
         salt_version            = var.salt_version
         ssh_public_key          = file(var.ssh_public_key_file)
         salt_master_ip          = openstack_networking_port_v2.salt_private.fixed_ip[0].ip_address
+        set_hostname            = true
+        hostname                = "ceph-monitor-${count.index}.${var.deploy_environment_name}"
     })
 
     connection {
diff --git a/terraform/openstack/ceph_osd.tf b/terraform/openstack/ceph_osd.tf
index 79d6e22..394caf4 100644
--- a/terraform/openstack/ceph_osd.tf
+++ b/terraform/openstack/ceph_osd.tf
@@ -32,7 +32,7 @@ resource "openstack_blockstorage_volume_v3" "ceph_osd_data_disk" {
 
 resource "openstack_compute_instance_v2" "ceph_osd" {
     count = var.ceph_osd_count
-    name = "ceph-osd-${count.index}"
+    name = "ceph-osd-${count.index}.${var.deploy_environment_name}"
 
     flavor_id = data.openstack_compute_flavor_v2.small.id
 
@@ -43,6 +43,8 @@ resource "openstack_compute_instance_v2" "ceph_osd" {
         salt_version            = var.salt_version
         ssh_public_key          = file(var.ssh_public_key_file)
         salt_master_ip          = openstack_networking_port_v2.salt_private.fixed_ip[0].ip_address
+        set_hostname            = true
+        hostname                = "ceph-osd-${count.index}.${var.deploy_environment_name}"
     })
 
     connection {
diff --git a/terraform/openstack/monitor.tf b/terraform/openstack/monitor.tf
index 30e4598..e714978 100644
--- a/terraform/openstack/monitor.tf
+++ b/terraform/openstack/monitor.tf
@@ -39,7 +39,7 @@ resource "openstack_blockstorage_volume_v3" "monitor_persistent_volume" {
 
 resource "openstack_compute_instance_v2" "monitor" {
     count = var.monitor_count
-    name = "openstack-serviceproxy-${count.index}"
+    name = "openstack-serviceproxy-${count.index}.${var.deploy_environment_name}"
 
     flavor_id = data.openstack_compute_flavor_v2.small.id
 
@@ -50,6 +50,8 @@ resource "openstack_compute_instance_v2" "monitor" {
         salt_version            = var.salt_version
         ssh_public_key          = file(var.ssh_public_key_file)
         salt_master_ip          = openstack_networking_port_v2.salt_private.fixed_ip[0].ip_address
+        set_hostname            = true
+        hostname                = "openstack-serviceproxy-${count.index}.${var.deploy_environment_name}"
     })
 
     connection {
diff --git a/terraform/openstack/openstack_compute.tf b/terraform/openstack/openstack_compute.tf
index 38af91d..9ce5289 100644
--- a/terraform/openstack/openstack_compute.tf
+++ b/terraform/openstack/openstack_compute.tf
@@ -27,7 +27,7 @@ resource "openstack_blockstorage_volume_v3" "openstack_compute_persistent_volume
 
 resource "openstack_compute_instance_v2" "openstack_compute" {
     count = var.openstack_compute_count
-    name = "openstack-compute-${count.index}"
+    name = "openstack-compute-${count.index}.${var.deploy_environment_name}"
 
     flavor_id = data.openstack_compute_flavor_v2.small.id
 
@@ -38,6 +38,8 @@ resource "openstack_compute_instance_v2" "openstack_compute" {
         salt_version            = var.salt_version
         ssh_public_key          = file(var.ssh_public_key_file)
         salt_master_ip          = openstack_networking_port_v2.salt_private.fixed_ip[0].ip_address
+        set_hostname            = true
+        hostname                = "openstack-compute-${count.index}.${var.deploy_environment_name}"
     })
 
     connection {
diff --git a/terraform/openstack/openstack_controller.tf b/terraform/openstack/openstack_controller.tf
index 01c80f7..52340b4 100644
--- a/terraform/openstack/openstack_controller.tf
+++ b/terraform/openstack/openstack_controller.tf
@@ -27,7 +27,7 @@ resource "openstack_blockstorage_volume_v3" "openstack_controller_persistent_vol
 
 resource "openstack_compute_instance_v2" "openstack_controller" {
     count = var.openstack_controller_count
-    name = "openstack-controller-${count.index}"
+    name = "openstack-controller-${count.index}.${var.deploy_environment_name}"
 
     flavor_id = data.openstack_compute_flavor_v2.small.id
 
@@ -38,6 +38,8 @@ resource "openstack_compute_instance_v2" "openstack_controller" {
         salt_version            = var.salt_version
         ssh_public_key          = file(var.ssh_public_key_file)
         salt_master_ip          = openstack_networking_port_v2.salt_private.fixed_ip[0].ip_address
+        set_hostname            = true
+        hostname                = "openstack-controller-${count.index}.${var.deploy_environment_name}"
     })
 
     connection {
diff --git a/terraform/openstack/openstack_database.tf b/terraform/openstack/openstack_database.tf
index 1b7cca2..27316b4 100644
--- a/terraform/openstack/openstack_database.tf
+++ b/terraform/openstack/openstack_database.tf
@@ -27,7 +27,7 @@ resource "openstack_blockstorage_volume_v3" "openstack_database_persistent_volum
 
 resource "openstack_compute_instance_v2" "openstack_database" {
     count = var.openstack_database_count
-    name = "openstack-database-${count.index}"
+    name = "openstack-database-${count.index}.${var.deploy_environment_name}"
 
     flavor_id = data.openstack_compute_flavor_v2.small.id
 
@@ -38,6 +38,8 @@ resource "openstack_compute_instance_v2" "openstack_database" {
         salt_version            = var.salt_version
         ssh_public_key          = file(var.ssh_public_key_file)
         salt_master_ip          = openstack_networking_port_v2.salt_private.fixed_ip[0].ip_address
+        set_hostname            = true
+        hostname                = "openstack-database-${count.index}.${var.deploy_environment_name}"
     })
 
     connection {
diff --git a/terraform/openstack/openstack_networker.tf b/terraform/openstack/openstack_networker.tf
index d02cc20..4af7a88 100644
--- a/terraform/openstack/openstack_networker.tf
+++ b/terraform/openstack/openstack_networker.tf
@@ -33,7 +33,7 @@ resource "openstack_blockstorage_volume_v3" "networker_persistent_volume" {
 
 resource "openstack_compute_instance_v2" "openstack_networker" {
     count = var.openstack_networker_count
-    name = "openstack-networker-${count.index}"
+    name = "openstack-networker-${count.index}.${var.deploy_environment_name}"
 
     flavor_id = data.openstack_compute_flavor_v2.small.id
 
@@ -44,6 +44,8 @@ resource "openstack_compute_instance_v2" "openstack_networker" {
         salt_version            = var.salt_version
         ssh_public_key          = file(var.ssh_public_key_file)
         salt_master_ip          = openstack_networking_port_v2.salt_private.fixed_ip[0].ip_address
+        set_hostname            = true
+        hostname                = "openstack-networker-${count.index}.${var.deploy_environment_name}"
     })
 
     connection {
diff --git a/terraform/openstack/openstack_serviceproxy.tf b/terraform/openstack/openstack_serviceproxy.tf
index 8b5c42b..13e05e8 100644
--- a/terraform/openstack/openstack_serviceproxy.tf
+++ b/terraform/openstack/openstack_serviceproxy.tf
@@ -33,7 +33,7 @@ resource "openstack_blockstorage_volume_v3" "openstack_serviceproxy_persistent_v
 
 resource "openstack_compute_instance_v2" "openstack_serviceproxy" {
     count = var.openstack_serviceproxy_count
-    name = "openstack-serviceproxy-${count.index}"
+    name = "openstack-serviceproxy-${count.index}.${var.deploy_environment_name}"
 
     flavor_id = data.openstack_compute_flavor_v2.small.id
 
@@ -44,6 +44,8 @@ resource "openstack_compute_instance_v2" "openstack_serviceproxy" {
         salt_version            = var.salt_version
         ssh_public_key          = file(var.ssh_public_key_file)
         salt_master_ip          = openstack_networking_port_v2.salt_private.fixed_ip[0].ip_address
+        set_hostname            = true
+        hostname                = "openstack-serviceproxy-${count.index}.${var.deploy_environment_name}"
     })
 
     connection {
diff --git a/terraform/openstack/salt.tf b/terraform/openstack/salt.tf
index c2b5c35..252ae47 100644
--- a/terraform/openstack/salt.tf
+++ b/terraform/openstack/salt.tf
@@ -46,7 +46,7 @@ resource "openstack_compute_floatingip_v2" "salt" {
 }
 
 resource "openstack_compute_instance_v2" "salt" {
-    name = "salt"
+    name = "salt.${var.deploy_environment_name}"
     security_groups = [
         "default",
     ]
@@ -67,6 +67,8 @@ resource "openstack_compute_instance_v2" "salt" {
         salt_version            = var.salt_version
         ssh_public_key          = file(var.ssh_public_key_file)
         salt_master_ip          = openstack_networking_port_v2.salt_private.fixed_ip[0]
+        set_hostname            = true
+        hostname                = "salt.${var.deploy_environment_name}"
     })
 
     network {
-- 
GitLab


From b52dc5e19d146fb75cb5dd10153d09bbd7e56fd9 Mon Sep 17 00:00:00 2001
From: David Visscher <d.j.visscher@rug.nl>
Date: Tue, 1 Apr 2025 10:52:55 +0200
Subject: [PATCH 08/43] reformat

---
 .../local_libvirt/cloud_init/user_data.tftpl  |   2 +
 terraform/openstack/ceph_monitor.tf           | 103 +++---
 terraform/openstack/ceph_osd.tf               | 137 +++----
 terraform/openstack/flavor.tf                 |   2 +-
 terraform/openstack/image.tf                  |   2 +-
 terraform/openstack/monitor.tf                | 140 +++----
 terraform/openstack/networking.tf             |  60 +--
 terraform/openstack/openstack_compute.tf      | 120 +++---
 terraform/openstack/openstack_controller.tf   | 101 ++---
 terraform/openstack/openstack_database.tf     | 101 ++---
 terraform/openstack/openstack_networker.tf    | 137 +++----
 terraform/openstack/openstack_serviceproxy.tf | 137 +++----
 terraform/openstack/salt.tf                   | 347 +++++++++---------
 terraform/openstack/terraform.tf              |  58 +--
 14 files changed, 736 insertions(+), 711 deletions(-)

diff --git a/terraform/local_libvirt/cloud_init/user_data.tftpl b/terraform/local_libvirt/cloud_init/user_data.tftpl
index 382dc36..b48f22e 100644
--- a/terraform/local_libvirt/cloud_init/user_data.tftpl
+++ b/terraform/local_libvirt/cloud_init/user_data.tftpl
@@ -18,6 +18,8 @@ runcmd:
   - "set -x"
 %{ if host_type != "salt-master" ~}
   - "echo '${salt_master_ip} salt' >> /etc/hosts"
+%{ else }
+  - "echo '127.0.0.1 salt' >> /etc/hosts"
 %{ endif ~}
   - 'sudo dnf install --assumeyes --refresh epel-release'
   - 'sudo dnf clean all'
diff --git a/terraform/openstack/ceph_monitor.tf b/terraform/openstack/ceph_monitor.tf
index edb99ff..8e0144d 100644
--- a/terraform/openstack/ceph_monitor.tf
+++ b/terraform/openstack/ceph_monitor.tf
@@ -1,74 +1,77 @@
 variable "ceph_mon_count" {
-    type = number
-    default = 1
+  type    = number
+  default = 1
 }
 
 variable "ceph_mon_size" {
-    type = number
-    default = 50
+  type    = number
+  default = 50
 }
 
 resource "openstack_networking_port_v2" "ceph_monitor_private" {
-    count = var.ceph_mon_count
-    network_id = openstack_networking_network_v2.private.id
-    admin_state_up = true
+  count          = var.ceph_mon_count
+  network_id     = openstack_networking_network_v2.private.id
+  admin_state_up = true
 
-    fixed_ip {
-        subnet_id = openstack_networking_subnet_v2.private.id
-        ip_address = cidrhost(openstack_networking_subnet_v2.private.cidr, count.index + 80)
-    }
+  fixed_ip {
+    subnet_id  = openstack_networking_subnet_v2.private.id
+    ip_address = cidrhost(openstack_networking_subnet_v2.private.cidr, count.index + 80)
+  }
 }
 
 resource "openstack_blockstorage_volume_v3" "ceph_monitor_persistent_volume" {
-    count = var.ceph_mon_count
-    size = 50
-    image_id = data.openstack_images_image_v2.base_image.id
-    enable_online_resize = true
+  count                = var.ceph_mon_count
+  size                 = 50
+  image_id             = data.openstack_images_image_v2.base_image.id
+  enable_online_resize = true
+  depends_on = [
+    openstack_compute_floatingip_associate_v2.salt
+  ]
 }
 
 resource "openstack_compute_instance_v2" "ceph_monitor" {
-    count = var.ceph_mon_count
-    name = "ceph-monitor-${count.index}.${var.deploy_environment_name}"
+  count = var.ceph_mon_count
+  name  = "ceph-monitor-${count.index}.${var.deploy_environment_name}"
 
-    flavor_id = data.openstack_compute_flavor_v2.small.id
+  flavor_id = data.openstack_compute_flavor_v2.small.id
 
-    user_data = templatefile("${path.module}/cloud_init/user_data.tftpl", {
-        deploy_environment_name = var.deploy_environment_name
-        deploy_username         = var.deploy_username
-        host_type               = "ceph-monitor"
-        salt_version            = var.salt_version
-        ssh_public_key          = file(var.ssh_public_key_file)
-        salt_master_ip          = openstack_networking_port_v2.salt_private.fixed_ip[0].ip_address
-        set_hostname            = true
-        hostname                = "ceph-monitor-${count.index}.${var.deploy_environment_name}"
-    })
+  user_data = templatefile("${path.module}/cloud_init/user_data.tftpl", {
+    deploy_environment_name = var.deploy_environment_name
+    deploy_username         = var.deploy_username
+    host_type               = "ceph-monitor"
+    salt_version            = var.salt_version
+    ssh_public_key          = file(var.ssh_public_key_file)
+    salt_master_ip          = openstack_networking_port_v2.salt_private.fixed_ip[0].ip_address
+    set_hostname            = true
+    hostname                = "ceph-monitor-${count.index}"
+  })
 
-    connection {
-        type = "ssh"
-        user = var.deploy_username
-        host = self.access_ip_v4
-        private_key = file(var.ssh_private_key_file)
+  connection {
+    type        = "ssh"
+    user        = var.deploy_username
+    host        = self.access_ip_v4
+    private_key = file(var.ssh_private_key_file)
 
-        bastion_host = openstack_compute_floatingip_v2.salt.address
-        bastion_user = var.deploy_username
-        bastion_private_key = file(var.ssh_private_key_file)
-    }
+    bastion_host        = openstack_compute_floatingip_v2.salt.address
+    bastion_user        = var.deploy_username
+    bastion_private_key = file(var.ssh_private_key_file)
+  }
 
-    provisioner "remote-exec" {
-        inline = [
-            "until [ -f /run/cloud-init-done ]; do sleep 5; done"
-        ]
-    }
+  provisioner "remote-exec" {
+    inline = [
+      "until [ -f /run/cloud-init-done ]; do sleep 5; done"
+    ]
+  }
 
-    network {
-        port = element(openstack_networking_port_v2.ceph_monitor_private.*.id, count.index)
-    }
+  network {
+    port = element(openstack_networking_port_v2.ceph_monitor_private.*.id, count.index)
+  }
 
-    block_device {
-        source_type = "volume"
-        destination_type = "volume"
-        uuid = element(openstack_blockstorage_volume_v3.ceph_monitor_persistent_volume.*.id, count.index)
-    }
+  block_device {
+    source_type      = "volume"
+    destination_type = "volume"
+    uuid             = element(openstack_blockstorage_volume_v3.ceph_monitor_persistent_volume.*.id, count.index)
+  }
 }
 
 
diff --git a/terraform/openstack/ceph_osd.tf b/terraform/openstack/ceph_osd.tf
index 394caf4..d19dc4e 100644
--- a/terraform/openstack/ceph_osd.tf
+++ b/terraform/openstack/ceph_osd.tf
@@ -1,86 +1,89 @@
 variable "ceph_osd_count" {
-    type = number
-    default = 3
+  type    = number
+  default = 3
 }
 
 variable "ceph_osd_size" {
-    type = number
-    default = 100
+  type    = number
+  default = 100
 }
 
 resource "openstack_networking_port_v2" "ceph_osd_private" {
-    count = var.ceph_osd_count
-    network_id = openstack_networking_network_v2.private.id
-    admin_state_up = true
-
-    fixed_ip {
-        subnet_id = openstack_networking_subnet_v2.private.id
-        ip_address = cidrhost(openstack_networking_subnet_v2.private.cidr, count.index + 70)
-    }
+  count          = var.ceph_osd_count
+  network_id     = openstack_networking_network_v2.private.id
+  admin_state_up = true
+
+  fixed_ip {
+    subnet_id  = openstack_networking_subnet_v2.private.id
+    ip_address = cidrhost(openstack_networking_subnet_v2.private.cidr, count.index + 70)
+  }
 }
 
 resource "openstack_blockstorage_volume_v3" "ceph_osd_persistent_volume" {
-    count = var.ceph_osd_count
-    size = var.ceph_osd_size
-    image_id = data.openstack_images_image_v2.base_image.id
+  count    = var.ceph_osd_count
+  size     = var.ceph_osd_size
+  image_id = data.openstack_images_image_v2.base_image.id
+  depends_on = [
+    openstack_compute_floatingip_associate_v2.salt
+  ]
 }
 
 resource "openstack_blockstorage_volume_v3" "ceph_osd_data_disk" {
-    size = 100
-    count = var.ceph_osd_count
+  size  = 100
+  count = var.ceph_osd_count
 }
 
 resource "openstack_compute_instance_v2" "ceph_osd" {
-    count = var.ceph_osd_count
-    name = "ceph-osd-${count.index}.${var.deploy_environment_name}"
-
-    flavor_id = data.openstack_compute_flavor_v2.small.id
-
-    user_data = templatefile("${path.module}/cloud_init/user_data.tftpl", {
-        deploy_environment_name = var.deploy_environment_name
-        deploy_username         = var.deploy_username
-        host_type               = "ceph-osd"
-        salt_version            = var.salt_version
-        ssh_public_key          = file(var.ssh_public_key_file)
-        salt_master_ip          = openstack_networking_port_v2.salt_private.fixed_ip[0].ip_address
-        set_hostname            = true
-        hostname                = "ceph-osd-${count.index}.${var.deploy_environment_name}"
-    })
-
-    connection {
-        type = "ssh"
-        user = var.deploy_username
-        host = self.access_ip_v4
-        private_key = file(var.ssh_private_key_file)
-
-        bastion_host = openstack_compute_floatingip_v2.salt.address
-        bastion_user = var.deploy_username
-        bastion_private_key = file(var.ssh_private_key_file)
-    }
-
-    provisioner "remote-exec" {
-        inline = [
-            "until [ -f /run/cloud-init-done ]; do sleep 5; done"
-        ]
-    }
-
-    network {
-        port = element(openstack_networking_port_v2.ceph_osd_private.*.id, count.index)
-    }
-
-    block_device {
-        source_type = "volume"
-        destination_type = "volume"
-        uuid = element(openstack_blockstorage_volume_v3.ceph_osd_persistent_volume.*.id, count.index)
-        boot_index = 0
-    }
-
-    block_device {
-        source_type = "volume"
-        destination_type = "volume"
-        uuid = element(openstack_blockstorage_volume_v3.ceph_osd_data_disk.*.id, count.index)
-        boot_index = 1
-    }
+  count = var.ceph_osd_count
+  name  = "ceph-osd-${count.index}.${var.deploy_environment_name}"
+
+  flavor_id = data.openstack_compute_flavor_v2.small.id
+
+  user_data = templatefile("${path.module}/cloud_init/user_data.tftpl", {
+    deploy_environment_name = var.deploy_environment_name
+    deploy_username         = var.deploy_username
+    host_type               = "ceph-osd"
+    salt_version            = var.salt_version
+    ssh_public_key          = file(var.ssh_public_key_file)
+    salt_master_ip          = openstack_networking_port_v2.salt_private.fixed_ip[0].ip_address
+    set_hostname            = true
+    hostname                = "ceph-osd-${count.index}"
+  })
+
+  connection {
+    type        = "ssh"
+    user        = var.deploy_username
+    host        = self.access_ip_v4
+    private_key = file(var.ssh_private_key_file)
+
+    bastion_host        = openstack_compute_floatingip_v2.salt.address
+    bastion_user        = var.deploy_username
+    bastion_private_key = file(var.ssh_private_key_file)
+  }
+
+  provisioner "remote-exec" {
+    inline = [
+      "until [ -f /run/cloud-init-done ]; do sleep 5; done"
+    ]
+  }
+
+  network {
+    port = element(openstack_networking_port_v2.ceph_osd_private.*.id, count.index)
+  }
+
+  block_device {
+    source_type      = "volume"
+    destination_type = "volume"
+    uuid             = element(openstack_blockstorage_volume_v3.ceph_osd_persistent_volume.*.id, count.index)
+    boot_index       = 0
+  }
+
+  block_device {
+    source_type      = "volume"
+    destination_type = "volume"
+    uuid             = element(openstack_blockstorage_volume_v3.ceph_osd_data_disk.*.id, count.index)
+    boot_index       = 1
+  }
 }
 
 
diff --git a/terraform/openstack/flavor.tf b/terraform/openstack/flavor.tf
index f7d9b01..64305bf 100644
--- a/terraform/openstack/flavor.tf
+++ b/terraform/openstack/flavor.tf
@@ -1,3 +1,3 @@
-data openstack_compute_flavor_v2 "small" {
+data "openstack_compute_flavor_v2" "small" {
   name = var.default_small_flavor_name
 }
\ No newline at end of file
diff --git a/terraform/openstack/image.tf b/terraform/openstack/image.tf
index 365fd48..5335d55 100644
--- a/terraform/openstack/image.tf
+++ b/terraform/openstack/image.tf
@@ -1,3 +1,3 @@
-data openstack_images_image_v2 "base_image" {
+data "openstack_images_image_v2" "base_image" {
   name = var.base_image_name
 }
\ No newline at end of file
diff --git a/terraform/openstack/monitor.tf b/terraform/openstack/monitor.tf
index e714978..06e9061 100644
--- a/terraform/openstack/monitor.tf
+++ b/terraform/openstack/monitor.tf
@@ -1,90 +1,90 @@
 variable "monitor_count" {
-    type = number
-    default = 1
+  type    = number
+  default = 1
 }
 
 variable "monitor_size" {
-    type = number
-    default = 50
+  type    = number
+  default = 50
 }
 
 resource "openstack_networking_port_v2" "monitor_private" {
-    count = var.monitor_count
-    network_id = openstack_networking_network_v2.private.id
-    admin_state_up = true
-
-    fixed_ip {
-        subnet_id = openstack_networking_subnet_v2.private.id
-        ip_address = cidrhost(openstack_networking_subnet_v2.private.cidr, count.index + 5)
-    }
+  count          = var.monitor_count
+  network_id     = openstack_networking_network_v2.private.id
+  admin_state_up = true
+
+  fixed_ip {
+    subnet_id  = openstack_networking_subnet_v2.private.id
+    ip_address = cidrhost(openstack_networking_subnet_v2.private.cidr, count.index + 5)
+  }
 }
 
 resource "openstack_networking_port_v2" "monitor_public" {
-    count = var.monitor_count
-    network_id = openstack_networking_network_v2.public.id
-    admin_state_up = true
-
-    fixed_ip {
-        subnet_id = openstack_networking_subnet_v2.public.id
-        ip_address = cidrhost(openstack_networking_subnet_v2.public.cidr, count.index + 5)
-    }
+  count          = var.monitor_count
+  network_id     = openstack_networking_network_v2.public.id
+  admin_state_up = true
+
+  fixed_ip {
+    subnet_id  = openstack_networking_subnet_v2.public.id
+    ip_address = cidrhost(openstack_networking_subnet_v2.public.cidr, count.index + 5)
+  }
 }
 
 
 resource "openstack_blockstorage_volume_v3" "monitor_persistent_volume" {
-    image_id = data.openstack_images_image_v2.base_image.id
-    count = var.monitor_count
-    size = var.monitor_size
+  image_id = data.openstack_images_image_v2.base_image.id
+  count    = var.monitor_count
+  size     = var.monitor_size
 }
 
 resource "openstack_compute_instance_v2" "monitor" {
-    count = var.monitor_count
-    name = "openstack-serviceproxy-${count.index}.${var.deploy_environment_name}"
-
-    flavor_id = data.openstack_compute_flavor_v2.small.id
-
-    user_data = templatefile("${path.module}/cloud_init/user_data.tftpl", {
-        deploy_environment_name = var.deploy_environment_name
-        deploy_username         = var.deploy_username
-        host_type               = "openstack-serviceproxy"
-        salt_version            = var.salt_version
-        ssh_public_key          = file(var.ssh_public_key_file)
-        salt_master_ip          = openstack_networking_port_v2.salt_private.fixed_ip[0].ip_address
-        set_hostname            = true
-        hostname                = "openstack-serviceproxy-${count.index}.${var.deploy_environment_name}"
-    })
-
-    connection {
-        type = "ssh"
-        user = var.deploy_username
-        host = self.access_ip_v4
-        private_key = file(var.ssh_private_key_file)
-
-        bastion_host = openstack_compute_floatingip_v2.salt.address
-        bastion_user = var.deploy_username
-        bastion_private_key = file(var.ssh_private_key_file)
-    }
-
-    provisioner "remote-exec" {
-        inline = [
-            "until [ -f /run/cloud-init-done ]; do sleep 5; done"
-        ]
-    }
-
-    network {
-        port = element(openstack_networking_port_v2.monitor_public.*.id, count.index)
-    }
-
-    network {
-        port = element(openstack_networking_port_v2.monitor_private.*.id, count.index)
-    }
-
-    block_device {
-        source_type = "volume"
-        destination_type = "volume"
-        uuid = element(openstack_blockstorage_volume_v3.monitor_persistent_volume.*.id, count.index)
-        boot_index = 0
-    }
+  count = var.monitor_count
+  name  = "openstack-serviceproxy-${count.index}.${var.deploy_environment_name}"
+
+  flavor_id = data.openstack_compute_flavor_v2.small.id
+
+  user_data = templatefile("${path.module}/cloud_init/user_data.tftpl", {
+    deploy_environment_name = var.deploy_environment_name
+    deploy_username         = var.deploy_username
+    host_type               = "openstack-serviceproxy"
+    salt_version            = var.salt_version
+    ssh_public_key          = file(var.ssh_public_key_file)
+    salt_master_ip          = openstack_networking_port_v2.salt_private.fixed_ip[0].ip_address
+    set_hostname            = true
+    hostname                = "openstack-serviceproxy-${count.index}"
+  })
+
+  connection {
+    type        = "ssh"
+    user        = var.deploy_username
+    host        = self.access_ip_v4
+    private_key = file(var.ssh_private_key_file)
+
+    bastion_host        = openstack_compute_floatingip_v2.salt.address
+    bastion_user        = var.deploy_username
+    bastion_private_key = file(var.ssh_private_key_file)
+  }
+
+  provisioner "remote-exec" {
+    inline = [
+      "until [ -f /run/cloud-init-done ]; do sleep 5; done"
+    ]
+  }
+
+  network {
+    port = element(openstack_networking_port_v2.monitor_public.*.id, count.index)
+  }
+
+  network {
+    port = element(openstack_networking_port_v2.monitor_private.*.id, count.index)
+  }
+
+  block_device {
+    source_type      = "volume"
+    destination_type = "volume"
+    uuid             = element(openstack_blockstorage_volume_v3.monitor_persistent_volume.*.id, count.index)
+    boot_index       = 0
+  }
 }
 
 
diff --git a/terraform/openstack/networking.tf b/terraform/openstack/networking.tf
index 40418dc..8396340 100644
--- a/terraform/openstack/networking.tf
+++ b/terraform/openstack/networking.tf
@@ -1,51 +1,51 @@
 data "openstack_networking_network_v2" "external" {
-    name = var.external_network_name
+  name = var.external_network_name
 }
 resource "openstack_networking_network_v2" "public" {
-    name           = "cloud4_public_network"
-    admin_state_up = "true"
-    mtu            = 1450
+  name           = "cloud4_public_network"
+  admin_state_up = "true"
+  mtu            = 1450
 }
 resource "openstack_networking_subnet_v2" "public" {
-    name       = "cloud4_public_subnet"
-    network_id = openstack_networking_network_v2.public.id
-    cidr       = "10.10.0.0/16"
-    ip_version = 4
-    dns_nameservers = ["1.1.1.1", "1.0.0.1"]
+  name            = "cloud4_public_subnet"
+  network_id      = openstack_networking_network_v2.public.id
+  cidr            = "10.10.0.0/16"
+  ip_version      = 4
+  dns_nameservers = ["1.1.1.1", "1.0.0.1"]
 }
 resource "openstack_networking_router_v2" "os_router" {
-    name                = "cloud4_public_router"
-    admin_state_up      = true
-    external_network_id = data.openstack_networking_network_v2.external.id
+  name                = "cloud4_public_router"
+  admin_state_up      = true
+  external_network_id = data.openstack_networking_network_v2.external.id
 }
 resource "openstack_networking_router_interface_v2" "public_subnet_interface" {
-    router_id = openstack_networking_router_v2.os_router.id
-    subnet_id = openstack_networking_subnet_v2.public.id
+  router_id = openstack_networking_router_v2.os_router.id
+  subnet_id = openstack_networking_subnet_v2.public.id
 }
 
 resource "openstack_networking_router_interface_v2" "private_subnet_interface" {
-    router_id = openstack_networking_router_v2.os_router.id
-    subnet_id = openstack_networking_subnet_v2.private.id
+  router_id = openstack_networking_router_v2.os_router.id
+  subnet_id = openstack_networking_subnet_v2.private.id
 }
 
 resource "openstack_networking_network_v2" "private" {
-    name           = "cloud4_private_network"
-    admin_state_up = "true"
-    mtu            = 1450
+  name           = "cloud4_private_network"
+  admin_state_up = "true"
+  mtu            = 1450
 }
 resource "openstack_networking_subnet_v2" "private" {
-    name          = "cloud4_private_subnet"
-    network_id    = openstack_networking_network_v2.private.id
-    cidr          = "10.11.0.0/24"
-    ip_version    = 4
+  name       = "cloud4_private_subnet"
+  network_id = openstack_networking_network_v2.private.id
+  cidr       = "10.11.0.0/24"
+  ip_version = 4
 
-    enable_dhcp       = true
+  enable_dhcp = true
 }
 resource "openstack_networking_floatingip_v2" "reserved" {
-    count = 2
-    pool  = var.external_network_name
-    lifecycle {
-        # Set this to true to keep hold of the floating IPs when the environment is destroyed
-        prevent_destroy = false
-    }
+  count = 2
+  pool  = var.external_network_name
+  lifecycle {
+    # Set this to true to keep hold of the floating IPs when the environment is destroyed
+    prevent_destroy = false
+  }
 }
\ No newline at end of file
diff --git a/terraform/openstack/openstack_compute.tf b/terraform/openstack/openstack_compute.tf
index 9ce5289..129a05c 100644
--- a/terraform/openstack/openstack_compute.tf
+++ b/terraform/openstack/openstack_compute.tf
@@ -1,74 +1,78 @@
 variable "openstack_compute_count" {
-    type = number
-    default = 1
+  type    = number
+  default = 1
 }
 
 variable "openstack_compute_size" {
-    type = number
-    default = 100
+  type    = number
+  default = 100
 }
 
 resource "openstack_networking_port_v2" "openstack_compute_private" {
-    count = var.openstack_compute_count
-    network_id = openstack_networking_network_v2.private.id
-    admin_state_up = true
-
-    fixed_ip {
-        subnet_id = openstack_networking_subnet_v2.private.id
-        ip_address = cidrhost(openstack_networking_subnet_v2.private.cidr, count.index + 20)
-    }
+  count          = var.openstack_compute_count
+  network_id     = openstack_networking_network_v2.private.id
+  admin_state_up = true
+
+  fixed_ip {
+    subnet_id  = openstack_networking_subnet_v2.private.id
+    ip_address = cidrhost(openstack_networking_subnet_v2.private.cidr, count.index + 20)
+  }
 }
 
 resource "openstack_blockstorage_volume_v3" "openstack_compute_persistent_volume" {
-    count = var.openstack_compute_count
-    size = var.openstack_compute_size
-    image_id = data.openstack_images_image_v2.base_image.id
+  count    = var.openstack_compute_count
+  size     = var.openstack_compute_size
+  image_id = data.openstack_images_image_v2.base_image.id
+
+  depends_on = [
+    openstack_compute_floatingip_associate_v2.salt
+  ]
 }
 
 resource "openstack_compute_instance_v2" "openstack_compute" {
-    count = var.openstack_compute_count
-    name = "openstack-compute-${count.index}.${var.deploy_environment_name}"
-
-    flavor_id = data.openstack_compute_flavor_v2.small.id
-
-    user_data = templatefile("${path.module}/cloud_init/user_data.tftpl", {
-        deploy_environment_name = var.deploy_environment_name
-        deploy_username         = var.deploy_username
-        host_type               = "salt-minion-openstack"
-        salt_version            = var.salt_version
-        ssh_public_key          = file(var.ssh_public_key_file)
-        salt_master_ip          = openstack_networking_port_v2.salt_private.fixed_ip[0].ip_address
-        set_hostname            = true
-        hostname                = "openstack-compute-${count.index}.${var.deploy_environment_name}"
-    })
-
-    connection {
-        type = "ssh"
-        user = var.deploy_username
-        host = self.access_ip_v4
-        private_key = file(var.ssh_private_key_file)
-
-        bastion_host = openstack_compute_floatingip_v2.salt.address
-        bastion_user = var.deploy_username
-        bastion_private_key = file(var.ssh_private_key_file)
-    }
-
-    provisioner "remote-exec" {
-        inline = [
-            "until [ -f /run/cloud-init-done ]; do sleep 5; done"
-        ]
-    }
-
-    network {
-        port = element(openstack_networking_port_v2.openstack_compute_private.*.id, count.index)
-    }
-
-    block_device {
-        source_type = "volume"
-        destination_type = "volume"
-        uuid = element(openstack_blockstorage_volume_v3.openstack_compute_persistent_volume.*.id, count.index)
-        boot_index = 0
-    }
+  count = var.openstack_compute_count
+  name  = "openstack-compute-${count.index}.${var.deploy_environment_name}"
+
+  flavor_id = data.openstack_compute_flavor_v2.small.id
+
+  user_data = templatefile("${path.module}/cloud_init/user_data.tftpl", {
+    deploy_environment_name = var.deploy_environment_name
+    deploy_username         = var.deploy_username
+    host_type               = "salt-minion-openstack"
+    salt_version            = var.salt_version
+    ssh_public_key          = file(var.ssh_public_key_file)
+    salt_master_ip          = openstack_networking_port_v2.salt_private.fixed_ip[0].ip_address
+    set_hostname            = true
+    hostname                = "openstack-compute-${count.index}"
+  })
+
+  connection {
+    type        = "ssh"
+    user        = var.deploy_username
+    host        = self.access_ip_v4
+    private_key = file(var.ssh_private_key_file)
+
+    bastion_host        = openstack_compute_floatingip_v2.salt.address
+    bastion_user        = var.deploy_username
+    bastion_private_key = file(var.ssh_private_key_file)
+  }
+
+  provisioner "remote-exec" {
+    inline = [
+      "until [ -f /run/cloud-init-done ]; do sleep 5; done"
+    ]
+  }
+
+  network {
+    port = element(openstack_networking_port_v2.openstack_compute_private.*.id, count.index)
+  }
+
+  block_device {
+    source_type      = "volume"
+    destination_type = "volume"
+    uuid             = element(openstack_blockstorage_volume_v3.openstack_compute_persistent_volume.*.id, count.index)
+    boot_index       = 0
+  }
 }
 
 
diff --git a/terraform/openstack/openstack_controller.tf b/terraform/openstack/openstack_controller.tf
index 52340b4..886ef26 100644
--- a/terraform/openstack/openstack_controller.tf
+++ b/terraform/openstack/openstack_controller.tf
@@ -1,73 +1,76 @@
 variable "openstack_controller_count" {
-    type = number
-    default = 1
+  type    = number
+  default = 1
 }
 
 variable "openstack_controller_size" {
-    type = number
-    default = 20
+  type    = number
+  default = 20
 }
 
 resource "openstack_networking_port_v2" "openstack_controller_private" {
-    count = var.openstack_controller_count
-    network_id = openstack_networking_network_v2.private.id
-    admin_state_up = true
+  count          = var.openstack_controller_count
+  network_id     = openstack_networking_network_v2.private.id
+  admin_state_up = true
 
-    fixed_ip {
-        subnet_id = openstack_networking_subnet_v2.private.id
-        ip_address = cidrhost(openstack_networking_subnet_v2.private.cidr, count.index + 10)
-    }
+  fixed_ip {
+    subnet_id  = openstack_networking_subnet_v2.private.id
+    ip_address = cidrhost(openstack_networking_subnet_v2.private.cidr, count.index + 10)
+  }
 }
 
 resource "openstack_blockstorage_volume_v3" "openstack_controller_persistent_volume" {
-    count = var.openstack_controller_count
-    size = var.openstack_controller_size
-    image_id = data.openstack_images_image_v2.base_image.id
+  count    = var.openstack_controller_count
+  size     = var.openstack_controller_size
+  image_id = data.openstack_images_image_v2.base_image.id
+  depends_on = [
+    openstack_compute_floatingip_associate_v2.salt
+  ]
 }
 
 resource "openstack_compute_instance_v2" "openstack_controller" {
-    count = var.openstack_controller_count
-    name = "openstack-controller-${count.index}.${var.deploy_environment_name}"
+  count = var.openstack_controller_count
+  name  = "openstack-controller-${count.index}.${var.deploy_environment_name}"
 
-    flavor_id = data.openstack_compute_flavor_v2.small.id
+  flavor_id = data.openstack_compute_flavor_v2.small.id
 
-    user_data = templatefile("${path.module}/cloud_init/user_data.tftpl", {
-        deploy_environment_name = var.deploy_environment_name
-        deploy_username         = var.deploy_username
-        host_type               = "salt-minion-openstack"
-        salt_version            = var.salt_version
-        ssh_public_key          = file(var.ssh_public_key_file)
-        salt_master_ip          = openstack_networking_port_v2.salt_private.fixed_ip[0].ip_address
-        set_hostname            = true
-        hostname                = "openstack-controller-${count.index}.${var.deploy_environment_name}"
-    })
+  user_data = templatefile("${path.module}/cloud_init/user_data.tftpl", {
+    deploy_environment_name = var.deploy_environment_name
+    deploy_username         = var.deploy_username
+    host_type               = "salt-minion-openstack"
+    salt_version            = var.salt_version
+    ssh_public_key          = file(var.ssh_public_key_file)
+    salt_master_ip          = openstack_networking_port_v2.salt_private.fixed_ip[0].ip_address
+    set_hostname            = true
+    hostname                = "openstack-controller-${count.index}"
+  })
 
-    connection {
-        type = "ssh"
-        user = var.deploy_username
-        host = self.access_ip_v4
-        private_key = file(var.ssh_private_key_file)
+  connection {
+    type        = "ssh"
+    user        = var.deploy_username
+    host        = self.access_ip_v4
+    private_key = file(var.ssh_private_key_file)
 
-        bastion_host = openstack_compute_floatingip_v2.salt.address
-        bastion_user = var.deploy_username
-        bastion_private_key = file(var.ssh_private_key_file)
-    }
+    bastion_host        = openstack_compute_floatingip_v2.salt.address
+    bastion_user        = var.deploy_username
+    bastion_private_key = file(var.ssh_private_key_file)
+  }
 
-    provisioner "remote-exec" {
-        inline = [
-            "until [ -f /run/cloud-init-done ]; do sleep 5; done"
-        ]
-    }
+  provisioner "remote-exec" {
+    inline = [
+      "until [ -f /run/cloud-init-done ]; do sleep 5; done"
+    ]
+  }
 
-    network {
-        port = element(openstack_networking_port_v2.openstack_controller_private.*.id, count.index)
-    }
+  network {
+    port = element(openstack_networking_port_v2.openstack_controller_private.*.id, count.index)
+  }
 
-    block_device {
-        source_type = "volume"
-        destination_type = "volume"
-        uuid = element(openstack_blockstorage_volume_v3.openstack_controller_persistent_volume.*.id, count.index)
-    }
+  block_device {
+    source_type      = "volume"
+    destination_type = "volume"
+    uuid             = element(openstack_blockstorage_volume_v3.openstack_controller_persistent_volume.*.id, count.index)
+  }
 }
 
 
diff --git a/terraform/openstack/openstack_database.tf b/terraform/openstack/openstack_database.tf
index 27316b4..9902fec 100644
--- a/terraform/openstack/openstack_database.tf
+++ b/terraform/openstack/openstack_database.tf
@@ -1,73 +1,76 @@
 variable "openstack_database_count" {
-    type = number
-    default = 1
+  type    = number
+  default = 1
 }
 
 variable "openstack_database_size" {
-    type = number
-    default = 20
+  type    = number
+  default = 20
 }
 
 resource "openstack_networking_port_v2" "openstack_database_private" {
-    count = var.openstack_database_count
-    network_id = openstack_networking_network_v2.private.id
-    admin_state_up = true
+  count          = var.openstack_database_count
+  network_id     = openstack_networking_network_v2.private.id
+  admin_state_up = true
 
-    fixed_ip {
-        subnet_id = openstack_networking_subnet_v2.private.id
-        ip_address = cidrhost(openstack_networking_subnet_v2.private.cidr, count.index + 30)
-    }
+  fixed_ip {
+    subnet_id  = openstack_networking_subnet_v2.private.id
+    ip_address = cidrhost(openstack_networking_subnet_v2.private.cidr, count.index + 30)
+  }
 }
 
 resource "openstack_blockstorage_volume_v3" "openstack_database_persistent_volume" {
-    count = var.openstack_database_count
-    size = var.openstack_database_size
-    image_id = data.openstack_images_image_v2.base_image.id
+  count    = var.openstack_database_count
+  size     = var.openstack_database_size
+  image_id = data.openstack_images_image_v2.base_image.id
+  depends_on = [
+    openstack_compute_floatingip_associate_v2.salt
+  ]
 }
 
 resource "openstack_compute_instance_v2" "openstack_database" {
-    count = var.openstack_database_count
-    name = "openstack-database-${count.index}.${var.deploy_environment_name}"
+  count = var.openstack_database_count
+  name  = "openstack-database-${count.index}.${var.deploy_environment_name}"
 
-    flavor_id = data.openstack_compute_flavor_v2.small.id
+  flavor_id = data.openstack_compute_flavor_v2.small.id
 
-    user_data = templatefile("${path.module}/cloud_init/user_data.tftpl", {
-        deploy_environment_name = var.deploy_environment_name
-        deploy_username         = var.deploy_username
-        host_type               = "salt-minion-openstack"
-        salt_version            = var.salt_version
-        ssh_public_key          = file(var.ssh_public_key_file)
-        salt_master_ip          = openstack_networking_port_v2.salt_private.fixed_ip[0].ip_address
-        set_hostname            = true
-        hostname                = "openstack-database-${count.index}.${var.deploy_environment_name}"
-    })
+  user_data = templatefile("${path.module}/cloud_init/user_data.tftpl", {
+    deploy_environment_name = var.deploy_environment_name
+    deploy_username         = var.deploy_username
+    host_type               = "salt-minion-openstack"
+    salt_version            = var.salt_version
+    ssh_public_key          = file(var.ssh_public_key_file)
+    salt_master_ip          = openstack_networking_port_v2.salt_private.fixed_ip[0].ip_address
+    set_hostname            = true
+    hostname                = "openstack-database-${count.index}"
+  })
 
-    connection {
-        type = "ssh"
-        user = var.deploy_username
-        host = self.access_ip_v4
-        private_key = file(var.ssh_private_key_file)
+  connection {
+    type        = "ssh"
+    user        = var.deploy_username
+    host        = self.access_ip_v4
+    private_key = file(var.ssh_private_key_file)
 
-        bastion_host = openstack_compute_floatingip_v2.salt.address
-        bastion_user = var.deploy_username
-        bastion_private_key = file(var.ssh_private_key_file)
-    }
+    bastion_host        = openstack_compute_floatingip_v2.salt.address
+    bastion_user        = var.deploy_username
+    bastion_private_key = file(var.ssh_private_key_file)
+  }
 
-    provisioner "remote-exec" {
-        inline = [
-            "until [ -f /run/cloud-init-done ]; do sleep 5; done"
-        ]
-    }
+  provisioner "remote-exec" {
+    inline = [
+      "until [ -f /run/cloud-init-done ]; do sleep 5; done"
+    ]
+  }
 
-    network {
-        port = element(openstack_networking_port_v2.openstack_database_private.*.id, count.index)
-    }
+  network {
+    port = element(openstack_networking_port_v2.openstack_database_private.*.id, count.index)
+  }
 
-    block_device {
-        source_type = "volume"
-        destination_type = "volume"
-        uuid = element(openstack_blockstorage_volume_v3.openstack_database_persistent_volume.*.id, count.index)
-    }
+  block_device {
+    source_type      = "volume"
+    destination_type = "volume"
+    uuid             = element(openstack_blockstorage_volume_v3.openstack_database_persistent_volume.*.id, count.index)
+  }
 }
 
 
diff --git a/terraform/openstack/openstack_networker.tf b/terraform/openstack/openstack_networker.tf
index 4af7a88..cc45208 100644
--- a/terraform/openstack/openstack_networker.tf
+++ b/terraform/openstack/openstack_networker.tf
@@ -1,83 +1,86 @@
 variable "openstack_networker_count" {
-    type = number
-    default = 1
+  type    = number
+  default = 1
 }
 
 resource "openstack_networking_port_v2" "openstack_networker_private" {
-    count = var.openstack_networker_count
-    network_id = openstack_networking_network_v2.private.id
-    admin_state_up = true
-
-    fixed_ip {
-        subnet_id = openstack_networking_subnet_v2.private.id
-        ip_address = cidrhost(openstack_networking_subnet_v2.private.cidr, count.index + 40)
-    }
+  count          = var.openstack_networker_count
+  network_id     = openstack_networking_network_v2.private.id
+  admin_state_up = true
+
+  fixed_ip {
+    subnet_id  = openstack_networking_subnet_v2.private.id
+    ip_address = cidrhost(openstack_networking_subnet_v2.private.cidr, count.index + 40)
+  }
 }
 
 resource "openstack_networking_port_v2" "openstack_networker_public" {
-    count = var.openstack_networker_count
-    network_id = openstack_networking_network_v2.public.id
-    admin_state_up = true
-
-    fixed_ip {
-        subnet_id = openstack_networking_subnet_v2.public.id
-        ip_address = cidrhost(openstack_networking_subnet_v2.public.cidr, count.index + 40)
-    }
+  count          = var.openstack_networker_count
+  network_id     = openstack_networking_network_v2.public.id
+  admin_state_up = true
+
+  fixed_ip {
+    subnet_id  = openstack_networking_subnet_v2.public.id
+    ip_address = cidrhost(openstack_networking_subnet_v2.public.cidr, count.index + 40)
+  }
 }
 
 resource "openstack_blockstorage_volume_v3" "networker_persistent_volume" {
-    count = var.openstack_networker_count
-    size = 30
-    image_id = data.openstack_images_image_v2.base_image.id
+  count    = var.openstack_networker_count
+  size     = 30
+  image_id = data.openstack_images_image_v2.base_image.id
+  depends_on = [
+    openstack_compute_floatingip_associate_v2.salt
+  ]
 }
 
 resource "openstack_compute_instance_v2" "openstack_networker" {
-    count = var.openstack_networker_count
-    name = "openstack-networker-${count.index}.${var.deploy_environment_name}"
-
-    flavor_id = data.openstack_compute_flavor_v2.small.id
-
-    user_data = templatefile("${path.module}/cloud_init/user_data.tftpl", {
-        deploy_environment_name = var.deploy_environment_name
-        deploy_username         = var.deploy_username
-        host_type               = "salt-minion-openstack"
-        salt_version            = var.salt_version
-        ssh_public_key          = file(var.ssh_public_key_file)
-        salt_master_ip          = openstack_networking_port_v2.salt_private.fixed_ip[0].ip_address
-        set_hostname            = true
-        hostname                = "openstack-networker-${count.index}.${var.deploy_environment_name}"
-    })
-
-    connection {
-        type = "ssh"
-        user = var.deploy_username
-        host = self.access_ip_v4
-        private_key = file(var.ssh_private_key_file)
-
-        bastion_host = openstack_compute_floatingip_v2.salt.address
-        bastion_user = var.deploy_username
-        bastion_private_key = file(var.ssh_private_key_file)
-    }
-
-    provisioner "remote-exec" {
-        inline = [
-            "until [ -f /run/cloud-init-done ]; do sleep 5; done"
-        ]
-    }
-
-    network {
-        port = element(openstack_networking_port_v2.openstack_networker_public.*.id, count.index)
-    }
-
-    network {
-        port = element(openstack_networking_port_v2.openstack_networker_private.*.id, count.index)
-    }
-
-    block_device {
-        source_type = "volume"
-        destination_type = "volume"
-        uuid = element(openstack_blockstorage_volume_v3.networker_persistent_volume.*.id, count.index)
-    }
+  count = var.openstack_networker_count
+  name  = "openstack-networker-${count.index}.${var.deploy_environment_name}"
+
+  flavor_id = data.openstack_compute_flavor_v2.small.id
+
+  user_data = templatefile("${path.module}/cloud_init/user_data.tftpl", {
+    deploy_environment_name = var.deploy_environment_name
+    deploy_username         = var.deploy_username
+    host_type               = "salt-minion-openstack"
+    salt_version            = var.salt_version
+    ssh_public_key          = file(var.ssh_public_key_file)
+    salt_master_ip          = openstack_networking_port_v2.salt_private.fixed_ip[0].ip_address
+    set_hostname            = true
+    hostname                = "openstack-networker-${count.index}"
+  })
+
+  connection {
+    type        = "ssh"
+    user        = var.deploy_username
+    host        = self.access_ip_v4
+    private_key = file(var.ssh_private_key_file)
+
+    bastion_host        = openstack_compute_floatingip_v2.salt.address
+    bastion_user        = var.deploy_username
+    bastion_private_key = file(var.ssh_private_key_file)
+  }
+
+  provisioner "remote-exec" {
+    inline = [
+      "until [ -f /run/cloud-init-done ]; do sleep 5; done"
+    ]
+  }
+
+  network {
+    port = element(openstack_networking_port_v2.openstack_networker_public.*.id, count.index)
+  }
+
+  network {
+    port = element(openstack_networking_port_v2.openstack_networker_private.*.id, count.index)
+  }
+
+  block_device {
+    source_type      = "volume"
+    destination_type = "volume"
+    uuid             = element(openstack_blockstorage_volume_v3.networker_persistent_volume.*.id, count.index)
+  }
 }
 
 
diff --git a/terraform/openstack/openstack_serviceproxy.tf b/terraform/openstack/openstack_serviceproxy.tf
index 13e05e8..189ff90 100644
--- a/terraform/openstack/openstack_serviceproxy.tf
+++ b/terraform/openstack/openstack_serviceproxy.tf
@@ -1,83 +1,86 @@
 variable "openstack_serviceproxy_count" {
-    type = number
-    default = 1
+  type    = number
+  default = 1
 }
 
 resource "openstack_networking_port_v2" "openstack_serviceproxy_private" {
-    count = var.openstack_serviceproxy_count
-    network_id = openstack_networking_network_v2.private.id
-    admin_state_up = true
-
-    fixed_ip {
-        subnet_id = openstack_networking_subnet_v2.private.id
-        ip_address = cidrhost(openstack_networking_subnet_v2.private.cidr, count.index + 100)
-    }
+  count          = var.openstack_serviceproxy_count
+  network_id     = openstack_networking_network_v2.private.id
+  admin_state_up = true
+
+  fixed_ip {
+    subnet_id  = openstack_networking_subnet_v2.private.id
+    ip_address = cidrhost(openstack_networking_subnet_v2.private.cidr, count.index + 100)
+  }
 }
 
 resource "openstack_networking_port_v2" "openstack_serviceproxy_public" {
-    count = var.openstack_serviceproxy_count
-    network_id = openstack_networking_network_v2.public.id
-    admin_state_up = true
-
-    fixed_ip {
-        subnet_id = openstack_networking_subnet_v2.public.id
-        ip_address = cidrhost(openstack_networking_subnet_v2.public.cidr, count.index + 100)
-    }
+  count          = var.openstack_serviceproxy_count
+  network_id     = openstack_networking_network_v2.public.id
+  admin_state_up = true
+
+  fixed_ip {
+    subnet_id  = openstack_networking_subnet_v2.public.id
+    ip_address = cidrhost(openstack_networking_subnet_v2.public.cidr, count.index + 100)
+  }
 }
 
 resource "openstack_blockstorage_volume_v3" "openstack_serviceproxy_persistent_volume" {
-    count = var.openstack_serviceproxy_count
-    size = 40
-    image_id = data.openstack_images_image_v2.base_image.id
+  count    = var.openstack_serviceproxy_count
+  size     = 40
+  image_id = data.openstack_images_image_v2.base_image.id
+  depends_on = [
+    openstack_compute_floatingip_associate_v2.salt
+  ]
 }
 
 resource "openstack_compute_instance_v2" "openstack_serviceproxy" {
-    count = var.openstack_serviceproxy_count
-    name = "openstack-serviceproxy-${count.index}.${var.deploy_environment_name}"
-
-    flavor_id = data.openstack_compute_flavor_v2.small.id
-
-    user_data = templatefile("${path.module}/cloud_init/user_data.tftpl", {
-        deploy_environment_name = var.deploy_environment_name
-        deploy_username         = var.deploy_username
-        host_type               = "salt-minion-openstack"
-        salt_version            = var.salt_version
-        ssh_public_key          = file(var.ssh_public_key_file)
-        salt_master_ip          = openstack_networking_port_v2.salt_private.fixed_ip[0].ip_address
-        set_hostname            = true
-        hostname                = "openstack-serviceproxy-${count.index}.${var.deploy_environment_name}"
-    })
-
-    connection {
-        type = "ssh"
-        user = var.deploy_username
-        host = self.access_ip_v4
-        private_key = file(var.ssh_private_key_file)
-
-        bastion_host = openstack_compute_floatingip_v2.salt.address
-        bastion_user = var.deploy_username
-        bastion_private_key = file(var.ssh_private_key_file)
-    }
-
-    provisioner "remote-exec" {
-        inline = [
-            "until [ -f /run/cloud-init-done ]; do sleep 5; done"
-        ]
-    }
-
-    network {
-        port = element(openstack_networking_port_v2.openstack_serviceproxy_public.*.id, count.index)
-    }
-
-    network {
-        port = element(openstack_networking_port_v2.openstack_serviceproxy_private.*.id, count.index)
-    }
-
-    block_device {
-        source_type = "volume"
-        destination_type = "volume"
-        uuid = element(openstack_blockstorage_volume_v3.openstack_serviceproxy_persistent_volume.*.id, count.index)
-    }
+  count = var.openstack_serviceproxy_count
+  name  = "openstack-serviceproxy-${count.index}.${var.deploy_environment_name}"
+
+  flavor_id = data.openstack_compute_flavor_v2.small.id
+
+  user_data = templatefile("${path.module}/cloud_init/user_data.tftpl", {
+    deploy_environment_name = var.deploy_environment_name
+    deploy_username         = var.deploy_username
+    host_type               = "salt-minion-openstack"
+    salt_version            = var.salt_version
+    ssh_public_key          = file(var.ssh_public_key_file)
+    salt_master_ip          = openstack_networking_port_v2.salt_private.fixed_ip[0].ip_address
+    set_hostname            = true
+    hostname                = "openstack-serviceproxy-${count.index}"
+  })
+
+  connection {
+    type        = "ssh"
+    user        = var.deploy_username
+    host        = self.access_ip_v4
+    private_key = file(var.ssh_private_key_file)
+
+    bastion_host        = openstack_compute_floatingip_v2.salt.address
+    bastion_user        = var.deploy_username
+    bastion_private_key = file(var.ssh_private_key_file)
+  }
+
+  provisioner "remote-exec" {
+    inline = [
+      "until [ -f /run/cloud-init-done ]; do sleep 5; done"
+    ]
+  }
+
+  network {
+    port = element(openstack_networking_port_v2.openstack_serviceproxy_public.*.id, count.index)
+  }
+
+  network {
+    port = element(openstack_networking_port_v2.openstack_serviceproxy_private.*.id, count.index)
+  }
+
+  block_device {
+    source_type      = "volume"
+    destination_type = "volume"
+    uuid             = element(openstack_blockstorage_volume_v3.openstack_serviceproxy_persistent_volume.*.id, count.index)
+  }
 }
 
 
diff --git a/terraform/openstack/salt.tf b/terraform/openstack/salt.tf
index 252ae47..02fd6c0 100644
--- a/terraform/openstack/salt.tf
+++ b/terraform/openstack/salt.tf
@@ -1,213 +1,214 @@
 resource "openstack_networking_port_v2" "salt_private" {
-    name           = "salt_private"
-    network_id     = openstack_networking_network_v2.private.id
-    admin_state_up = true
-
-    fixed_ip {
-        subnet_id  = openstack_networking_subnet_v2.private.id
-        ip_address = cidrhost(openstack_networking_subnet_v2.private.cidr, 3)
-    }
+  name           = "salt_private"
+  network_id     = openstack_networking_network_v2.private.id
+  admin_state_up = true
+
+  fixed_ip {
+    subnet_id  = openstack_networking_subnet_v2.private.id
+    ip_address = cidrhost(openstack_networking_subnet_v2.private.cidr, 3)
+  }
 }
 
 resource "openstack_networking_port_v2" "salt_public" {
-    name           = "salt_public"
-    network_id     = openstack_networking_network_v2.public.id
-    admin_state_up = true
-
-    fixed_ip {
-        subnet_id  = openstack_networking_subnet_v2.public.id
-        ip_address = cidrhost(openstack_networking_subnet_v2.public.cidr, 3)
-    }
+  name           = "salt_public"
+  network_id     = openstack_networking_network_v2.public.id
+  admin_state_up = true
+
+  fixed_ip {
+    subnet_id  = openstack_networking_subnet_v2.public.id
+    ip_address = cidrhost(openstack_networking_subnet_v2.public.cidr, 3)
+  }
 }
 
 resource "openstack_blockstorage_volume_v3" "salt_persistent_volume" {
-    name                 = "salt_persistent_volume"
-    description          = "Stores persistent state for the salt master."
-    size                 = 20
-    enable_online_resize = true
-    image_id = data.openstack_images_image_v2.base_image.id
+  name                 = "salt_persistent_volume"
+  description          = "Stores persistent state for the salt master."
+  size                 = 20
+  enable_online_resize = true
+  image_id             = data.openstack_images_image_v2.base_image.id
 }
 
 data "openstack_networking_secgroup_v2" "default" {
-    name = "default"
+  name = "default"
 }
 
 resource "openstack_networking_secgroup_rule_v2" "salt_ssh_in" {
-    direction         = "ingress"
-    security_group_id =  data.openstack_networking_secgroup_v2.default.id
-    port_range_min    = 22
-    port_range_max    = 22
-    protocol          = "tcp"
-    ethertype         = "IPv4"
+  direction         = "ingress"
+  security_group_id = data.openstack_networking_secgroup_v2.default.id
+  port_range_min    = 22
+  port_range_max    = 22
+  protocol          = "tcp"
+  ethertype         = "IPv4"
 }
 
 resource "openstack_compute_floatingip_v2" "salt" {
-    pool = var.external_network_name
+  pool = var.external_network_name
 }
 
 resource "openstack_compute_instance_v2" "salt" {
-    name = "salt.${var.deploy_environment_name}"
-    security_groups = [
-        "default",
-    ]
-
-    flavor_id = data.openstack_compute_flavor_v2.small.id
-
-    block_device {
-        source_type = "volume"
-        destination_type = "volume"
-        uuid   = openstack_blockstorage_volume_v3.salt_persistent_volume.id
-        boot_index  = 0
-    }
-
-    user_data = templatefile("${path.module}/cloud_init/user_data.tftpl", {
-        deploy_environment_name = var.deploy_environment_name
-        deploy_username         = var.deploy_username
-        host_type               = "salt-master"
-        salt_version            = var.salt_version
-        ssh_public_key          = file(var.ssh_public_key_file)
-        salt_master_ip          = openstack_networking_port_v2.salt_private.fixed_ip[0]
-        set_hostname            = true
-        hostname                = "salt.${var.deploy_environment_name}"
-    })
-
-    network {
-        port = openstack_networking_port_v2.salt_public.id
-    }
-    network {
-        port = openstack_networking_port_v2.salt_private.id
-    }
+  name = "salt.${var.deploy_environment_name}"
+  security_groups = [
+    "default",
+  ]
+
+  flavor_id = data.openstack_compute_flavor_v2.small.id
+
+  block_device {
+    source_type      = "volume"
+    destination_type = "volume"
+    uuid             = openstack_blockstorage_volume_v3.salt_persistent_volume.id
+    boot_index       = 0
+  }
+
+  user_data = templatefile("${path.module}/cloud_init/user_data.tftpl", {
+    deploy_environment_name = var.deploy_environment_name
+    deploy_username         = var.deploy_username
+    host_type               = "salt-master"
+    salt_version            = var.salt_version
+    ssh_public_key          = file(var.ssh_public_key_file)
+    salt_master_ip          = openstack_networking_port_v2.salt_private.fixed_ip[0]
+    set_hostname            = true
+    hostname                = "salt"
+  })
+
+  network {
+    port = openstack_networking_port_v2.salt_public.id
+  }
+  network {
+    port = openstack_networking_port_v2.salt_private.id
+  }
 
 }
 
 resource "openstack_compute_floatingip_associate_v2" "salt" {
-    floating_ip = openstack_compute_floatingip_v2.salt.address
-    instance_id = openstack_compute_instance_v2.salt.id
-
-    connection {
-        type = "ssh"
-        user = var.deploy_username
-        host = openstack_compute_floatingip_v2.salt.address
-        private_key = file(var.ssh_private_key_file)
-    }
-
-    provisioner "remote-exec" {
-        inline = [
-            "until [ -f /run/cloud-init-done ]; do sleep 5; done",
-            "sudo bash -c 'echo \"auto_accept: True\" > /etc/salt/master.d/auto_accept.conf'",
-            "sudo systemctl restart salt-master"
-        ]
-    }
+  floating_ip = openstack_compute_floatingip_v2.salt.address
+  instance_id = openstack_compute_instance_v2.salt.id
+
+  connection {
+    type        = "ssh"
+    user        = var.deploy_username
+    host        = openstack_compute_floatingip_v2.salt.address
+    private_key = file(var.ssh_private_key_file)
+  }
+
+  provisioner "remote-exec" {
+    inline = [
+      "until [ -f /run/cloud-init-done ]; do sleep 5; done",
+      "sudo bash -c 'echo \"auto_accept: True\" > /etc/salt/master.d/auto_accept.conf'",
+      "sudo systemctl restart salt-master"
+    ]
+  }
 }
 
 resource "null_resource" "sync_salt_states" {
-    depends_on = [
-        openstack_compute_instance_v2.salt,
-        openstack_compute_instance_v2.ceph_monitor,
-        openstack_compute_instance_v2.ceph_osd,
-        openstack_compute_instance_v2.openstack_controller,
-        openstack_compute_instance_v2.openstack_compute,
-        openstack_compute_instance_v2.openstack_networker,
-        openstack_compute_instance_v2.openstack_serviceproxy,
-        openstack_compute_instance_v2.openstack_database,
-        openstack_compute_instance_v2.monitor,
+  depends_on = [
+    openstack_compute_floatingip_associate_v2.salt,
+    openstack_compute_instance_v2.salt,
+    openstack_compute_instance_v2.ceph_monitor,
+    openstack_compute_instance_v2.ceph_osd,
+    openstack_compute_instance_v2.openstack_controller,
+    openstack_compute_instance_v2.openstack_compute,
+    openstack_compute_instance_v2.openstack_networker,
+    openstack_compute_instance_v2.openstack_serviceproxy,
+    openstack_compute_instance_v2.openstack_database,
+    openstack_compute_instance_v2.monitor,
+  ]
+
+  triggers = {
+    # Easy way to watch for changes in all files in a directory
+    # Creates a long string of all file hashes concatenated together, and then hashes that again.
+    # If one file changes, the end hash also changes, triggering resync of states.
+    dir_hash = sha256(join("", [
+      for filename in fileset("${path.cwd}/../../salt/", "**") :
+      filesha256("../../salt/${filename}")
+    ]))
+  }
+
+  connection {
+    type        = "ssh"
+    user        = var.deploy_username
+    host        = openstack_compute_floatingip_v2.salt.address
+    private_key = file(var.ssh_private_key_file)
+  }
+
+  provisioner "file" {
+    source      = "${path.module}/../../salt"
+    destination = "/tmp/"
+  }
+
+  provisioner "remote-exec" {
+    inline = [
+      "set -x",
+      "sudo rm -rf /srv/{salt,pillar,reactor,files}",
+      "sudo mv /tmp/salt/{salt,pillar,reactor,files} /srv/",
+      "sudo rm -rf /tmp/salt",
+      "sudo chown root: -R /srv/{salt,reactor,pillar,files}",
+      "sleep 5",
+      "sudo salt \\* test.ping",
+      "sudo salt-call --output-diff state.apply monitoring.prometheus.node_exporter.master_fetch_archive",
+      "sudo salt-call --output-diff state.highstate",
+      "sudo systemctl restart salt-master",
+      "sleep 5",
     ]
-
-    triggers = {
-        # Easy way to watch for changes in all files in a directory
-        # Creates a long string of all file hashes concatenated together, and then hashes that again.
-        # If one file changes, the end hash also changes, triggering resync of states.
-        dir_hash = sha256(join("", [
-            for filename in fileset("${path.cwd}/../salt/", "**") :
-            filesha256("../salt/${filename}")
-        ]))
-    }
-
-    connection {
-        type = "ssh"
-        user = var.deploy_username
-        host = openstack_compute_floatingip_v2.salt.address
-        private_key = file(var.ssh_private_key_file)
-    }
-
-    provisioner "file" {
-        source      = "${path.module}/../salt"
-        destination = "/tmp/"
-    }
-
-    provisioner "remote-exec" {
-        inline = [
-            "set -x",
-            "sudo rm -rf /srv/{salt,pillar,reactor,files}",
-            "sudo mv /tmp/salt/{salt,pillar,reactor,files} /srv/",
-            "sudo rm -rf /tmp/salt",
-            "sudo chown root: -R /srv/{salt,reactor,pillar,files}",
-            "sleep 5",
-            "sudo salt \\* test.ping",
-            "sudo salt-call --output-diff state.apply monitoring.prometheus.node_exporter.master_fetch_archive",
-            "sudo salt-call --output-diff state.highstate",
-            "sudo systemctl restart salt-master",
-            "sleep 5",
-        ]
-    }
+  }
 }
 
 resource "null_resource" "monitoring_orchestrate" {
-    depends_on = [
-        null_resource.sync_salt_states
+  depends_on = [
+    null_resource.sync_salt_states
+  ]
+
+  connection {
+    type        = "ssh"
+    user        = var.deploy_username
+    host        = openstack_compute_floatingip_v2.salt.address
+    private_key = file(var.ssh_private_key_file)
+  }
+
+  provisioner "remote-exec" {
+    inline = [
+      "sudo salt-run manage.status",
+      "sudo salt-run --state-output mixed state.orchestrate orch.bootstrap_monitoring",
     ]
-
-    connection {
-        type = "ssh"
-        user = var.deploy_username
-        host = openstack_compute_floatingip_v2.salt.address
-        private_key = file(var.ssh_private_key_file)
-    }
-
-    provisioner "remote-exec" {
-        inline = [
-            "sudo salt-run manage.status",
-            "sudo salt-run --state-output mixed state.orchestrate orch.bootstrap_monitoring",
-        ]
-    }
+  }
 }
 
 resource "null_resource" "ceph_orchestrate" {
-    depends_on = [
-        null_resource.monitoring_orchestrate
+  depends_on = [
+    null_resource.monitoring_orchestrate
+  ]
+
+  connection {
+    type        = "ssh"
+    user        = var.deploy_username
+    host        = openstack_compute_floatingip_v2.salt.address
+    private_key = file(var.ssh_private_key_file)
+  }
+
+  provisioner "remote-exec" {
+    inline = [
+      "sudo salt-run manage.status",
+      "sudo salt-run --state-output mixed state.orchestrate orch.bootstrap_ceph",
     ]
-
-    connection {
-        type = "ssh"
-        user = var.deploy_username
-        host = openstack_compute_floatingip_v2.salt.address
-        private_key = file(var.ssh_private_key_file)
-    }
-
-    provisioner "remote-exec" {
-        inline = [
-            "sudo salt-run manage.status",
-            "sudo salt-run --state-output mixed state.orchestrate orch.bootstrap_ceph",
-        ]
-    }
+  }
 }
 
 resource "null_resource" "openstack_orchestrate" {
-    depends_on = [
-        null_resource.ceph_orchestrate
+  depends_on = [
+    null_resource.ceph_orchestrate
+  ]
+
+  connection {
+    type        = "ssh"
+    user        = var.deploy_username
+    host        = openstack_compute_floatingip_v2.salt.address
+    private_key = file(var.ssh_private_key_file)
+  }
+
+  provisioner "remote-exec" {
+    inline = [
+      "sudo salt-run manage.status",
+      "sudo salt-run --state-output mixed state.orchestrate orch.bootstrap_openstack",
     ]
-
-    connection {
-        type = "ssh"
-        user = var.deploy_username
-        host = openstack_compute_floatingip_v2.salt.address
-        private_key = file(var.ssh_private_key_file)
-    }
-
-    provisioner "remote-exec" {
-        inline = [
-            "sudo salt-run manage.status",
-            "sudo salt-run --state-output mixed state.orchestrate orch.bootstrap_openstack",
-        ]
-    }
+  }
 }
diff --git a/terraform/openstack/terraform.tf b/terraform/openstack/terraform.tf
index 45a8f72..d18c70e 100644
--- a/terraform/openstack/terraform.tf
+++ b/terraform/openstack/terraform.tf
@@ -1,51 +1,51 @@
 variable "external_network_name" {
-    type        = string
-    description = "The name of the external network to use"
+  type        = string
+  description = "The name of the external network to use"
 }
 variable "base_image_name" {
-    type        = string
-    description = "The base image to use when creating instance volumes"
+  type        = string
+  description = "The base image to use when creating instance volumes"
 }
 variable "default_small_flavor_name" {
-    type = string
-    description = "The name of the default flavor to use for small instances"
-    default = "m1.small"
+  type        = string
+  description = "The name of the default flavor to use for small instances"
+  default     = "m1.small"
 }
 variable "deploy_environment_name" {
-    type        = string
-    description = "Domain to affix to instance names, used for env-specific variables."
-    default     = "local.cloud4"
+  type        = string
+  description = "Domain to affix to instance names, used for env-specific variables."
+  default     = "local.cloud4"
 }
 variable "deploy_username" {
-    type        = string
-    description = "Default user to use when deploying over ssh. Change when using a different OS."
-    default     = "rocky"
+  type        = string
+  description = "Default user to use when deploying over ssh. Change when using a different OS."
+  default     = "rocky"
 }
 variable "salt_version" {
-    type = string
-    description = "The version of salt to install on the salt master and minions"
-    default = "3007.1"
+  type        = string
+  description = "The version of salt to install on the salt master and minions"
+  default     = "3007.1"
 }
 variable "ssh_public_key_file" {
-    type = string
-    description = "The path to the public key file to use for ssh access"
-    default = "~/.ssh/id_rsa.pub"
+  type        = string
+  description = "The path to the public key file to use for ssh access"
+  default     = "~/.ssh/id_rsa.pub"
 }
 variable "ssh_private_key_file" {
-    type = string
-    description = "The path to the private key file to use for ssh access"
-    default = "~/.ssh/id_rsa"
+  type        = string
+  description = "The path to the private key file to use for ssh access"
+  default     = "~/.ssh/id_rsa"
 }
 
 terraform {
-    backend "http" {
-    }
-    required_providers {
-        openstack = {
-            source  = "terraform-provider-openstack/openstack"
-            version = "1.53.0"
-        }
+  backend "http" {
+  }
+  required_providers {
+    openstack = {
+      source  = "terraform-provider-openstack/openstack"
+      version = "1.53.0"
     }
+  }
 }
 provider "openstack" {
 }
\ No newline at end of file
-- 
GitLab


From ba07a518e886ac7b136c7c5a374dd89687320c99 Mon Sep 17 00:00:00 2001
From: David Visscher <d.j.visscher@rug.nl>
Date: Tue, 1 Apr 2025 14:55:31 +0200
Subject: [PATCH 09/43] Always put own localhost hostname

---
 terraform/local_libvirt/cloud_init/user_data.tftpl | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/terraform/local_libvirt/cloud_init/user_data.tftpl b/terraform/local_libvirt/cloud_init/user_data.tftpl
index b48f22e..fae1c61 100644
--- a/terraform/local_libvirt/cloud_init/user_data.tftpl
+++ b/terraform/local_libvirt/cloud_init/user_data.tftpl
@@ -17,10 +17,9 @@ ssh_authorized_keys:
 runcmd:
   - "set -x"
 %{ if host_type != "salt-master" ~}
-  - "echo '${salt_master_ip} salt' >> /etc/hosts"
-%{ else }
-  - "echo '127.0.0.1 salt' >> /etc/hosts"
+  - "sudo echo '${salt_master_ip} salt' >> /etc/hosts"
 %{ endif ~}
+  - "sudo echo '127.0.0.1 ${hostname}' >> /etc/hosts"
   - 'sudo dnf install --assumeyes --refresh epel-release'
   - 'sudo dnf clean all'
   - 'sudo rm -Rf /var/cache/dnf/'
-- 
GitLab


From 321ec52739897e4362a6366258497f781e448f77 Mon Sep 17 00:00:00 2001
From: David Visscher <d.j.visscher@rug.nl>
Date: Mon, 7 Apr 2025 15:11:44 +0200
Subject: [PATCH 10/43] Fix name duplication on monitoring box

---
 terraform/openstack/monitor.tf   | 4 ++--
 terraform/openstack/terraform.tf | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/terraform/openstack/monitor.tf b/terraform/openstack/monitor.tf
index 06e9061..f0b7fc2 100644
--- a/terraform/openstack/monitor.tf
+++ b/terraform/openstack/monitor.tf
@@ -46,12 +46,12 @@ resource "openstack_compute_instance_v2" "monitor" {
   user_data = templatefile("${path.module}/cloud_init/user_data.tftpl", {
     deploy_environment_name = var.deploy_environment_name
     deploy_username         = var.deploy_username
-    host_type               = "openstack-serviceproxy"
+    host_type               = "salt-minion"
     salt_version            = var.salt_version
     ssh_public_key          = file(var.ssh_public_key_file)
     salt_master_ip          = openstack_networking_port_v2.salt_private.fixed_ip[0].ip_address
     set_hostname            = true
-    hostname                = "openstack-serviceproxy-${count.index}"
+    hostname                = "monitoring-${count.index}"
   })
 
   connection {
diff --git a/terraform/openstack/terraform.tf b/terraform/openstack/terraform.tf
index d18c70e..6456550 100644
--- a/terraform/openstack/terraform.tf
+++ b/terraform/openstack/terraform.tf
@@ -24,7 +24,7 @@ variable "deploy_username" {
 variable "salt_version" {
   type        = string
   description = "The version of salt to install on the salt master and minions"
-  default     = "3007.1"
+  default     = "3007"
 }
 variable "ssh_public_key_file" {
   type        = string
-- 
GitLab


From ef4ed2f839b503bb859544e3365416114757acc3 Mon Sep 17 00:00:00 2001
From: David Visscher <d.j.visscher@rug.nl>
Date: Wed, 9 Apr 2025 11:21:05 +0200
Subject: [PATCH 11/43] Allow retries

---
 terraform/openstack/terraform.tf | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/terraform/openstack/terraform.tf b/terraform/openstack/terraform.tf
index 6456550..06acb6a 100644
--- a/terraform/openstack/terraform.tf
+++ b/terraform/openstack/terraform.tf
@@ -44,8 +44,9 @@ terraform {
     openstack = {
       source  = "terraform-provider-openstack/openstack"
       version = "1.53.0"
+      max_retries = 5
     }
   }
 }
 provider "openstack" {
-}
\ No newline at end of file
+}
-- 
GitLab


From 9c3ee532ccaaea01f72dc335c292f0ba21600f5a Mon Sep 17 00:00:00 2001
From: David Visscher <d.j.visscher@rug.nl>
Date: Wed, 9 Apr 2025 11:21:26 +0200
Subject: [PATCH 12/43] Configure retries in the correct place

---
 terraform/openstack/terraform.tf | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/terraform/openstack/terraform.tf b/terraform/openstack/terraform.tf
index 06acb6a..fb0502f 100644
--- a/terraform/openstack/terraform.tf
+++ b/terraform/openstack/terraform.tf
@@ -44,9 +44,9 @@ terraform {
     openstack = {
       source  = "terraform-provider-openstack/openstack"
       version = "1.53.0"
-      max_retries = 5
     }
   }
 }
 provider "openstack" {
+    max_retries = 5
 }
-- 
GitLab


From fe2c7cbed0efab874842f05c33b7199f49667dbf Mon Sep 17 00:00:00 2001
From: David Visscher <d.j.visscher@rug.nl>
Date: Wed, 9 Apr 2025 11:43:07 +0200
Subject: [PATCH 13/43] Add separate storage network

---
 terraform/openstack/ceph_monitor.tf         | 15 +++++++++++++++
 terraform/openstack/ceph_osd.tf             | 15 +++++++++++++++
 terraform/openstack/networking.tf           | 17 ++++++++++++++++-
 terraform/openstack/openstack_compute.tf    | 15 +++++++++++++++
 terraform/openstack/openstack_controller.tf | 15 +++++++++++++++
 5 files changed, 76 insertions(+), 1 deletion(-)

diff --git a/terraform/openstack/ceph_monitor.tf b/terraform/openstack/ceph_monitor.tf
index 8e0144d..1b5d596 100644
--- a/terraform/openstack/ceph_monitor.tf
+++ b/terraform/openstack/ceph_monitor.tf
@@ -19,6 +19,17 @@ resource "openstack_networking_port_v2" "ceph_monitor_private" {
   }
 }
 
+resource "openstack_networking_port_v2" "ceph_monitor_storage" {
+  count          = var.ceph_mon_count
+  network_id     = openstack_networking_network_v2.storage.id
+  admin_state_up = true
+
+  fixed_ip {
+    subnet_id  = openstack_networking_subnet_v2.storage.id
+    ip_address = cidrhost(openstack_networking_subnet_v2.storage.cidr, count.index + 80)
+  }
+}
+
 resource "openstack_blockstorage_volume_v3" "ceph_monitor_persistent_volume" {
   count                = var.ceph_mon_count
   size                 = 50
@@ -67,6 +78,10 @@ resource "openstack_compute_instance_v2" "ceph_monitor" {
     port = element(openstack_networking_port_v2.ceph_monitor_private.*.id, count.index)
   }
 
+  network {
+    port = element(openstack_networking_port_v2.ceph_monitor_storage.*.id, count.index)
+  }
+
   block_device {
     source_type      = "volume"
     destination_type = "volume"
diff --git a/terraform/openstack/ceph_osd.tf b/terraform/openstack/ceph_osd.tf
index d19dc4e..616e50f 100644
--- a/terraform/openstack/ceph_osd.tf
+++ b/terraform/openstack/ceph_osd.tf
@@ -19,6 +19,17 @@ resource "openstack_networking_port_v2" "ceph_osd_private" {
   }
 }
 
+resource "openstack_networking_port_v2" "ceph_osd_storage" {
+  count          = var.ceph_osd_count
+  network_id     = openstack_networking_network_v2.storage.id
+  admin_state_up = true
+
+  fixed_ip {
+    subnet_id  = openstack_networking_subnet_v2.storage.id
+    ip_address = cidrhost(openstack_networking_subnet_v2.storage.cidr, count.index + 70)
+  }
+}
+
 resource "openstack_blockstorage_volume_v3" "ceph_osd_persistent_volume" {
   count    = var.ceph_osd_count
   size     = var.ceph_osd_size
@@ -71,6 +82,10 @@ resource "openstack_compute_instance_v2" "ceph_osd" {
     port = element(openstack_networking_port_v2.ceph_osd_private.*.id, count.index)
   }
 
+  network {
+    port = element(openstack_networking_port_v2.ceph_osd_storage.*.id, count.index)
+  }
+
   block_device {
     source_type      = "volume"
     destination_type = "volume"
diff --git a/terraform/openstack/networking.tf b/terraform/openstack/networking.tf
index 8396340..67429fa 100644
--- a/terraform/openstack/networking.tf
+++ b/terraform/openstack/networking.tf
@@ -48,4 +48,19 @@ resource "openstack_networking_floatingip_v2" "reserved" {
     # Set this to true to keep hold of the floating IPs when the environment is destroyed
     prevent_destroy = false
   }
-}
\ No newline at end of file
+}
+
+resource "openstack_networking_network_v2" "storage" {
+  name           = "cloud4_storage_network"
+  admin_state_up = "true"
+  mtu            = 9000
+}
+
+resource "openstack_networking_subnet_v2" "storage" {
+  name       = "cloud4_storage_subnet"
+  network_id = openstack_networking_network_v2.private.id
+  cidr       = "10.12.0.0/24"
+  ip_version = 4
+
+  enable_dhcp = true
+}
diff --git a/terraform/openstack/openstack_compute.tf b/terraform/openstack/openstack_compute.tf
index 129a05c..d6aeffa 100644
--- a/terraform/openstack/openstack_compute.tf
+++ b/terraform/openstack/openstack_compute.tf
@@ -19,6 +19,17 @@ resource "openstack_networking_port_v2" "openstack_compute_private" {
   }
 }
 
+resource "openstack_networking_port_v2" "openstack_compute_storage" {
+  count          = var.openstack_compute_count
+  network_id     = openstack_networking_network_v2.storage.id
+  admin_state_up = true
+
+  fixed_ip {
+    subnet_id  = openstack_networking_subnet_v2.storage.id
+    ip_address = cidrhost(openstack_networking_subnet_v2.storage.cidr, count.index + 20)
+  }
+}
+
 resource "openstack_blockstorage_volume_v3" "openstack_compute_persistent_volume" {
   count    = var.openstack_compute_count
   size     = var.openstack_compute_size
@@ -67,6 +78,10 @@ resource "openstack_compute_instance_v2" "openstack_compute" {
     port = element(openstack_networking_port_v2.openstack_compute_private.*.id, count.index)
   }
 
+  network {
+    port = element(openstack_networking_port_v2.openstack_compute_storage.*.id, count.index)
+  }
+
   block_device {
     source_type      = "volume"
     destination_type = "volume"
diff --git a/terraform/openstack/openstack_controller.tf b/terraform/openstack/openstack_controller.tf
index 886ef26..5043cc9 100644
--- a/terraform/openstack/openstack_controller.tf
+++ b/terraform/openstack/openstack_controller.tf
@@ -19,6 +19,17 @@ resource "openstack_networking_port_v2" "openstack_controller_private" {
   }
 }
 
+resource "openstack_networking_port_v2" "openstack_controller_storage" {
+  count          = var.openstack_controller_count
+  network_id     = openstack_networking_network_v2.storage.id
+  admin_state_up = true
+
+  fixed_ip {
+    subnet_id  = openstack_networking_subnet_v2.storage.id
+    ip_address = cidrhost(openstack_networking_subnet_v2.storage.cidr, count.index + 80)
+  }
+}
+
 resource "openstack_blockstorage_volume_v3" "openstack_controller_persistent_volume" {
   count    = var.openstack_controller_count
   size     = var.openstack_controller_size
@@ -66,6 +77,10 @@ resource "openstack_compute_instance_v2" "openstack_controller" {
     port = element(openstack_networking_port_v2.openstack_controller_private.*.id, count.index)
   }
 
+  network {
+    port = element(openstack_networking_port_v2.openstack_controller_storage.*.id, count.index)
+  }
+
   block_device {
     source_type      = "volume"
     destination_type = "volume"
-- 
GitLab


From eab076a9b704f60377e9817d7f8220ed42ce9ecc Mon Sep 17 00:00:00 2001
From: David Visscher <d.j.visscher@rug.nl>
Date: Wed, 9 Apr 2025 12:01:37 +0200
Subject: [PATCH 14/43] Bump versions

---
 salt/pillar/defaults.sls | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/salt/pillar/defaults.sls b/salt/pillar/defaults.sls
index 65267ff..a1f7a61 100644
--- a/salt/pillar/defaults.sls
+++ b/salt/pillar/defaults.sls
@@ -79,7 +79,7 @@ ceph:
       keyring: /var/lib/ceph/radosgw/ceph-{{ grains['id'] }}/keyring
       log_file: /var/log/ceph/radosgw.log
       rgw_frontends: "beast port=7480"
-  release: reef
+  release: squid
   keyrings:
     # Replace these keyring in prod
     /etc/ceph/ceph.client.admin.keyring:
@@ -169,7 +169,7 @@ loki:
 
 openstack:
   region: "cloud4"
-  release_version: bobcat
+  release_version: epoxy
 
   keystone:
     admin_password: &keystone_admin_pass "Knock.Knock.Whos.There? ... Keystone"
-- 
GitLab


From 18ce7a662992eca509d0a3c23dfb5d175a0fd48e Mon Sep 17 00:00:00 2001
From: David Visscher <d.j.visscher@rug.nl>
Date: Wed, 9 Apr 2025 12:04:10 +0200
Subject: [PATCH 15/43] Add ci config

---
 .../environments/ci_cloud4/defaults.sls       | 21 +++++++++++
 terraform/openstack/ceph_osd.tf               | 37 +++++++++----------
 2 files changed, 38 insertions(+), 20 deletions(-)
 create mode 100644 salt/pillar/environments/ci_cloud4/defaults.sls

diff --git a/salt/pillar/environments/ci_cloud4/defaults.sls b/salt/pillar/environments/ci_cloud4/defaults.sls
new file mode 100644
index 0000000..8617f93
--- /dev/null
+++ b/salt/pillar/environments/ci_cloud4/defaults.sls
@@ -0,0 +1,21 @@
+motd:
+  art: |-2
+     ██████ ██   ██  ██████ ██
+    ██      ██   ██ ██      ██
+    ██      ███████ ██      ██
+    ██           ██ ██      ██
+     ██████      ██  ██████ ██
+
+mine_functions:
+  network.ip_addrs:
+    - 10.11.0.0/24
+
+ceph:
+  config:
+    global:
+      fsid: "c4c4c4c4-c4c4-c4c4-c4c4c4c4c4"
+      public_network: 10.11.0.0/24
+      cluster_network: 10.12.0.0./24
+  osd_disks:
+    - name: /dev/vd_ceph
+      type: lvm
\ No newline at end of file
diff --git a/terraform/openstack/ceph_osd.tf b/terraform/openstack/ceph_osd.tf
index 616e50f..3204cb6 100644
--- a/terraform/openstack/ceph_osd.tf
+++ b/terraform/openstack/ceph_osd.tf
@@ -14,7 +14,7 @@ resource "openstack_networking_port_v2" "ceph_osd_private" {
   admin_state_up = true
 
   fixed_ip {
-    subnet_id  = openstack_networking_subnet_v2.private.id
+    subnet_id = openstack_networking_subnet_v2.private.id
     ip_address = cidrhost(openstack_networking_subnet_v2.private.cidr, count.index + 70)
   }
 }
@@ -25,7 +25,7 @@ resource "openstack_networking_port_v2" "ceph_osd_storage" {
   admin_state_up = true
 
   fixed_ip {
-    subnet_id  = openstack_networking_subnet_v2.storage.id
+    subnet_id = openstack_networking_subnet_v2.storage.id
     ip_address = cidrhost(openstack_networking_subnet_v2.storage.cidr, count.index + 70)
   }
 }
@@ -55,20 +55,20 @@ resource "openstack_compute_instance_v2" "ceph_osd" {
     deploy_username         = var.deploy_username
     host_type               = "ceph-osd"
     salt_version            = var.salt_version
-    ssh_public_key          = file(var.ssh_public_key_file)
+    ssh_public_key = file(var.ssh_public_key_file)
     salt_master_ip          = openstack_networking_port_v2.salt_private.fixed_ip[0].ip_address
     set_hostname            = true
     hostname                = "ceph-osd-${count.index}"
   })
 
   connection {
-    type        = "ssh"
-    user        = var.deploy_username
-    host        = self.access_ip_v4
+    type = "ssh"
+    user = var.deploy_username
+    host = self.access_ip_v4
     private_key = file(var.ssh_private_key_file)
 
-    bastion_host        = openstack_compute_floatingip_v2.salt.address
-    bastion_user        = var.deploy_username
+    bastion_host = openstack_compute_floatingip_v2.salt.address
+    bastion_user = var.deploy_username
     bastion_private_key = file(var.ssh_private_key_file)
   }
 
@@ -79,27 +79,24 @@ resource "openstack_compute_instance_v2" "ceph_osd" {
   }
 
   network {
-    port = element(openstack_networking_port_v2.ceph_osd_private.*.id, count.index)
+    port = openstack_networking_port_v2.ceph_osd_private.*.id[count.index]
   }
 
   network {
-    port = element(openstack_networking_port_v2.ceph_osd_storage.*.id, count.index)
+    port = openstack_networking_port_v2.ceph_osd_storage.*.id[count.index]
   }
 
   block_device {
     source_type      = "volume"
     destination_type = "volume"
-    uuid             = element(openstack_blockstorage_volume_v3.ceph_osd_persistent_volume.*.id, count.index)
+    uuid             = openstack_blockstorage_volume_v3.ceph_osd_persistent_volume.*.id[count.index]
     boot_index       = 0
   }
-
-  block_device {
-    source_type      = "volume"
-    destination_type = "volume"
-    uuid             = element(openstack_blockstorage_volume_v3.ceph_osd_data_disk.*.id, count.index)
-    boot_index       = 1
-  }
 }
 
-
-
+resource "openstack_compute_volume_attach_v2" "ceph_osd_data_disk" {
+  count       = var.ceph_osd_count
+  instance_id = openstack_compute_instance_v2.ceph_osd.*.id[count.index]
+  volume_id   = openstack_blockstorage_volume_v3.ceph_osd_data_disk.*.id[count.index]
+  device      = "/dev/vd_cephosd"
+}
-- 
GitLab


From 2304e5249c25bee8c7ee20e2fcde26326a405568 Mon Sep 17 00:00:00 2001
From: David Visscher <d.j.visscher@rug.nl>
Date: Wed, 9 Apr 2025 13:59:44 +0200
Subject: [PATCH 16/43] Set ceph config correctly in the pillar

---
 salt/pillar/environments/ci_cloud4/defaults.sls | 4 ++--
 terraform/openstack/ceph_osd.tf                 | 2 +-
 terraform/openstack/networking.tf               | 6 +++---
 terraform/openstack/openstack_controller.tf     | 2 +-
 4 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/salt/pillar/environments/ci_cloud4/defaults.sls b/salt/pillar/environments/ci_cloud4/defaults.sls
index 8617f93..afd2c81 100644
--- a/salt/pillar/environments/ci_cloud4/defaults.sls
+++ b/salt/pillar/environments/ci_cloud4/defaults.sls
@@ -15,7 +15,7 @@ ceph:
     global:
       fsid: "c4c4c4c4-c4c4-c4c4-c4c4c4c4c4"
       public_network: 10.11.0.0/24
-      cluster_network: 10.12.0.0./24
+      cluster_network: 10.12.0.0/24
   osd_disks:
-    - name: /dev/vd_ceph
+    - name: /dev/vdceph
       type: lvm
\ No newline at end of file
diff --git a/terraform/openstack/ceph_osd.tf b/terraform/openstack/ceph_osd.tf
index 3204cb6..9038476 100644
--- a/terraform/openstack/ceph_osd.tf
+++ b/terraform/openstack/ceph_osd.tf
@@ -98,5 +98,5 @@ resource "openstack_compute_volume_attach_v2" "ceph_osd_data_disk" {
   count       = var.ceph_osd_count
   instance_id = openstack_compute_instance_v2.ceph_osd.*.id[count.index]
   volume_id   = openstack_blockstorage_volume_v3.ceph_osd_data_disk.*.id[count.index]
-  device      = "/dev/vd_cephosd"
+  device      = "/dev/vdcephosd"
 }
diff --git a/terraform/openstack/networking.tf b/terraform/openstack/networking.tf
index 67429fa..1fd87e2 100644
--- a/terraform/openstack/networking.tf
+++ b/terraform/openstack/networking.tf
@@ -9,7 +9,7 @@ resource "openstack_networking_network_v2" "public" {
 resource "openstack_networking_subnet_v2" "public" {
   name            = "cloud4_public_subnet"
   network_id      = openstack_networking_network_v2.public.id
-  cidr            = "10.10.0.0/16"
+  cidr            = "10.10.0.0/24"
   ip_version      = 4
   dns_nameservers = ["1.1.1.1", "1.0.0.1"]
 }
@@ -53,12 +53,12 @@ resource "openstack_networking_floatingip_v2" "reserved" {
 resource "openstack_networking_network_v2" "storage" {
   name           = "cloud4_storage_network"
   admin_state_up = "true"
-  mtu            = 9000
+  mtu            = 8950
 }
 
 resource "openstack_networking_subnet_v2" "storage" {
   name       = "cloud4_storage_subnet"
-  network_id = openstack_networking_network_v2.private.id
+  network_id = openstack_networking_network_v2.storage.id
   cidr       = "10.12.0.0/24"
   ip_version = 4
 
diff --git a/terraform/openstack/openstack_controller.tf b/terraform/openstack/openstack_controller.tf
index 5043cc9..fb6c19d 100644
--- a/terraform/openstack/openstack_controller.tf
+++ b/terraform/openstack/openstack_controller.tf
@@ -26,7 +26,7 @@ resource "openstack_networking_port_v2" "openstack_controller_storage" {
 
   fixed_ip {
     subnet_id  = openstack_networking_subnet_v2.storage.id
-    ip_address = cidrhost(openstack_networking_subnet_v2.storage.cidr, count.index + 80)
+    ip_address = cidrhost(openstack_networking_subnet_v2.storage.cidr, count.index + 10)
   }
 }
 
-- 
GitLab


From a3bc0d482cf3033650b9680fa22ed0844277806f Mon Sep 17 00:00:00 2001
From: David Visscher <d.j.visscher@rug.nl>
Date: Wed, 9 Apr 2025 14:05:42 +0200
Subject: [PATCH 17/43] Add explicit dependency of salt float on router
 interface

---
 terraform/openstack/salt.tf | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/terraform/openstack/salt.tf b/terraform/openstack/salt.tf
index 02fd6c0..552bc59 100644
--- a/terraform/openstack/salt.tf
+++ b/terraform/openstack/salt.tf
@@ -84,6 +84,10 @@ resource "openstack_compute_floatingip_associate_v2" "salt" {
   floating_ip = openstack_compute_floatingip_v2.salt.address
   instance_id = openstack_compute_instance_v2.salt.id
 
+  depends_on = [
+    openstack_networking_router_interface_v2.public_subnet_interface
+  ]
+
   connection {
     type        = "ssh"
     user        = var.deploy_username
-- 
GitLab


From 0ce282805ee484e6812b73108b628a685ac40d55 Mon Sep 17 00:00:00 2001
From: David Visscher <d.j.visscher@rug.nl>
Date: Wed, 9 Apr 2025 14:34:00 +0200
Subject: [PATCH 18/43] Fix ceph mon_host address lookup to respect the CIDR of
 the cluster_network subnet

---
 .../environments/ci_cloud4/defaults.sls       |  6 +-----
 salt/salt/ceph/config.sls                     | 20 +++++++++++++------
 terraform/openstack/ceph_osd.tf               | 18 ++++++++---------
 terraform/openstack/terraform.tf              |  2 +-
 4 files changed, 25 insertions(+), 21 deletions(-)

diff --git a/salt/pillar/environments/ci_cloud4/defaults.sls b/salt/pillar/environments/ci_cloud4/defaults.sls
index afd2c81..4454144 100644
--- a/salt/pillar/environments/ci_cloud4/defaults.sls
+++ b/salt/pillar/environments/ci_cloud4/defaults.sls
@@ -6,10 +6,6 @@ motd:
     ██           ██ ██      ██
      ██████      ██  ██████ ██
 
-mine_functions:
-  network.ip_addrs:
-    - 10.11.0.0/24
-
 ceph:
   config:
     global:
@@ -17,5 +13,5 @@ ceph:
       public_network: 10.11.0.0/24
       cluster_network: 10.12.0.0/24
   osd_disks:
-    - name: /dev/vdceph
+    - name: /dev/vdb
       type: lvm
\ No newline at end of file
diff --git a/salt/salt/ceph/config.sls b/salt/salt/ceph/config.sls
index b6ab54f..53b0812 100644
--- a/salt/salt/ceph/config.sls
+++ b/salt/salt/ceph/config.sls
@@ -2,7 +2,7 @@
 # vim: set ft=python ts=4 sw=4 et:
 
 import collections.abc
-
+from ipaddress import ip_network, ip_address
 
 def run():
     """
@@ -23,14 +23,22 @@ def run():
     mon_hosts = []
     mon_initial_members = []
     mds_config = {}
+
+    cluster_network = ip_network(__salt__['pillar.get']("ceph_config:global:cluster_network"))
+
     for minion_name, addrs in __salt__["mine.get"](
         "ceph-monitor*", "network.ip_addrs"
     ).items():
-        mon_initial_members.append(minion_name)
-        mon_hosts.extend(addrs)  # add all IP addresses of the monitor
-        # Each mon also has an mds, so we need to add the mds to the config
-        mds_config[f"mds.{minion_name}"] = {"host": minion_name}
-
+        # Check every address for this minion
+        for addr in addrs:
+            ip = ip_address(addr)
+            # Check if the IP address is in the cluster network
+            if ip in cluster_network:
+                # If it is, we add it to the list of monitors
+                mon_initial_members.append(minion_name)
+                mon_hosts.append(addr)
+                mds_config[f"mds.{minion_name}"] = {"host": minion_name}
+                break # We've found the address for this minion, so we can stop looking
 
     # Add the just assembled list of monitors to the configuration.
     config_items = {
diff --git a/terraform/openstack/ceph_osd.tf b/terraform/openstack/ceph_osd.tf
index 9038476..dbfeb0d 100644
--- a/terraform/openstack/ceph_osd.tf
+++ b/terraform/openstack/ceph_osd.tf
@@ -14,7 +14,7 @@ resource "openstack_networking_port_v2" "ceph_osd_private" {
   admin_state_up = true
 
   fixed_ip {
-    subnet_id = openstack_networking_subnet_v2.private.id
+    subnet_id  = openstack_networking_subnet_v2.private.id
     ip_address = cidrhost(openstack_networking_subnet_v2.private.cidr, count.index + 70)
   }
 }
@@ -25,7 +25,7 @@ resource "openstack_networking_port_v2" "ceph_osd_storage" {
   admin_state_up = true
 
   fixed_ip {
-    subnet_id = openstack_networking_subnet_v2.storage.id
+    subnet_id  = openstack_networking_subnet_v2.storage.id
     ip_address = cidrhost(openstack_networking_subnet_v2.storage.cidr, count.index + 70)
   }
 }
@@ -55,20 +55,20 @@ resource "openstack_compute_instance_v2" "ceph_osd" {
     deploy_username         = var.deploy_username
     host_type               = "ceph-osd"
     salt_version            = var.salt_version
-    ssh_public_key = file(var.ssh_public_key_file)
+    ssh_public_key          = file(var.ssh_public_key_file)
     salt_master_ip          = openstack_networking_port_v2.salt_private.fixed_ip[0].ip_address
     set_hostname            = true
     hostname                = "ceph-osd-${count.index}"
   })
 
   connection {
-    type = "ssh"
-    user = var.deploy_username
-    host = self.access_ip_v4
+    type        = "ssh"
+    user        = var.deploy_username
+    host        = self.access_ip_v4
     private_key = file(var.ssh_private_key_file)
 
-    bastion_host = openstack_compute_floatingip_v2.salt.address
-    bastion_user = var.deploy_username
+    bastion_host        = openstack_compute_floatingip_v2.salt.address
+    bastion_user        = var.deploy_username
     bastion_private_key = file(var.ssh_private_key_file)
   }
 
@@ -98,5 +98,5 @@ resource "openstack_compute_volume_attach_v2" "ceph_osd_data_disk" {
   count       = var.ceph_osd_count
   instance_id = openstack_compute_instance_v2.ceph_osd.*.id[count.index]
   volume_id   = openstack_blockstorage_volume_v3.ceph_osd_data_disk.*.id[count.index]
-  device      = "/dev/vdcephosd"
+  device      = "/dev/vdb"
 }
diff --git a/terraform/openstack/terraform.tf b/terraform/openstack/terraform.tf
index fb0502f..2d791e6 100644
--- a/terraform/openstack/terraform.tf
+++ b/terraform/openstack/terraform.tf
@@ -48,5 +48,5 @@ terraform {
   }
 }
 provider "openstack" {
-    max_retries = 5
+  max_retries = 5
 }
-- 
GitLab


From 8c113178aa42dd1d9d695d5e57c48f9434639330 Mon Sep 17 00:00:00 2001
From: David Visscher <d.j.visscher@rug.nl>
Date: Wed, 9 Apr 2025 14:36:26 +0200
Subject: [PATCH 19/43] Fix ceph mon_host address lookup to respect the CIDR of
 the cluster_network subnet

---
 salt/salt/ceph/config.sls | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/salt/salt/ceph/config.sls b/salt/salt/ceph/config.sls
index 53b0812..6b45e6c 100644
--- a/salt/salt/ceph/config.sls
+++ b/salt/salt/ceph/config.sls
@@ -24,7 +24,7 @@ def run():
     mon_initial_members = []
     mds_config = {}
 
-    cluster_network = ip_network(__salt__['pillar.get']("ceph_config:global:cluster_network"))
+    cluster_network = ip_network(__salt__['pillar.get']("ceph:global:cluster_network"))
 
     for minion_name, addrs in __salt__["mine.get"](
         "ceph-monitor*", "network.ip_addrs"
-- 
GitLab


From ebb8552fe6349450615f018749283861432195f9 Mon Sep 17 00:00:00 2001
From: David Visscher <d.j.visscher@rug.nl>
Date: Wed, 9 Apr 2025 14:37:00 +0200
Subject: [PATCH 20/43] Fix ceph mon_host address lookup to respect the CIDR of
 the cluster_network subnet

---
 salt/salt/ceph/config.sls | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/salt/salt/ceph/config.sls b/salt/salt/ceph/config.sls
index 6b45e6c..c6d405d 100644
--- a/salt/salt/ceph/config.sls
+++ b/salt/salt/ceph/config.sls
@@ -24,7 +24,7 @@ def run():
     mon_initial_members = []
     mds_config = {}
 
-    cluster_network = ip_network(__salt__['pillar.get']("ceph:global:cluster_network"))
+    cluster_network = ip_network(__salt__['pillar.get']("ceph:config:global:cluster_network"))
 
     for minion_name, addrs in __salt__["mine.get"](
         "ceph-monitor*", "network.ip_addrs"
-- 
GitLab


From 7f42739e8242e69fa2e03510b3b9b0db2b5580cc Mon Sep 17 00:00:00 2001
From: David Visscher <d.j.visscher@rug.nl>
Date: Wed, 9 Apr 2025 15:34:31 +0200
Subject: [PATCH 21/43] Update gitignore to allow ci_cloud4

---
 .gitignore                                  |  1 +
 .gitlab-ci.yml                              |  3 +-
 terraform/ci.yml                            | 90 +++++++++++++++++++++
 terraform/openstack/openstack_compute.tf    |  2 +-
 terraform/openstack/openstack_controller.tf |  2 +-
 terraform/openstack/openstack_database.tf   |  2 +-
 6 files changed, 96 insertions(+), 4 deletions(-)
 create mode 100644 terraform/ci.yml

diff --git a/.gitignore b/.gitignore
index 008b006..a2b9a4a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,6 +2,7 @@
 
 salt/pillar/environments/**
 !salt/pillar/environments/local_cloud4/**
+!salt/pillar/environments/ci_cloud4/**
 
 ### GENERIC STUFF:
 
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index d072b91..5afb9cc 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,3 +1,4 @@
 include:
   - 'documentation/pipeline.yml'
-  - 'salt/pipeline.yml'
\ No newline at end of file
+  - 'salt/pipeline.yml'
+  - 'terraform/ci.yml'
\ No newline at end of file
diff --git a/terraform/ci.yml b/terraform/ci.yml
new file mode 100644
index 0000000..d7d73a4
--- /dev/null
+++ b/terraform/ci.yml
@@ -0,0 +1,90 @@
+stages:
+  - validate
+  - build
+  - deploy
+  - test
+  - destroy
+
+variables:
+  TF_STATE: cloud4-ci
+  TF_ROOT: terraform/openstack/
+  TF_VAR_external_network_name: vlan1066
+  TF_VAR_base_image_name: Rocky-9.5
+  TF_VAR_default_small_flavor_name: m1.medium
+  TF_VAR_deploy_username: rocky
+  TF_VAR_deploy_environment_name: "ci.cloud4"
+
+cache:
+  key: ${TF_STATE}
+  paths:
+    - terraform/openstack/.terraform/
+    - terraform/openstack/.terraform-version
+  tags:
+    - container
+
+before_script:
+  - echo "$TF_ROOT"
+  - cd ${TF_ROOT}
+
+tofu_init:
+  image: registry.gitlab.com/gitlab-org/terraform-images/stable:latest
+  stage: .pre
+  script:
+    - gitlab-terraform init
+  tags:
+    - container
+
+tofu_fmt:
+  image: registry.gitlab.com/gitlab-org/terraform-images/stable:latest
+  stage: .pre
+  script:
+    - gitlab-terraform fmt
+  tags:
+    - container
+
+tofu_validate:
+  image: registry.gitlab.com/gitlab-org/terraform-images/stable:latest
+  stage: validate
+  script:
+    - gitlab-terraform validate
+  tags:
+    - container
+
+tofu_plan:
+  image: registry.gitlab.com/gitlab-org/terraform-images/stable:latest
+  stage: build
+  script:
+    - gitlab-terraform plan
+    - gitlab-terraform plan-json
+  artefacts:
+    name: plan
+    paths:
+      - ${TF_ROOT}/plan.cache
+  tags:
+    - container
+
+tofu_apply:
+  image: registry.gitlab.com/gitlab-org/terraform-images/stable:latest
+  stage: deploy
+  script:
+      - gitlab-terraform apply
+  dependencies:
+    - tofu_plan
+  only:
+    - main
+    - merge_requests
+  tags:
+    - container
+
+tofu_destroy:
+  image: registry.gitlab.com/gitlab-org/terraform-images/stable:latest
+  stage: destroy
+  script:
+    - gitlab-terraform destroy
+  dependencies:
+    - tofu_apply
+  only:
+    - main
+    - merge_requests
+  tags:
+    - container
diff --git a/terraform/openstack/openstack_compute.tf b/terraform/openstack/openstack_compute.tf
index d6aeffa..07d568d 100644
--- a/terraform/openstack/openstack_compute.tf
+++ b/terraform/openstack/openstack_compute.tf
@@ -1,6 +1,6 @@
 variable "openstack_compute_count" {
   type    = number
-  default = 1
+  default = 2
 }
 
 variable "openstack_compute_size" {
diff --git a/terraform/openstack/openstack_controller.tf b/terraform/openstack/openstack_controller.tf
index fb6c19d..812615c 100644
--- a/terraform/openstack/openstack_controller.tf
+++ b/terraform/openstack/openstack_controller.tf
@@ -1,6 +1,6 @@
 variable "openstack_controller_count" {
   type    = number
-  default = 1
+  default = 3
 }
 
 variable "openstack_controller_size" {
diff --git a/terraform/openstack/openstack_database.tf b/terraform/openstack/openstack_database.tf
index 9902fec..e4ce2fa 100644
--- a/terraform/openstack/openstack_database.tf
+++ b/terraform/openstack/openstack_database.tf
@@ -1,6 +1,6 @@
 variable "openstack_database_count" {
   type    = number
-  default = 1
+  default = 2
 }
 
 variable "openstack_database_size" {
-- 
GitLab


From dcf95af747ed71343925060756cd3d0583d979f9 Mon Sep 17 00:00:00 2001
From: David Visscher <d.j.visscher@rug.nl>
Date: Wed, 9 Apr 2025 15:39:29 +0200
Subject: [PATCH 22/43] Fix CI cache config

---
 terraform/ci.yml                            | 2 --
 terraform/openstack/openstack_controller.tf | 2 +-
 2 files changed, 1 insertion(+), 3 deletions(-)

diff --git a/terraform/ci.yml b/terraform/ci.yml
index d7d73a4..20a09e3 100644
--- a/terraform/ci.yml
+++ b/terraform/ci.yml
@@ -19,8 +19,6 @@ cache:
   paths:
     - terraform/openstack/.terraform/
     - terraform/openstack/.terraform-version
-  tags:
-    - container
 
 before_script:
   - echo "$TF_ROOT"
diff --git a/terraform/openstack/openstack_controller.tf b/terraform/openstack/openstack_controller.tf
index 812615c..027705c 100644
--- a/terraform/openstack/openstack_controller.tf
+++ b/terraform/openstack/openstack_controller.tf
@@ -1,6 +1,6 @@
 variable "openstack_controller_count" {
   type    = number
-  default = 3
+  default = 2
 }
 
 variable "openstack_controller_size" {
-- 
GitLab


From 01662ad93336f9a780d5873c2e4cc7d242aa6ad8 Mon Sep 17 00:00:00 2001
From: David Visscher <d.j.visscher@rug.nl>
Date: Wed, 9 Apr 2025 15:39:58 +0200
Subject: [PATCH 23/43] Spell artifacts correctly

---
 terraform/ci.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/terraform/ci.yml b/terraform/ci.yml
index 20a09e3..6232ed4 100644
--- a/terraform/ci.yml
+++ b/terraform/ci.yml
@@ -54,7 +54,7 @@ tofu_plan:
   script:
     - gitlab-terraform plan
     - gitlab-terraform plan-json
-  artefacts:
+  artifacts:
     name: plan
     paths:
       - ${TF_ROOT}/plan.cache
-- 
GitLab


From 99b0ec5a6ecb38dea4188509a25c586e5f69e2c8 Mon Sep 17 00:00:00 2001
From: David Visscher <d.j.visscher@rug.nl>
Date: Wed, 9 Apr 2025 16:15:16 +0200
Subject: [PATCH 24/43] Add backend config to CI

---
 terraform/ci.yml | 26 ++++++++++++++++----------
 1 file changed, 16 insertions(+), 10 deletions(-)

diff --git a/terraform/ci.yml b/terraform/ci.yml
index 6232ed4..2b2b47d 100644
--- a/terraform/ci.yml
+++ b/terraform/ci.yml
@@ -6,7 +6,7 @@ stages:
   - destroy
 
 variables:
-  TF_STATE: cloud4-ci
+  TF_STATE: merlin-cloud4-ci
   TF_ROOT: terraform/openstack/
   TF_VAR_external_network_name: vlan1066
   TF_VAR_base_image_name: Rocky-9.5
@@ -24,15 +24,21 @@ before_script:
   - echo "$TF_ROOT"
   - cd ${TF_ROOT}
 
-tofu_init:
+terraform_init:
   image: registry.gitlab.com/gitlab-org/terraform-images/stable:latest
   stage: .pre
   script:
-    - gitlab-terraform init
+    - gitlab-terraform init \
+      -backend-config="address=https://gitrepo.service.rug.nl/api/v4/projects/142/terraform/state/$TF_STATE_NAME"
+      -backend-config="lock_address=https://gitrepo.service.rug.nl/api/v4/projects/142/terraform/state/$TF_STATE_NAME/lock" \
+      -backend-config="unlock_address=https://gitrepo.service.rug.nl/api/v4/projects/142/terraform/state/$TF_STATE_NAME/lock" \
+      -backend-config="lock_method=POST" \
+      -backend-config="unlock_method=DELETE" \
+      -backend-config="retry_wait_min=5"
   tags:
     - container
 
-tofu_fmt:
+terraform_fmt:
   image: registry.gitlab.com/gitlab-org/terraform-images/stable:latest
   stage: .pre
   script:
@@ -40,7 +46,7 @@ tofu_fmt:
   tags:
     - container
 
-tofu_validate:
+terraform_validate:
   image: registry.gitlab.com/gitlab-org/terraform-images/stable:latest
   stage: validate
   script:
@@ -48,7 +54,7 @@ tofu_validate:
   tags:
     - container
 
-tofu_plan:
+terraform_plan:
   image: registry.gitlab.com/gitlab-org/terraform-images/stable:latest
   stage: build
   script:
@@ -61,26 +67,26 @@ tofu_plan:
   tags:
     - container
 
-tofu_apply:
+terraform_apply:
   image: registry.gitlab.com/gitlab-org/terraform-images/stable:latest
   stage: deploy
   script:
       - gitlab-terraform apply
   dependencies:
-    - tofu_plan
+    - terraform_plan
   only:
     - main
     - merge_requests
   tags:
     - container
 
-tofu_destroy:
+terraform_destroy:
   image: registry.gitlab.com/gitlab-org/terraform-images/stable:latest
   stage: destroy
   script:
     - gitlab-terraform destroy
   dependencies:
-    - tofu_apply
+    - terraform_apply
   only:
     - main
     - merge_requests
-- 
GitLab


From e299a3559b0a1ff8042b680991581cb596c8d878 Mon Sep 17 00:00:00 2001
From: David Visscher <d.j.visscher@rug.nl>
Date: Wed, 9 Apr 2025 16:16:15 +0200
Subject: [PATCH 25/43] Remove backend config from CI

---
 terraform/ci.yml | 8 +-------
 1 file changed, 1 insertion(+), 7 deletions(-)

diff --git a/terraform/ci.yml b/terraform/ci.yml
index 2b2b47d..19761d0 100644
--- a/terraform/ci.yml
+++ b/terraform/ci.yml
@@ -28,13 +28,7 @@ terraform_init:
   image: registry.gitlab.com/gitlab-org/terraform-images/stable:latest
   stage: .pre
   script:
-    - gitlab-terraform init \
-      -backend-config="address=https://gitrepo.service.rug.nl/api/v4/projects/142/terraform/state/$TF_STATE_NAME"
-      -backend-config="lock_address=https://gitrepo.service.rug.nl/api/v4/projects/142/terraform/state/$TF_STATE_NAME/lock" \
-      -backend-config="unlock_address=https://gitrepo.service.rug.nl/api/v4/projects/142/terraform/state/$TF_STATE_NAME/lock" \
-      -backend-config="lock_method=POST" \
-      -backend-config="unlock_method=DELETE" \
-      -backend-config="retry_wait_min=5"
+    - gitlab-terraform init
   tags:
     - container
 
-- 
GitLab


From 8e0289dca3c54e5495d57dd5094faa0100e84e89 Mon Sep 17 00:00:00 2001
From: David Visscher <d.j.visscher@rug.nl>
Date: Wed, 9 Apr 2025 16:17:18 +0200
Subject: [PATCH 26/43] Fix TF_STATE_NAME

---
 terraform/ci.yml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/terraform/ci.yml b/terraform/ci.yml
index 19761d0..0e4e5af 100644
--- a/terraform/ci.yml
+++ b/terraform/ci.yml
@@ -6,7 +6,7 @@ stages:
   - destroy
 
 variables:
-  TF_STATE: merlin-cloud4-ci
+  TF_STATE_NAME: merlin-cloud4-ci
   TF_ROOT: terraform/openstack/
   TF_VAR_external_network_name: vlan1066
   TF_VAR_base_image_name: Rocky-9.5
@@ -15,7 +15,7 @@ variables:
   TF_VAR_deploy_environment_name: "ci.cloud4"
 
 cache:
-  key: ${TF_STATE}
+  key: ${TF_STATE_NAME}
   paths:
     - terraform/openstack/.terraform/
     - terraform/openstack/.terraform-version
-- 
GitLab


From 83ff5268b905be2fa54134a57fd14a40d38d9ff6 Mon Sep 17 00:00:00 2001
From: David Visscher <d.j.visscher@rug.nl>
Date: Wed, 9 Apr 2025 16:20:12 +0200
Subject: [PATCH 27/43] Move all static checking to .pre phase

---
 documentation/pipeline.yml | 2 +-
 salt/pipeline.yml          | 2 +-
 terraform/ci.yml           | 1 -
 3 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/documentation/pipeline.yml b/documentation/pipeline.yml
index a0cf5a9..34dcd86 100644
--- a/documentation/pipeline.yml
+++ b/documentation/pipeline.yml
@@ -3,7 +3,7 @@ image: python:3.10-buster
 before_script:
 
 test_docs:
-  stage: test
+  stage: .pre
   script:
     - cd documentation
     - pip install -r requirements.txt
diff --git a/salt/pipeline.yml b/salt/pipeline.yml
index 8414fb6..4dd4ecb 100644
--- a/salt/pipeline.yml
+++ b/salt/pipeline.yml
@@ -1,6 +1,6 @@
 salt-lint:
   image: python:3.10-buster
-  stage: test
+  stage: .pre
   script:
     - pip install salt-lint
     - 'find salt -type f -name "*.sls" -print0 | xargs -0 --no-run-if-empty salt-lint'
diff --git a/terraform/ci.yml b/terraform/ci.yml
index 0e4e5af..1baff0d 100644
--- a/terraform/ci.yml
+++ b/terraform/ci.yml
@@ -18,7 +18,6 @@ cache:
   key: ${TF_STATE_NAME}
   paths:
     - terraform/openstack/.terraform/
-    - terraform/openstack/.terraform-version
 
 before_script:
   - echo "$TF_ROOT"
-- 
GitLab


From 6ac1f68f7ea49b587d1fde1dc9fdb889e6914d82 Mon Sep 17 00:00:00 2001
From: David Visscher <d.j.visscher@rug.nl>
Date: Wed, 9 Apr 2025 16:22:10 +0200
Subject: [PATCH 28/43] Use openstack version dalmatian

---
 salt/pillar/defaults.sls | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/salt/pillar/defaults.sls b/salt/pillar/defaults.sls
index a1f7a61..cbd37bc 100644
--- a/salt/pillar/defaults.sls
+++ b/salt/pillar/defaults.sls
@@ -169,7 +169,7 @@ loki:
 
 openstack:
   region: "cloud4"
-  release_version: epoxy
+  release_version: dalmatian
 
   keystone:
     admin_password: &keystone_admin_pass "Knock.Knock.Whos.There? ... Keystone"
-- 
GitLab


From 65e2cbc86ec2cc7d0f95a0c99f100c9704f8c8a4 Mon Sep 17 00:00:00 2001
From: David Visscher <d.j.visscher@rug.nl>
Date: Wed, 9 Apr 2025 16:24:52 +0200
Subject: [PATCH 29/43] before_script conflicts with other build parts

---
 terraform/ci.yml | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/terraform/ci.yml b/terraform/ci.yml
index 1baff0d..7e94def 100644
--- a/terraform/ci.yml
+++ b/terraform/ci.yml
@@ -19,14 +19,12 @@ cache:
   paths:
     - terraform/openstack/.terraform/
 
-before_script:
-  - echo "$TF_ROOT"
-  - cd ${TF_ROOT}
-
 terraform_init:
   image: registry.gitlab.com/gitlab-org/terraform-images/stable:latest
   stage: .pre
   script:
+    - echo "$TF_ROOT"
+    - cd ${TF_ROOT}
     - gitlab-terraform init
   tags:
     - container
@@ -35,6 +33,8 @@ terraform_fmt:
   image: registry.gitlab.com/gitlab-org/terraform-images/stable:latest
   stage: .pre
   script:
+    - echo "$TF_ROOT"
+    - cd ${TF_ROOT}
     - gitlab-terraform fmt
   tags:
     - container
@@ -43,6 +43,8 @@ terraform_validate:
   image: registry.gitlab.com/gitlab-org/terraform-images/stable:latest
   stage: validate
   script:
+    - echo "$TF_ROOT"
+    - cd ${TF_ROOT}
     - gitlab-terraform validate
   tags:
     - container
@@ -51,6 +53,8 @@ terraform_plan:
   image: registry.gitlab.com/gitlab-org/terraform-images/stable:latest
   stage: build
   script:
+    - echo "$TF_ROOT"
+    - cd ${TF_ROOT}
     - gitlab-terraform plan
     - gitlab-terraform plan-json
   artifacts:
@@ -64,6 +68,8 @@ terraform_apply:
   image: registry.gitlab.com/gitlab-org/terraform-images/stable:latest
   stage: deploy
   script:
+    - echo "$TF_ROOT"
+    - cd ${TF_ROOT}
       - gitlab-terraform apply
   dependencies:
     - terraform_plan
@@ -77,6 +83,8 @@ terraform_destroy:
   image: registry.gitlab.com/gitlab-org/terraform-images/stable:latest
   stage: destroy
   script:
+    - echo "$TF_ROOT"
+    - cd ${TF_ROOT}
     - gitlab-terraform destroy
   dependencies:
     - terraform_apply
-- 
GitLab


From 36060b197cbd9b47f1054ae826417f784be67608 Mon Sep 17 00:00:00 2001
From: David Visscher <d.j.visscher@rug.nl>
Date: Wed, 9 Apr 2025 16:31:00 +0200
Subject: [PATCH 30/43] Generate an ssh key when deploying

---
 terraform/ci.yml | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/terraform/ci.yml b/terraform/ci.yml
index 7e94def..242db07 100644
--- a/terraform/ci.yml
+++ b/terraform/ci.yml
@@ -13,11 +13,15 @@ variables:
   TF_VAR_default_small_flavor_name: m1.medium
   TF_VAR_deploy_username: rocky
   TF_VAR_deploy_environment_name: "ci.cloud4"
+  TF_VAR_ssh_private_key_file: terraform/openstack/.terraform.key
+  TF_VAR_ssh_public_key_file: terraform/openstack/.terraform.key.pub
 
 cache:
   key: ${TF_STATE_NAME}
   paths:
     - terraform/openstack/.terraform/
+    - terraform/openstack/.terraform.key
+    - terraform/openstack/.terraform.key.pub
 
 terraform_init:
   image: registry.gitlab.com/gitlab-org/terraform-images/stable:latest
@@ -25,6 +29,7 @@ terraform_init:
   script:
     - echo "$TF_ROOT"
     - cd ${TF_ROOT}
+    - ssh-keygen -t ed25519 -f .terraform.key -N ''
     - gitlab-terraform init
   tags:
     - container
-- 
GitLab


From c214fb14cdaa5e8d4a1c426eda31df7977e79c0e Mon Sep 17 00:00:00 2001
From: David Visscher <d.j.visscher@rug.nl>
Date: Wed, 9 Apr 2025 16:33:31 +0200
Subject: [PATCH 31/43] TF variables are relative to TF_ROOT

---
 terraform/ci.yml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/terraform/ci.yml b/terraform/ci.yml
index 242db07..5837618 100644
--- a/terraform/ci.yml
+++ b/terraform/ci.yml
@@ -13,8 +13,8 @@ variables:
   TF_VAR_default_small_flavor_name: m1.medium
   TF_VAR_deploy_username: rocky
   TF_VAR_deploy_environment_name: "ci.cloud4"
-  TF_VAR_ssh_private_key_file: terraform/openstack/.terraform.key
-  TF_VAR_ssh_public_key_file: terraform/openstack/.terraform.key.pub
+  TF_VAR_ssh_private_key_file: .terraform.key
+  TF_VAR_ssh_public_key_file: .terraform.key.pub
 
 cache:
   key: ${TF_STATE_NAME}
-- 
GitLab


From 8e05a2f2eb3af544f30deffb79f511677034012d Mon Sep 17 00:00:00 2001
From: David Visscher <d.j.visscher@rug.nl>
Date: Wed, 9 Apr 2025 17:22:12 +0200
Subject: [PATCH 32/43] Add the extra hostsfile entries required for OS to work

---
 salt/pillar/environments/ci_cloud4/defaults.sls | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/salt/pillar/environments/ci_cloud4/defaults.sls b/salt/pillar/environments/ci_cloud4/defaults.sls
index 4454144..2150937 100644
--- a/salt/pillar/environments/ci_cloud4/defaults.sls
+++ b/salt/pillar/environments/ci_cloud4/defaults.sls
@@ -14,4 +14,18 @@ ceph:
       cluster_network: 10.12.0.0/24
   osd_disks:
     - name: /dev/vdb
-      type: lvm
\ No newline at end of file
+      type: lvm
+
+hostsfile:
+  identity.local.cloud4:
+    - 10.11.0.100
+  image.local.cloud4:
+    - 10.11.0.100
+  network.local.cloud4:
+    - 10.11.0.100
+  compute.local.cloud4:
+    - 10.11.0.100
+  block-storage.local.cloud4:
+    - 10.11.0.100
+  placement.local.cloud4:
+    - 10.11.0.100
-- 
GitLab


From cba1e343b3988f9efacb8d098c8a599b2bddac7b Mon Sep 17 00:00:00 2001
From: David Visscher <d.j.visscher@rug.nl>
Date: Wed, 9 Apr 2025 17:24:29 +0200
Subject: [PATCH 33/43] Filter the CI mine function to local IPs only

---
 salt/pillar/environments/ci_cloud4/defaults.sls | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/salt/pillar/environments/ci_cloud4/defaults.sls b/salt/pillar/environments/ci_cloud4/defaults.sls
index 2150937..ef7fd4d 100644
--- a/salt/pillar/environments/ci_cloud4/defaults.sls
+++ b/salt/pillar/environments/ci_cloud4/defaults.sls
@@ -6,6 +6,14 @@ motd:
     ██           ██ ██      ██
      ██████      ██  ██████ ██
 
+
+# Only mine local IP addresses
+# 10.10.0.0/24 is considered "public" for the CI
+mine_functions:
+  network.ip_addrs:
+    - 10.11.0.0/24  # private network
+    - 10.12.0.0/24  # storage network
+
 ceph:
   config:
     global:
-- 
GitLab


From 4adb0a28347158090851eb634a90e711566d866c Mon Sep 17 00:00:00 2001
From: David Visscher <d.j.visscher@rug.nl>
Date: Wed, 9 Apr 2025 17:50:53 +0200
Subject: [PATCH 34/43] Fix incorrect indent in CI.yml for cloud4_ci

---
 terraform/ci.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/terraform/ci.yml b/terraform/ci.yml
index 5837618..4be3095 100644
--- a/terraform/ci.yml
+++ b/terraform/ci.yml
@@ -75,7 +75,7 @@ terraform_apply:
   script:
     - echo "$TF_ROOT"
     - cd ${TF_ROOT}
-      - gitlab-terraform apply
+    - gitlab-terraform apply
   dependencies:
     - terraform_plan
   only:
-- 
GitLab


From b5ca265c8af66241f9da60ac40b218c79015be17 Mon Sep 17 00:00:00 2001
From: David Visscher <d.j.visscher@rug.nl>
Date: Wed, 9 Apr 2025 17:58:01 +0200
Subject: [PATCH 35/43] Make sure early stages run when needed

---
 terraform/ci.yml | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/terraform/ci.yml b/terraform/ci.yml
index 4be3095..849ffff 100644
--- a/terraform/ci.yml
+++ b/terraform/ci.yml
@@ -31,6 +31,11 @@ terraform_init:
     - cd ${TF_ROOT}
     - ssh-keygen -t ed25519 -f .terraform.key -N ''
     - gitlab-terraform init
+  only:
+    - main
+    - branches
+    - tags
+    - merge_requests
   tags:
     - container
 
@@ -41,6 +46,11 @@ terraform_fmt:
     - echo "$TF_ROOT"
     - cd ${TF_ROOT}
     - gitlab-terraform fmt
+  only:
+    - main
+    - branches
+    - tags
+    - merge_requests
   tags:
     - container
 
@@ -51,6 +61,11 @@ terraform_validate:
     - echo "$TF_ROOT"
     - cd ${TF_ROOT}
     - gitlab-terraform validate
+  only:
+    - main
+    - branches
+    - tags
+    - merge_requests
   tags:
     - container
 
@@ -66,6 +81,11 @@ terraform_plan:
     name: plan
     paths:
       - ${TF_ROOT}/plan.cache
+  only:
+    - main
+    - branches
+    - tags
+    - merge_requests
   tags:
     - container
 
-- 
GitLab


From 5e65e9a32bcf80352ab607ee5480cd15e3107f8b Mon Sep 17 00:00:00 2001
From: David Visscher <d.j.visscher@rug.nl>
Date: Wed, 9 Apr 2025 18:30:06 +0200
Subject: [PATCH 36/43] Dont regen key if it already exists

---
 terraform/ci.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/terraform/ci.yml b/terraform/ci.yml
index 849ffff..b639e5c 100644
--- a/terraform/ci.yml
+++ b/terraform/ci.yml
@@ -29,7 +29,7 @@ terraform_init:
   script:
     - echo "$TF_ROOT"
     - cd ${TF_ROOT}
-    - ssh-keygen -t ed25519 -f .terraform.key -N ''
+    - "if [ ! -f .terraform.key ]; then ssh-keygen -t ed25519 -f .terraform.key -N ''; fi"
     - gitlab-terraform init
   only:
     - main
-- 
GitLab


From 7afd94320b4ff1ac087560e41a518dfac7b822bd Mon Sep 17 00:00:00 2001
From: David Visscher <d.j.visscher@rug.nl>
Date: Wed, 9 Apr 2025 18:39:07 +0200
Subject: [PATCH 37/43] Caching causes some problems

---
 terraform/ci.yml | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/terraform/ci.yml b/terraform/ci.yml
index b639e5c..c2ec613 100644
--- a/terraform/ci.yml
+++ b/terraform/ci.yml
@@ -16,12 +16,12 @@ variables:
   TF_VAR_ssh_private_key_file: .terraform.key
   TF_VAR_ssh_public_key_file: .terraform.key.pub
 
-cache:
-  key: ${TF_STATE_NAME}
-  paths:
-    - terraform/openstack/.terraform/
-    - terraform/openstack/.terraform.key
-    - terraform/openstack/.terraform.key.pub
+#cache:
+#  key: ${TF_STATE_NAME}
+#  paths:
+#    - terraform/openstack/.terraform/
+#    - terraform/openstack/.terraform.key
+#    - terraform/openstack/.terraform.key.pub
 
 terraform_init:
   image: registry.gitlab.com/gitlab-org/terraform-images/stable:latest
-- 
GitLab


From c76ac9ee2c6b3a2aa6facba8227e3e3b6cf680dc Mon Sep 17 00:00:00 2001
From: David Visscher <d.j.visscher@rug.nl>
Date: Wed, 9 Apr 2025 21:37:54 +0200
Subject: [PATCH 38/43] Not caching is also not good

---
 terraform/ci.yml | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/terraform/ci.yml b/terraform/ci.yml
index c2ec613..b639e5c 100644
--- a/terraform/ci.yml
+++ b/terraform/ci.yml
@@ -16,12 +16,12 @@ variables:
   TF_VAR_ssh_private_key_file: .terraform.key
   TF_VAR_ssh_public_key_file: .terraform.key.pub
 
-#cache:
-#  key: ${TF_STATE_NAME}
-#  paths:
-#    - terraform/openstack/.terraform/
-#    - terraform/openstack/.terraform.key
-#    - terraform/openstack/.terraform.key.pub
+cache:
+  key: ${TF_STATE_NAME}
+  paths:
+    - terraform/openstack/.terraform/
+    - terraform/openstack/.terraform.key
+    - terraform/openstack/.terraform.key.pub
 
 terraform_init:
   image: registry.gitlab.com/gitlab-org/terraform-images/stable:latest
-- 
GitLab


From f922d5c3a036cd293130612ba1bb5b85fbbbbf6a Mon Sep 17 00:00:00 2001
From: David Visscher <d.j.visscher@rug.nl>
Date: Thu, 10 Apr 2025 16:59:53 +0200
Subject: [PATCH 39/43] remove trailing slash from TF_ROOT

---
 terraform/ci.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/terraform/ci.yml b/terraform/ci.yml
index b639e5c..f7dc00f 100644
--- a/terraform/ci.yml
+++ b/terraform/ci.yml
@@ -7,7 +7,7 @@ stages:
 
 variables:
   TF_STATE_NAME: merlin-cloud4-ci
-  TF_ROOT: terraform/openstack/
+  TF_ROOT: terraform/openstack
   TF_VAR_external_network_name: vlan1066
   TF_VAR_base_image_name: Rocky-9.5
   TF_VAR_default_small_flavor_name: m1.medium
-- 
GitLab


From e6efd82ec058d7ff231b25bab30793eb6518b7e0 Mon Sep 17 00:00:00 2001
From: David Visscher <d.j.visscher@rug.nl>
Date: Thu, 10 Apr 2025 17:05:50 +0200
Subject: [PATCH 40/43] NOCACHE

---
 terraform/ci.yml | 20 ++++++++++++--------
 1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/terraform/ci.yml b/terraform/ci.yml
index f7dc00f..5433f7a 100644
--- a/terraform/ci.yml
+++ b/terraform/ci.yml
@@ -16,12 +16,12 @@ variables:
   TF_VAR_ssh_private_key_file: .terraform.key
   TF_VAR_ssh_public_key_file: .terraform.key.pub
 
-cache:
-  key: ${TF_STATE_NAME}
-  paths:
-    - terraform/openstack/.terraform/
-    - terraform/openstack/.terraform.key
-    - terraform/openstack/.terraform.key.pub
+# cache:
+#   key: ${TF_STATE_NAME}
+#   paths:
+#     - terraform/openstack/.terraform/
+#     - terraform/openstack/.terraform.key
+#     - terraform/openstack/.terraform.key.pub
 
 terraform_init:
   image: registry.gitlab.com/gitlab-org/terraform-images/stable:latest
@@ -75,6 +75,8 @@ terraform_plan:
   script:
     - echo "$TF_ROOT"
     - cd ${TF_ROOT}
+    - "if [ ! -f .terraform.key ]; then ssh-keygen -t ed25519 -f .terraform.key -N ''; fi"
+    - gitlab-terraform init
     - gitlab-terraform plan
     - gitlab-terraform plan-json
   artifacts:
@@ -95,9 +97,9 @@ terraform_apply:
   script:
     - echo "$TF_ROOT"
     - cd ${TF_ROOT}
+    - "if [ ! -f .terraform.key ]; then ssh-keygen -t ed25519 -f .terraform.key -N ''; fi"
+    - gitlab-terraform init
     - gitlab-terraform apply
-  dependencies:
-    - terraform_plan
   only:
     - main
     - merge_requests
@@ -110,6 +112,8 @@ terraform_destroy:
   script:
     - echo "$TF_ROOT"
     - cd ${TF_ROOT}
+    - "if [ ! -f .terraform.key ]; then ssh-keygen -t ed25519 -f .terraform.key -N ''; fi"
+    - gitlab-terraform init
     - gitlab-terraform destroy
   dependencies:
     - terraform_apply
-- 
GitLab


From 9f0e42383fc1f1e38c7bb6aeda9580747ae62ad4 Mon Sep 17 00:00:00 2001
From: David Visscher <d.j.visscher@rug.nl>
Date: Thu, 10 Apr 2025 17:13:25 +0200
Subject: [PATCH 41/43] Revert "NOCACHE"

This reverts commit e6efd82ec058d7ff231b25bab30793eb6518b7e0.
---
 terraform/ci.yml | 20 ++++++++------------
 1 file changed, 8 insertions(+), 12 deletions(-)

diff --git a/terraform/ci.yml b/terraform/ci.yml
index 5433f7a..f7dc00f 100644
--- a/terraform/ci.yml
+++ b/terraform/ci.yml
@@ -16,12 +16,12 @@ variables:
   TF_VAR_ssh_private_key_file: .terraform.key
   TF_VAR_ssh_public_key_file: .terraform.key.pub
 
-# cache:
-#   key: ${TF_STATE_NAME}
-#   paths:
-#     - terraform/openstack/.terraform/
-#     - terraform/openstack/.terraform.key
-#     - terraform/openstack/.terraform.key.pub
+cache:
+  key: ${TF_STATE_NAME}
+  paths:
+    - terraform/openstack/.terraform/
+    - terraform/openstack/.terraform.key
+    - terraform/openstack/.terraform.key.pub
 
 terraform_init:
   image: registry.gitlab.com/gitlab-org/terraform-images/stable:latest
@@ -75,8 +75,6 @@ terraform_plan:
   script:
     - echo "$TF_ROOT"
     - cd ${TF_ROOT}
-    - "if [ ! -f .terraform.key ]; then ssh-keygen -t ed25519 -f .terraform.key -N ''; fi"
-    - gitlab-terraform init
     - gitlab-terraform plan
     - gitlab-terraform plan-json
   artifacts:
@@ -97,9 +95,9 @@ terraform_apply:
   script:
     - echo "$TF_ROOT"
     - cd ${TF_ROOT}
-    - "if [ ! -f .terraform.key ]; then ssh-keygen -t ed25519 -f .terraform.key -N ''; fi"
-    - gitlab-terraform init
     - gitlab-terraform apply
+  dependencies:
+    - terraform_plan
   only:
     - main
     - merge_requests
@@ -112,8 +110,6 @@ terraform_destroy:
   script:
     - echo "$TF_ROOT"
     - cd ${TF_ROOT}
-    - "if [ ! -f .terraform.key ]; then ssh-keygen -t ed25519 -f .terraform.key -N ''; fi"
-    - gitlab-terraform init
     - gitlab-terraform destroy
   dependencies:
     - terraform_apply
-- 
GitLab


From 12758c71887593b42a23a170f7a42c3a0caa73b1 Mon Sep 17 00:00:00 2001
From: David Visscher <d.j.visscher@rug.nl>
Date: Thu, 10 Apr 2025 17:14:37 +0200
Subject: [PATCH 42/43] FUCK YOU AND YOUR PLANS

---
 terraform/ci.yml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/terraform/ci.yml b/terraform/ci.yml
index f7dc00f..4ebc2e7 100644
--- a/terraform/ci.yml
+++ b/terraform/ci.yml
@@ -95,6 +95,7 @@ terraform_apply:
   script:
     - echo "$TF_ROOT"
     - cd ${TF_ROOT}
+    - "rm -rf plan.cache *.tfplan"
     - gitlab-terraform apply
   dependencies:
     - terraform_plan
-- 
GitLab


From dbd2f5438ea337089bbb6c9baaef39067dfa7d4b Mon Sep 17 00:00:00 2001
From: David Visscher <d.j.visscher@rug.nl>
Date: Tue, 29 Apr 2025 14:52:58 +0000
Subject: [PATCH 43/43] Revert "FUCK YOU AND YOUR PLANS"

This reverts commit 12758c71887593b42a23a170f7a42c3a0caa73b1
---
 terraform/ci.yml | 1 -
 1 file changed, 1 deletion(-)

diff --git a/terraform/ci.yml b/terraform/ci.yml
index 4ebc2e7..f7dc00f 100644
--- a/terraform/ci.yml
+++ b/terraform/ci.yml
@@ -95,7 +95,6 @@ terraform_apply:
   script:
     - echo "$TF_ROOT"
     - cd ${TF_ROOT}
-    - "rm -rf plan.cache *.tfplan"
     - gitlab-terraform apply
   dependencies:
     - terraform_plan
-- 
GitLab