diff --git a/docs/_releasenotes/2225.feature.1.individual-root-volumes b/docs/_releasenotes/2225.feature.1.individual-root-volumes new file mode 100644 index 0000000000000000000000000000000000000000..a0990367ef8b03c70c29d285e22ef85907e1d0b7 --- /dev/null +++ b/docs/_releasenotes/2225.feature.1.individual-root-volumes @@ -0,0 +1 @@ +TBD diff --git a/docs/user/reference/options/yk8s.openstack.rst b/docs/user/reference/options/yk8s.openstack.rst index b70e689f7649f0374c06fd35db1c996efd785741..7719e076b4841e3515af7cecbb3bfa0314dbd56c 100644 --- a/docs/user/reference/options/yk8s.openstack.rst +++ b/docs/user/reference/options/yk8s.openstack.rst @@ -194,7 +194,7 @@ https://gitlab.com/alasca.cloud/tarook/tarook/-/tree/devel/nix/yk8s/openstack.ni ``yk8s.openstack.create_root_disk_on_volume`` ############################################# -Whether to enable creation of root disk volumes. +Whether to enable creation of root disk volumes for all instances. If true, create block volume for each instance and boot from there. Equivalent to ``openstack server create --boot-from-volume […]``. . @@ -310,6 +310,30 @@ https://gitlab.com/alasca.cloud/tarook/tarook/-/tree/devel/nix/yk8s/openstack.ni https://gitlab.com/alasca.cloud/tarook/tarook/-/tree/devel/nix/yk8s/openstack.nix +.. _configuration-options.yk8s.openstack.gateway_defaults.create_root_disk_on_volume: + +``yk8s.openstack.gateway_defaults.create_root_disk_on_volume`` +############################################################## + +Enable creation of root disk volume for gateways. +If true, create block volume for all gateways and boot from there. +Equivalent to ``openstack server create --boot-from-volume […]``. + + +**Type:**:: + + null or boolean + + +**Default:**:: + + null + + +**Declared by** +https://gitlab.com/alasca.cloud/tarook/tarook/-/tree/devel/nix/yk8s/openstack.nix + + .. _configuration-options.yk8s.openstack.gateway_defaults.flavor: ``yk8s.openstack.gateway_defaults.flavor`` @@ -348,16 +372,17 @@ https://gitlab.com/alasca.cloud/tarook/tarook/-/tree/devel/nix/yk8s/openstack.ni ################################################## Only applies if :ref:`configuration-options.yk8s.openstack.create_root_disk_on_volume` is set to ``true`` +If null, the disk size of the configured flavor will be used. **Type:**:: - positive integer, meaning >0 + null or (positive integer, meaning >0) **Default:**:: - 10 + null **Declared by** @@ -411,6 +436,30 @@ Will most of the time be set via the environment variable TF_VAR_keypair https://gitlab.com/alasca.cloud/tarook/tarook/-/tree/devel/nix/yk8s/openstack.nix +.. _configuration-options.yk8s.openstack.master_defaults.create_root_disk_on_volume: + +``yk8s.openstack.master_defaults.create_root_disk_on_volume`` +############################################################# + +Enable creation of root disk volume for masters by default. +If true, create block volume for masters by default and boot from there. +Equivalent to ``openstack server create --boot-from-volume […]``. + + +**Type:**:: + + null or boolean + + +**Default:**:: + + null + + +**Declared by** +https://gitlab.com/alasca.cloud/tarook/tarook/-/tree/devel/nix/yk8s/openstack.nix + + .. _configuration-options.yk8s.openstack.master_defaults.flavor: ``yk8s.openstack.master_defaults.flavor`` @@ -449,16 +498,17 @@ https://gitlab.com/alasca.cloud/tarook/tarook/-/tree/devel/nix/yk8s/openstack.ni ################################################# Only applies if :ref:`configuration-options.yk8s.openstack.create_root_disk_on_volume` is set to ``true`` +If null, the disk size of the configured flavor will be used. **Type:**:: - positive integer, meaning >0 + null or (positive integer, meaning >0) **Default:**:: - 50 + null **Declared by** @@ -612,6 +662,37 @@ https://gitlab.com/alasca.cloud/tarook/tarook/-/tree/devel/nix/yk8s/openstack.ni https://gitlab.com/alasca.cloud/tarook/tarook/-/tree/devel/nix/yk8s/openstack.nix +.. _configuration-options.yk8s.openstack.nodes..create_root_disk_on_volume: + +``yk8s.openstack.nodes..create_root_disk_on_volume`` +########################################################## + +Enable creation of root disk volume for this instance. +If true, create block volume for this instance and boot from there. +Equivalent to ``openstack server create --boot-from-volume […]``. + +This option takes precedence over +:ref:`configuration-options.yk8s.openstack.gateway_defaults.create_root_disk_on_volume`, +:ref:`configuration-options.yk8s.openstack.master_defaults.create_root_disk_on_volume`, +:ref:`configuration-options.yk8s.openstack.worker_defaults.create_root_disk_on_volume`, +and +:ref:``. + + +**Type:**:: + + null or boolean + + +**Default:**:: + + null + + +**Declared by** +https://gitlab.com/alasca.cloud/tarook/tarook/-/tree/devel/nix/yk8s/openstack.nix + + .. _configuration-options.yk8s.openstack.nodes..flavor: ``yk8s.openstack.nodes..flavor`` @@ -803,6 +884,30 @@ Leaving this empty means to not join any anti affinity group https://gitlab.com/alasca.cloud/tarook/tarook/-/tree/devel/nix/yk8s/openstack.nix +.. _configuration-options.yk8s.openstack.worker_defaults.create_root_disk_on_volume: + +``yk8s.openstack.worker_defaults.create_root_disk_on_volume`` +############################################################# + +Enable creation of root disk volume for workers by default. +If true, create block volume for workers by default and boot from there. +Equivalent to ``openstack server create --boot-from-volume […]``. + + +**Type:**:: + + null or boolean + + +**Default:**:: + + null + + +**Declared by** +https://gitlab.com/alasca.cloud/tarook/tarook/-/tree/devel/nix/yk8s/openstack.nix + + .. _configuration-options.yk8s.openstack.worker_defaults.flavor: ``yk8s.openstack.worker_defaults.flavor`` @@ -841,16 +946,17 @@ https://gitlab.com/alasca.cloud/tarook/tarook/-/tree/devel/nix/yk8s/openstack.ni ################################################# Only applies if :ref:`configuration-options.yk8s.openstack.create_root_disk_on_volume` is set to ``true`` +If null, the disk size of the configured flavor will be used. **Type:**:: - positive integer, meaning >0 + null or (positive integer, meaning >0) **Default:**:: - 50 + null **Declared by** diff --git a/nix/yk8s/openstack.nix b/nix/yk8s/openstack.nix index 69a8c1c7acdebf2d6f374710fed78c73df7e8364..3441de050b5afcc2cd0f4f3cbbf4bca1922f4105 100644 --- a/nix/yk8s/openstack.nix +++ b/nix/yk8s/openstack.nix @@ -25,8 +25,10 @@ root_disk_size = mkOption { description = '' Only applies if :ref:`configuration-options.yk8s.openstack.create_root_disk_on_volume` is set to ``true`` + If null, the disk size of the configured flavor will be used. ''; - type = types.ints.positive; + type = with types; nullOr types.ints.positive; + default = null; }; root_disk_volume_type = mkOption { description = '' @@ -36,6 +38,20 @@ type = with types; nullOr yk8s.openstack.volumeTypeName; default = null; }; + create_root_disk_on_volume = mkOption { + description = '' + Enable creation of root disk volume. + If true, create block volume for instances by default and boot from there. + Equivalent to ``openstack server create --boot-from-volume […]``. + + This option is inferior to + :ref:`configuration-options.yk8s.openstack.nodes..create_root_disk_on_volume`, + but takes precedence over + :ref:`configuration-options.yk8s.openstack.create_root_disk_on_volume` + ''; + type = with types; nullOr types.bool; + default = null; + }; }; # NOTE: Some options are not used by Ansible but other parts of the LCM, # such as Terraform. Therefore they are filtered out. @@ -183,7 +199,7 @@ in { }; create_root_disk_on_volume = mkEnableOption '' - creation of root disk volumes. + creation of root disk volumes for all instances. If true, create block volume for each instance and boot from there. Equivalent to ``openstack server create --boot-from-volume […]``. ''; @@ -224,20 +240,26 @@ in { }; gateway_defaults = recursiveUpdate commonNodeDefaultOptions { - root_disk_size.default = 10; common_name = mkOption { type = types.str; default = "gw-"; }; + create_root_disk_on_volume.description = '' + Enable creation of root disk volume for gateways. + If true, create block volume for all gateways and boot from there. + Equivalent to ``openstack server create --boot-from-volume […]``. + ''; }; master_defaults = recursiveUpdate commonNodeDefaultOptions { - root_disk_size.default = 50; + create_root_disk_on_volume.description = '' + Enable creation of root disk volume for masters by default. + If true, create block volume for masters by default and boot from there. + Equivalent to ``openstack server create --boot-from-volume […]``. + ''; }; worker_defaults = recursiveUpdate commonNodeDefaultOptions { - root_disk_size.default = 50; - anti_affinity_group = mkOption { description = '' Leaving this empty means to not join any anti affinity group @@ -245,6 +267,11 @@ in { type = with types; nullOr yk8s.openstack.serverGroupName; default = null; }; + create_root_disk_on_volume.description = '' + Enable creation of root disk volume for workers by default. + If true, create block volume for workers by default and boot from there. + Equivalent to ``openstack server create --boot-from-volume […]``. + ''; }; nodes = mkOption { @@ -284,6 +311,22 @@ in { type = with types; nullOr yk8s.openstack.volumeTypeName; default = null; }; + create_root_disk_on_volume = mkOption { + description = '' + Enable creation of root disk volume for this instance. + If true, create block volume for this instance and boot from there. + Equivalent to ``openstack server create --boot-from-volume […]``. + + This option takes precedence over + :ref:`configuration-options.yk8s.openstack.gateway_defaults.create_root_disk_on_volume`, + :ref:`configuration-options.yk8s.openstack.master_defaults.create_root_disk_on_volume`, + :ref:`configuration-options.yk8s.openstack.worker_defaults.create_root_disk_on_volume`, + and + :ref:``. + ''; + type = with types; nullOr types.bool; + default = null; + }; anti_affinity_group = mkOption { description = '' Must not be set when role!="worker". diff --git a/terraform/00-variables.tf b/terraform/00-variables.tf index 637a2278c19a43c2bd84d2d8197a6722671c187a..c0ac2a132871468270d2e00b9bec3747e64c969f 100644 --- a/terraform/00-variables.tf +++ b/terraform/00-variables.tf @@ -100,8 +100,9 @@ variable "gateway_defaults" { common_name = string image = string flavor = string - root_disk_size = number + root_disk_size = optional(number) root_disk_volume_type = optional(string) + create_root_disk_on_volume = optional(bool) }) } @@ -109,8 +110,9 @@ variable "master_defaults" { type = object({ # --- template spec --- image = string flavor = string - root_disk_size = number + root_disk_size = optional(number) root_disk_volume_type = optional(string) + create_root_disk_on_volume = optional(bool) }) } @@ -118,9 +120,10 @@ variable "worker_defaults" { type = object({ # --- template spec --- image = string flavor = string - root_disk_size = number + root_disk_size = optional(number) root_disk_volume_type = optional(string) anti_affinity_group = optional(string) + create_root_disk_on_volume = optional(bool) }) } @@ -135,6 +138,7 @@ variable "nodes" { root_disk_size = optional(number) root_disk_volume_type = optional(string) anti_affinity_group = optional(string) + create_root_disk_on_volume = optional(bool) }) ) } diff --git a/terraform/20-gateway.tf b/terraform/20-gateway.tf index de8a26ae1b0ce8c7f0c140ada8e6e542deaacd97..6d0e382beacf5f7d0e350fe4d50168c342c5d0b5 100644 --- a/terraform/20-gateway.tf +++ b/terraform/20-gateway.tf @@ -126,7 +126,7 @@ resource "openstack_networking_port_v2" "gateway" { } resource "openstack_blockstorage_volume_v3" "gateway-volume" { - for_each = var.create_root_disk_on_volume == true ? local.gateway_nodes : {} + for_each = var.create_root_disk_on_volume == true || var.gateway_defaults.create_root_disk_on_volume == true ? local.gateway_nodes : {} name = each.value.volume_name size = (data.openstack_compute_flavor_v2.gateway.disk > 0) ? data.openstack_compute_flavor_v2.gateway.disk : each.value.root_disk_size image_id = data.openstack_images_image_v2.gateway.id @@ -155,7 +155,7 @@ resource "openstack_compute_instance_v2" "gateway" { dynamic block_device { # Using "for_each" for check the conditional "create_root_disk_on_volume". It's not working as a loop. "dummy" should make this just more visible. - for_each = var.create_root_disk_on_volume == true ? ["dummy"] : [] + for_each = var.create_root_disk_on_volume == true || var.gateway_defaults.create_root_disk_on_volume == true ? ["dummy"] : [] content { uuid = openstack_blockstorage_volume_v3.gateway-volume[each.key].id source_type = "volume" diff --git a/terraform/30-master-nodes.tf b/terraform/30-master-nodes.tf index 307b5cdcc1ab051376eb69f2ff0785aac86d8c91..1468f14c27407d7b4770fe8f1eb78914c08b566d 100644 --- a/terraform/30-master-nodes.tf +++ b/terraform/30-master-nodes.tf @@ -7,9 +7,18 @@ locals { flavor = coalesce(values.flavor, var.master_defaults.flavor) az = values.az # default: null volume_name = "${var.cluster_name}-master-volume-${name}" - root_disk_size = coalesce(values.root_disk_size, var.master_defaults.root_disk_size) + root_disk_size = values.root_disk_size != null ? values.root_disk_size : var.worker_defaults.root_disk_size != null ? var.worker_defaults.root_disk_size : null root_disk_volume_type = values.root_disk_volume_type != null ? values.root_disk_volume_type : var.master_defaults.root_disk_volume_type + create_root_disk_on_volume = coalesce( + values.create_root_disk_on_volume, + var.master_defaults.create_root_disk_on_volume, + var.create_root_disk_on_volume + ) } if values.role == "master" + } + master_nodes_with_volumes = { + for k, v in local.master_nodes : k => v + if v.create_root_disk_on_volume == true } } @@ -48,10 +57,10 @@ data "openstack_images_image_v2" "master" { } resource "openstack_blockstorage_volume_v3" "master-volume" { - for_each = var.create_root_disk_on_volume == true ? local.master_nodes : {} + for_each = local.master_nodes_with_volumes name = each.value.volume_name - size = (data.openstack_compute_flavor_v2.master[each.key].disk > 0) ? data.openstack_compute_flavor_v2.master[each.key].disk : each.value.root_disk_size + size = each.value.root_disk_size != null ? each.value.root_disk_size : (data.openstack_compute_flavor_v2.worker[each.key].disk > 0) ? data.openstack_compute_flavor_v2.worker[each.key].disk : null image_id = data.openstack_images_image_v2.master[each.key].id volume_type = each.value.root_disk_volume_type availability_zone = each.value.az @@ -73,13 +82,13 @@ resource "openstack_compute_instance_v2" "master" { availability_zone = each.value.az config_drive = true flavor_id = data.openstack_compute_flavor_v2.master[each.key].id - image_id = var.create_root_disk_on_volume == false ? data.openstack_images_image_v2.master[each.key].id : null + image_id = each.value.create_root_disk_on_volume == false ? data.openstack_images_image_v2.master[each.key].id : null key_pair = var.keypair dynamic block_device { # Abusing 'for_each' as a conditional # It's not working as a loop. The outer `each.key` is "passed" into the inner `for_each` - for_each = var.create_root_disk_on_volume == true ? [each.key] : [] + for_each = each.value.create_root_disk_on_volume == true ? ["dummy"] : [] content { uuid = openstack_blockstorage_volume_v3.master-volume[each.key].id source_type = "volume" diff --git a/terraform/40-worker-nodes.tf b/terraform/40-worker-nodes.tf index ad96bd0c7bd716303b2ee9685492681eaaeec9e9..920d04ccb170a77789405d89fddac61a34b258b3 100644 --- a/terraform/40-worker-nodes.tf +++ b/terraform/40-worker-nodes.tf @@ -7,11 +7,20 @@ locals { flavor = coalesce(values.flavor, var.worker_defaults.flavor) az = values.az # default: null volume_name = "${var.cluster_name}-worker-volume-${name}" - root_disk_size = coalesce(values.root_disk_size, var.worker_defaults.root_disk_size) + root_disk_size = values.root_disk_size != null ? values.root_disk_size : var.worker_defaults.root_disk_size != null ? var.worker_defaults.root_disk_size : null root_disk_volume_type = values.root_disk_volume_type != null ? values.root_disk_volume_type : var.worker_defaults.root_disk_volume_type anti_affinity_group = values.anti_affinity_group != null ? values.anti_affinity_group : var.worker_defaults.anti_affinity_group + create_root_disk_on_volume = coalesce( + values.create_root_disk_on_volume, + var.worker_defaults.create_root_disk_on_volume, + var.create_root_disk_on_volume + ) } if values.role == "worker" } + worker_nodes_with_volumes = { + for k, v in local.worker_nodes : k => v + if v.create_root_disk_on_volume == true + } } resource "openstack_networking_port_v2" "worker" { @@ -58,9 +67,9 @@ data "openstack_images_image_v2" "worker" { } resource "openstack_blockstorage_volume_v3" "worker-volume" { - for_each = var.create_root_disk_on_volume == true ? local.worker_nodes : {} + for_each = local.worker_nodes_with_volumes name = each.value.volume_name - size = (data.openstack_compute_flavor_v2.worker[each.key].disk > 0) ? data.openstack_compute_flavor_v2.worker[each.key].disk : each.value.root_disk_size + size = each.value.root_disk_size != null ? each.value.root_disk_size : (data.openstack_compute_flavor_v2.worker[each.key].disk > 0) ? data.openstack_compute_flavor_v2.worker[each.key].disk : null image_id = data.openstack_images_image_v2.worker[each.key].id volume_type = each.value.root_disk_volume_type availability_zone = each.value.az @@ -81,7 +90,7 @@ resource "openstack_compute_instance_v2" "worker" { availability_zone = each.value.az flavor_id = data.openstack_compute_flavor_v2.worker[each.key].id - image_id = var.create_root_disk_on_volume == false ? data.openstack_images_image_v2.worker[each.key].id : null + image_id = each.value.create_root_disk_on_volume == false ? data.openstack_images_image_v2.worker[each.key].id : null key_pair = var.keypair config_drive = true @@ -97,7 +106,7 @@ resource "openstack_compute_instance_v2" "worker" { dynamic block_device { # Abusing 'for_each' as a conditional # It's not working as a loop. The outer `each.key` is "passed" into the inner `for_each` - for_each = var.create_root_disk_on_volume == true ? [each.key] : [] + for_each = each.value.create_root_disk_on_volume == true ? ["dummy"] : [] content { uuid = openstack_blockstorage_volume_v3.worker-volume[each.key].id source_type = "volume"