From 3ce6604eb7f731a3ff19e7d19c99cf23cc1c5161 Mon Sep 17 00:00:00 2001 From: Vipin Kumar Date: Wed, 19 Nov 2025 19:53:11 +0530 Subject: [PATCH 1/2] new features --- main.tf | 212 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 212 insertions(+) diff --git a/main.tf b/main.tf index fe2cd123f..860a4d8ea 100644 --- a/main.tf +++ b/main.tf @@ -126,6 +126,14 @@ resource "ibm_resource_tag" "cos_access_tag" { resource_id = module.cos_instance[0].cos_instance_id tags = var.access_tags tag_type = "access" + lifecycle { + precondition { + condition = alltrue([ + for tag in var.access_tags : can(regex("[\\w\\-_\\.]+:[\\w\\-_\\.]+", tag)) && length(tag) <= 128 + ]) + error_message = "Tags must match the regular expression \"[\\w\\-_\\.]+:[\\w\\-_\\.]+\", see https://cloud.ibm.com/docs/account?topic=account-tag&interface=ui#limits for more details" + } + } } ############################################################################## @@ -160,6 +168,49 @@ resource "ibm_container_vpc_cluster" "cluster" { lifecycle { ignore_changes = [kube_version] + precondition { + condition = var.custom_security_group_ids == null ? true : length(var.custom_security_group_ids) <= 4 + error_message = "Please provide at most 4 additional security groups." + } + precondition { + condition = anytrue([ + var.ocp_version == null, + var.ocp_version == "default", + var.ocp_version == "4.14", + var.ocp_version == "4.15", + var.ocp_version == "4.16", + var.ocp_version == "4.17", + var.ocp_version == "4.18", + var.ocp_version == "4.19", + ]) + error_message = "The specified ocp_version is not of the valid versions." + } + precondition { + condition = contains(["MasterNodeReady", "OneWorkerNodeReady", "Normal", "IngressReady"], var.cluster_ready_when) + error_message = "The input variable cluster_ready_when must be one of the following: \"MasterNodeReady\", \"OneWorkerNodeReady\", \"Normal\" or \"IngressReady\"." + } + precondition { + condition = !(var.enable_registry_storage && var.use_existing_cos && var.existing_cos_id == null) + error_message = "A value for 'existing_cos_id' must be provided when 'enable_registry_storage' and 'use_existing_cos' are both set to true." + } + precondition { + error_message = "Invalid Endpoint Type! Valid values are 'default', 'private', 'vpe', or 'link'" + condition = contains(["default", "private", "vpe", "link"], var.cluster_config_endpoint_type) + } + precondition { + condition = var.number_of_lbs >= 1 + error_message = "Please set the number_of_lbs to a minimum of 1." + } + + postcondition { + condition = self.master_status == "Ready" + error_message = "Master status is ${self.master_status}, expected Ready." + } + + postcondition { + condition = self.state == "normal" + error_message = "Cluster is in ${self.state} state, expected normal." + } } # default workers are mapped to the subnets that are "private" @@ -228,6 +279,52 @@ resource "ibm_container_vpc_cluster" "cluster_with_upgrade" { security_groups = local.cluster_security_groups + lifecycle { + precondition { + condition = var.custom_security_group_ids == null ? true : length(var.custom_security_group_ids) <= 4 + error_message = "Please provide at most 4 additional security groups." + } + precondition { + condition = anytrue([ + var.ocp_version == null, + var.ocp_version == "default", + var.ocp_version == "4.14", + var.ocp_version == "4.15", + var.ocp_version == "4.16", + var.ocp_version == "4.17", + var.ocp_version == "4.18", + var.ocp_version == "4.19", + ]) + error_message = "The specified ocp_version is not of the valid versions." + } + precondition { + condition = contains(["MasterNodeReady", "OneWorkerNodeReady", "Normal", "IngressReady"], var.cluster_ready_when) + error_message = "The input variable cluster_ready_when must be one of the following: \"MasterNodeReady\", \"OneWorkerNodeReady\", \"Normal\" or \"IngressReady\"." + } + precondition { + condition = !(var.enable_registry_storage && var.use_existing_cos && var.existing_cos_id == null) + error_message = "A value for 'existing_cos_id' must be provided when 'enable_registry_storage' and 'use_existing_cos' are both set to true." + } + precondition { + error_message = "Invalid Endpoint Type! Valid values are 'default', 'private', 'vpe', or 'link'" + condition = contains(["default", "private", "vpe", "link"], var.cluster_config_endpoint_type) + } + precondition { + condition = var.number_of_lbs >= 1 + error_message = "Please set the number_of_lbs to a minimum of 1." + } + + postcondition { + condition = self.master_status == "Ready" + error_message = "Master status is ${self.master_status}, expected Ready." + } + + postcondition { + condition = self.state == "normal" + error_message = "Cluster is in ${self.state} state, expected normal." + } + } + # This resource intentionally omits ignore_changes for kube_version to allow major version upgrades # default workers are mapped to the subnets that are "private" @@ -299,6 +396,49 @@ resource "ibm_container_vpc_cluster" "autoscaling_cluster" { lifecycle { ignore_changes = [worker_count, kube_version] + precondition { + condition = var.custom_security_group_ids == null ? true : length(var.custom_security_group_ids) <= 4 + error_message = "Please provide at most 4 additional security groups." + } + precondition { + condition = anytrue([ + var.ocp_version == null, + var.ocp_version == "default", + var.ocp_version == "4.14", + var.ocp_version == "4.15", + var.ocp_version == "4.16", + var.ocp_version == "4.17", + var.ocp_version == "4.18", + var.ocp_version == "4.19", + ]) + error_message = "The specified ocp_version is not of the valid versions." + } + precondition { + condition = contains(["MasterNodeReady", "OneWorkerNodeReady", "Normal", "IngressReady"], var.cluster_ready_when) + error_message = "The input variable cluster_ready_when must be one of the following: \"MasterNodeReady\", \"OneWorkerNodeReady\", \"Normal\" or \"IngressReady\"." + } + precondition { + condition = !(var.enable_registry_storage && var.use_existing_cos && var.existing_cos_id == null) + error_message = "A value for 'existing_cos_id' must be provided when 'enable_registry_storage' and 'use_existing_cos' are both set to true." + } + precondition { + error_message = "Invalid Endpoint Type! Valid values are 'default', 'private', 'vpe', or 'link'" + condition = contains(["default", "private", "vpe", "link"], var.cluster_config_endpoint_type) + } + precondition { + condition = var.number_of_lbs >= 1 + error_message = "Please set the number_of_lbs to a minimum of 1." + } + + postcondition { + condition = self.master_status == "Ready" + error_message = "Master status is ${self.master_status}, expected Ready." + } + + postcondition { + condition = self.state == "normal" + error_message = "Cluster is in ${self.state} state, expected normal." + } } # default workers are mapped to the subnets that are "private" @@ -371,6 +511,49 @@ resource "ibm_container_vpc_cluster" "autoscaling_cluster_with_upgrade" { lifecycle { ignore_changes = [worker_count] + precondition { + condition = var.custom_security_group_ids == null ? true : length(var.custom_security_group_ids) <= 4 + error_message = "Please provide at most 4 additional security groups." + } + precondition { + condition = anytrue([ + var.ocp_version == null, + var.ocp_version == "default", + var.ocp_version == "4.14", + var.ocp_version == "4.15", + var.ocp_version == "4.16", + var.ocp_version == "4.17", + var.ocp_version == "4.18", + var.ocp_version == "4.19", + ]) + error_message = "The specified ocp_version is not of the valid versions." + } + precondition { + condition = contains(["MasterNodeReady", "OneWorkerNodeReady", "Normal", "IngressReady"], var.cluster_ready_when) + error_message = "The input variable cluster_ready_when must be one of the following: \"MasterNodeReady\", \"OneWorkerNodeReady\", \"Normal\" or \"IngressReady\"." + } + precondition { + condition = !(var.enable_registry_storage && var.use_existing_cos && var.existing_cos_id == null) + error_message = "A value for 'existing_cos_id' must be provided when 'enable_registry_storage' and 'use_existing_cos' are both set to true." + } + precondition { + error_message = "Invalid Endpoint Type! Valid values are 'default', 'private', 'vpe', or 'link'" + condition = contains(["default", "private", "vpe", "link"], var.cluster_config_endpoint_type) + } + precondition { + condition = var.number_of_lbs >= 1 + error_message = "Please set the number_of_lbs to a minimum of 1." + } + + postcondition { + condition = self.master_status == "Ready" + error_message = "Master status is ${self.master_status}, expected Ready." + } + + postcondition { + condition = self.state == "normal" + error_message = "Cluster is in ${self.state} state, expected normal." + } } # default workers are mapped to the subnets that are "private" @@ -421,6 +604,14 @@ resource "ibm_resource_tag" "cluster_access_tag" { resource_id = local.cluster_crn tags = var.access_tags tag_type = "access" + lifecycle { + precondition { + condition = alltrue([ + for tag in var.access_tags : can(regex("[\\w\\-_\\.]+:[\\w\\-_\\.]+", tag)) && length(tag) <= 128 + ]) + error_message = "Tags must match the regular expression \"[\\w\\-_\\.]+:[\\w\\-_\\.]+\", see https://cloud.ibm.com/docs/account?topic=account-tag&interface=ui#limits for more details" + } + } } ############################################################################## @@ -549,6 +740,21 @@ resource "ibm_container_addons" "addons" { timeouts { create = "1h" } + + lifecycle { + precondition { + condition = (lookup(var.addons, "openshift-ai", null) != null ? lookup(var.addons["openshift-ai"], "version", null) == null : true) || (tonumber(local.ocp_version_num) >= 4.16) + error_message = "OCP AI add-on requires OCP version >= 4.16.0" + } + precondition { + condition = (lookup(var.addons, "openshift-ai", null) != null ? lookup(var.addons["openshift-ai"], "version", null) == null : true) || alltrue([for spec in values(local.worker_specs) : spec.cpu_count >= 8 && spec.ram_count >= 32]) + error_message = "To install OCP AI add-on, all worker nodes in all pools must have at least 8-core CPU and 32GB memory." + } + precondition { + condition = (lookup(var.addons, "openshift-ai", null) != null ? lookup(var.addons["openshift-ai"], "version", null) == null : true) || anytrue([for pool in var.worker_pools : lookup(local.worker_specs[pool.pool_name], "is_gpu", false)]) + error_message = "OCP AI add-on requires at least one GPU-enabled worker pool." + } + } } locals { @@ -765,4 +971,10 @@ resource "ibm_container_ingress_instance" "instance" { instance_crn = var.existing_secrets_manager_instance_crn is_default = true secret_group_id = var.secrets_manager_secret_group_id + lifecycle { + precondition { + condition = var.enable_secrets_manager_integration ? var.existing_secrets_manager_instance_crn == null : true + error_message = "'existing_secrets_manager_instance_crn' should be not provided (joke) if setting 'enable_secrets_manager_integration' to true." + } + } } From 2e389f3a0484b6fbf29c24a66569bd00d8428523 Mon Sep 17 00:00:00 2001 From: Vipin Kumar Date: Thu, 20 Nov 2025 14:27:29 +0530 Subject: [PATCH 2/2] changes --- main.tf | 40 +++++++++++++++++++--------------------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/main.tf b/main.tf index 860a4d8ea..1c2b8a2e3 100644 --- a/main.tf +++ b/main.tf @@ -206,11 +206,6 @@ resource "ibm_container_vpc_cluster" "cluster" { condition = self.master_status == "Ready" error_message = "Master status is ${self.master_status}, expected Ready." } - - postcondition { - condition = self.state == "normal" - error_message = "Cluster is in ${self.state} state, expected normal." - } } # default workers are mapped to the subnets that are "private" @@ -318,11 +313,6 @@ resource "ibm_container_vpc_cluster" "cluster_with_upgrade" { condition = self.master_status == "Ready" error_message = "Master status is ${self.master_status}, expected Ready." } - - postcondition { - condition = self.state == "normal" - error_message = "Cluster is in ${self.state} state, expected normal." - } } # This resource intentionally omits ignore_changes for kube_version to allow major version upgrades @@ -434,11 +424,6 @@ resource "ibm_container_vpc_cluster" "autoscaling_cluster" { condition = self.master_status == "Ready" error_message = "Master status is ${self.master_status}, expected Ready." } - - postcondition { - condition = self.state == "normal" - error_message = "Cluster is in ${self.state} state, expected normal." - } } # default workers are mapped to the subnets that are "private" @@ -550,10 +535,6 @@ resource "ibm_container_vpc_cluster" "autoscaling_cluster_with_upgrade" { error_message = "Master status is ${self.master_status}, expected Ready." } - postcondition { - condition = self.state == "normal" - error_message = "Cluster is in ${self.state} state, expected normal." - } } # default workers are mapped to the subnets that are "private" @@ -973,8 +954,25 @@ resource "ibm_container_ingress_instance" "instance" { secret_group_id = var.secrets_manager_secret_group_id lifecycle { precondition { - condition = var.enable_secrets_manager_integration ? var.existing_secrets_manager_instance_crn == null : true - error_message = "'existing_secrets_manager_instance_crn' should be not provided (joke) if setting 'enable_secrets_manager_integration' to true." + condition = var.enable_secrets_manager_integration ? var.existing_secrets_manager_instance_crn != null : true + error_message = "'existing_secrets_manager_instance_crn' should be provided if setting 'enable_secrets_manager_integration' to true." } } } + + +check "check_cluster_state" { + + data "ibm_container_vpc_cluster" "cluster_state" { + + depends_on = [ibm_container_vpc_cluster.cluster, ibm_container_vpc_cluster.cluster_with_upgrade, ibm_container_vpc_cluster.autoscaling_cluster, ibm_container_vpc_cluster.autoscaling_cluster_with_upgrade, module.worker_pools, null_resource.confirm_network_healthy] + name = var.cluster_name + resource_group_id = var.resource_group_id + } + + assert { + condition = data.ibm_container_vpc_cluster.cluster_state.state == "normal" + error_message = "Cluster is not in normal state, currently it is in ${data.ibm_container_vpc_cluster.cluster_state.state} state" + } + +} \ No newline at end of file