From 8a9c587effeb292e7e32366493996e666396895b Mon Sep 17 00:00:00 2001 From: Andrea Panisson Date: Wed, 6 Nov 2024 18:08:58 +0100 Subject: [PATCH] refs platform/3230: enable label based namespace selector --- .gitignore | 1 + CHANGELOG.md | 4 ++-- README.md | 2 +- main.tf | 34 ++++++++++++++++++++++++---------- outputs.tf | 2 +- variables.tf | 7 ------- 6 files changed, 29 insertions(+), 21 deletions(-) diff --git a/.gitignore b/.gitignore index 696ec96..89f6322 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,7 @@ crash.log # IDE files .idea +.fleet # Ignore any .tfvars files that are generated automatically for each Terraform run. Most # .tfvars files are managed as part of configuration and so should be included in diff --git a/CHANGELOG.md b/CHANGELOG.md index f9f06a4..5c00096 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,6 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). --- -## [0.1.0] - 2024-11-05 +## [0.1.0] - 2024-11-06 -- First release. \ No newline at end of file +- First release. diff --git a/README.md b/README.md index d82c21b..ea20e4d 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,6 @@ This is a Terraform module to install a cron job on a Kubernetes cluster that us | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| [additional\_managed\_namespaces](#input\_additional\_managed\_namespaces) | List of additional namespaces where the controller should manage the scale of deployments. | `list(string)` | `[]` | no | | [cluster\_role\_name\_prefix](#input\_cluster\_role\_name\_prefix) | Name of the cluster role. | `string` | `"custom:application-sleep-cycles:controller"` | no | | [configmap\_name\_prefix](#input\_configmap\_name\_prefix) | Name prefix for the Config Maps. | `string` | `"application-sleep-cycles-config"` | no | | [create\_namespace](#input\_create\_namespace) | Create namespace. If false, the namespace must be created before using this module. | `bool` | `true` | no | @@ -62,6 +61,7 @@ This is a Terraform module to install a cron job on a Kubernetes cluster that us | [kubernetes_secret_v1.this](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/secret_v1) | resource | | [kubernetes_service_account_v1.this](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/service_account_v1) | resource | | [kubernetes_namespace_v1.this](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/data-sources/namespace_v1) | data source | +| [kubernetes_resources.managed_namespaces_by_labels](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/data-sources/resources) | data source | ## Modules diff --git a/main.tf b/main.tf index 6b7576e..878ffb5 100644 --- a/main.tf +++ b/main.tf @@ -1,3 +1,10 @@ +# Get list of namespaces with a given label, where the controller should manage +# the scale of deployments. +data "kubernetes_resources" "managed_namespaces_by_labels" { + kind = "Namespace" + api_version = "v1" + label_selector = join(",", [for k, v in var.managed_namespaces_label_selector : "${k}=${v}"]) +} locals { k8s_full_labels = merge( @@ -5,11 +12,14 @@ locals { var.k8s_additional_labels, ) - final_namespace = var.create_namespace ? resource.kubernetes_namespace_v1.this[0].metadata[0].name : data.kubernetes_namespace_v1.this[0].metadata[0].name + cronjob_namespace = var.create_namespace ? var.namespace : data.kubernetes_namespace_v1.this[0].metadata[0].name - managed_namespaces = distinct(concat(var.managed_namespaces, var.additional_managed_namespaces)) + managed_namespaces = distinct(concat(var.managed_namespaces, data.kubernetes_resources.managed_namespaces_by_labels.objects[*].metadata.name)) } +# The namespace in which we want to deploy the cronjob is created only if the +# `create_namespace` variable is set to true. +# Otherwise, the namespace must be created before using this module. resource "kubernetes_namespace_v1" "this" { count = var.create_namespace ? 1 : 0 @@ -30,10 +40,11 @@ data "kubernetes_namespace_v1" "this" { } } +# The service account used by the cronjob to interact with the Kubernetes API. resource "kubernetes_service_account_v1" "this" { metadata { name = var.service_account_name - namespace = local.final_namespace + namespace = local.cronjob_namespace labels = local.k8s_full_labels } } @@ -42,7 +53,7 @@ resource "kubernetes_secret_v1" "this" { metadata { # This is the prefix, used by the server, to generate a unique name ONLY IF the name field has not been provided. This value will also be combined with a unique suffix. generate_name = "${var.service_account_name}-" - namespace = local.final_namespace + namespace = local.cronjob_namespace labels = local.k8s_full_labels annotations = { @@ -54,6 +65,7 @@ resource "kubernetes_secret_v1" "this" { wait_for_service_account_token = true } +# Service account permissions. resource "kubernetes_cluster_role_v1" "cluster_scoped" { metadata { name = "${var.cluster_role_name_prefix}-cluster-scoped" @@ -82,7 +94,7 @@ resource "kubernetes_cluster_role_binding_v1" "cluster_scoped" { subject { kind = "ServiceAccount" name = kubernetes_service_account_v1.this.metadata[0].name - namespace = local.final_namespace + namespace = local.cronjob_namespace } } @@ -105,6 +117,8 @@ resource "kubernetes_cluster_role_v1" "namespace_scoped" { } } +# This role binding must be created in each namespace where the controller should +# manage the scale of deployments. resource "kubernetes_role_binding_v1" "this" { for_each = toset(local.managed_namespaces) @@ -123,14 +137,14 @@ resource "kubernetes_role_binding_v1" "this" { subject { kind = "ServiceAccount" name = kubernetes_service_account_v1.this.metadata[0].name - namespace = local.final_namespace + namespace = local.cronjob_namespace } } resource "kubernetes_config_map_v1" "app_env" { metadata { name = "${var.configmap_name_prefix}-env" - namespace = local.final_namespace + namespace = local.cronjob_namespace labels = local.k8s_full_labels } @@ -144,7 +158,7 @@ resource "kubernetes_config_map_v1" "app_env" { resource "kubernetes_config_map_v1" "app" { metadata { name = "${var.configmap_name_prefix}-app" - namespace = local.final_namespace + namespace = local.cronjob_namespace labels = local.k8s_full_labels } @@ -160,7 +174,7 @@ resource "kubernetes_manifest" "scale_down" { "${path.module}/files/k8s-working-hours-cronjob.yaml.tftpl", { name = "${var.working_hours_resource_prefix}-scale-down" - namespace = local.final_namespace + namespace = local.cronjob_namespace labels = local.k8s_full_labels suspend = var.working_hours_suspend schedule = var.working_hours_scale_down_schedule @@ -183,7 +197,7 @@ resource "kubernetes_manifest" "scale_up" { "${path.module}/files/k8s-working-hours-cronjob.yaml.tftpl", { name = "${var.working_hours_resource_prefix}-scale-up" - namespace = local.final_namespace + namespace = local.cronjob_namespace labels = local.k8s_full_labels suspend = var.working_hours_suspend schedule = var.working_hours_scale_up_schedule diff --git a/outputs.tf b/outputs.tf index e83f69f..6982f2c 100644 --- a/outputs.tf +++ b/outputs.tf @@ -1,6 +1,6 @@ output "namespace" { description = "Namespace where the descheduler is installed." - value = local.final_namespace + value = local.cronjob_namespace } output "k8s_full_labels" { diff --git a/variables.tf b/variables.tf index 73c737c..debc086 100644 --- a/variables.tf +++ b/variables.tf @@ -49,13 +49,6 @@ variable "managed_namespaces" { default = [] } -variable "additional_managed_namespaces" { - description = "List of additional namespaces where the controller should manage the scale of deployments." - type = list(string) - default = [] -} - - variable "managed_namespaces_label_selector" { description = "Label selector for the namespaces where the controller should manage the scale of deployments. The namespaces fetched by this selector will be merged with the `managed_namespaces` variable. **WARNING:** remember that if the labels specified here are added to new namespaces, the module will send the Terraform state into drift, as the list of namespaces is retrieved dynamically. You must then re-apply your Terraform configuration to fix the drift.." type = map(string)