diff --git a/modules/test-ske/README.md b/modules/test-ske/README.md new file mode 100644 index 0000000..6c23eb5 --- /dev/null +++ b/modules/test-ske/README.md @@ -0,0 +1,54 @@ +# Test SKE Module + +This module is designed to quickly spin up an SKE cluster. Internally, we use it to +debug network connectivity and deploy test applications in a simple, frictionless manner. +It automatically selects the latest SKE and node pool machine versions. + + + +## Requirements + +| Name | Version | +| ------------------------------------------------------------------ | -------- | +| [random](#requirement_random) | 3.9.0 | +| [stackit](#requirement_stackit) | >=0.95.0 | + +## Providers + +| Name | Version | +| ------------------------------------------------------------ | -------- | +| [random](#provider_random) | 3.9.0 | +| [stackit](#provider_stackit) | >=0.95.0 | + +## Modules + +No modules. + +## Resources + +| Name | Type | +| ----------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | +| [random_string.this](https://registry.terraform.io/providers/hashicorp/random/3.9.0/docs/resources/string) | resource | +| [stackit_ske_cluster.this](https://registry.terraform.io/providers/stackitcloud/stackit/latest/docs/resources/ske_cluster) | resource | +| [stackit_ske_kubeconfig.this](https://registry.terraform.io/providers/stackitcloud/stackit/latest/docs/resources/ske_kubeconfig) | resource | +| [stackit_ske_kubernetes_versions.this](https://registry.terraform.io/providers/stackitcloud/stackit/latest/docs/data-sources/ske_kubernetes_versions) | data source | +| [stackit_ske_machine_image_versions.this](https://registry.terraform.io/providers/stackitcloud/stackit/latest/docs/data-sources/ske_machine_image_versions) | data source | + +## Inputs + +| Name | Description | Type | Default | Required | +| --------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------: | +| [cluster_name](#input_cluster_name) | The name of the Kubernetes cluster | `string` | `null` | no | +| [maintenance](#input_maintenance) | Maintenance window configuration for the cluster |
object({
enable_kubernetes_version_updates = bool
enable_machine_image_version_updates = bool
start = string
end = string
}) | {
"enable_kubernetes_version_updates": true,
"enable_machine_image_version_updates": true,
"end": "02:00:00Z",
"start": "01:00:00Z"
} | no |
+| [network_id](#input_network_id) | The ID of the STACKIT network in which the SKE cluster will be deployed. If not provided, the cluster will automatically create a network on demand. Specifying a network ID is only supported in SNA setups | `string` | `null` | no |
+| [node_pools](#input_node_pools) | Configuration for the cluster node pools | `any` | [| no | +| [project_id](#input_project_id) | The STACKIT project ID | `string` | n/a | yes | + +## Outputs + +| Name | Description | +| ----------------------------------------------------------------------- | --------------------------------------------- | +| [cluster_name](#output_cluster_name) | The name of the provisioned SKE cluster | +| [kubeconfig](#output_kubeconfig) | The kubeconfig contents to access the cluster | + + diff --git a/modules/test-ske/main.tf b/modules/test-ske/main.tf new file mode 100644 index 0000000..38bf7f4 --- /dev/null +++ b/modules/test-ske/main.tf @@ -0,0 +1,84 @@ +# Copyright 2026 Schwarz Digits Cloud GmbH & Co. KG +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +data "stackit_ske_kubernetes_versions" "this" { + version_state = "SUPPORTED" +} + +data "stackit_ske_machine_image_versions" "this" { + version_state = "SUPPORTED" +} + +resource "random_string" "this" { + length = 6 + special = false + upper = false +} + +locals { + flatcar_supported_versions = flatten([ + for mi in data.stackit_ske_machine_image_versions.this.machine_images : [ + for v in mi.versions : v.version if mi.name == "flatcar" + ] + ]) + flatcar_supported_version = length(local.flatcar_supported_versions) > 0 ? local.flatcar_supported_versions[0] : null + + ubuntu_supported_versions = flatten([ + for mi in data.stackit_ske_machine_image_versions.this.machine_images : [ + for v in mi.versions : v.version if mi.name == "ubuntu" + ] + ]) + ubuntu_supported_version = length(local.ubuntu_supported_versions) > 0 ? local.ubuntu_supported_versions[0] : null +} + +resource "stackit_ske_cluster" "this" { + project_id = var.project_id + name = var.cluster_name != null && var.cluster_name != "" ? var.cluster_name : "ske-${random_string.this.result}" + kubernetes_version_min = data.stackit_ske_kubernetes_versions.this.kubernetes_versions[0].version + + maintenance = var.maintenance + + network = var.network_id != null && var.network_id != "" ? { + id = var.network_id + } : null + + node_pools = [ + for np in var.node_pools : { + name = np.name + machine_type = np.machine_type + minimum = np.minimum + maximum = np.maximum + max_surge = np.max_surge + availability_zones = np.availability_zones + os_name = np.os_name + # Dynamically injects the latest OS version based on os_name if not explicitly set + os_version_min = lookup(np, "os_version_min", np.os_name == "flatcar" ? local.flatcar_supported_version : local.ubuntu_supported_version) + volume_size = np.volume_size + volume_type = np.volume_type + } + ] + + lifecycle { + ignore_changes = [ + kubernetes_version_min, + node_pools + ] + } +} + +resource "stackit_ske_kubeconfig" "this" { + project_id = var.project_id + cluster_name = stackit_ske_cluster.this.name + refresh = true +} diff --git a/modules/test-ske/outputs.tf b/modules/test-ske/outputs.tf new file mode 100644 index 0000000..3a16cc5 --- /dev/null +++ b/modules/test-ske/outputs.tf @@ -0,0 +1,24 @@ +# Copyright 2026 Schwarz Digits Cloud GmbH & Co. KG +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +output "cluster_name" { + description = "The name of the provisioned SKE cluster" + value = stackit_ske_cluster.this.name +} + +output "kubeconfig" { + description = "The kubeconfig contents to access the cluster" + value = stackit_ske_kubeconfig.this.kube_config + sensitive = true +} diff --git a/modules/test-ske/provider.tf b/modules/test-ske/provider.tf new file mode 100644 index 0000000..994578e --- /dev/null +++ b/modules/test-ske/provider.tf @@ -0,0 +1,26 @@ +# Copyright 2026 Schwarz Digits Cloud GmbH & Co. KG +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +terraform { + required_providers { + stackit = { + source = "stackitcloud/stackit" + version = ">=0.95.0" + } + random = { + source = "hashicorp/random" + version = "3.9.0" + } + } +} diff --git a/modules/test-ske/variables.tf b/modules/test-ske/variables.tf new file mode 100644 index 0000000..c029aa2 --- /dev/null +++ b/modules/test-ske/variables.tf @@ -0,0 +1,64 @@ +# Copyright 2026 Schwarz Digits Cloud GmbH & Co. KG +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +variable "project_id" { + description = "The STACKIT project ID" + type = string +} + +variable "cluster_name" { + description = "The name of the Kubernetes cluster" + type = string + default = null +} + +variable "network_id" { + description = "The ID of the STACKIT network in which the SKE cluster will be deployed. If not provided, the cluster will automatically create a network on demand. Specifying a network ID is only supported in SNA setups" + type = string + default = null +} + +variable "maintenance" { + description = "Maintenance window configuration for the cluster" + type = object({ + enable_kubernetes_version_updates = bool + enable_machine_image_version_updates = bool + start = string + end = string + }) + default = { + enable_kubernetes_version_updates = true + enable_machine_image_version_updates = true + start = "01:00:00Z" + end = "02:00:00Z" + } +} + +variable "node_pools" { + description = "Configuration for the cluster node pools" + type = any + default = [ + { + name = "standard" + machine_type = "g2i.4" + minimum = 1 + maximum = 3 + max_surge = 3 + availability_zones = ["eu01-1", "eu01-2", "eu01-3"] + os_name = "flatcar" + volume_size = 20 + volume_type = "storage_premium_perf6" + } + ] +}
{
"availability_zones": [
"eu01-1",
"eu01-2",
"eu01-3"
],
"machine_type": "g2i.4",
"max_surge": 3,
"maximum": 3,
"minimum": 1,
"name": "standard",
"os_name": "flatcar",
"volume_size": 20,
"volume_type": "storage_premium_perf6"
}
]