diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index d966273..773e61d 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -26,7 +26,7 @@ jobs: - uses: terraform-linters/setup-tflint@v1 name: Setup TFLint with: - tflint_version: v0.29.0 + tflint_version: v0.53.0 - name: Show version run: tflint --version @@ -35,4 +35,4 @@ jobs: run: tflint --init - name: Run TFLint - run: tflint -f compact \ No newline at end of file + run: tflint -f compact diff --git a/README.md b/README.md index 1a940b8..8a3b5dd 100644 --- a/README.md +++ b/README.md @@ -303,6 +303,7 @@ Usage examples are located in [terraform provider repo](https://github.com/casta | [castai](#requirement\_castai) | ~> 7.17 | | [google](#requirement\_google) | >= 2.49 | | [helm](#requirement\_helm) | >= 2.0.0 | +| [null](#requirement\_null) | >= 3.0.0 | ## Providers @@ -310,7 +311,7 @@ Usage examples are located in [terraform provider repo](https://github.com/casta |------|---------| | [castai](#provider\_castai) | ~> 7.17 | | [helm](#provider\_helm) | >= 2.0.0 | -| [null](#provider\_null) | n/a | +| [null](#provider\_null) | >= 3.0.0 | ## Modules @@ -368,7 +369,7 @@ No modules. | [evictor\_version](#input\_evictor\_version) | Version of castai-evictor chart. Default latest | `string` | `null` | no | | [gke\_cluster\_location](#input\_gke\_cluster\_location) | Location of the cluster to be connected to CAST AI. Can be region or zone for zonal clusters | `string` | n/a | yes | | [gke\_cluster\_name](#input\_gke\_cluster\_name) | Name of the cluster to be connected to CAST AI. | `string` | n/a | yes | -| [gke\_credentials](#input\_gke\_credentials) | Optional GCP Service account credentials.json | `string` | n/a | yes | +| [gke\_credentials](#input\_gke\_credentials) | Optional GCP Service account credentials.json. Set to `null` to connect in read-only mode | `string` | n/a | yes | | [grpc\_url](#input\_grpc\_url) | gRPC endpoint used by pod-pinner | `string` | `"grpc.cast.ai:443"` | no | | [install\_cloud\_proxy](#input\_install\_cloud\_proxy) | Optional flag for installation of castai-cloud-proxy | `bool` | `false` | no | | [install\_security\_agent](#input\_install\_security\_agent) | Optional flag for installation of security agent (https://docs.cast.ai/product-overview/console/security-insights/) | `bool` | `false` | no | diff --git a/main.tf b/main.tf index cca22b8..69f6460 100644 --- a/main.tf +++ b/main.tf @@ -1,3 +1,27 @@ +locals { + read_only_mode = nonsensitive(var.gke_credentials == null) +} + +moved { + from = castai_node_configuration_default.this + to = castai_node_configuration_default.this[0] +} + +moved { + from = helm_release.castai_evictor_ext + to = helm_release.castai_evictor_ext[0] +} + +moved { + from = helm_release.castai_spot_handler + to = helm_release.castai_spot_handler[0] +} + +moved { + from = castai_autoscaler.castai_autoscaler_policies + to = castai_autoscaler.castai_autoscaler_policies[0] +} + resource "castai_gke_cluster" "castai_cluster" { project_id = var.project_id location = var.gke_cluster_location @@ -7,7 +31,7 @@ resource "castai_gke_cluster" "castai_cluster" { } resource "castai_node_configuration" "this" { - for_each = { for k, v in var.node_configurations : k => v } + for_each = local.read_only_mode ? tomap({}) : { for k, v in var.node_configurations : k => v } cluster_id = castai_gke_cluster.castai_cluster.id @@ -30,12 +54,13 @@ resource "castai_node_configuration" "this" { } resource "castai_node_configuration_default" "this" { + count = local.read_only_mode ? 0 : 1 cluster_id = castai_gke_cluster.castai_cluster.id configuration_id = var.default_node_configuration_name != "" ? castai_node_configuration.this[var.default_node_configuration_name].id : var.default_node_configuration } resource "castai_node_template" "this" { - for_each = { for k, v in var.node_templates : k => v } + for_each = local.read_only_mode ? tomap({}) : { for k, v in var.node_templates : k => v } cluster_id = castai_gke_cluster.castai_cluster.id @@ -143,7 +168,7 @@ resource "castai_node_template" "this" { } resource "castai_workload_scaling_policy" "this" { - for_each = { for k, v in var.workload_scaling_policies : k => v } + for_each = local.read_only_mode ? {} : { for k, v in var.workload_scaling_policies : k => v } name = try(each.value.name, each.key) cluster_id = castai_gke_cluster.castai_cluster.id @@ -218,7 +243,7 @@ resource "helm_release" "castai_agent" { } resource "helm_release" "castai_cluster_controller" { - count = var.self_managed ? 0 : 1 + count = !local.read_only_mode && !var.self_managed ? 1 : 0 name = "cluster-controller" repository = "https://castai.github.io/helm-charts" @@ -265,7 +290,7 @@ resource "helm_release" "castai_cluster_controller" { } resource "helm_release" "castai_cluster_controller_self_managed" { - count = var.self_managed ? 1 : 0 + count = !local.read_only_mode && var.self_managed ? 1 : 0 name = "cluster-controller" repository = "https://castai.github.io/helm-charts" @@ -311,6 +336,10 @@ resource "null_resource" "wait_for_cluster" { count = var.wait_for_cluster_ready ? 1 : 0 depends_on = [helm_release.castai_cluster_controller, helm_release.castai_agent] + triggers = { + credentials = var.gke_credentials, + } + provisioner "local-exec" { environment = { API_KEY = var.castai_api_token @@ -333,7 +362,7 @@ resource "null_resource" "wait_for_cluster" { } resource "helm_release" "castai_evictor" { - count = var.self_managed ? 0 : 1 + count = !local.read_only_mode && !var.self_managed ? 1 : 0 name = "castai-evictor" repository = "https://castai.github.io/helm-charts" @@ -372,7 +401,7 @@ resource "helm_release" "castai_evictor" { } resource "helm_release" "castai_evictor_self_managed" { - count = var.self_managed ? 1 : 0 + count = !local.read_only_mode && var.self_managed ? 1 : 0 name = "castai-evictor" repository = "https://castai.github.io/helm-charts" @@ -402,6 +431,7 @@ resource "helm_release" "castai_evictor_self_managed" { } resource "helm_release" "castai_evictor_ext" { + count = !local.read_only_mode ? 1 : 0 name = "castai-evictor-ext" repository = "https://castai.github.io/helm-charts" chart = "castai-evictor-ext" @@ -417,7 +447,7 @@ resource "helm_release" "castai_evictor_ext" { } resource "helm_release" "castai_pod_pinner" { - count = var.self_managed ? 0 : 1 + count = !local.read_only_mode && !var.self_managed ? 1 : 0 name = "castai-pod-pinner" repository = "https://castai.github.io/helm-charts" @@ -477,7 +507,7 @@ resource "helm_release" "castai_pod_pinner" { } resource "helm_release" "castai_pod_pinner_self_managed" { - count = var.self_managed ? 1 : 0 + count = !local.read_only_mode && var.self_managed ? 1 : 0 name = "castai-pod-pinner" repository = "https://castai.github.io/helm-charts" @@ -528,6 +558,7 @@ resource "helm_release" "castai_pod_pinner_self_managed" { } resource "helm_release" "castai_spot_handler" { + count = !local.read_only_mode ? 1 : 0 name = "castai-spot-handler" repository = "https://castai.github.io/helm-charts" chart = "castai-spot-handler" @@ -619,36 +650,6 @@ resource "helm_release" "castai_kvisor" { } } -resource "helm_release" "castai_cloud_proxy" { - count = var.install_cloud_proxy ? 1 : 0 - - name = "castai-cloud-proxy" - repository = "https://castai.github.io/helm-charts" - chart = "castai-cloud-proxy" - version = var.cloud_proxy_version - namespace = "castai-agent" - create_namespace = true - cleanup_on_fail = true - wait = true - - values = var.cloud_proxy_values - - set { - name = "castai.clusterID" - value = castai_gke_cluster.castai_cluster.id - } - - set_sensitive { - name = "castai.apiKey" - value = castai_gke_cluster.castai_cluster.cluster_token - } - - set { - name = "castai.grpcURL" - value = coalesce(var.cloud_proxy_grpc_url_override, var.grpc_url) - } -} - resource "helm_release" "castai_kvisor_self_managed" { count = var.install_security_agent && var.self_managed ? 1 : 0 @@ -691,6 +692,36 @@ resource "helm_release" "castai_kvisor_self_managed" { } } +resource "helm_release" "castai_cloud_proxy" { + count = var.install_cloud_proxy ? 1 : 0 + + name = "castai-cloud-proxy" + repository = "https://castai.github.io/helm-charts" + chart = "castai-cloud-proxy" + version = var.cloud_proxy_version + namespace = "castai-agent" + create_namespace = true + cleanup_on_fail = true + wait = true + + values = var.cloud_proxy_values + + set { + name = "castai.clusterID" + value = castai_gke_cluster.castai_cluster.id + } + + set_sensitive { + name = "castai.apiKey" + value = castai_gke_cluster.castai_cluster.cluster_token + } + + set { + name = "castai.grpcURL" + value = coalesce(var.cloud_proxy_grpc_url_override, var.grpc_url) + } +} + #---------------------------------------------------# # CAST.AI Workload Autoscaler configuration # #---------------------------------------------------# @@ -754,6 +785,8 @@ resource "helm_release" "castai_workload_autoscaler_self_managed" { resource "castai_autoscaler" "castai_autoscaler_policies" { + count = !local.read_only_mode ? 1 : 0 + cluster_id = castai_gke_cluster.castai_cluster.id autoscaler_policies_json = var.autoscaler_policies_json diff --git a/variables.tf b/variables.tf index 7fa8f8a..b7e0351 100644 --- a/variables.tf +++ b/variables.tf @@ -64,12 +64,12 @@ variable "delete_nodes_on_disconnect" { variable "gke_cluster_location" { type = string description = "Location of the cluster to be connected to CAST AI. Can be region or zone for zonal clusters" - } variable "gke_credentials" { type = string - description = "Optional GCP Service account credentials.json" + description = "Optional GCP Service account credentials.json. Set to `null` to connect in read-only mode" + sensitive = true } variable "castai_components_labels" { diff --git a/versions.tf b/versions.tf index 3cc24f3..b11e61a 100644 --- a/versions.tf +++ b/versions.tf @@ -14,6 +14,10 @@ terraform { source = "hashicorp/helm" version = ">= 2.0.0" } + null = { + source = "hashicorp/null" + version = ">= 3.0.0" + } } }