From ca69a5405fb93cb12bf9edabff24063e05e79c98 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Fri, 17 Apr 2026 17:57:00 -0400 Subject: [PATCH 01/10] fix: Remove the TF channel input validation --- .../tests/channel_validation.tftest.hcl | 38 ----------------- terraform/cos-lite/variables.tf | 6 --- .../cos/tests/channel_validation.tftest.hcl | 41 ------------------- terraform/cos/variables.tf | 6 --- 4 files changed, 91 deletions(-) delete mode 100644 terraform/cos-lite/tests/channel_validation.tftest.hcl delete mode 100644 terraform/cos/tests/channel_validation.tftest.hcl diff --git a/terraform/cos-lite/tests/channel_validation.tftest.hcl b/terraform/cos-lite/tests/channel_validation.tftest.hcl deleted file mode 100644 index 5f38c6a9..00000000 --- a/terraform/cos-lite/tests/channel_validation.tftest.hcl +++ /dev/null @@ -1,38 +0,0 @@ -mock_provider "juju" {} - -variables { - model_uuid = "00000000-0000-0000-0000-000000000000" -} - -# ---Happy path--- - -run "valid_channel_stable" { - command = plan - variables { channel = "dev/stable" } -} - -run "valid_channel_candidate" { - command = plan - variables { channel = "dev/candidate" } -} - -run "valid_channel_beta" { - command = plan - variables { channel = "dev/beta" } -} - -run "valid_channel_edge" { - command = plan - variables { channel = "dev/edge" } -} - -# ---Failure path--- -# NOTE: Invalid risks (e.g. "dev/risk") are validated by the Juju provider at the -# resource level inside child modules. Terraform test's expect_failures cannot -# reference resources inside child modules, so we cannot assert on that here. - -run "invalid_channel_track_2" { - command = plan - variables { channel = "2/stable" } - expect_failures = [var.channel] -} diff --git a/terraform/cos-lite/variables.tf b/terraform/cos-lite/variables.tf index 0a2ffaef..5421f6c6 100644 --- a/terraform/cos-lite/variables.tf +++ b/terraform/cos-lite/variables.tf @@ -14,12 +14,6 @@ variable "channel" { description = "Channel that the applications are (unless overwritten by individual channels) deployed from" type = string default = "dev/edge" - - validation { - # the TF Juju provider correctly identifies invalid risks; no need to validate it - condition = startswith(var.channel, "dev/") - error_message = "The track of the channel must be 'dev/'. e.g. 'dev/edge'." - } } variable "model_uuid" { diff --git a/terraform/cos/tests/channel_validation.tftest.hcl b/terraform/cos/tests/channel_validation.tftest.hcl deleted file mode 100644 index c2fdf469..00000000 --- a/terraform/cos/tests/channel_validation.tftest.hcl +++ /dev/null @@ -1,41 +0,0 @@ -mock_provider "juju" {} - -variables { - model_uuid = "00000000-0000-0000-0000-000000000000" - s3_endpoint = "foo" - s3_access_key = "foo" - s3_secret_key = "foo" -} - -# ---Happy path--- - -run "valid_channel_stable" { - command = plan - variables { channel = "dev/stable" } -} - -run "valid_channel_candidate" { - command = plan - variables { channel = "dev/candidate" } -} - -run "valid_channel_beta" { - command = plan - variables { channel = "dev/beta" } -} - -run "valid_channel_edge" { - command = plan - variables { channel = "dev/edge" } -} - -# ---Failure path--- -# NOTE: Invalid risks (e.g. "dev/risk") are validated by the Juju provider at the -# resource level inside child modules. Terraform test's expect_failures cannot -# reference resources inside child modules, so we cannot assert on that here. - -run "invalid_channel_track_2" { - command = plan - variables { channel = "2/stable" } - expect_failures = [var.channel] -} diff --git a/terraform/cos/variables.tf b/terraform/cos/variables.tf index 4a2057ef..2c45184d 100644 --- a/terraform/cos/variables.tf +++ b/terraform/cos/variables.tf @@ -14,12 +14,6 @@ variable "channel" { description = "Channel that the applications are (unless overwritten by individual channels) deployed from" type = string default = "dev/edge" - - validation { - # the TF Juju provider correctly identifies invalid risks; no need to validate it - condition = startswith(var.channel, "dev/") - error_message = "The track of the channel must be 'dev/'. e.g. 'dev/edge'." - } } variable "model_uuid" { From 281792ec33def2d9257d1be95f8bcbe66f8bee5b Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Fri, 17 Apr 2026 18:19:46 -0400 Subject: [PATCH 02/10] fix: Replace the channel input with risk --- terraform/cos-lite/README.md | 2 +- terraform/cos-lite/applications.tf | 14 ++++---- terraform/cos-lite/variables.tf | 15 +++++++-- terraform/cos/README.md | 2 +- terraform/cos/applications.tf | 54 +++++++++++++----------------- terraform/cos/variables.tf | 17 ++++++++-- 6 files changed, 58 insertions(+), 46 deletions(-) diff --git a/terraform/cos-lite/README.md b/terraform/cos-lite/README.md index 404bc531..9d1e5dd5 100644 --- a/terraform/cos-lite/README.md +++ b/terraform/cos-lite/README.md @@ -27,7 +27,6 @@ This is a Terraform module facilitating the deployment of the COS Lite solution, |------|-------------|------|---------|:--------:| | [alertmanager](#input\_alertmanager) | Application configuration for Alertmanager. For more details: https://registry.terraform.io/providers/juju/juju/latest/docs/resources/application |
object({
app_name = optional(string, "alertmanager")
config = optional(map(string), {})
constraints = optional(string, "arch=amd64")
revision = optional(number, null)
storage_directives = optional(map(string), {})
units = optional(number, 1)
})
| `{}` | no | | [catalogue](#input\_catalogue) | Application configuration for Catalogue. For more details: https://registry.terraform.io/providers/juju/juju/latest/docs/resources/application |
object({
app_name = optional(string, "catalogue")
config = optional(map(string), {})
constraints = optional(string, "arch=amd64")
revision = optional(number, null)
storage_directives = optional(map(string), {})
units = optional(number, 1)
})
| `{}` | no | -| [channel](#input\_channel) | Channel that the applications are (unless overwritten by individual channels) deployed from | `string` | `"dev/edge"` | no | | [external\_ca\_cert\_offer\_url](#input\_external\_ca\_cert\_offer\_url) | A Juju offer URL (e.g. admin/external-ca.send-ca-cert) of a CA providing the 'certificate\_transfer' integration for applications to trust ingress via Traefik. | `string` | `null` | no | | [external\_certificates\_offer\_url](#input\_external\_certificates\_offer\_url) | A Juju offer URL (e.g. admin/external-ca.certificates) of a CA providing the 'tls\_certificates' integration for Traefik to supply it with server certificates. | `string` | `null` | no | | [grafana](#input\_grafana) | Application configuration for Grafana. For more details: https://registry.terraform.io/providers/juju/juju/latest/docs/resources/application |
object({
app_name = optional(string, "grafana")
config = optional(map(string), {})
constraints = optional(string, "arch=amd64")
revision = optional(number, null)
storage_directives = optional(map(string), {})
units = optional(number, 1)
})
| `{}` | no | @@ -36,6 +35,7 @@ This is a Terraform module facilitating the deployment of the COS Lite solution, | [loki](#input\_loki) | Application configuration for Loki. For more details: https://registry.terraform.io/providers/juju/juju/latest/docs/resources/application |
object({
app_name = optional(string, "loki")
config = optional(map(string), {})
constraints = optional(string, "arch=amd64")
revision = optional(number, null)
storage_directives = optional(map(string), {})
units = optional(number, 1)
})
| `{}` | no | | [model\_uuid](#input\_model\_uuid) | Reference to an existing model resource or data source for the model to deploy to | `string` | n/a | yes | | [prometheus](#input\_prometheus) | Application configuration for Prometheus. For more details: https://registry.terraform.io/providers/juju/juju/latest/docs/resources/application |
object({
app_name = optional(string, "prometheus")
config = optional(map(string), {})
constraints = optional(string, "arch=amd64")
revision = optional(number, null)
storage_directives = optional(map(string), {})
units = optional(number, 1)
})
| `{}` | no | +| [risk](#input\_risk) | Risk level that the applications are (unless overwritten by individual channels) deployed from | `string` | `"edge"` | no | | [ssc](#input\_ssc) | Application configuration for self-signed-certificates. For more details: https://registry.terraform.io/providers/juju/juju/latest/docs/resources/application |
object({
app_name = optional(string, "ca")
channel = optional(string, "1/stable")
config = optional(map(string), {})
constraints = optional(string, "arch=amd64")
revision = optional(number, null)
storage_directives = optional(map(string), {})
units = optional(number, 1)
})
| `{}` | no | | [traefik](#input\_traefik) | Application configuration for Traefik. For more details: https://registry.terraform.io/providers/juju/juju/latest/docs/resources/application |
object({
app_name = optional(string, "traefik")
channel = optional(string, "latest/stable")
config = optional(map(string), {})
constraints = optional(string, "arch=amd64")
revision = optional(number, null)
storage_directives = optional(map(string), {})
units = optional(number, 1)
})
| `{}` | no | diff --git a/terraform/cos-lite/applications.tf b/terraform/cos-lite/applications.tf index dd1bd5ab..0fd945df 100644 --- a/terraform/cos-lite/applications.tf +++ b/terraform/cos-lite/applications.tf @@ -1,7 +1,7 @@ module "alertmanager" { source = "git::https://github.com/canonical/alertmanager-k8s-operator//terraform" app_name = var.alertmanager.app_name - channel = var.channel + channel = local.tracks.alertmanager + "/" + var.risk config = var.alertmanager.config constraints = var.alertmanager.constraints model_uuid = var.model_uuid @@ -13,7 +13,7 @@ module "alertmanager" { module "catalogue" { source = "git::https://github.com/canonical/catalogue-k8s-operator//terraform" app_name = var.catalogue.app_name - channel = var.channel + channel = local.tracks.catalogue + "/" + var.risk config = var.catalogue.config constraints = var.catalogue.constraints model_uuid = var.model_uuid @@ -25,7 +25,7 @@ module "catalogue" { module "grafana" { source = "git::https://github.com/canonical/grafana-k8s-operator//terraform" app_name = var.grafana.app_name - channel = var.channel + channel = local.tracks.grafana + "/" + var.risk config = var.grafana.config constraints = var.grafana.constraints model_uuid = var.model_uuid @@ -37,7 +37,7 @@ module "grafana" { module "loki" { source = "git::https://github.com/canonical/loki-k8s-operator//terraform" app_name = var.loki.app_name - channel = var.channel + channel = local.tracks.loki + "/" + var.risk config = var.loki.config constraints = var.loki.constraints model_uuid = var.model_uuid @@ -49,7 +49,7 @@ module "loki" { module "prometheus" { source = "git::https://github.com/canonical/prometheus-k8s-operator//terraform" app_name = var.prometheus.app_name - channel = var.channel + channel = local.tracks.prometheus + "/" + var.risk config = var.prometheus.config constraints = var.prometheus.constraints model_uuid = var.model_uuid @@ -62,7 +62,7 @@ module "ssc" { count = var.internal_tls ? 1 : 0 source = "git::https://github.com/canonical/self-signed-certificates-operator//terraform" app_name = var.ssc.app_name - channel = var.ssc.channel + channel = local.tracks.ssc + "/" + var.risk config = var.ssc.config constraints = var.ssc.constraints model_uuid = var.model_uuid @@ -73,7 +73,7 @@ module "ssc" { module "traefik" { source = "git::https://github.com/canonical/traefik-k8s-operator//terraform" app_name = var.traefik.app_name - channel = var.traefik.channel + channel = local.tracks.traefik + "/" + var.risk config = var.traefik.config constraints = var.traefik.constraints model_uuid = var.model_uuid diff --git a/terraform/cos-lite/variables.tf b/terraform/cos-lite/variables.tf index 5421f6c6..fe8e4d75 100644 --- a/terraform/cos-lite/variables.tf +++ b/terraform/cos-lite/variables.tf @@ -8,12 +8,21 @@ locals { # https://github.com/juju/terraform-provider-juju/issues/972 tls_termination = var.external_certificates_offer_url != null ? true : false + tracks = { + alertmanager = "0.31" + catalogue = "3.0" + grafana = "12.4" + loki = "3.7" + prometheus = "3.10" + ssc = "latest" + traefik = "latest" + } } -variable "channel" { - description = "Channel that the applications are (unless overwritten by individual channels) deployed from" +variable "risk" { + description = "Risk level that the applications are (unless overwritten by individual channels) deployed from" type = string - default = "dev/edge" + default = "edge" } variable "model_uuid" { diff --git a/terraform/cos/README.md b/terraform/cos/README.md index bd294b6a..f608486d 100644 --- a/terraform/cos/README.md +++ b/terraform/cos/README.md @@ -33,7 +33,6 @@ This is a Terraform module facilitating the deployment of the COS solution, usin | [alertmanager](#input\_alertmanager) | Application configuration for Alertmanager. For more details: https://registry.terraform.io/providers/juju/juju/latest/docs/resources/application |
object({
app_name = optional(string, "alertmanager")
config = optional(map(string), {})
constraints = optional(string, "arch=amd64")
revision = optional(number, null)
storage_directives = optional(map(string), {})
units = optional(number, 1)
})
| `{}` | no | | [anti\_affinity](#input\_anti\_affinity) | Enable anti-affinity constraints across all HA modules (Mimir, Loki, Tempo) | `bool` | `true` | no | | [catalogue](#input\_catalogue) | Application configuration for Catalogue. For more details: https://registry.terraform.io/providers/juju/juju/latest/docs/resources/application |
object({
app_name = optional(string, "catalogue")
config = optional(map(string), {})
constraints = optional(string, "arch=amd64")
revision = optional(number, null)
storage_directives = optional(map(string), {})
units = optional(number, 1)
})
| `{}` | no | -| [channel](#input\_channel) | Channel that the applications are (unless overwritten by individual channels) deployed from | `string` | `"dev/edge"` | no | | [cloud](#input\_cloud) | Kubernetes cloud or environment where this COS module will be deployed (e.g self-managed, aws) | `string` | `"self-managed"` | no | | [external\_ca\_cert\_offer\_url](#input\_external\_ca\_cert\_offer\_url) | A Juju offer URL (e.g. admin/external-ca.send-ca-cert) of a CA providing the 'certificate\_transfer' integration for applications to trust ingress via Traefik. | `string` | `null` | no | | [external\_certificates\_offer\_url](#input\_external\_certificates\_offer\_url) | A Juju offer URL of a CA providing the 'tls\_certificates' integration for Traefik to supply it with server certificates | `string` | `null` | no | @@ -48,6 +47,7 @@ This is a Terraform module facilitating the deployment of the COS solution, usin | [mimir\_worker](#input\_mimir\_worker) | Application configuration for all Mimir Workers. For more details: https://registry.terraform.io/providers/juju/juju/latest/docs/resources/application |
object({
backend_config = optional(map(string), {})
read_config = optional(map(string), {})
write_config = optional(map(string), {})
constraints = optional(string, "arch=amd64")
revision = optional(number, null)
backend_storage_directives = optional(map(string), {})
read_storage_directives = optional(map(string), {})
write_storage_directives = optional(map(string), {})
backend_units = optional(number, 3)
read_units = optional(number, 3)
write_units = optional(number, 3)
})
| `{}` | no | | [model\_uuid](#input\_model\_uuid) | Reference to an existing model resource or data source for the model to deploy to | `string` | n/a | yes | | [opentelemetry\_collector](#input\_opentelemetry\_collector) | Application configuration for OpenTelemetry Collector. For more details: https://registry.terraform.io/providers/juju/juju/latest/docs/resources/application |
object({
app_name = optional(string, "otelcol")
config = optional(map(string), {})
constraints = optional(string, "arch=amd64")
revision = optional(number, null)
storage_directives = optional(map(string), {})
units = optional(number, 1)
})
| `{}` | no | +| [risk](#input\_risk) | Risk level that the applications are (unless overwritten by individual channels) deployed from | `string` | `"edge"` | no | | [s3\_access\_key](#input\_s3\_access\_key) | S3 access-key credential | `string` | n/a | yes | | [s3\_endpoint](#input\_s3\_endpoint) | S3 endpoint | `string` | n/a | yes | | [s3\_integrator](#input\_s3\_integrator) | Application configuration for all S3-integrators in coordinated workers. For more details: https://registry.terraform.io/providers/juju/juju/latest/docs/resources/application |
object({
channel = optional(string, "2/edge")
config = optional(map(string), {})
constraints = optional(string, "arch=amd64")
revision = optional(number, null)
storage_directives = optional(map(string), {})
units = optional(number, 1)
})
| `{}` | no | diff --git a/terraform/cos/applications.tf b/terraform/cos/applications.tf index 8420484e..11ac4165 100644 --- a/terraform/cos/applications.tf +++ b/terraform/cos/applications.tf @@ -1,7 +1,7 @@ module "alertmanager" { source = "git::https://github.com/canonical/alertmanager-k8s-operator//terraform" app_name = var.alertmanager.app_name - channel = var.channel + channel = local.tracks.alertmanager + "/" + var.risk config = var.alertmanager.config constraints = var.alertmanager.constraints model_uuid = var.model_uuid @@ -13,7 +13,7 @@ module "alertmanager" { module "catalogue" { source = "git::https://github.com/canonical/catalogue-k8s-operator//terraform" app_name = var.catalogue.app_name - channel = var.channel + channel = local.tracks.catalogue + "/" + var.risk config = var.catalogue.config constraints = var.catalogue.constraints model_uuid = var.model_uuid @@ -25,7 +25,7 @@ module "catalogue" { module "grafana" { source = "git::https://github.com/canonical/grafana-k8s-operator//terraform" app_name = var.grafana.app_name - channel = var.channel + channel = local.tracks.grafana + "/" + var.risk config = var.grafana.config constraints = var.grafana.constraints model_uuid = var.model_uuid @@ -37,7 +37,7 @@ module "grafana" { module "loki" { source = "git::https://github.com/canonical/loki-operators//terraform" anti_affinity = var.anti_affinity - channel = var.channel + channel = local.tracks.loki + "/" + var.risk model_uuid = var.model_uuid s3_endpoint = var.s3_endpoint s3_secret_key = var.s3_secret_key @@ -68,29 +68,21 @@ module "loki" { } module "mimir" { - source = "git::https://github.com/canonical/mimir-operators//terraform" - anti_affinity = var.anti_affinity - channel = var.channel - model_uuid = var.model_uuid - s3_endpoint = var.s3_endpoint - s3_secret_key = var.s3_secret_key - s3_access_key = var.s3_access_key - s3_bucket = var.mimir_bucket - s3_integrator_channel = var.s3_integrator.channel - s3_integrator_config = var.s3_integrator.config - s3_integrator_constraints = var.s3_integrator.constraints - s3_integrator_revision = var.s3_integrator.revision - s3_integrator_storage_directives = var.s3_integrator.storage_directives - s3_integrator_units = var.s3_integrator.units - coordinator_config = merge( - var.mimir_coordinator.config, - # enable exemplar storage (required for metrics-to-traces). - # This config option is not supported in track `1`, so we'll set it only - # for newer tracks to maintain backward compatibility. - can(regex("^1/", var.channel)) ? {} : { - "max_global_exemplars_per_user" = "100000" - } - ) + source = "git::https://github.com/canonical/mimir-operators//terraform" + anti_affinity = var.anti_affinity + channel = local.tracks.mimir + "/" + var.risk + model_uuid = var.model_uuid + s3_endpoint = var.s3_endpoint + s3_secret_key = var.s3_secret_key + s3_access_key = var.s3_access_key + s3_bucket = var.mimir_bucket + s3_integrator_channel = var.s3_integrator.channel + s3_integrator_config = var.s3_integrator.config + s3_integrator_constraints = var.s3_integrator.constraints + s3_integrator_revision = var.s3_integrator.revision + s3_integrator_storage_directives = var.s3_integrator.storage_directives + s3_integrator_units = var.s3_integrator.units + coordinator_config = { "max_global_exemplars_per_user" = "100000" } coordinator_constraints = var.mimir_coordinator.constraints coordinator_revision = var.mimir_coordinator.revision coordinator_storage_directives = var.mimir_coordinator.storage_directives @@ -111,7 +103,7 @@ module "mimir" { module "opentelemetry_collector" { source = "git::https://github.com/canonical/opentelemetry-collector-k8s-operator//terraform" app_name = var.opentelemetry_collector.app_name - channel = var.channel + channel = local.tracks.otelcol + "/" + var.risk config = var.opentelemetry_collector.config constraints = var.opentelemetry_collector.constraints model_uuid = var.model_uuid @@ -124,7 +116,7 @@ module "ssc" { count = var.internal_tls ? 1 : 0 source = "git::https://github.com/canonical/self-signed-certificates-operator//terraform" app_name = var.ssc.app_name - channel = var.ssc.channel + channel = local.tracks.ssc + "/" + var.risk config = var.ssc.config constraints = var.ssc.constraints model_uuid = var.model_uuid @@ -135,7 +127,7 @@ module "ssc" { module "tempo" { source = "git::https://github.com/canonical/tempo-operators//terraform" anti_affinity = var.anti_affinity - channel = var.channel + channel = local.tracks.tempo + "/" + var.risk model_uuid = var.model_uuid s3_endpoint = var.s3_endpoint s3_access_key = var.s3_access_key @@ -177,7 +169,7 @@ module "tempo" { module "traefik" { source = "git::https://github.com/canonical/traefik-k8s-operator//terraform" app_name = var.traefik.app_name - channel = var.traefik.channel + channel = local.tracks.traefik + "/" + var.risk config = var.cloud == "aws" ? { "loadbalancer_annotations" = "service.beta.kubernetes.io/aws-load-balancer-scheme=internet-facing" } : var.traefik.config constraints = var.traefik.constraints model_uuid = var.model_uuid diff --git a/terraform/cos/variables.tf b/terraform/cos/variables.tf index 2c45184d..62a2d47d 100644 --- a/terraform/cos/variables.tf +++ b/terraform/cos/variables.tf @@ -8,12 +8,23 @@ locals { clouds = ["aws", "self-managed"] # list of k8s clouds where this COS module can be deployed. tls_termination = var.external_certificates_offer_url != null ? true : false + tracks = { + alertmanager = "0.31" + catalogue = "3.0" + grafana = "12.4" + loki = "3.7" + mimir = "3.0" + otelcol = "0.130" + ssc = "latest" + tempo = "2.10" + traefik = "latest" + } } -variable "channel" { - description = "Channel that the applications are (unless overwritten by individual channels) deployed from" +variable "risk" { + description = "Risk level that the applications are (unless overwritten by individual channels) deployed from" type = string - default = "dev/edge" + default = "edge" } variable "model_uuid" { From 31ddb7a7d55f0babd584ad942ca199c935fae568 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Fri, 17 Apr 2026 22:54:34 -0400 Subject: [PATCH 03/10] feat: Juju-charm datasource --- terraform/cos-lite/applications.tf | 14 +++--- terraform/cos-lite/upgrades.tf | 43 ++++++++++++++++++ terraform/cos-lite/variables.tf | 15 +++++++ terraform/cos/applications.tf | 30 ++++++------- terraform/cos/upgrades.tf | 71 ++++++++++++++++++++++++++++++ terraform/cos/variables.tf | 20 +++++++++ 6 files changed, 171 insertions(+), 22 deletions(-) create mode 100644 terraform/cos-lite/upgrades.tf create mode 100644 terraform/cos/upgrades.tf diff --git a/terraform/cos-lite/applications.tf b/terraform/cos-lite/applications.tf index 0fd945df..b7e69947 100644 --- a/terraform/cos-lite/applications.tf +++ b/terraform/cos-lite/applications.tf @@ -5,7 +5,7 @@ module "alertmanager" { config = var.alertmanager.config constraints = var.alertmanager.constraints model_uuid = var.model_uuid - revision = var.alertmanager.revision + revision = local.revisions.alertmanager storage_directives = var.alertmanager.storage_directives units = var.alertmanager.units } @@ -17,7 +17,7 @@ module "catalogue" { config = var.catalogue.config constraints = var.catalogue.constraints model_uuid = var.model_uuid - revision = var.catalogue.revision + revision = local.revisions.catalogue storage_directives = var.catalogue.storage_directives units = var.catalogue.units } @@ -29,7 +29,7 @@ module "grafana" { config = var.grafana.config constraints = var.grafana.constraints model_uuid = var.model_uuid - revision = var.grafana.revision + revision = local.revisions.grafana storage_directives = var.grafana.storage_directives units = var.grafana.units } @@ -42,7 +42,7 @@ module "loki" { constraints = var.loki.constraints model_uuid = var.model_uuid storage_directives = var.loki.storage_directives - revision = var.loki.revision + revision = local.revisions.loki units = var.loki.units } @@ -54,7 +54,7 @@ module "prometheus" { constraints = var.prometheus.constraints model_uuid = var.model_uuid storage_directives = var.prometheus.storage_directives - revision = var.prometheus.revision + revision = local.revisions.prometheus units = var.prometheus.units } @@ -66,7 +66,7 @@ module "ssc" { config = var.ssc.config constraints = var.ssc.constraints model_uuid = var.model_uuid - revision = var.ssc.revision + revision = local.revisions.ssc units = var.ssc.units } @@ -77,7 +77,7 @@ module "traefik" { config = var.traefik.config constraints = var.traefik.constraints model_uuid = var.model_uuid - revision = var.traefik.revision + revision = local.revisions.traefik storage_directives = var.traefik.storage_directives units = var.traefik.units } diff --git a/terraform/cos-lite/upgrades.tf b/terraform/cos-lite/upgrades.tf new file mode 100644 index 00000000..f0c6306a --- /dev/null +++ b/terraform/cos-lite/upgrades.tf @@ -0,0 +1,43 @@ +# TODO: If we only use the juju-charm datasource then users won't be able to revision pin + +data "juju_charm" "alertmanager_info" { + charm = "alertmanager-k8s" + channel = local.tracks.alertmanager + "/" + var.risk + base = var.base +} + +data "juju_charm" "catalogue_info" { + charm = "catalogue-k8s" + channel = local.tracks.catalogue + "/" + var.risk + base = var.base +} + +data "juju_charm" "grafana_info" { + charm = "grafana-k8s" + channel = local.tracks.grafana + "/" + var.risk + base = var.base +} + +data "juju_charm" "loki_info" { + charm = "loki-k8s" + channel = local.tracks.loki + "/" + var.risk + base = var.base +} + +data "juju_charm" "prometheus_info" { + charm = "prometheus-k8s" + channel = local.tracks.prometheus + "/" + var.risk + base = var.base +} + +data "juju_charm" "ssc_info" { + charm = "self-signed-certificates" + channel = local.tracks.ssc + "/" + var.risk + base = var.base +} + +data "juju_charm" "traefik_info" { + charm = "traefik-k8s" + channel = local.tracks.traefik + "/" + var.risk + base = var.base +} \ No newline at end of file diff --git a/terraform/cos-lite/variables.tf b/terraform/cos-lite/variables.tf index fe8e4d75..39fca29f 100644 --- a/terraform/cos-lite/variables.tf +++ b/terraform/cos-lite/variables.tf @@ -17,6 +17,15 @@ locals { ssc = "latest" traefik = "latest" } + revisions = { + alertmanager = var.alertmanager.revision ? var.alertmanager.revision: data.juju_charm.alertmanager_info.revision + catalogue = var.catalogue.revision ? var.catalogue.revision : data.juju_charm.catalogue_info.revision + grafana = var.grafana.revision ? var.grafana.revision : data.juju_charm.grafana_info.revision + loki = var.loki.revision ? var.loki.revision : data.juju_charm.loki_info.revision + prometheus = var.prometheus.revision ? var.prometheus.revision : data.juju_charm.prometheus_info.revision + ssc = var.ssc.revision ? var.ssc.revision : data.juju_charm.ssc_info.revision + traefik = var.traefik.revision ? var.traefik.revision : data.juju_charm.traefik_info.revision + } } variable "risk" { @@ -25,6 +34,12 @@ variable "risk" { default = "edge" } +variable "base" { + description = "The operating system on which to deploy. E.g. ubuntu@22.04. Changing this value for machine charms will trigger a replace by terraform. Check Charmhub for per-charm base support." + default = "ubuntu@24.04" + type = string +} + variable "model_uuid" { description = "Reference to an existing model resource or data source for the model to deploy to" type = string diff --git a/terraform/cos/applications.tf b/terraform/cos/applications.tf index 11ac4165..7e31a959 100644 --- a/terraform/cos/applications.tf +++ b/terraform/cos/applications.tf @@ -5,7 +5,7 @@ module "alertmanager" { config = var.alertmanager.config constraints = var.alertmanager.constraints model_uuid = var.model_uuid - revision = var.alertmanager.revision + revision = local.revisions.alertmanager storage_directives = var.alertmanager.storage_directives units = var.alertmanager.units } @@ -17,7 +17,7 @@ module "catalogue" { config = var.catalogue.config constraints = var.catalogue.constraints model_uuid = var.model_uuid - revision = var.catalogue.revision + revision = local.revisions.catalogue storage_directives = var.catalogue.storage_directives units = var.catalogue.units } @@ -29,7 +29,7 @@ module "grafana" { config = var.grafana.config constraints = var.grafana.constraints model_uuid = var.model_uuid - revision = var.grafana.revision + revision = local.revisions.grafana storage_directives = var.grafana.storage_directives units = var.grafana.units } @@ -46,19 +46,19 @@ module "loki" { s3_integrator_channel = var.s3_integrator.channel s3_integrator_config = var.s3_integrator.config s3_integrator_constraints = var.s3_integrator.constraints - s3_integrator_revision = var.s3_integrator.revision + s3_integrator_revision = local.revisions.s3_integrator s3_integrator_storage_directives = var.s3_integrator.storage_directives s3_integrator_units = var.s3_integrator.units coordinator_config = var.loki_coordinator.config coordinator_constraints = var.loki_coordinator.constraints - coordinator_revision = var.loki_coordinator.revision + coordinator_revision = local.revisions.loki_coordinator coordinator_storage_directives = var.loki_coordinator.storage_directives coordinator_units = var.loki_coordinator.units backend_config = var.loki_worker.backend_config read_config = var.loki_worker.read_config write_config = var.loki_worker.write_config worker_constraints = var.loki_worker.constraints - worker_revision = var.loki_worker.revision + worker_revision = local.revisions.loki_worker backend_worker_storage_directives = var.loki_worker.backend_storage_directives read_worker_storage_directives = var.loki_worker.read_storage_directives write_worker_storage_directives = var.loki_worker.write_storage_directives @@ -79,19 +79,19 @@ module "mimir" { s3_integrator_channel = var.s3_integrator.channel s3_integrator_config = var.s3_integrator.config s3_integrator_constraints = var.s3_integrator.constraints - s3_integrator_revision = var.s3_integrator.revision + s3_integrator_revision = local.revisions.s3_integrator s3_integrator_storage_directives = var.s3_integrator.storage_directives s3_integrator_units = var.s3_integrator.units coordinator_config = { "max_global_exemplars_per_user" = "100000" } coordinator_constraints = var.mimir_coordinator.constraints - coordinator_revision = var.mimir_coordinator.revision + coordinator_revision = local.revisions.mimir_coordinator coordinator_storage_directives = var.mimir_coordinator.storage_directives coordinator_units = var.mimir_coordinator.units backend_config = var.mimir_worker.backend_config read_config = var.mimir_worker.read_config write_config = var.mimir_worker.write_config worker_constraints = var.mimir_worker.constraints - worker_revision = var.mimir_worker.revision + worker_revision = local.revisions.mimir_worker backend_worker_storage_directives = var.mimir_worker.backend_storage_directives read_worker_storage_directives = var.mimir_worker.read_storage_directives write_worker_storage_directives = var.mimir_worker.write_storage_directives @@ -107,7 +107,7 @@ module "opentelemetry_collector" { config = var.opentelemetry_collector.config constraints = var.opentelemetry_collector.constraints model_uuid = var.model_uuid - revision = var.opentelemetry_collector.revision + revision = local.revisions.otelcol storage_directives = var.opentelemetry_collector.storage_directives units = var.opentelemetry_collector.units } @@ -120,7 +120,7 @@ module "ssc" { config = var.ssc.config constraints = var.ssc.constraints model_uuid = var.model_uuid - revision = var.ssc.revision + revision = local.revisions.ssc units = var.ssc.units } @@ -136,12 +136,12 @@ module "tempo" { s3_integrator_channel = var.s3_integrator.channel s3_integrator_config = var.s3_integrator.config s3_integrator_constraints = var.s3_integrator.constraints - s3_integrator_revision = var.s3_integrator.revision + s3_integrator_revision = local.revisions.s3_integrator s3_integrator_storage_directives = var.s3_integrator.storage_directives s3_integrator_units = var.s3_integrator.units coordinator_config = var.tempo_coordinator.config coordinator_constraints = var.tempo_coordinator.constraints - coordinator_revision = var.tempo_coordinator.revision + coordinator_revision = local.revisions.tempo_coordinator coordinator_storage_directives = var.tempo_coordinator.storage_directives coordinator_units = var.tempo_coordinator.units querier_config = var.tempo_worker.querier_config @@ -151,7 +151,7 @@ module "tempo" { compactor_config = var.tempo_worker.compactor_config metrics_generator_config = var.tempo_worker.metrics_generator_config worker_constraints = var.tempo_worker.constraints - worker_revision = var.tempo_worker.revision + worker_revision = local.revisions.tempo_worker compactor_worker_storage_directives = var.tempo_worker.compactor_worker_storage_directives distributor_worker_storage_directives = var.tempo_worker.distributor_worker_storage_directives ingester_worker_storage_directives = var.tempo_worker.ingester_worker_storage_directives @@ -173,7 +173,7 @@ module "traefik" { config = var.cloud == "aws" ? { "loadbalancer_annotations" = "service.beta.kubernetes.io/aws-load-balancer-scheme=internet-facing" } : var.traefik.config constraints = var.traefik.constraints model_uuid = var.model_uuid - revision = var.traefik.revision + revision = local.revisions.traefik storage_directives = var.traefik.storage_directives units = var.traefik.units } diff --git a/terraform/cos/upgrades.tf b/terraform/cos/upgrades.tf new file mode 100644 index 00000000..78a5d243 --- /dev/null +++ b/terraform/cos/upgrades.tf @@ -0,0 +1,71 @@ +data "juju_charm" "alertmanager_info" { + charm = "alertmanager-k8s" + channel = local.tracks.alertmanager + "/" + var.risk + base = var.base +} + +data "juju_charm" "catalogue_info" { + charm = "catalogue-k8s" + channel = local.tracks.catalogue + "/" + var.risk + base = var.base +} + +data "juju_charm" "grafana_info" { + charm = "grafana-k8s" + channel = local.tracks.grafana + "/" + var.risk + base = var.base +} + +data "juju_charm" "loki_coordinator_info" { + charm = "loki-coordinator-k8s" + channel = local.tracks.loki + "/" + var.risk + base = var.base +} + +data "juju_charm" "loki_worker_info" { + charm = "loki-worker-k8s" + channel = local.tracks.loki + "/" + var.risk + base = var.base +} + +data "juju_charm" "mimir_coordinator_info" { + charm = "mimir-coordinator-k8s" + channel = local.tracks.mimir + "/" + var.risk + base = var.base +} + +data "juju_charm" "mimir_worker_info" { + charm = "mimir-worker-k8s" + channel = local.tracks.mimir + "/" + var.risk + base = var.base +} + +data "juju_charm" "otelcol_info" { + charm = "opentelemetry-collector-k8s" + channel = local.tracks.otelcol + "/" + var.risk + base = var.base +} + +data "juju_charm" "tempo_coordinator_info" { + charm = "tempo-coordinator-k8s" + channel = local.tracks.tempo + "/" + var.risk + base = var.base +} + +data "juju_charm" "tempo_worker_info" { + charm = "tempo-worker-k8s" + channel = local.tracks.tempo + "/" + var.risk + base = var.base +} + +data "juju_charm" "ssc_info" { + charm = "self-signed-certificates" + channel = local.tracks.ssc + "/" + var.risk + base = var.base +} + +data "juju_charm" "traefik_info" { + charm = "traefik-k8s" + channel = local.tracks.traefik + "/" + var.risk + base = var.base +} \ No newline at end of file diff --git a/terraform/cos/variables.tf b/terraform/cos/variables.tf index 62a2d47d..a298fa04 100644 --- a/terraform/cos/variables.tf +++ b/terraform/cos/variables.tf @@ -19,6 +19,20 @@ locals { tempo = "2.10" traefik = "latest" } + revisions = { + alertmanager = var.alertmanager.revision ? var.alertmanager.revision : data.juju_charm.alertmanager_info.revision + catalogue = var.catalogue.revision ? var.catalogue.revision : data.juju_charm.catalogue_info.revision + grafana = var.grafana.revision ? var.grafana.revision : data.juju_charm.grafana_info.revision + loki_coordinator = var.loki_coordinator.revision ? var.loki_coordinator.revision : data.juju_charm.loki_info.revision + loki_worker = var.loki_worker.revision ? var.loki_worker.revision : data.juju_charm.loki_info.revision + mimir_coordinator = var.mimir_coordinator.revision ? var.mimir_coordinator.revision : data.juju_charm.mimir_info.revision + mimir_worker = var.mimir_worker.revision ? var.mimir_worker.revision : data.juju_charm.mimir_info.revision + otelcol = var.otelcol.revision ? var.otelcol.revision : data.juju_charm.otelcol_info.revision + tempo_coordinator = var.tempo_coordinator.revision ? var.tempo_coordinator.revision : data.juju_charm.tempo_info.revision + tempo_worker = var.tempo_worker.revision ? var.tempo_worker.revision : data.juju_charm.tempo_info.revision + ssc = var.ssc.revision ? var.ssc.revision : data.juju_charm.ssc_info.revision + traefik = var.traefik.revision ? var.traefik.revision : data.juju_charm.traefik_info.revision + } } variable "risk" { @@ -27,6 +41,12 @@ variable "risk" { default = "edge" } +variable "base" { + description = "The operating system on which to deploy. E.g. ubuntu@22.04. Changing this value for machine charms will trigger a replace by terraform. Check Charmhub for per-charm base support." + default = "ubuntu@24.04" + type = string +} + variable "model_uuid" { description = "Reference to an existing model resource or data source for the model to deploy to" type = string From 7a04a625915c92ca2fed83f195bedcab31e4cb5a Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Mon, 20 Apr 2026 09:34:41 -0400 Subject: [PATCH 04/10] chore --- terraform/cos-lite/applications.tf | 14 +-- terraform/cos-lite/locals.tf | 30 ++++++ .../tests/conditional_ingress.tftest.hcl | 4 +- .../cos-lite/tests/revision_pin.tftest.hcl | 90 ++++++++++++++++++ terraform/cos-lite/upgrades.tf | 16 ++-- terraform/cos-lite/variables.tf | 23 ----- terraform/cos/applications.tf | 25 ++--- terraform/cos/locals.tf | 44 +++++++++ terraform/cos/tests/revision_pin.tftest.hcl | 95 +++++++++++++++++++ terraform/cos/upgrades.tf | 37 +++++--- terraform/cos/variables.tf | 30 ------ 11 files changed, 312 insertions(+), 96 deletions(-) create mode 100644 terraform/cos-lite/locals.tf create mode 100644 terraform/cos-lite/tests/revision_pin.tftest.hcl create mode 100644 terraform/cos/locals.tf create mode 100644 terraform/cos/tests/revision_pin.tftest.hcl diff --git a/terraform/cos-lite/applications.tf b/terraform/cos-lite/applications.tf index b7e69947..72d34dd1 100644 --- a/terraform/cos-lite/applications.tf +++ b/terraform/cos-lite/applications.tf @@ -1,7 +1,7 @@ module "alertmanager" { source = "git::https://github.com/canonical/alertmanager-k8s-operator//terraform" app_name = var.alertmanager.app_name - channel = local.tracks.alertmanager + "/" + var.risk + channel = local.channels.alertmanager config = var.alertmanager.config constraints = var.alertmanager.constraints model_uuid = var.model_uuid @@ -13,7 +13,7 @@ module "alertmanager" { module "catalogue" { source = "git::https://github.com/canonical/catalogue-k8s-operator//terraform" app_name = var.catalogue.app_name - channel = local.tracks.catalogue + "/" + var.risk + channel = local.channels.catalogue config = var.catalogue.config constraints = var.catalogue.constraints model_uuid = var.model_uuid @@ -25,7 +25,7 @@ module "catalogue" { module "grafana" { source = "git::https://github.com/canonical/grafana-k8s-operator//terraform" app_name = var.grafana.app_name - channel = local.tracks.grafana + "/" + var.risk + channel = local.channels.grafana config = var.grafana.config constraints = var.grafana.constraints model_uuid = var.model_uuid @@ -37,7 +37,7 @@ module "grafana" { module "loki" { source = "git::https://github.com/canonical/loki-k8s-operator//terraform" app_name = var.loki.app_name - channel = local.tracks.loki + "/" + var.risk + channel = local.channels.loki config = var.loki.config constraints = var.loki.constraints model_uuid = var.model_uuid @@ -49,7 +49,7 @@ module "loki" { module "prometheus" { source = "git::https://github.com/canonical/prometheus-k8s-operator//terraform" app_name = var.prometheus.app_name - channel = local.tracks.prometheus + "/" + var.risk + channel = local.channels.prometheus config = var.prometheus.config constraints = var.prometheus.constraints model_uuid = var.model_uuid @@ -62,7 +62,7 @@ module "ssc" { count = var.internal_tls ? 1 : 0 source = "git::https://github.com/canonical/self-signed-certificates-operator//terraform" app_name = var.ssc.app_name - channel = local.tracks.ssc + "/" + var.risk + channel = local.channels.ssc config = var.ssc.config constraints = var.ssc.constraints model_uuid = var.model_uuid @@ -73,7 +73,7 @@ module "ssc" { module "traefik" { source = "git::https://github.com/canonical/traefik-k8s-operator//terraform" app_name = var.traefik.app_name - channel = local.tracks.traefik + "/" + var.risk + channel = local.channels.traefik config = var.traefik.config constraints = var.traefik.constraints model_uuid = var.model_uuid diff --git a/terraform/cos-lite/locals.tf b/terraform/cos-lite/locals.tf new file mode 100644 index 00000000..e1204dd0 --- /dev/null +++ b/terraform/cos-lite/locals.tf @@ -0,0 +1,30 @@ +locals { + tls_termination = var.external_certificates_offer_url != null ? true : false + tracks = { + alertmanager = "0.31" + catalogue = "3.0" + grafana = "12.4" + loki = "3.7" + prometheus = "3.10" + ssc = "latest" + traefik = "latest" + } + channels = { + alertmanager = "${local.tracks.alertmanager}/${var.risk}" + catalogue = "${local.tracks.catalogue}/${var.risk}" + grafana = "${local.tracks.grafana}/${var.risk}" + loki = "${local.tracks.loki}/${var.risk}" + prometheus = "${local.tracks.prometheus}/${var.risk}" + ssc = "${local.tracks.ssc}/${var.risk}" + traefik = "${local.tracks.traefik}/${var.risk}" + } + revisions = { + alertmanager = var.alertmanager.revision != null ? var.alertmanager.revision : data.juju_charm.alertmanager_info.revision + catalogue = var.catalogue.revision != null ? var.catalogue.revision : data.juju_charm.catalogue_info.revision + grafana = var.grafana.revision != null ? var.grafana.revision : data.juju_charm.grafana_info.revision + loki = var.loki.revision != null ? var.loki.revision : data.juju_charm.loki_info.revision + prometheus = var.prometheus.revision != null ? var.prometheus.revision : data.juju_charm.prometheus_info.revision + ssc = var.ssc.revision != null ? var.ssc.revision : data.juju_charm.ssc_info.revision + traefik = var.traefik.revision != null ? var.traefik.revision : data.juju_charm.traefik_info.revision + } +} \ No newline at end of file diff --git a/terraform/cos-lite/tests/conditional_ingress.tftest.hcl b/terraform/cos-lite/tests/conditional_ingress.tftest.hcl index 4c5d6c7b..eeee8b17 100644 --- a/terraform/cos-lite/tests/conditional_ingress.tftest.hcl +++ b/terraform/cos-lite/tests/conditional_ingress.tftest.hcl @@ -1,8 +1,6 @@ mock_provider "juju" {} -variables { - model_uuid = "00000000-0000-0000-0000-000000000000" -} +variables {model_uuid = "00000000-0000-0000-0000-000000000000"} # --- Default: all ingress integrations enabled --- diff --git a/terraform/cos-lite/tests/revision_pin.tftest.hcl b/terraform/cos-lite/tests/revision_pin.tftest.hcl new file mode 100644 index 00000000..b36a999a --- /dev/null +++ b/terraform/cos-lite/tests/revision_pin.tftest.hcl @@ -0,0 +1,90 @@ +mock_provider "juju" {} + +variables { model_uuid = "00000000-0000-0000-0000-000000000000" } + +# --- User revision pin is respected and not overridden by juju_charm datasource --- + +run "user_revision_pin_is_respected" { + command = plan + + variables { + alertmanager = { revision = 1 } + catalogue = { revision = 1 } + grafana = { revision = 1 } + loki_coordinator = { revision = 1 } + loki_worker = { revision = 1 } + mimir_coordinator = { revision = 1 } + mimir_worker = { revision = 1 } + opentelemetry_collector = { revision = 1 } + ssc = { revision = 1 } + s3_integrator = { revision = 1 } + tempo_coordinator = { revision = 1 } + tempo_worker = { revision = 1 } + traefik = { revision = 1 } + } + + assert { + condition = local.revisions.alertmanager == 1 + error_message = "Expected alertmanager revision 1, got ${local.revisions.alertmanager}" + } + + assert { + condition = local.revisions.catalogue == 1 + error_message = "Expected catalogue revision 1, got ${local.revisions.catalogue}" + } + + assert { + condition = local.revisions.grafana == 1 + error_message = "Expected grafana revision 1, got ${local.revisions.grafana}" + } + + assert { + condition = local.revisions.loki_coordinator == 1 + error_message = "Expected loki_coordinator revision 1, got ${local.revisions.loki_coordinator}" + } + + assert { + condition = local.revisions.loki_worker == 1 + error_message = "Expected loki_worker revision 1, got ${local.revisions.loki_worker}" + } + + assert { + condition = local.revisions.mimir_coordinator == 1 + error_message = "Expected mimir_coordinator revision 1, got ${local.revisions.mimir_coordinator}" + } + + assert { + condition = local.revisions.mimir_worker == 1 + error_message = "Expected mimir_worker revision 1, got ${local.revisions.mimir_worker}" + } + + assert { + condition = local.revisions.otelcol == 1 + error_message = "Expected otelcol revision 1, got ${local.revisions.otelcol}" + } + + assert { + condition = local.revisions.ssc == 1 + error_message = "Expected ssc revision 1, got ${local.revisions.ssc}" + } + + assert { + condition = local.revisions.s3_integrator == 1 + error_message = "Expected s3_integrator revision 1, got ${local.revisions.s3_integrator}" + } + + assert { + condition = local.revisions.tempo_coordinator == 1 + error_message = "Expected tempo_coordinator revision 1, got ${local.revisions.tempo_coordinator}" + } + + assert { + condition = local.revisions.tempo_worker == 1 + error_message = "Expected tempo_worker revision 1, got ${local.revisions.tempo_worker}" + } + + assert { + condition = local.revisions.traefik == 1 + error_message = "Expected traefik revision 1, got ${local.revisions.traefik}" + } +} diff --git a/terraform/cos-lite/upgrades.tf b/terraform/cos-lite/upgrades.tf index f0c6306a..821cd607 100644 --- a/terraform/cos-lite/upgrades.tf +++ b/terraform/cos-lite/upgrades.tf @@ -2,42 +2,42 @@ data "juju_charm" "alertmanager_info" { charm = "alertmanager-k8s" - channel = local.tracks.alertmanager + "/" + var.risk + channel = local.channels.alertmanager base = var.base } data "juju_charm" "catalogue_info" { charm = "catalogue-k8s" - channel = local.tracks.catalogue + "/" + var.risk + channel = local.channels.catalogue base = var.base } data "juju_charm" "grafana_info" { charm = "grafana-k8s" - channel = local.tracks.grafana + "/" + var.risk + channel = local.channels.grafana base = var.base } data "juju_charm" "loki_info" { charm = "loki-k8s" - channel = local.tracks.loki + "/" + var.risk + channel = local.channels.loki base = var.base } data "juju_charm" "prometheus_info" { charm = "prometheus-k8s" - channel = local.tracks.prometheus + "/" + var.risk + channel = local.channels.prometheus base = var.base } data "juju_charm" "ssc_info" { charm = "self-signed-certificates" - channel = local.tracks.ssc + "/" + var.risk + channel = local.channels.ssc base = var.base } data "juju_charm" "traefik_info" { charm = "traefik-k8s" - channel = local.tracks.traefik + "/" + var.risk + channel = local.channels.traefik base = var.base -} \ No newline at end of file +} diff --git a/terraform/cos-lite/variables.tf b/terraform/cos-lite/variables.tf index 39fca29f..40176124 100644 --- a/terraform/cos-lite/variables.tf +++ b/terraform/cos-lite/variables.tf @@ -5,29 +5,6 @@ # causes the operation to fail due to https://github.com/juju/terraform-provider-juju/issues/344 # Therefore, we set a default value of "arch=amd64" for all applications. -locals { - # https://github.com/juju/terraform-provider-juju/issues/972 - tls_termination = var.external_certificates_offer_url != null ? true : false - tracks = { - alertmanager = "0.31" - catalogue = "3.0" - grafana = "12.4" - loki = "3.7" - prometheus = "3.10" - ssc = "latest" - traefik = "latest" - } - revisions = { - alertmanager = var.alertmanager.revision ? var.alertmanager.revision: data.juju_charm.alertmanager_info.revision - catalogue = var.catalogue.revision ? var.catalogue.revision : data.juju_charm.catalogue_info.revision - grafana = var.grafana.revision ? var.grafana.revision : data.juju_charm.grafana_info.revision - loki = var.loki.revision ? var.loki.revision : data.juju_charm.loki_info.revision - prometheus = var.prometheus.revision ? var.prometheus.revision : data.juju_charm.prometheus_info.revision - ssc = var.ssc.revision ? var.ssc.revision : data.juju_charm.ssc_info.revision - traefik = var.traefik.revision ? var.traefik.revision : data.juju_charm.traefik_info.revision - } -} - variable "risk" { description = "Risk level that the applications are (unless overwritten by individual channels) deployed from" type = string diff --git a/terraform/cos/applications.tf b/terraform/cos/applications.tf index 7e31a959..4f969e95 100644 --- a/terraform/cos/applications.tf +++ b/terraform/cos/applications.tf @@ -1,7 +1,7 @@ module "alertmanager" { source = "git::https://github.com/canonical/alertmanager-k8s-operator//terraform" app_name = var.alertmanager.app_name - channel = local.tracks.alertmanager + "/" + var.risk + channel = local.channels.alertmanager config = var.alertmanager.config constraints = var.alertmanager.constraints model_uuid = var.model_uuid @@ -13,7 +13,7 @@ module "alertmanager" { module "catalogue" { source = "git::https://github.com/canonical/catalogue-k8s-operator//terraform" app_name = var.catalogue.app_name - channel = local.tracks.catalogue + "/" + var.risk + channel = local.channels.catalogue config = var.catalogue.config constraints = var.catalogue.constraints model_uuid = var.model_uuid @@ -25,7 +25,7 @@ module "catalogue" { module "grafana" { source = "git::https://github.com/canonical/grafana-k8s-operator//terraform" app_name = var.grafana.app_name - channel = local.tracks.grafana + "/" + var.risk + channel = local.channels.grafana config = var.grafana.config constraints = var.grafana.constraints model_uuid = var.model_uuid @@ -37,13 +37,13 @@ module "grafana" { module "loki" { source = "git::https://github.com/canonical/loki-operators//terraform" anti_affinity = var.anti_affinity - channel = local.tracks.loki + "/" + var.risk + channel = local.channels.loki model_uuid = var.model_uuid s3_endpoint = var.s3_endpoint s3_secret_key = var.s3_secret_key s3_access_key = var.s3_access_key s3_bucket = var.loki_bucket - s3_integrator_channel = var.s3_integrator.channel + s3_integrator_channel = local.channels.s3_integrator s3_integrator_config = var.s3_integrator.config s3_integrator_constraints = var.s3_integrator.constraints s3_integrator_revision = local.revisions.s3_integrator @@ -70,13 +70,13 @@ module "loki" { module "mimir" { source = "git::https://github.com/canonical/mimir-operators//terraform" anti_affinity = var.anti_affinity - channel = local.tracks.mimir + "/" + var.risk + channel = local.channels.mimir model_uuid = var.model_uuid s3_endpoint = var.s3_endpoint s3_secret_key = var.s3_secret_key s3_access_key = var.s3_access_key s3_bucket = var.mimir_bucket - s3_integrator_channel = var.s3_integrator.channel + s3_integrator_channel = local.channels.s3_integrator s3_integrator_config = var.s3_integrator.config s3_integrator_constraints = var.s3_integrator.constraints s3_integrator_revision = local.revisions.s3_integrator @@ -103,7 +103,7 @@ module "mimir" { module "opentelemetry_collector" { source = "git::https://github.com/canonical/opentelemetry-collector-k8s-operator//terraform" app_name = var.opentelemetry_collector.app_name - channel = local.tracks.otelcol + "/" + var.risk + channel = local.channels.otelcol config = var.opentelemetry_collector.config constraints = var.opentelemetry_collector.constraints model_uuid = var.model_uuid @@ -116,7 +116,7 @@ module "ssc" { count = var.internal_tls ? 1 : 0 source = "git::https://github.com/canonical/self-signed-certificates-operator//terraform" app_name = var.ssc.app_name - channel = local.tracks.ssc + "/" + var.risk + channel = local.channels.ssc config = var.ssc.config constraints = var.ssc.constraints model_uuid = var.model_uuid @@ -127,13 +127,14 @@ module "ssc" { module "tempo" { source = "git::https://github.com/canonical/tempo-operators//terraform" anti_affinity = var.anti_affinity - channel = local.tracks.tempo + "/" + var.risk + channel = local.channels.tempo model_uuid = var.model_uuid s3_endpoint = var.s3_endpoint s3_access_key = var.s3_access_key s3_secret_key = var.s3_secret_key s3_bucket = var.tempo_bucket - s3_integrator_channel = var.s3_integrator.channel + # TODO: The same s3_integrator channel for all coordinated-workers? + s3_integrator_channel = local.channels.s3_integrator s3_integrator_config = var.s3_integrator.config s3_integrator_constraints = var.s3_integrator.constraints s3_integrator_revision = local.revisions.s3_integrator @@ -169,7 +170,7 @@ module "tempo" { module "traefik" { source = "git::https://github.com/canonical/traefik-k8s-operator//terraform" app_name = var.traefik.app_name - channel = local.tracks.traefik + "/" + var.risk + channel = local.channels.traefik config = var.cloud == "aws" ? { "loadbalancer_annotations" = "service.beta.kubernetes.io/aws-load-balancer-scheme=internet-facing" } : var.traefik.config constraints = var.traefik.constraints model_uuid = var.model_uuid diff --git a/terraform/cos/locals.tf b/terraform/cos/locals.tf new file mode 100644 index 00000000..a610ebe1 --- /dev/null +++ b/terraform/cos/locals.tf @@ -0,0 +1,44 @@ +locals { + clouds = ["aws", "self-managed"] # list of k8s clouds where this COS module can be deployed. + tls_termination = var.external_certificates_offer_url != null ? true : false + tracks = { + alertmanager = "0.31" + catalogue = "3.0" + grafana = "12.4" + loki = "3.7" + mimir = "3.0" + otelcol = "0.130" + # TODO: update track + s3_integrator = "latest" + ssc = "latest" + tempo = "2.10" + traefik = "latest" + } + channels = { + alertmanager = "${local.tracks.alertmanager}/${var.risk}" + catalogue = "${local.tracks.catalogue}/${var.risk}" + grafana = "${local.tracks.grafana}/${var.risk}" + loki = "${local.tracks.loki}/${var.risk}" + mimir = "${local.tracks.mimir}/${var.risk}" + otelcol = "${local.tracks.otelcol}/${var.risk}" + s3_integrator = "${local.tracks.s3_integrator}/${var.risk}" + ssc = "${local.tracks.ssc}/${var.risk}" + tempo = "${local.tracks.tempo}/${var.risk}" + traefik = "${local.tracks.traefik}/${var.risk}" + } + revisions = { + alertmanager = var.alertmanager.revision != null ? var.alertmanager.revision : data.juju_charm.alertmanager_info.revision + catalogue = var.catalogue.revision != null ? var.catalogue.revision : data.juju_charm.catalogue_info.revision + grafana = var.grafana.revision != null ? var.grafana.revision : data.juju_charm.grafana_info.revision + loki_coordinator = var.loki_coordinator.revision != null ? var.loki_coordinator.revision : data.juju_charm.loki_coordinator_info.revision + loki_worker = var.loki_worker.revision != null ? var.loki_worker.revision : data.juju_charm.loki_worker_info.revision + mimir_coordinator = var.mimir_coordinator.revision != null ? var.mimir_coordinator.revision : data.juju_charm.mimir_coordinator_info.revision + mimir_worker = var.mimir_worker.revision != null ? var.mimir_worker.revision : data.juju_charm.mimir_worker_info.revision + otelcol = var.otelcol.revision != null ? var.otelcol.revision : data.juju_charm.otelcol_info.revision + s3_integrator = var.s3_integrator.revision != null ? var.s3_integrator.revision : data.juju_charm.s3_integrator_info.revision + ssc = var.ssc.revision != null ? var.ssc.revision : data.juju_charm.ssc_info.revision + tempo_coordinator = var.tempo_coordinator.revision != null ? var.tempo_coordinator.revision : data.juju_charm.tempo_coordinator_info.revision + tempo_worker = var.tempo_worker.revision != null ? var.tempo_worker.revision : data.juju_charm.tempo_worker_info.revision + traefik = var.traefik.revision != null ? var.traefik.revision : data.juju_charm.traefik_info.revision + } +} diff --git a/terraform/cos/tests/revision_pin.tftest.hcl b/terraform/cos/tests/revision_pin.tftest.hcl new file mode 100644 index 00000000..79bcb1a2 --- /dev/null +++ b/terraform/cos/tests/revision_pin.tftest.hcl @@ -0,0 +1,95 @@ +mock_provider "juju" {} + +variables { + model_uuid = "00000000-0000-0000-0000-000000000000" + s3_endpoint = "foo" + s3_access_key = "foo" + s3_secret_key = "foo" +} + +# --- User revision pin is respected and not overridden by juju_charm datasource --- + +run "user_revision_pin_is_respected" { + command = plan + + variables { + alertmanager = {revision = 1 } + catalogue = {revision = 1 } + grafana = {revision = 1 } + loki_coordinator = {revision = 1 } + loki_worker = {revision = 1 } + mimir_coordinator = {revision = 1 } + mimir_worker = {revision = 1 } + opentelemetry_collector = {revision = 1 } + ssc = {revision = 1 } + s3_integrator = {revision = 1 } + tempo_coordinator = {revision = 1 } + tempo_worker = {revision = 1 } + traefik = {revision = 1 } + } + + assert { + condition = local.revisions.alertmanager == 1 + error_message = "Expected alertmanager revision 1, got ${local.revisions.alertmanager}" + } + + assert { + condition = local.revisions.catalogue == 1 + error_message = "Expected catalogue revision 1, got ${local.revisions.catalogue}" + } + + assert { + condition = local.revisions.grafana == 1 + error_message = "Expected grafana revision 1, got ${local.revisions.grafana}" + } + + assert { + condition = local.revisions.loki_coordinator == 1 + error_message = "Expected loki_coordinator revision 1, got ${local.revisions.loki_coordinator}" + } + + assert { + condition = local.revisions.loki_worker == 1 + error_message = "Expected loki_worker revision 1, got ${local.revisions.loki_worker}" + } + + assert { + condition = local.revisions.mimir_coordinator == 1 + error_message = "Expected mimir_coordinator revision 1, got ${local.revisions.mimir_coordinator}" + } + + assert { + condition = local.revisions.mimir_worker == 1 + error_message = "Expected mimir_worker revision 1, got ${local.revisions.mimir_worker}" + } + + assert { + condition = local.revisions.otelcol == 1 + error_message = "Expected otelcol revision 1, got ${local.revisions.otelcol}" + } + + assert { + condition = local.revisions.ssc == 1 + error_message = "Expected ssc revision 1, got ${local.revisions.ssc}" + } + + assert { + condition = local.revisions.s3_integrator == 1 + error_message = "Expected s3_integrator revision 1, got ${local.revisions.s3_integrator}" + } + + assert { + condition = local.revisions.tempo_coordinator == 1 + error_message = "Expected tempo_coordinator revision 1, got ${local.revisions.tempo_coordinator}" + } + + assert { + condition = local.revisions.tempo_worker == 1 + error_message = "Expected tempo_worker revision 1, got ${local.revisions.tempo_worker}" + } + + assert { + condition = local.revisions.traefik == 1 + error_message = "Expected traefik revision 1, got ${local.revisions.traefik}" + } +} diff --git a/terraform/cos/upgrades.tf b/terraform/cos/upgrades.tf index 78a5d243..40bbde6b 100644 --- a/terraform/cos/upgrades.tf +++ b/terraform/cos/upgrades.tf @@ -1,71 +1,82 @@ +# -------------- # CharmHub API -------------- # + +# TODO: Add a utest to assert that a user revision pin is respected and doesn't get overridden by the juju-charm datasource. +# TODO: assert that if a user doesn't provide a revision pin then the juju-charm datasource is used to determine the revision. +# TODO: We want one per component to avoid mistakes not applied to all components. data "juju_charm" "alertmanager_info" { charm = "alertmanager-k8s" - channel = local.tracks.alertmanager + "/" + var.risk + channel = local.channels.alertmanager base = var.base } data "juju_charm" "catalogue_info" { charm = "catalogue-k8s" - channel = local.tracks.catalogue + "/" + var.risk + channel = local.channels.catalogue base = var.base } data "juju_charm" "grafana_info" { charm = "grafana-k8s" - channel = local.tracks.grafana + "/" + var.risk + channel = local.channels.grafana base = var.base } data "juju_charm" "loki_coordinator_info" { charm = "loki-coordinator-k8s" - channel = local.tracks.loki + "/" + var.risk + channel = local.channels.loki base = var.base } data "juju_charm" "loki_worker_info" { charm = "loki-worker-k8s" - channel = local.tracks.loki + "/" + var.risk + channel = local.channels.loki base = var.base } data "juju_charm" "mimir_coordinator_info" { charm = "mimir-coordinator-k8s" - channel = local.tracks.mimir + "/" + var.risk + channel = local.channels.mimir base = var.base } data "juju_charm" "mimir_worker_info" { charm = "mimir-worker-k8s" - channel = local.tracks.mimir + "/" + var.risk + channel = local.channels.mimir base = var.base } data "juju_charm" "otelcol_info" { charm = "opentelemetry-collector-k8s" - channel = local.tracks.otelcol + "/" + var.risk + channel = local.channels.otelcol base = var.base } data "juju_charm" "tempo_coordinator_info" { charm = "tempo-coordinator-k8s" - channel = local.tracks.tempo + "/" + var.risk + channel = local.channels.tempo base = var.base } data "juju_charm" "tempo_worker_info" { charm = "tempo-worker-k8s" - channel = local.tracks.tempo + "/" + var.risk + channel = local.channels.tempo base = var.base } data "juju_charm" "ssc_info" { charm = "self-signed-certificates" - channel = local.tracks.ssc + "/" + var.risk + channel = local.channels.ssc + base = var.base +} + +data "juju_charm" "s3_integrator_info" { + charm = "s3-integrator-k8s" + channel = local.channels.s3_integrator base = var.base } data "juju_charm" "traefik_info" { charm = "traefik-k8s" - channel = local.tracks.traefik + "/" + var.risk + channel = local.channels.traefik base = var.base -} \ No newline at end of file +} diff --git a/terraform/cos/variables.tf b/terraform/cos/variables.tf index a298fa04..cad34b28 100644 --- a/terraform/cos/variables.tf +++ b/terraform/cos/variables.tf @@ -5,36 +5,6 @@ # causes the operation to fail due to https://github.com/juju/terraform-provider-juju/issues/344 # Therefore, we set a default value of "arch=amd64" for all applications. -locals { - clouds = ["aws", "self-managed"] # list of k8s clouds where this COS module can be deployed. - tls_termination = var.external_certificates_offer_url != null ? true : false - tracks = { - alertmanager = "0.31" - catalogue = "3.0" - grafana = "12.4" - loki = "3.7" - mimir = "3.0" - otelcol = "0.130" - ssc = "latest" - tempo = "2.10" - traefik = "latest" - } - revisions = { - alertmanager = var.alertmanager.revision ? var.alertmanager.revision : data.juju_charm.alertmanager_info.revision - catalogue = var.catalogue.revision ? var.catalogue.revision : data.juju_charm.catalogue_info.revision - grafana = var.grafana.revision ? var.grafana.revision : data.juju_charm.grafana_info.revision - loki_coordinator = var.loki_coordinator.revision ? var.loki_coordinator.revision : data.juju_charm.loki_info.revision - loki_worker = var.loki_worker.revision ? var.loki_worker.revision : data.juju_charm.loki_info.revision - mimir_coordinator = var.mimir_coordinator.revision ? var.mimir_coordinator.revision : data.juju_charm.mimir_info.revision - mimir_worker = var.mimir_worker.revision ? var.mimir_worker.revision : data.juju_charm.mimir_info.revision - otelcol = var.otelcol.revision ? var.otelcol.revision : data.juju_charm.otelcol_info.revision - tempo_coordinator = var.tempo_coordinator.revision ? var.tempo_coordinator.revision : data.juju_charm.tempo_info.revision - tempo_worker = var.tempo_worker.revision ? var.tempo_worker.revision : data.juju_charm.tempo_info.revision - ssc = var.ssc.revision ? var.ssc.revision : data.juju_charm.ssc_info.revision - traefik = var.traefik.revision ? var.traefik.revision : data.juju_charm.traefik_info.revision - } -} - variable "risk" { description = "Risk level that the applications are (unless overwritten by individual channels) deployed from" type = string From d0d7115104bb76a3be0352f2a9f999d8d5146efc Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Mon, 20 Apr 2026 14:57:51 -0400 Subject: [PATCH 05/10] chore: docs --- terraform/cos-lite/README.md | 1 + terraform/cos/README.md | 1 + 2 files changed, 2 insertions(+) diff --git a/terraform/cos-lite/README.md b/terraform/cos-lite/README.md index 9d1e5dd5..e1e3b4ac 100644 --- a/terraform/cos-lite/README.md +++ b/terraform/cos-lite/README.md @@ -26,6 +26,7 @@ This is a Terraform module facilitating the deployment of the COS Lite solution, | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| | [alertmanager](#input\_alertmanager) | Application configuration for Alertmanager. For more details: https://registry.terraform.io/providers/juju/juju/latest/docs/resources/application |
object({
app_name = optional(string, "alertmanager")
config = optional(map(string), {})
constraints = optional(string, "arch=amd64")
revision = optional(number, null)
storage_directives = optional(map(string), {})
units = optional(number, 1)
})
| `{}` | no | +| [base](#input\_base) | The operating system on which to deploy. E.g. ubuntu@22.04. Changing this value for machine charms will trigger a replace by terraform. Check Charmhub for per-charm base support. | `string` | `"ubuntu@24.04"` | no | | [catalogue](#input\_catalogue) | Application configuration for Catalogue. For more details: https://registry.terraform.io/providers/juju/juju/latest/docs/resources/application |
object({
app_name = optional(string, "catalogue")
config = optional(map(string), {})
constraints = optional(string, "arch=amd64")
revision = optional(number, null)
storage_directives = optional(map(string), {})
units = optional(number, 1)
})
| `{}` | no | | [external\_ca\_cert\_offer\_url](#input\_external\_ca\_cert\_offer\_url) | A Juju offer URL (e.g. admin/external-ca.send-ca-cert) of a CA providing the 'certificate\_transfer' integration for applications to trust ingress via Traefik. | `string` | `null` | no | | [external\_certificates\_offer\_url](#input\_external\_certificates\_offer\_url) | A Juju offer URL (e.g. admin/external-ca.certificates) of a CA providing the 'tls\_certificates' integration for Traefik to supply it with server certificates. | `string` | `null` | no | diff --git a/terraform/cos/README.md b/terraform/cos/README.md index f608486d..e9ab7ac8 100644 --- a/terraform/cos/README.md +++ b/terraform/cos/README.md @@ -32,6 +32,7 @@ This is a Terraform module facilitating the deployment of the COS solution, usin |------|-------------|------|---------|:--------:| | [alertmanager](#input\_alertmanager) | Application configuration for Alertmanager. For more details: https://registry.terraform.io/providers/juju/juju/latest/docs/resources/application |
object({
app_name = optional(string, "alertmanager")
config = optional(map(string), {})
constraints = optional(string, "arch=amd64")
revision = optional(number, null)
storage_directives = optional(map(string), {})
units = optional(number, 1)
})
| `{}` | no | | [anti\_affinity](#input\_anti\_affinity) | Enable anti-affinity constraints across all HA modules (Mimir, Loki, Tempo) | `bool` | `true` | no | +| [base](#input\_base) | The operating system on which to deploy. E.g. ubuntu@22.04. Changing this value for machine charms will trigger a replace by terraform. Check Charmhub for per-charm base support. | `string` | `"ubuntu@24.04"` | no | | [catalogue](#input\_catalogue) | Application configuration for Catalogue. For more details: https://registry.terraform.io/providers/juju/juju/latest/docs/resources/application |
object({
app_name = optional(string, "catalogue")
config = optional(map(string), {})
constraints = optional(string, "arch=amd64")
revision = optional(number, null)
storage_directives = optional(map(string), {})
units = optional(number, 1)
})
| `{}` | no | | [cloud](#input\_cloud) | Kubernetes cloud or environment where this COS module will be deployed (e.g self-managed, aws) | `string` | `"self-managed"` | no | | [external\_ca\_cert\_offer\_url](#input\_external\_ca\_cert\_offer\_url) | A Juju offer URL (e.g. admin/external-ca.send-ca-cert) of a CA providing the 'certificate\_transfer' integration for applications to trust ingress via Traefik. | `string` | `null` | no | From 8c460ba845fd55a1debc0d74f8200ede98c888e7 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Mon, 20 Apr 2026 15:59:12 -0400 Subject: [PATCH 06/10] chore --- .../cos-lite/tests/revision_pin.tftest.hcl | 56 ++++--------------- terraform/cos/locals.tf | 5 +- terraform/cos/tests/revision_pin.tftest.hcl | 26 ++++----- 3 files changed, 25 insertions(+), 62 deletions(-) diff --git a/terraform/cos-lite/tests/revision_pin.tftest.hcl b/terraform/cos-lite/tests/revision_pin.tftest.hcl index b36a999a..bb220700 100644 --- a/terraform/cos-lite/tests/revision_pin.tftest.hcl +++ b/terraform/cos-lite/tests/revision_pin.tftest.hcl @@ -9,18 +9,12 @@ run "user_revision_pin_is_respected" { variables { alertmanager = { revision = 1 } - catalogue = { revision = 1 } - grafana = { revision = 1 } - loki_coordinator = { revision = 1 } - loki_worker = { revision = 1 } - mimir_coordinator = { revision = 1 } - mimir_worker = { revision = 1 } - opentelemetry_collector = { revision = 1 } - ssc = { revision = 1 } - s3_integrator = { revision = 1 } - tempo_coordinator = { revision = 1 } - tempo_worker = { revision = 1 } - traefik = { revision = 1 } + catalogue = { revision = 1 } + grafana = { revision = 1 } + loki = { revision = 1 } + prometheus = { revision = 1 } + ssc = { revision = 1 } + traefik = { revision = 1 } } assert { @@ -39,28 +33,13 @@ run "user_revision_pin_is_respected" { } assert { - condition = local.revisions.loki_coordinator == 1 - error_message = "Expected loki_coordinator revision 1, got ${local.revisions.loki_coordinator}" + condition = local.revisions.loki == 1 + error_message = "Expected loki revision 1, got ${local.revisions.loki}" } assert { - condition = local.revisions.loki_worker == 1 - error_message = "Expected loki_worker revision 1, got ${local.revisions.loki_worker}" - } - - assert { - condition = local.revisions.mimir_coordinator == 1 - error_message = "Expected mimir_coordinator revision 1, got ${local.revisions.mimir_coordinator}" - } - - assert { - condition = local.revisions.mimir_worker == 1 - error_message = "Expected mimir_worker revision 1, got ${local.revisions.mimir_worker}" - } - - assert { - condition = local.revisions.otelcol == 1 - error_message = "Expected otelcol revision 1, got ${local.revisions.otelcol}" + condition = local.revisions.prometheus == 1 + error_message = "Expected prometheus revision 1, got ${local.revisions.prometheus}" } assert { @@ -68,21 +47,6 @@ run "user_revision_pin_is_respected" { error_message = "Expected ssc revision 1, got ${local.revisions.ssc}" } - assert { - condition = local.revisions.s3_integrator == 1 - error_message = "Expected s3_integrator revision 1, got ${local.revisions.s3_integrator}" - } - - assert { - condition = local.revisions.tempo_coordinator == 1 - error_message = "Expected tempo_coordinator revision 1, got ${local.revisions.tempo_coordinator}" - } - - assert { - condition = local.revisions.tempo_worker == 1 - error_message = "Expected tempo_worker revision 1, got ${local.revisions.tempo_worker}" - } - assert { condition = local.revisions.traefik == 1 error_message = "Expected traefik revision 1, got ${local.revisions.traefik}" diff --git a/terraform/cos/locals.tf b/terraform/cos/locals.tf index a610ebe1..a55136e1 100644 --- a/terraform/cos/locals.tf +++ b/terraform/cos/locals.tf @@ -8,8 +8,7 @@ locals { loki = "3.7" mimir = "3.0" otelcol = "0.130" - # TODO: update track - s3_integrator = "latest" + s3_integrator = "2" ssc = "latest" tempo = "2.10" traefik = "latest" @@ -34,7 +33,7 @@ locals { loki_worker = var.loki_worker.revision != null ? var.loki_worker.revision : data.juju_charm.loki_worker_info.revision mimir_coordinator = var.mimir_coordinator.revision != null ? var.mimir_coordinator.revision : data.juju_charm.mimir_coordinator_info.revision mimir_worker = var.mimir_worker.revision != null ? var.mimir_worker.revision : data.juju_charm.mimir_worker_info.revision - otelcol = var.otelcol.revision != null ? var.otelcol.revision : data.juju_charm.otelcol_info.revision + otelcol = var.opentelemetry_collector.revision != null ? var.opentelemetry_collector.revision : data.juju_charm.otelcol_info.revision s3_integrator = var.s3_integrator.revision != null ? var.s3_integrator.revision : data.juju_charm.s3_integrator_info.revision ssc = var.ssc.revision != null ? var.ssc.revision : data.juju_charm.ssc_info.revision tempo_coordinator = var.tempo_coordinator.revision != null ? var.tempo_coordinator.revision : data.juju_charm.tempo_coordinator_info.revision diff --git a/terraform/cos/tests/revision_pin.tftest.hcl b/terraform/cos/tests/revision_pin.tftest.hcl index 79bcb1a2..510f967d 100644 --- a/terraform/cos/tests/revision_pin.tftest.hcl +++ b/terraform/cos/tests/revision_pin.tftest.hcl @@ -13,19 +13,19 @@ run "user_revision_pin_is_respected" { command = plan variables { - alertmanager = {revision = 1 } - catalogue = {revision = 1 } - grafana = {revision = 1 } - loki_coordinator = {revision = 1 } - loki_worker = {revision = 1 } - mimir_coordinator = {revision = 1 } - mimir_worker = {revision = 1 } - opentelemetry_collector = {revision = 1 } - ssc = {revision = 1 } - s3_integrator = {revision = 1 } - tempo_coordinator = {revision = 1 } - tempo_worker = {revision = 1 } - traefik = {revision = 1 } + alertmanager = { revision = 1 } + catalogue = { revision = 1 } + grafana = { revision = 1 } + loki_coordinator = { revision = 1 } + loki_worker = { revision = 1 } + mimir_coordinator = { revision = 1 } + mimir_worker = { revision = 1 } + opentelemetry_collector = { revision = 1 } + ssc = { revision = 1 } + s3_integrator = { revision = 1 } + tempo_coordinator = { revision = 1 } + tempo_worker = { revision = 1 } + traefik = { revision = 1 } } assert { From 674c7670236dd312a4c1684cd0a586149d26a890 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Mon, 20 Apr 2026 16:06:59 -0400 Subject: [PATCH 07/10] chore --- .../cos-lite/tests/revision_pin.tftest.hcl | 77 +++++++--- terraform/cos-lite/upgrades.tf | 2 - terraform/cos/applications.tf | 16 +- terraform/cos/locals.tf | 12 +- terraform/cos/tests/revision_pin.tftest.hcl | 143 +++++++++++++----- terraform/cos/upgrades.tf | 3 - terraform/cos/variables.tf | 1 - 7 files changed, 180 insertions(+), 74 deletions(-) diff --git a/terraform/cos-lite/tests/revision_pin.tftest.hcl b/terraform/cos-lite/tests/revision_pin.tftest.hcl index bb220700..82c61e73 100644 --- a/terraform/cos-lite/tests/revision_pin.tftest.hcl +++ b/terraform/cos-lite/tests/revision_pin.tftest.hcl @@ -9,12 +9,12 @@ run "user_revision_pin_is_respected" { variables { alertmanager = { revision = 1 } - catalogue = { revision = 1 } - grafana = { revision = 1 } - loki = { revision = 1 } - prometheus = { revision = 1 } - ssc = { revision = 1 } - traefik = { revision = 1 } + catalogue = { revision = 2 } + grafana = { revision = 3 } + loki = { revision = 4 } + prometheus = { revision = 5 } + ssc = { revision = 6 } + traefik = { revision = 7 } } assert { @@ -23,32 +23,73 @@ run "user_revision_pin_is_respected" { } assert { - condition = local.revisions.catalogue == 1 - error_message = "Expected catalogue revision 1, got ${local.revisions.catalogue}" + condition = local.revisions.catalogue == 2 + error_message = "Expected catalogue revision 2, got ${local.revisions.catalogue}" } assert { - condition = local.revisions.grafana == 1 - error_message = "Expected grafana revision 1, got ${local.revisions.grafana}" + condition = local.revisions.grafana == 3 + error_message = "Expected grafana revision 3, got ${local.revisions.grafana}" } assert { - condition = local.revisions.loki == 1 - error_message = "Expected loki revision 1, got ${local.revisions.loki}" + condition = local.revisions.loki == 4 + error_message = "Expected loki revision 4, got ${local.revisions.loki}" } assert { - condition = local.revisions.prometheus == 1 - error_message = "Expected prometheus revision 1, got ${local.revisions.prometheus}" + condition = local.revisions.prometheus == 5 + error_message = "Expected prometheus revision 5, got ${local.revisions.prometheus}" } assert { - condition = local.revisions.ssc == 1 - error_message = "Expected ssc revision 1, got ${local.revisions.ssc}" + condition = local.revisions.ssc == 6 + error_message = "Expected ssc revision 6, got ${local.revisions.ssc}" } assert { - condition = local.revisions.traefik == 1 - error_message = "Expected traefik revision 1, got ${local.revisions.traefik}" + condition = local.revisions.traefik == 7 + error_message = "Expected traefik revision 7, got ${local.revisions.traefik}" + } +} + +# --- Without a revision pin, the juju_charm datasource determines the revision --- + +run "no_pin_uses_datasource" { + command = plan + + assert { + condition = local.revisions.alertmanager == data.juju_charm.alertmanager_info.revision + error_message = "alertmanager revision should come from datasource when no pin is set" + } + + assert { + condition = local.revisions.catalogue == data.juju_charm.catalogue_info.revision + error_message = "catalogue revision should come from datasource when no pin is set" + } + + assert { + condition = local.revisions.grafana == data.juju_charm.grafana_info.revision + error_message = "grafana revision should come from datasource when no pin is set" + } + + assert { + condition = local.revisions.loki == data.juju_charm.loki_info.revision + error_message = "loki revision should come from datasource when no pin is set" + } + + assert { + condition = local.revisions.prometheus == data.juju_charm.prometheus_info.revision + error_message = "prometheus revision should come from datasource when no pin is set" + } + + assert { + condition = local.revisions.ssc == data.juju_charm.ssc_info.revision + error_message = "ssc revision should come from datasource when no pin is set" + } + + assert { + condition = local.revisions.traefik == data.juju_charm.traefik_info.revision + error_message = "traefik revision should come from datasource when no pin is set" } } diff --git a/terraform/cos-lite/upgrades.tf b/terraform/cos-lite/upgrades.tf index 821cd607..0150362d 100644 --- a/terraform/cos-lite/upgrades.tf +++ b/terraform/cos-lite/upgrades.tf @@ -1,5 +1,3 @@ -# TODO: If we only use the juju-charm datasource then users won't be able to revision pin - data "juju_charm" "alertmanager_info" { charm = "alertmanager-k8s" channel = local.channels.alertmanager diff --git a/terraform/cos/applications.tf b/terraform/cos/applications.tf index 4f969e95..deaec9aa 100644 --- a/terraform/cos/applications.tf +++ b/terraform/cos/applications.tf @@ -125,14 +125,14 @@ module "ssc" { } module "tempo" { - source = "git::https://github.com/canonical/tempo-operators//terraform" - anti_affinity = var.anti_affinity - channel = local.channels.tempo - model_uuid = var.model_uuid - s3_endpoint = var.s3_endpoint - s3_access_key = var.s3_access_key - s3_secret_key = var.s3_secret_key - s3_bucket = var.tempo_bucket + source = "git::https://github.com/canonical/tempo-operators//terraform" + anti_affinity = var.anti_affinity + channel = local.channels.tempo + model_uuid = var.model_uuid + s3_endpoint = var.s3_endpoint + s3_access_key = var.s3_access_key + s3_secret_key = var.s3_secret_key + s3_bucket = var.tempo_bucket # TODO: The same s3_integrator channel for all coordinated-workers? s3_integrator_channel = local.channels.s3_integrator s3_integrator_config = var.s3_integrator.config diff --git a/terraform/cos/locals.tf b/terraform/cos/locals.tf index a55136e1..bae1f726 100644 --- a/terraform/cos/locals.tf +++ b/terraform/cos/locals.tf @@ -2,12 +2,12 @@ locals { clouds = ["aws", "self-managed"] # list of k8s clouds where this COS module can be deployed. tls_termination = var.external_certificates_offer_url != null ? true : false tracks = { - alertmanager = "0.31" - catalogue = "3.0" - grafana = "12.4" - loki = "3.7" - mimir = "3.0" - otelcol = "0.130" + alertmanager = "0.31" + catalogue = "3.0" + grafana = "12.4" + loki = "3.7" + mimir = "3.0" + otelcol = "0.130" s3_integrator = "2" ssc = "latest" tempo = "2.10" diff --git a/terraform/cos/tests/revision_pin.tftest.hcl b/terraform/cos/tests/revision_pin.tftest.hcl index 510f967d..c9536cf5 100644 --- a/terraform/cos/tests/revision_pin.tftest.hcl +++ b/terraform/cos/tests/revision_pin.tftest.hcl @@ -14,18 +14,18 @@ run "user_revision_pin_is_respected" { variables { alertmanager = { revision = 1 } - catalogue = { revision = 1 } - grafana = { revision = 1 } - loki_coordinator = { revision = 1 } - loki_worker = { revision = 1 } - mimir_coordinator = { revision = 1 } - mimir_worker = { revision = 1 } - opentelemetry_collector = { revision = 1 } - ssc = { revision = 1 } - s3_integrator = { revision = 1 } - tempo_coordinator = { revision = 1 } - tempo_worker = { revision = 1 } - traefik = { revision = 1 } + catalogue = { revision = 2 } + grafana = { revision = 3 } + loki_coordinator = { revision = 4 } + loki_worker = { revision = 5 } + mimir_coordinator = { revision = 6 } + mimir_worker = { revision = 7 } + opentelemetry_collector = { revision = 8 } + ssc = { revision = 9 } + s3_integrator = { revision = 10 } + tempo_coordinator = { revision = 11 } + tempo_worker = { revision = 12 } + traefik = { revision = 13 } } assert { @@ -34,62 +34,133 @@ run "user_revision_pin_is_respected" { } assert { - condition = local.revisions.catalogue == 1 - error_message = "Expected catalogue revision 1, got ${local.revisions.catalogue}" + condition = local.revisions.catalogue == 2 + error_message = "Expected catalogue revision 2, got ${local.revisions.catalogue}" } assert { - condition = local.revisions.grafana == 1 - error_message = "Expected grafana revision 1, got ${local.revisions.grafana}" + condition = local.revisions.grafana == 3 + error_message = "Expected grafana revision 3, got ${local.revisions.grafana}" } assert { - condition = local.revisions.loki_coordinator == 1 - error_message = "Expected loki_coordinator revision 1, got ${local.revisions.loki_coordinator}" + condition = local.revisions.loki_coordinator == 4 + error_message = "Expected loki_coordinator revision 4, got ${local.revisions.loki_coordinator}" } assert { - condition = local.revisions.loki_worker == 1 - error_message = "Expected loki_worker revision 1, got ${local.revisions.loki_worker}" + condition = local.revisions.loki_worker == 5 + error_message = "Expected loki_worker revision 5, got ${local.revisions.loki_worker}" } assert { - condition = local.revisions.mimir_coordinator == 1 - error_message = "Expected mimir_coordinator revision 1, got ${local.revisions.mimir_coordinator}" + condition = local.revisions.mimir_coordinator == 6 + error_message = "Expected mimir_coordinator revision 6, got ${local.revisions.mimir_coordinator}" } assert { - condition = local.revisions.mimir_worker == 1 - error_message = "Expected mimir_worker revision 1, got ${local.revisions.mimir_worker}" + condition = local.revisions.mimir_worker == 7 + error_message = "Expected mimir_worker revision 7, got ${local.revisions.mimir_worker}" } assert { - condition = local.revisions.otelcol == 1 - error_message = "Expected otelcol revision 1, got ${local.revisions.otelcol}" + condition = local.revisions.otelcol == 8 + error_message = "Expected otelcol revision 8, got ${local.revisions.otelcol}" } assert { - condition = local.revisions.ssc == 1 - error_message = "Expected ssc revision 1, got ${local.revisions.ssc}" + condition = local.revisions.ssc == 9 + error_message = "Expected ssc revision 9, got ${local.revisions.ssc}" } assert { - condition = local.revisions.s3_integrator == 1 - error_message = "Expected s3_integrator revision 1, got ${local.revisions.s3_integrator}" + condition = local.revisions.s3_integrator == 10 + error_message = "Expected s3_integrator revision 10, got ${local.revisions.s3_integrator}" } assert { - condition = local.revisions.tempo_coordinator == 1 - error_message = "Expected tempo_coordinator revision 1, got ${local.revisions.tempo_coordinator}" + condition = local.revisions.tempo_coordinator == 11 + error_message = "Expected tempo_coordinator revision 11, got ${local.revisions.tempo_coordinator}" } assert { - condition = local.revisions.tempo_worker == 1 - error_message = "Expected tempo_worker revision 1, got ${local.revisions.tempo_worker}" + condition = local.revisions.tempo_worker == 12 + error_message = "Expected tempo_worker revision 12, got ${local.revisions.tempo_worker}" } assert { - condition = local.revisions.traefik == 1 - error_message = "Expected traefik revision 1, got ${local.revisions.traefik}" + condition = local.revisions.traefik == 13 + error_message = "Expected traefik revision 13, got ${local.revisions.traefik}" + } +} + +# --- Without a revision pin, the juju_charm datasource determines the revision --- + +run "no_pin_uses_datasource" { + command = plan + + assert { + condition = local.revisions.alertmanager == data.juju_charm.alertmanager_info.revision + error_message = "alertmanager revision should come from datasource when no pin is set" + } + + assert { + condition = local.revisions.catalogue == data.juju_charm.catalogue_info.revision + error_message = "catalogue revision should come from datasource when no pin is set" + } + + assert { + condition = local.revisions.grafana == data.juju_charm.grafana_info.revision + error_message = "grafana revision should come from datasource when no pin is set" + } + + assert { + condition = local.revisions.loki_coordinator == data.juju_charm.loki_coordinator_info.revision + error_message = "loki_coordinator revision should come from datasource when no pin is set" + } + + assert { + condition = local.revisions.loki_worker == data.juju_charm.loki_worker_info.revision + error_message = "loki_worker revision should come from datasource when no pin is set" + } + + assert { + condition = local.revisions.mimir_coordinator == data.juju_charm.mimir_coordinator_info.revision + error_message = "mimir_coordinator revision should come from datasource when no pin is set" + } + + assert { + condition = local.revisions.mimir_worker == data.juju_charm.mimir_worker_info.revision + error_message = "mimir_worker revision should come from datasource when no pin is set" + } + + assert { + condition = local.revisions.otelcol == data.juju_charm.otelcol_info.revision + error_message = "otelcol revision should come from datasource when no pin is set" + } + + assert { + condition = local.revisions.ssc == data.juju_charm.ssc_info.revision + error_message = "ssc revision should come from datasource when no pin is set" + } + + assert { + condition = local.revisions.s3_integrator == data.juju_charm.s3_integrator_info.revision + error_message = "s3_integrator revision should come from datasource when no pin is set" + } + + assert { + condition = local.revisions.tempo_coordinator == data.juju_charm.tempo_coordinator_info.revision + error_message = "tempo_coordinator revision should come from datasource when no pin is set" + } + + assert { + condition = local.revisions.tempo_worker == data.juju_charm.tempo_worker_info.revision + error_message = "tempo_worker revision should come from datasource when no pin is set" + } + + assert { + condition = local.revisions.traefik == data.juju_charm.traefik_info.revision + error_message = "traefik revision should come from datasource when no pin is set" } } diff --git a/terraform/cos/upgrades.tf b/terraform/cos/upgrades.tf index 40bbde6b..429bcaa4 100644 --- a/terraform/cos/upgrades.tf +++ b/terraform/cos/upgrades.tf @@ -1,8 +1,5 @@ # -------------- # CharmHub API -------------- # -# TODO: Add a utest to assert that a user revision pin is respected and doesn't get overridden by the juju-charm datasource. -# TODO: assert that if a user doesn't provide a revision pin then the juju-charm datasource is used to determine the revision. -# TODO: We want one per component to avoid mistakes not applied to all components. data "juju_charm" "alertmanager_info" { charm = "alertmanager-k8s" channel = local.channels.alertmanager diff --git a/terraform/cos/variables.tf b/terraform/cos/variables.tf index cad34b28..3a337536 100644 --- a/terraform/cos/variables.tf +++ b/terraform/cos/variables.tf @@ -235,7 +235,6 @@ variable "opentelemetry_collector" { description = "Application configuration for OpenTelemetry Collector. For more details: https://registry.terraform.io/providers/juju/juju/latest/docs/resources/application" } - variable "ssc" { type = object({ app_name = optional(string, "ca") From 3a8326f9df15809d45b3a3d82615c727a7b85485 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Mon, 20 Apr 2026 16:08:44 -0400 Subject: [PATCH 08/10] chore --- terraform/cos-lite/upgrades.tf | 2 ++ 1 file changed, 2 insertions(+) diff --git a/terraform/cos-lite/upgrades.tf b/terraform/cos-lite/upgrades.tf index 0150362d..1d1d0587 100644 --- a/terraform/cos-lite/upgrades.tf +++ b/terraform/cos-lite/upgrades.tf @@ -1,3 +1,5 @@ +# -------------- # CharmHub API -------------- # + data "juju_charm" "alertmanager_info" { charm = "alertmanager-k8s" channel = local.channels.alertmanager From 10d37fa10df05d81a96877897bf99bae6343a6c5 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Tue, 21 Apr 2026 14:54:51 -0400 Subject: [PATCH 09/10] chore --- terraform/cos-lite/locals.tf | 18 ++++++++++++------ terraform/cos-lite/upgrades.tf | 2 +- terraform/cos-lite/variables.tf | 2 -- terraform/cos/locals.tf | 25 +++++++++++++++++-------- terraform/cos/upgrades.tf | 4 ++-- terraform/cos/variables.tf | 3 --- 6 files changed, 32 insertions(+), 22 deletions(-) diff --git a/terraform/cos-lite/locals.tf b/terraform/cos-lite/locals.tf index e1204dd0..ff173cc1 100644 --- a/terraform/cos-lite/locals.tf +++ b/terraform/cos-lite/locals.tf @@ -1,12 +1,18 @@ locals { tls_termination = var.external_certificates_offer_url != null ? true : false + traefik_base = "ubuntu@20.04" tracks = { - alertmanager = "0.31" - catalogue = "3.0" - grafana = "12.4" - loki = "3.7" - prometheus = "3.10" - ssc = "latest" + alertmanager = "dev" + catalogue = "dev" + grafana = "dev" + loki = "dev" + prometheus = "dev" + # alertmanager = "0.31" + # catalogue = "3.0" + # grafana = "12.4" + # loki = "3.7" + # prometheus = "3.10" + ssc = "1" traefik = "latest" } channels = { diff --git a/terraform/cos-lite/upgrades.tf b/terraform/cos-lite/upgrades.tf index 1d1d0587..dade7e62 100644 --- a/terraform/cos-lite/upgrades.tf +++ b/terraform/cos-lite/upgrades.tf @@ -39,5 +39,5 @@ data "juju_charm" "ssc_info" { data "juju_charm" "traefik_info" { charm = "traefik-k8s" channel = local.channels.traefik - base = var.base + base = local.traefik_base } diff --git a/terraform/cos-lite/variables.tf b/terraform/cos-lite/variables.tf index 40176124..0856498c 100644 --- a/terraform/cos-lite/variables.tf +++ b/terraform/cos-lite/variables.tf @@ -134,7 +134,6 @@ variable "prometheus" { variable "ssc" { type = object({ app_name = optional(string, "ca") - channel = optional(string, "1/stable") config = optional(map(string), {}) constraints = optional(string, "arch=amd64") revision = optional(number, null) @@ -148,7 +147,6 @@ variable "ssc" { variable "traefik" { type = object({ app_name = optional(string, "traefik") - channel = optional(string, "latest/stable") config = optional(map(string), {}) constraints = optional(string, "arch=amd64") revision = optional(number, null) diff --git a/terraform/cos/locals.tf b/terraform/cos/locals.tf index bae1f726..3a012a80 100644 --- a/terraform/cos/locals.tf +++ b/terraform/cos/locals.tf @@ -1,16 +1,25 @@ locals { clouds = ["aws", "self-managed"] # list of k8s clouds where this COS module can be deployed. tls_termination = var.external_certificates_offer_url != null ? true : false + traefik_base = "ubuntu@20.04" tracks = { - alertmanager = "0.31" - catalogue = "3.0" - grafana = "12.4" - loki = "3.7" - mimir = "3.0" - otelcol = "0.130" + alertmanager = "dev" + catalogue = "dev" + grafana = "dev" + loki = "dev" + mimir = "dev" + otelcol = "dev" + tempo = "dev" + + # alertmanager = "0.31" + # catalogue = "3.0" + # grafana = "12.4" + # loki = "3.7" + # mimir = "3.0" + # otelcol = "0.130" s3_integrator = "2" - ssc = "latest" - tempo = "2.10" + ssc = "1" + # tempo = "2.10" traefik = "latest" } channels = { diff --git a/terraform/cos/upgrades.tf b/terraform/cos/upgrades.tf index 429bcaa4..df3d2028 100644 --- a/terraform/cos/upgrades.tf +++ b/terraform/cos/upgrades.tf @@ -67,7 +67,7 @@ data "juju_charm" "ssc_info" { } data "juju_charm" "s3_integrator_info" { - charm = "s3-integrator-k8s" + charm = "s3-integrator" channel = local.channels.s3_integrator base = var.base } @@ -75,5 +75,5 @@ data "juju_charm" "s3_integrator_info" { data "juju_charm" "traefik_info" { charm = "traefik-k8s" channel = local.channels.traefik - base = var.base + base = local.traefik_base } diff --git a/terraform/cos/variables.tf b/terraform/cos/variables.tf index 3a337536..6e1d3ba9 100644 --- a/terraform/cos/variables.tf +++ b/terraform/cos/variables.tf @@ -238,7 +238,6 @@ variable "opentelemetry_collector" { variable "ssc" { type = object({ app_name = optional(string, "ca") - channel = optional(string, "1/stable") config = optional(map(string), {}) constraints = optional(string, "arch=amd64") revision = optional(number, null) @@ -251,7 +250,6 @@ variable "ssc" { variable "s3_integrator" { type = object({ - channel = optional(string, "2/edge") config = optional(map(string), {}) constraints = optional(string, "arch=amd64") revision = optional(number, null) @@ -304,7 +302,6 @@ variable "tempo_worker" { variable "traefik" { type = object({ app_name = optional(string, "traefik") - channel = optional(string, "latest/stable") config = optional(map(string), {}) constraints = optional(string, "arch=amd64") revision = optional(number, null) From 3c427b10b5cca91fab06f0b919e9f347b2af8a9b Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Tue, 21 Apr 2026 15:03:34 -0400 Subject: [PATCH 10/10] chore --- terraform/cos-lite/README.md | 4 ++-- terraform/cos-lite/locals.tf | 6 +++--- terraform/cos/README.md | 6 +++--- terraform/cos/locals.tf | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/terraform/cos-lite/README.md b/terraform/cos-lite/README.md index e1e3b4ac..63f57131 100644 --- a/terraform/cos-lite/README.md +++ b/terraform/cos-lite/README.md @@ -37,8 +37,8 @@ This is a Terraform module facilitating the deployment of the COS Lite solution, | [model\_uuid](#input\_model\_uuid) | Reference to an existing model resource or data source for the model to deploy to | `string` | n/a | yes | | [prometheus](#input\_prometheus) | Application configuration for Prometheus. For more details: https://registry.terraform.io/providers/juju/juju/latest/docs/resources/application |
object({
app_name = optional(string, "prometheus")
config = optional(map(string), {})
constraints = optional(string, "arch=amd64")
revision = optional(number, null)
storage_directives = optional(map(string), {})
units = optional(number, 1)
})
| `{}` | no | | [risk](#input\_risk) | Risk level that the applications are (unless overwritten by individual channels) deployed from | `string` | `"edge"` | no | -| [ssc](#input\_ssc) | Application configuration for self-signed-certificates. For more details: https://registry.terraform.io/providers/juju/juju/latest/docs/resources/application |
object({
app_name = optional(string, "ca")
channel = optional(string, "1/stable")
config = optional(map(string), {})
constraints = optional(string, "arch=amd64")
revision = optional(number, null)
storage_directives = optional(map(string), {})
units = optional(number, 1)
})
| `{}` | no | -| [traefik](#input\_traefik) | Application configuration for Traefik. For more details: https://registry.terraform.io/providers/juju/juju/latest/docs/resources/application |
object({
app_name = optional(string, "traefik")
channel = optional(string, "latest/stable")
config = optional(map(string), {})
constraints = optional(string, "arch=amd64")
revision = optional(number, null)
storage_directives = optional(map(string), {})
units = optional(number, 1)
})
| `{}` | no | +| [ssc](#input\_ssc) | Application configuration for self-signed-certificates. For more details: https://registry.terraform.io/providers/juju/juju/latest/docs/resources/application |
object({
app_name = optional(string, "ca")
config = optional(map(string), {})
constraints = optional(string, "arch=amd64")
revision = optional(number, null)
storage_directives = optional(map(string), {})
units = optional(number, 1)
})
| `{}` | no | +| [traefik](#input\_traefik) | Application configuration for Traefik. For more details: https://registry.terraform.io/providers/juju/juju/latest/docs/resources/application |
object({
app_name = optional(string, "traefik")
config = optional(map(string), {})
constraints = optional(string, "arch=amd64")
revision = optional(number, null)
storage_directives = optional(map(string), {})
units = optional(number, 1)
})
| `{}` | no | ## Outputs diff --git a/terraform/cos-lite/locals.tf b/terraform/cos-lite/locals.tf index ff173cc1..a3907ac0 100644 --- a/terraform/cos-lite/locals.tf +++ b/terraform/cos-lite/locals.tf @@ -1,6 +1,6 @@ locals { tls_termination = var.external_certificates_offer_url != null ? true : false - traefik_base = "ubuntu@20.04" + traefik_base = "ubuntu@20.04" tracks = { alertmanager = "dev" catalogue = "dev" @@ -12,8 +12,8 @@ locals { # grafana = "12.4" # loki = "3.7" # prometheus = "3.10" - ssc = "1" - traefik = "latest" + ssc = "1" + traefik = "latest" } channels = { alertmanager = "${local.tracks.alertmanager}/${var.risk}" diff --git a/terraform/cos/README.md b/terraform/cos/README.md index e9ab7ac8..68e2330d 100644 --- a/terraform/cos/README.md +++ b/terraform/cos/README.md @@ -51,13 +51,13 @@ This is a Terraform module facilitating the deployment of the COS solution, usin | [risk](#input\_risk) | Risk level that the applications are (unless overwritten by individual channels) deployed from | `string` | `"edge"` | no | | [s3\_access\_key](#input\_s3\_access\_key) | S3 access-key credential | `string` | n/a | yes | | [s3\_endpoint](#input\_s3\_endpoint) | S3 endpoint | `string` | n/a | yes | -| [s3\_integrator](#input\_s3\_integrator) | Application configuration for all S3-integrators in coordinated workers. For more details: https://registry.terraform.io/providers/juju/juju/latest/docs/resources/application |
object({
channel = optional(string, "2/edge")
config = optional(map(string), {})
constraints = optional(string, "arch=amd64")
revision = optional(number, null)
storage_directives = optional(map(string), {})
units = optional(number, 1)
})
| `{}` | no | +| [s3\_integrator](#input\_s3\_integrator) | Application configuration for all S3-integrators in coordinated workers. For more details: https://registry.terraform.io/providers/juju/juju/latest/docs/resources/application |
object({
config = optional(map(string), {})
constraints = optional(string, "arch=amd64")
revision = optional(number, null)
storage_directives = optional(map(string), {})
units = optional(number, 1)
})
| `{}` | no | | [s3\_secret\_key](#input\_s3\_secret\_key) | S3 secret-key credential | `string` | n/a | yes | -| [ssc](#input\_ssc) | Application configuration for Self-signed-certificates. For more details: https://registry.terraform.io/providers/juju/juju/latest/docs/resources/application |
object({
app_name = optional(string, "ca")
channel = optional(string, "1/stable")
config = optional(map(string), {})
constraints = optional(string, "arch=amd64")
revision = optional(number, null)
storage_directives = optional(map(string), {})
units = optional(number, 1)
})
| `{}` | no | +| [ssc](#input\_ssc) | Application configuration for Self-signed-certificates. For more details: https://registry.terraform.io/providers/juju/juju/latest/docs/resources/application |
object({
app_name = optional(string, "ca")
config = optional(map(string), {})
constraints = optional(string, "arch=amd64")
revision = optional(number, null)
storage_directives = optional(map(string), {})
units = optional(number, 1)
})
| `{}` | no | | [tempo\_bucket](#input\_tempo\_bucket) | Tempo bucket name | `string` | `"tempo"` | no | | [tempo\_coordinator](#input\_tempo\_coordinator) | Application configuration for Tempo Coordinator. For more details: https://registry.terraform.io/providers/juju/juju/latest/docs/resources/application |
object({
config = optional(map(string), {})
constraints = optional(string, "arch=amd64")
revision = optional(number, null)
storage_directives = optional(map(string), {})
units = optional(number, 3)
})
| `{}` | no | | [tempo\_worker](#input\_tempo\_worker) | Application configuration for all Tempo workers. For more details: https://registry.terraform.io/providers/juju/juju/latest/docs/resources/application |
object({
querier_config = optional(map(string), {})
query_frontend_config = optional(map(string), {})
ingester_config = optional(map(string), {})
distributor_config = optional(map(string), {})
compactor_config = optional(map(string), {})
metrics_generator_config = optional(map(string), {})
constraints = optional(string, "arch=amd64")
revision = optional(number, null)
compactor_worker_storage_directives = optional(map(string), {})
distributor_worker_storage_directives = optional(map(string), {})
ingester_worker_storage_directives = optional(map(string), {})
metrics_generator_worker_storage_directives = optional(map(string), {})
querier_worker_storage_directives = optional(map(string), {})
query_frontend_worker_storage_directives = optional(map(string), {})
compactor_units = optional(number, 3)
distributor_units = optional(number, 3)
ingester_units = optional(number, 3)
metrics_generator_units = optional(number, 3)
querier_units = optional(number, 3)
query_frontend_units = optional(number, 3)
})
| `{}` | no | -| [traefik](#input\_traefik) | Application configuration for Traefik. For more details: https://registry.terraform.io/providers/juju/juju/latest/docs/resources/application |
object({
app_name = optional(string, "traefik")
channel = optional(string, "latest/stable")
config = optional(map(string), {})
constraints = optional(string, "arch=amd64")
revision = optional(number, null)
storage_directives = optional(map(string), {})
units = optional(number, 1)
})
| `{}` | no | +| [traefik](#input\_traefik) | Application configuration for Traefik. For more details: https://registry.terraform.io/providers/juju/juju/latest/docs/resources/application |
object({
app_name = optional(string, "traefik")
config = optional(map(string), {})
constraints = optional(string, "arch=amd64")
revision = optional(number, null)
storage_directives = optional(map(string), {})
units = optional(number, 1)
})
| `{}` | no | ## Outputs diff --git a/terraform/cos/locals.tf b/terraform/cos/locals.tf index 3a012a80..526736a5 100644 --- a/terraform/cos/locals.tf +++ b/terraform/cos/locals.tf @@ -20,7 +20,7 @@ locals { s3_integrator = "2" ssc = "1" # tempo = "2.10" - traefik = "latest" + traefik = "latest" } channels = { alertmanager = "${local.tracks.alertmanager}/${var.risk}"