Skip to content

Commit a3cc3fc

Browse files
feat: tenant namespace module
add: proper description explaining the module fix: change to local variables Update the label format to display namespace quota information correctly Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> fix: add spacing
1 parent 25cb78e commit a3cc3fc

4 files changed

Lines changed: 162 additions & 0 deletions

File tree

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/**
2+
* @module management/tenant-namespace
3+
* @description Provisions Kubernetes namespaces within a specified Rancher v2 project.
4+
*
5+
* ### Features
6+
* - Dynamically creates multiple namespaces from a provided list.
7+
* - Applies custom labels and annotations for organizational tagging.
8+
* - Configures optional container resource limits (CPU/Memory).
9+
* - Enforces optional resource quotas (Pods, Storage, LoadBalancers, etc.).
10+
*
11+
* ### Prerequisites
12+
* 1. **Provider**: Requires the `rancher2` provider authenticated to your Rancher server.
13+
* 2. **Project**: You must have a pre-existing Rancher `project_id` to pass as a variable.
14+
*
15+
*/
16+
17+
locals {
18+
namespaces = toset(var.namespaces != null ? var.namespaces : [])
19+
container_resource_limit = var.container_resource_limit != null ? [var.container_resource_limit] : []
20+
resource_quota = var.resource_quota != null ? [var.resource_quota] : []
21+
}
22+
23+
resource "rancher2_namespace" "this" {
24+
for_each = local.namespaces
25+
26+
name = each.value
27+
project_id = var.project_id
28+
description = var.description
29+
30+
labels = merge(var.labels, {
31+
"field.cattle.io/projectId" = split(":", var.project_id)[1]
32+
})
33+
annotations = var.annotations
34+
wait_for_cluster = var.wait_for_cluster
35+
36+
dynamic "container_resource_limit" {
37+
for_each = local.container_resource_limit
38+
content {
39+
limits_cpu = container_resource_limit.value.cpu_limit
40+
limits_memory = container_resource_limit.value.memory_limit
41+
requests_cpu = container_resource_limit.value.cpu_request
42+
requests_memory = container_resource_limit.value.memory_request
43+
}
44+
}
45+
46+
dynamic "resource_quota" {
47+
for_each = local.resource_quota
48+
content {
49+
limit {
50+
config_maps = resource_quota.value.config_maps
51+
limits_cpu = resource_quota.value.cpu_limit
52+
limits_memory = resource_quota.value.memory_limit
53+
persistent_volume_claims = resource_quota.value.persistent_volume_claims
54+
pods = resource_quota.value.pods
55+
replication_controllers = resource_quota.value.replication_controllers
56+
requests_cpu = resource_quota.value.cpu_request
57+
requests_memory = resource_quota.value.memory_request
58+
requests_storage = resource_quota.value.storage_request
59+
secrets = resource_quota.value.secrets
60+
services_load_balancers = resource_quota.value.services_load_balancers
61+
services_node_ports = resource_quota.value.services_node_ports
62+
}
63+
}
64+
}
65+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
output "namespaces" {
2+
description = "Map of created rancher2_namespace resources keyed by namespace name."
3+
value = rancher2_namespace.this
4+
}
5+
6+
output "namespace_ids" {
7+
description = "Map of created namespace IDs."
8+
value = { for k, v in rancher2_namespace.this : k => v.id }
9+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
variable "project_id" {
2+
description = "The Rancher v2 project ID (format: <cluster_id>:<project_id>)"
3+
type = string
4+
}
5+
6+
variable "namespaces" {
7+
description = "List of namespace names to create."
8+
type = any
9+
10+
validation {
11+
condition = can(
12+
[for ns in toset(flatten(tolist([var.namespaces]))) : regex("^[a-z0-9]([-a-z0-9]*[a-z0-9])?$", ns)]
13+
)
14+
error_message = "Namespace names must consist of lowercase alphanumeric characters or '-', and must start and end with an alphanumeric character."
15+
}
16+
}
17+
18+
variable "description" {
19+
description = "Optional description applied to all created namespaces."
20+
type = string
21+
default = null
22+
}
23+
24+
variable "labels" {
25+
description = "Labels to apply to the namespaces."
26+
type = map(string)
27+
default = {}
28+
}
29+
30+
variable "annotations" {
31+
description = "Annotations to apply to the namespaces."
32+
type = map(string)
33+
default = {}
34+
}
35+
36+
variable "wait_for_cluster" {
37+
description = "Wait for cluster to become active before creating namespaces."
38+
type = bool
39+
default = false
40+
}
41+
42+
variable "container_resource_limit" {
43+
description = "Default container resource limits for workloads in these namespaces."
44+
type = object({
45+
cpu_limit = optional(string)
46+
memory_limit = optional(string)
47+
cpu_request = optional(string)
48+
memory_request = optional(string)
49+
})
50+
default = null
51+
}
52+
53+
variable "resource_quota" {
54+
description = "Resource quotas applied to each namespace."
55+
type = object({
56+
config_maps = optional(string)
57+
cpu_limit = optional(string)
58+
memory_limit = optional(string)
59+
persistent_volume_claims = optional(string)
60+
pods = optional(string)
61+
replication_controllers = optional(string)
62+
cpu_request = optional(string)
63+
memory_request = optional(string)
64+
storage_request = optional(string)
65+
secrets = optional(string)
66+
services_load_balancers = optional(string)
67+
services_node_ports = optional(string)
68+
})
69+
default = null
70+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
terraform {
2+
required_version = ">= 1.5"
3+
required_providers {
4+
rancher2 = {
5+
source = "rancher/rancher2"
6+
version = "~> 13.1"
7+
}
8+
harvester = {
9+
source = "harvester/harvester"
10+
version = "~> 1.7"
11+
}
12+
kubernetes = {
13+
source = "hashicorp/kubernetes"
14+
version = "~> 2.35"
15+
configuration_aliases = [kubernetes.harvester]
16+
}
17+
}
18+
}

0 commit comments

Comments
 (0)