Skip to content

Commit

Permalink
refs platform/3230: enable label based namespace selector
Browse files Browse the repository at this point in the history
  • Loading branch information
andypanix committed Nov 6, 2024
1 parent ada6663 commit 8a9c587
Show file tree
Hide file tree
Showing 6 changed files with 29 additions and 21 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
- First release.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 |
|------|-------------|------|---------|:--------:|
| <a name="input_additional_managed_namespaces"></a> [additional\_managed\_namespaces](#input\_additional\_managed\_namespaces) | List of additional namespaces where the controller should manage the scale of deployments. | `list(string)` | `[]` | no |
| <a name="input_cluster_role_name_prefix"></a> [cluster\_role\_name\_prefix](#input\_cluster\_role\_name\_prefix) | Name of the cluster role. | `string` | `"custom:application-sleep-cycles:controller"` | no |
| <a name="input_configmap_name_prefix"></a> [configmap\_name\_prefix](#input\_configmap\_name\_prefix) | Name prefix for the Config Maps. | `string` | `"application-sleep-cycles-config"` | no |
| <a name="input_create_namespace"></a> [create\_namespace](#input\_create\_namespace) | Create namespace. If false, the namespace must be created before using this module. | `bool` | `true` | no |
Expand Down Expand Up @@ -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

Expand Down
34 changes: 24 additions & 10 deletions main.tf
Original file line number Diff line number Diff line change
@@ -1,15 +1,25 @@
# 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(
var.k8s_labels,
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

Expand All @@ -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
}
}
Expand All @@ -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 = {
Expand All @@ -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"
Expand Down Expand Up @@ -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
}
}

Expand All @@ -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)

Expand All @@ -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
}

Expand All @@ -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
}

Expand All @@ -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
Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion outputs.tf
Original file line number Diff line number Diff line change
@@ -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" {
Expand Down
7 changes: 0 additions & 7 deletions variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down

0 comments on commit 8a9c587

Please sign in to comment.