From 6e90c840dfadb5567362aff8a809aaaf6bccec66 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Wed, 3 Jun 2026 09:06:03 -0400 Subject: [PATCH 01/41] feat: COS 3.0 --- terraform/cos-lite/README.md | 16 ++--- terraform/cos-lite/applications.tf | 15 ++--- terraform/cos-lite/locals.tf | 13 ++-- terraform/cos-lite/variables.tf | 2 +- terraform/cos/README.md | 20 +++--- terraform/cos/applications.tf | 19 +++--- terraform/cos/locals.tf | 22 ++----- terraform/cos/variables.tf | 2 +- .../test_upgrade_cos_tls_external.py | 13 ++++ .../integration/cos/tls_external/track-3.0.tf | 64 +++++++++++++++++++ .../cos/tls_full/test_upgrade_cos_tls_full.py | 13 ++++ tests/integration/cos/tls_full/track-3.0.tf | 64 +++++++++++++++++++ .../test_upgrade_cos_tls_internal.py | 11 ++++ .../integration/cos/tls_internal/track-3.0.tf | 48 ++++++++++++++ .../cos/tls_none/test_upgrade_cos_tls_none.py | 13 +++- tests/integration/cos/tls_none/track-3.0.tf | 48 ++++++++++++++ .../test_upgrade_cos_lite_tls_external.py | 12 ++++ .../cos_lite/tls_external/track-3.0.tf | 41 ++++++++++++ .../test_upgrade_cos_lite_tls_full.py | 12 ++++ .../cos_lite/tls_full/track-3.0.tf | 41 ++++++++++++ .../test_upgrade_cos_lite_tls_internal.py | 10 +++ .../cos_lite/tls_internal/track-3.0.tf | 25 ++++++++ .../test_upgrade_cos_lite_tls_none.py | 10 +++ .../cos_lite/tls_none/track-3.0.tf | 25 ++++++++ 24 files changed, 498 insertions(+), 61 deletions(-) create mode 100644 tests/integration/cos/tls_external/track-3.0.tf create mode 100644 tests/integration/cos/tls_full/track-3.0.tf create mode 100644 tests/integration/cos/tls_internal/track-3.0.tf create mode 100644 tests/integration/cos/tls_none/track-3.0.tf create mode 100644 tests/integration/cos_lite/tls_external/track-3.0.tf create mode 100644 tests/integration/cos_lite/tls_full/track-3.0.tf create mode 100644 tests/integration/cos_lite/tls_internal/track-3.0.tf create mode 100644 tests/integration/cos_lite/tls_none/track-3.0.tf diff --git a/terraform/cos-lite/README.md b/terraform/cos-lite/README.md index edd5315a..2fea19be 100644 --- a/terraform/cos-lite/README.md +++ b/terraform/cos-lite/README.md @@ -14,20 +14,20 @@ This is a Terraform module facilitating the deployment of the COS Lite solution, | Name | Source | Version | |------|--------|---------| -| [alertmanager](#module\_alertmanager) | git::https://github.com/canonical/alertmanager-k8s-operator//terraform | n/a | -| [catalogue](#module\_catalogue) | git::https://github.com/canonical/catalogue-k8s-operator//terraform | n/a | -| [grafana](#module\_grafana) | git::https://github.com/canonical/grafana-k8s-operator//terraform | n/a | -| [loki](#module\_loki) | git::https://github.com/canonical/loki-k8s-operator//terraform | n/a | -| [prometheus](#module\_prometheus) | git::https://github.com/canonical/prometheus-k8s-operator//terraform | n/a | -| [ssc](#module\_ssc) | git::https://github.com/canonical/self-signed-certificates-operator//terraform | 0216698683a757a44d02e98c003a19aa7ffcfb63 | -| [traefik](#module\_traefik) | git::https://github.com/canonical/traefik-k8s-operator//terraform | n/a | +| [alertmanager](#module\_alertmanager) | git::https://github.com/canonical/alertmanager-k8s-operator//terraform | tf-0.31.0 | +| [catalogue](#module\_catalogue) | git::https://github.com/canonical/catalogue-k8s-operator//terraform | tf-3.0.0 | +| [grafana](#module\_grafana) | git::https://github.com/canonical/grafana-k8s-operator//terraform | tf-12.4.0 | +| [loki](#module\_loki) | git::https://github.com/canonical/loki-k8s-operator//terraform | tf-3.7.0 | +| [prometheus](#module\_prometheus) | git::https://github.com/canonical/prometheus-k8s-operator//terraform | tf-3.11.0 | +| [ssc](#module\_ssc) | git::https://github.com/canonical/self-signed-certificates-operator//terraform | rev653 | +| [traefik](#module\_traefik) | git::https://github.com/canonical/traefik-k8s-operator//terraform | rev301 | ## Inputs | 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@24.04. Check Charmhub for per-charm base support. | `string` | `"ubuntu@24.04"` | no | +| [base](#input\_base) | The operating system on which to deploy. E.g. ubuntu@24.04. Check Charmhub for per-charm base support. | `string` | `"ubuntu@26.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-lite/applications.tf b/terraform/cos-lite/applications.tf index adfbffa2..c1a3af3b 100644 --- a/terraform/cos-lite/applications.tf +++ b/terraform/cos-lite/applications.tf @@ -1,5 +1,5 @@ module "alertmanager" { - source = "git::https://github.com/canonical/alertmanager-k8s-operator//terraform" + source = "git::https://github.com/canonical/alertmanager-k8s-operator//terraform?ref=tf-0.31.0" app_name = var.alertmanager.app_name channel = local.channels.alertmanager @@ -12,7 +12,7 @@ module "alertmanager" { } module "catalogue" { - source = "git::https://github.com/canonical/catalogue-k8s-operator//terraform" + source = "git::https://github.com/canonical/catalogue-k8s-operator//terraform?ref=tf-3.0.0" app_name = var.catalogue.app_name channel = local.channels.catalogue @@ -25,7 +25,7 @@ module "catalogue" { } module "grafana" { - source = "git::https://github.com/canonical/grafana-k8s-operator//terraform" + source = "git::https://github.com/canonical/grafana-k8s-operator//terraform?ref=tf-12.4.0" app_name = var.grafana.app_name channel = local.channels.grafana @@ -39,7 +39,7 @@ module "grafana" { } module "loki" { - source = "git::https://github.com/canonical/loki-k8s-operator//terraform" + source = "git::https://github.com/canonical/loki-k8s-operator//terraform?ref=tf-3.7.0" app_name = var.loki.app_name channel = local.channels.loki @@ -52,7 +52,7 @@ module "loki" { } module "prometheus" { - source = "git::https://github.com/canonical/prometheus-k8s-operator//terraform" + source = "git::https://github.com/canonical/prometheus-k8s-operator//terraform?ref=tf-3.11.0" app_name = var.prometheus.app_name channel = local.channels.prometheus @@ -65,8 +65,7 @@ module "prometheus" { } module "ssc" { - # The TF module bumped the Juju provider to v2 after this commit, pin for compatibility with provider v1 - source = "git::https://github.com/canonical/self-signed-certificates-operator//terraform?ref=0216698683a757a44d02e98c003a19aa7ffcfb63" + source = "git::https://github.com/canonical/self-signed-certificates-operator//terraform?ref=rev653" count = var.internal_tls ? 1 : 0 app_name = var.ssc.app_name @@ -79,7 +78,7 @@ module "ssc" { } module "traefik" { - source = "git::https://github.com/canonical/traefik-k8s-operator//terraform" + source = "git::https://github.com/canonical/traefik-k8s-operator//terraform?ref=rev301" count = local.traefik_enabled ? 1 : 0 app_name = var.traefik.app_name diff --git a/terraform/cos-lite/locals.tf b/terraform/cos-lite/locals.tf index e86877ad..0423b192 100644 --- a/terraform/cos-lite/locals.tf +++ b/terraform/cos-lite/locals.tf @@ -4,13 +4,12 @@ locals { traefik_enabled = local.reverse_proxy_enabled traefik_base = "ubuntu@20.04" tracks = { - alertmanager = "dev" - catalogue = "dev" - grafana = "dev" - loki = "dev" - prometheus = "dev" - - ssc = "1" + alertmanager = "0.31" + catalogue = "3.0" + grafana = "12.4" + loki = "3.7" + prometheus = "3.11" + ssc = "1" traefik = "latest" } channels = { diff --git a/terraform/cos-lite/variables.tf b/terraform/cos-lite/variables.tf index c23a2515..965f2959 100644 --- a/terraform/cos-lite/variables.tf +++ b/terraform/cos-lite/variables.tf @@ -13,7 +13,7 @@ variable "risk" { variable "base" { description = "The operating system on which to deploy. E.g. ubuntu@24.04. Check Charmhub for per-charm base support." - default = "ubuntu@24.04" + default = "ubuntu@26.04" type = string } diff --git a/terraform/cos/README.md b/terraform/cos/README.md index 6e60e060..fc7ba096 100644 --- a/terraform/cos/README.md +++ b/terraform/cos/README.md @@ -17,15 +17,15 @@ This is a Terraform module facilitating the deployment of the COS solution, usin | Name | Source | Version | |------|--------|---------| -| [alertmanager](#module\_alertmanager) | git::https://github.com/canonical/alertmanager-k8s-operator//terraform | n/a | -| [catalogue](#module\_catalogue) | git::https://github.com/canonical/catalogue-k8s-operator//terraform | n/a | -| [grafana](#module\_grafana) | git::https://github.com/canonical/grafana-k8s-operator//terraform | n/a | -| [loki](#module\_loki) | git::https://github.com/canonical/loki-operators//terraform | n/a | -| [mimir](#module\_mimir) | git::https://github.com/canonical/mimir-operators//terraform | n/a | -| [opentelemetry\_collector](#module\_opentelemetry\_collector) | git::https://github.com/canonical/opentelemetry-collector-k8s-operator//terraform | n/a | -| [ssc](#module\_ssc) | git::https://github.com/canonical/self-signed-certificates-operator//terraform | 0216698683a757a44d02e98c003a19aa7ffcfb63 | -| [tempo](#module\_tempo) | git::https://github.com/canonical/tempo-operators//terraform | n/a | -| [traefik](#module\_traefik) | git::https://github.com/canonical/traefik-k8s-operator//terraform | n/a | +| [alertmanager](#module\_alertmanager) | git::https://github.com/canonical/alertmanager-k8s-operator//terraform | tf-0.31.0 | +| [catalogue](#module\_catalogue) | git::https://github.com/canonical/catalogue-k8s-operator//terraform | tf-3.0.0 | +| [grafana](#module\_grafana) | git::https://github.com/canonical/grafana-k8s-operator//terraform | tf-12.4.0 | +| [loki](#module\_loki) | git::https://github.com/canonical/loki-operators//terraform | tf-3.7.0 | +| [mimir](#module\_mimir) | git::https://github.com/canonical/mimir-operators//terraform | tf-2.17.0 | +| [opentelemetry\_collector](#module\_opentelemetry\_collector) | git::https://github.com/canonical/opentelemetry-collector-k8s-operator//terraform | tf-0.130.0 | +| [ssc](#module\_ssc) | git::https://github.com/canonical/self-signed-certificates-operator//terraform | rev653 | +| [tempo](#module\_tempo) | git::https://github.com/canonical/tempo-operators//terraform | tf-2.10.0 | +| [traefik](#module\_traefik) | git::https://github.com/canonical/traefik-k8s-operator//terraform | rev301 | ## Inputs @@ -33,7 +33,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@24.04. Check Charmhub for per-charm base support. | `string` | `"ubuntu@24.04"` | no | +| [base](#input\_base) | The operating system on which to deploy. E.g. ubuntu@24.04. Check Charmhub for per-charm base support. | `string` | `"ubuntu@26.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 | diff --git a/terraform/cos/applications.tf b/terraform/cos/applications.tf index 33320a05..ba7c943c 100644 --- a/terraform/cos/applications.tf +++ b/terraform/cos/applications.tf @@ -1,5 +1,5 @@ module "alertmanager" { - source = "git::https://github.com/canonical/alertmanager-k8s-operator//terraform" + source = "git::https://github.com/canonical/alertmanager-k8s-operator//terraform?ref=tf-0.31.0" app_name = var.alertmanager.app_name channel = local.channels.alertmanager @@ -12,7 +12,7 @@ module "alertmanager" { } module "catalogue" { - source = "git::https://github.com/canonical/catalogue-k8s-operator//terraform" + source = "git::https://github.com/canonical/catalogue-k8s-operator//terraform?ref=tf-3.0.0" app_name = var.catalogue.app_name channel = local.channels.catalogue @@ -25,7 +25,7 @@ module "catalogue" { } module "grafana" { - source = "git::https://github.com/canonical/grafana-k8s-operator//terraform" + source = "git::https://github.com/canonical/grafana-k8s-operator//terraform?ref=tf-12.4.0" app_name = var.grafana.app_name channel = local.channels.grafana @@ -39,7 +39,7 @@ module "grafana" { } module "loki" { - source = "git::https://github.com/canonical/loki-operators//terraform" + source = "git::https://github.com/canonical/loki-operators//terraform?ref=tf-3.7.0" anti_affinity = var.anti_affinity channel = local.channels.loki @@ -73,7 +73,7 @@ module "loki" { } module "mimir" { - source = "git::https://github.com/canonical/mimir-operators//terraform" + source = "git::https://github.com/canonical/mimir-operators//terraform?ref=tf-2.17.0" anti_affinity = var.anti_affinity channel = local.channels.mimir @@ -107,7 +107,7 @@ module "mimir" { } module "opentelemetry_collector" { - source = "git::https://github.com/canonical/opentelemetry-collector-k8s-operator//terraform" + source = "git::https://github.com/canonical/opentelemetry-collector-k8s-operator//terraform?ref=tf-0.130.0" app_name = var.opentelemetry_collector.app_name channel = local.channels.otelcol @@ -120,8 +120,7 @@ module "opentelemetry_collector" { } module "ssc" { - # The TF module bumped the Juju provider to v2 after this commit, pin for compatibility with provider v1 - source = "git::https://github.com/canonical/self-signed-certificates-operator//terraform?ref=0216698683a757a44d02e98c003a19aa7ffcfb63" + source = "git::https://github.com/canonical/self-signed-certificates-operator//terraform?ref=rev653" count = var.internal_tls ? 1 : 0 app_name = var.ssc.app_name @@ -134,7 +133,7 @@ module "ssc" { } module "tempo" { - source = "git::https://github.com/canonical/tempo-operators//terraform" + source = "git::https://github.com/canonical/tempo-operators//terraform?ref=tf-2.10.0" anti_affinity = var.anti_affinity channel = local.channels.tempo @@ -177,7 +176,7 @@ module "tempo" { } module "traefik" { - source = "git::https://github.com/canonical/traefik-k8s-operator//terraform" + source = "git::https://github.com/canonical/traefik-k8s-operator//terraform?ref=rev301" count = local.traefik_enabled ? 1 : 0 app_name = var.traefik.app_name diff --git a/terraform/cos/locals.tf b/terraform/cos/locals.tf index 6a0a8f68..991b2434 100644 --- a/terraform/cos/locals.tf +++ b/terraform/cos/locals.tf @@ -5,23 +5,15 @@ locals { traefik_enabled = local.reverse_proxy_enabled traefik_base = "ubuntu@20.04" tracks = { - 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" + alertmanager = "0.31" + catalogue = "3.0" + grafana = "12.4" + loki = "3.7" + mimir = "2.17" + otelcol = "0.130" s3_integrator = "2" ssc = "1" - # tempo = "2.10" + tempo = "2.10" traefik = "latest" } channels = { diff --git a/terraform/cos/variables.tf b/terraform/cos/variables.tf index 109b4404..ceb15541 100644 --- a/terraform/cos/variables.tf +++ b/terraform/cos/variables.tf @@ -13,7 +13,7 @@ variable "risk" { variable "base" { description = "The operating system on which to deploy. E.g. ubuntu@24.04. Check Charmhub for per-charm base support." - default = "ubuntu@24.04" + default = "ubuntu@26.04" type = string } diff --git a/tests/integration/cos/tls_external/test_upgrade_cos_tls_external.py b/tests/integration/cos/tls_external/test_upgrade_cos_tls_external.py index 33b46e17..febe59e5 100644 --- a/tests/integration/cos/tls_external/test_upgrade_cos_tls_external.py +++ b/tests/integration/cos/tls_external/test_upgrade_cos_tls_external.py @@ -11,6 +11,7 @@ from helpers import generic_assertions, no_errors_in_otelcol_logs TRACK_2_TF_FILE = Path(__file__).parent.resolve() / "track-2.tf" +TRACK_3_TF_FILE = Path(__file__).parent.resolve() / "track-3.0.tf" TRACK_DEV_TF_FILE = Path(__file__).parent.resolve() / "track-dev.tf" S3_ENDPOINT = { "s3_endpoint": os.getenv("S3_ENDPOINT"), @@ -35,6 +36,18 @@ def test_deploy_from_track_2( no_errors_in_otelcol_logs(cos_model) +def test_deploy_to_track_3( + tmp_path, tf_manager, ca_model: jubilant.Juju, cos_model: jubilant.Juju +): + # WHEN upgraded to track 3.0 + tf_manager.init(TRACK_3_TF_FILE) + tf_manager.apply(ca_model=ca_model.model, cos_model=cos_model.model, **S3_ENDPOINT) + + # THEN the model is upgraded and is healthy + generic_assertions(cos_model, ca_model, tmp_path) + no_errors_in_otelcol_logs(cos_model) + + def test_deploy_to_track_dev( tmp_path, tf_manager, ca_model: jubilant.Juju, cos_model: jubilant.Juju ): diff --git a/tests/integration/cos/tls_external/track-3.0.tf b/tests/integration/cos/tls_external/track-3.0.tf new file mode 100644 index 00000000..49681537 --- /dev/null +++ b/tests/integration/cos/tls_external/track-3.0.tf @@ -0,0 +1,64 @@ +terraform { + required_version = ">= 1.5" + required_providers { + juju = { + source = "juju/juju" + version = ">= 1.0" + } + } +} + +variable "cos_model" { + type = string +} + +variable "ca_model" { + type = string +} + +data "juju_model" "ca-model" { + name = var.ca_model + owner = "admin" +} + +data "juju_model" "cos-model" { + name = var.cos_model + owner = "admin" +} + +variable "s3_endpoint" { + type = string +} + +variable "s3_secret_key" { + type = string +} + +variable "s3_access_key" { + type = string +} + +module "ssc" { + source = "git::https://github.com/canonical/self-signed-certificates-operator//terraform" + model_uuid = data.juju_model.ca-model.uuid +} + +module "cos" { + source = "git::https://github.com/canonical/observability-stack//terraform/cos?ref=tf-cos-3.0.0" + model_uuid = data.juju_model.cos-model.uuid + risk = "edge" + internal_tls = false + external_certificates_offer_url = "admin/${var.ca_model}.certificates" + external_ca_cert_offer_url = "admin/${var.ca_model}.send-ca-cert" + + s3_endpoint = var.s3_endpoint + s3_secret_key = var.s3_secret_key + s3_access_key = var.s3_access_key + + loki_coordinator = { units = 1 } + loki_worker = { backend_units = 1, read_units = 1, write_units = 1 } + mimir_coordinator = { units = 1 } + mimir_worker = { backend_units = 1, read_units = 1, write_units = 1 } + tempo_coordinator = { units = 1 } + tempo_worker = { compactor_units = 1, distributor_units = 1, ingester_units = 1, metrics_generator_units = 1, querier_units = 1, query_frontend_units = 1 } +} diff --git a/tests/integration/cos/tls_full/test_upgrade_cos_tls_full.py b/tests/integration/cos/tls_full/test_upgrade_cos_tls_full.py index 9a48df79..7926c65f 100644 --- a/tests/integration/cos/tls_full/test_upgrade_cos_tls_full.py +++ b/tests/integration/cos/tls_full/test_upgrade_cos_tls_full.py @@ -11,6 +11,7 @@ from helpers import generic_assertions, no_errors_in_otelcol_logs TRACK_2_TF_FILE = Path(__file__).parent.resolve() / "track-2.tf" +TRACK_3_TF_FILE = Path(__file__).parent.resolve() / "track-3.0.tf" TRACK_DEV_TF_FILE = Path(__file__).parent.resolve() / "track-dev.tf" S3_ENDPOINT = { "s3_endpoint": os.getenv("S3_ENDPOINT"), @@ -35,6 +36,18 @@ def test_deploy_from_track_2( no_errors_in_otelcol_logs(cos_model) +def test_deploy_to_track_3( + tmp_path, tf_manager, ca_model: jubilant.Juju, cos_model: jubilant.Juju +): + # WHEN upgraded to track 3.0 + tf_manager.init(TRACK_3_TF_FILE) + tf_manager.apply(ca_model=ca_model.model, cos_model=cos_model.model, **S3_ENDPOINT) + + # THEN the model is upgraded and is healthy + generic_assertions(cos_model, ca_model, tmp_path) + no_errors_in_otelcol_logs(cos_model) + + def test_deploy_to_track_dev( tmp_path, tf_manager, ca_model: jubilant.Juju, cos_model: jubilant.Juju ): diff --git a/tests/integration/cos/tls_full/track-3.0.tf b/tests/integration/cos/tls_full/track-3.0.tf new file mode 100644 index 00000000..2f457056 --- /dev/null +++ b/tests/integration/cos/tls_full/track-3.0.tf @@ -0,0 +1,64 @@ +terraform { + required_version = ">= 1.5" + required_providers { + juju = { + source = "juju/juju" + version = ">= 1.0" + } + } +} + +variable "cos_model" { + type = string +} + +variable "ca_model" { + type = string +} + +data "juju_model" "ca-model" { + name = var.ca_model + owner = "admin" +} + +data "juju_model" "cos-model" { + name = var.cos_model + owner = "admin" +} + +variable "s3_endpoint" { + type = string +} + +variable "s3_secret_key" { + type = string +} + +variable "s3_access_key" { + type = string +} + +module "ssc" { + source = "git::https://github.com/canonical/self-signed-certificates-operator//terraform" + model_uuid = data.juju_model.ca-model.uuid +} + +module "cos" { + source = "git::https://github.com/canonical/observability-stack//terraform/cos?ref=tf-cos-3.0.0" + model_uuid = data.juju_model.cos-model.uuid + risk = "edge" + internal_tls = true + external_certificates_offer_url = "admin/${var.ca_model}.certificates" + external_ca_cert_offer_url = "admin/${var.ca_model}.send-ca-cert" + + s3_endpoint = var.s3_endpoint + s3_secret_key = var.s3_secret_key + s3_access_key = var.s3_access_key + + loki_coordinator = { units = 1 } + loki_worker = { backend_units = 1, read_units = 1, write_units = 1 } + mimir_coordinator = { units = 1 } + mimir_worker = { backend_units = 1, read_units = 1, write_units = 1 } + tempo_coordinator = { units = 1 } + tempo_worker = { compactor_units = 1, distributor_units = 1, ingester_units = 1, metrics_generator_units = 1, querier_units = 1, query_frontend_units = 1 } +} diff --git a/tests/integration/cos/tls_internal/test_upgrade_cos_tls_internal.py b/tests/integration/cos/tls_internal/test_upgrade_cos_tls_internal.py index c0425362..dc0116f2 100644 --- a/tests/integration/cos/tls_internal/test_upgrade_cos_tls_internal.py +++ b/tests/integration/cos/tls_internal/test_upgrade_cos_tls_internal.py @@ -11,6 +11,7 @@ from helpers import generic_assertions, no_errors_in_otelcol_logs TRACK_2_TF_FILE = Path(__file__).parent.resolve() / "track-2.tf" +TRACK_3_TF_FILE = Path(__file__).parent.resolve() / "track-3.0.tf" TRACK_DEV_TF_FILE = Path(__file__).parent.resolve() / "track-dev.tf" S3_ENDPOINT = { "s3_endpoint": os.getenv("S3_ENDPOINT"), @@ -33,6 +34,16 @@ def test_deploy_from_track_2(tf_manager, cos_model: jubilant.Juju): no_errors_in_otelcol_logs(cos_model) +def test_deploy_to_track_3(tf_manager, cos_model: jubilant.Juju): + # WHEN upgraded to track 3.0 + tf_manager.init(TRACK_3_TF_FILE) + tf_manager.apply(model=cos_model.model, **S3_ENDPOINT) + + # THEN the model is upgraded and is healthy + generic_assertions(cos_model) + no_errors_in_otelcol_logs(cos_model) + + def test_deploy_to_track_dev(tf_manager, cos_model: jubilant.Juju): # WHEN upgraded to track dev tf_manager.init(TRACK_DEV_TF_FILE) diff --git a/tests/integration/cos/tls_internal/track-3.0.tf b/tests/integration/cos/tls_internal/track-3.0.tf new file mode 100644 index 00000000..920a1916 --- /dev/null +++ b/tests/integration/cos/tls_internal/track-3.0.tf @@ -0,0 +1,48 @@ +terraform { + required_version = ">= 1.5" + required_providers { + juju = { + source = "juju/juju" + version = ">= 1.0" + } + } +} + +variable "model" { + type = string +} + +data "juju_model" "model" { + name = var.model + owner = "admin" +} + +variable "s3_endpoint" { + type = string +} + +variable "s3_secret_key" { + type = string +} + +variable "s3_access_key" { + type = string +} + +module "cos" { + source = "git::https://github.com/canonical/observability-stack//terraform/cos?ref=tf-cos-3.0.0" + model_uuid = data.juju_model.model.uuid + risk = "edge" + internal_tls = true + + s3_endpoint = var.s3_endpoint + s3_secret_key = var.s3_secret_key + s3_access_key = var.s3_access_key + + loki_coordinator = { units = 1 } + loki_worker = { backend_units = 1, read_units = 1, write_units = 1 } + mimir_coordinator = { units = 1 } + mimir_worker = { backend_units = 1, read_units = 1, write_units = 1 } + tempo_coordinator = { units = 1 } + tempo_worker = { compactor_units = 1, distributor_units = 1, ingester_units = 1, metrics_generator_units = 1, querier_units = 1, query_frontend_units = 1 } +} diff --git a/tests/integration/cos/tls_none/test_upgrade_cos_tls_none.py b/tests/integration/cos/tls_none/test_upgrade_cos_tls_none.py index 7f33b146..ebbe37d9 100644 --- a/tests/integration/cos/tls_none/test_upgrade_cos_tls_none.py +++ b/tests/integration/cos/tls_none/test_upgrade_cos_tls_none.py @@ -11,6 +11,7 @@ from helpers import generic_assertions, no_errors_in_otelcol_logs TRACK_2_TF_FILE = Path(__file__).parent.resolve() / "track-2.tf" +TRACK_3_TF_FILE = Path(__file__).parent.resolve() / "track-3.0.tf" TRACK_DEV_TF_FILE = Path(__file__).parent.resolve() / "track-dev.tf" S3_ENDPOINT = { "s3_endpoint": os.getenv("S3_ENDPOINT"), @@ -33,6 +34,16 @@ def test_deploy_from_track_2(tf_manager, cos_model: jubilant.Juju): no_errors_in_otelcol_logs(cos_model) +def test_deploy_to_track_3(tf_manager, cos_model: jubilant.Juju): + # WHEN upgraded to track 3.0 + tf_manager.init(TRACK_3_TF_FILE) + tf_manager.apply(model=cos_model.model, **S3_ENDPOINT) + + # THEN the model is upgraded and is healthy + generic_assertions(cos_model) + no_errors_in_otelcol_logs(cos_model) + + def test_deploy_to_track_dev(tf_manager, cos_model: jubilant.Juju): # WHEN upgraded to track dev tf_manager.init(TRACK_DEV_TF_FILE) @@ -40,4 +51,4 @@ def test_deploy_to_track_dev(tf_manager, cos_model: jubilant.Juju): # THEN the model is upgraded and is healthy generic_assertions(cos_model) - no_errors_in_otelcol_logs(cos_model) + no_errors_in_otelcol_logs(cos_model) \ No newline at end of file diff --git a/tests/integration/cos/tls_none/track-3.0.tf b/tests/integration/cos/tls_none/track-3.0.tf new file mode 100644 index 00000000..d387e924 --- /dev/null +++ b/tests/integration/cos/tls_none/track-3.0.tf @@ -0,0 +1,48 @@ +terraform { + required_version = ">= 1.5" + required_providers { + juju = { + source = "juju/juju" + version = ">= 1.0" + } + } +} + +variable "model" { + type = string +} + +data "juju_model" "model" { + name = var.model + owner = "admin" +} + +variable "s3_endpoint" { + type = string +} + +variable "s3_secret_key" { + type = string +} + +variable "s3_access_key" { + type = string +} + +module "cos" { + source = "git::https://github.com/canonical/observability-stack//terraform/cos?ref=tf-cos-3.0.0" + model_uuid = data.juju_model.model.uuid + risk = "edge" + internal_tls = false + + s3_endpoint = var.s3_endpoint + s3_secret_key = var.s3_secret_key + s3_access_key = var.s3_access_key + + loki_coordinator = { units = 1 } + loki_worker = { backend_units = 1, read_units = 1, write_units = 1 } + mimir_coordinator = { units = 1 } + mimir_worker = { backend_units = 1, read_units = 1, write_units = 1 } + tempo_coordinator = { units = 1 } + tempo_worker = { compactor_units = 1, distributor_units = 1, ingester_units = 1, metrics_generator_units = 1, querier_units = 1, query_frontend_units = 1 } +} diff --git a/tests/integration/cos_lite/tls_external/test_upgrade_cos_lite_tls_external.py b/tests/integration/cos_lite/tls_external/test_upgrade_cos_lite_tls_external.py index 46e5285a..5ab852e8 100644 --- a/tests/integration/cos_lite/tls_external/test_upgrade_cos_lite_tls_external.py +++ b/tests/integration/cos_lite/tls_external/test_upgrade_cos_lite_tls_external.py @@ -10,6 +10,7 @@ from helpers import generic_assertions TRACK_2_TF_FILE = Path(__file__).parent.resolve() / "track-2.tf" +TRACK_3_TF_FILE = Path(__file__).parent.resolve() / "track-3.0.tf" TRACK_DEV_TF_FILE = Path(__file__).parent.resolve() / "track-dev.tf" @@ -22,6 +23,17 @@ def test_deploy_from_track_2( generic_assertions(cos_model, ca_model, tmp_path) +def test_deploy_to_track_3( + tmp_path, tf_manager, ca_model: jubilant.Juju, cos_model: jubilant.Juju +): + # WHEN upgraded to track 3.0 + tf_manager.init(TRACK_3_TF_FILE) + tf_manager.apply(ca_model=ca_model.model, cos_model=cos_model.model) + + # THEN the model is upgraded and is healthy + generic_assertions(cos_model, ca_model, tmp_path) + + def test_deploy_to_track_dev( tmp_path, tf_manager, ca_model: jubilant.Juju, cos_model: jubilant.Juju ): diff --git a/tests/integration/cos_lite/tls_external/track-3.0.tf b/tests/integration/cos_lite/tls_external/track-3.0.tf new file mode 100644 index 00000000..24c354ad --- /dev/null +++ b/tests/integration/cos_lite/tls_external/track-3.0.tf @@ -0,0 +1,41 @@ +terraform { + required_version = ">= 1.5" + required_providers { + juju = { + source = "juju/juju" + version = ">= 1.0" + } + } +} + +variable "ca_model" { + type = string +} + +variable "cos_model" { + type = string +} + +data "juju_model" "ca-model" { + name = var.ca_model + owner = "admin" +} + +data "juju_model" "cos-model" { + name = var.cos_model + owner = "admin" +} + +module "ssc" { + source = "git::https://github.com/canonical/self-signed-certificates-operator//terraform" + model_uuid = data.juju_model.ca-model.uuid +} + +module "cos-lite" { + source = "git::https://github.com/canonical/observability-stack//terraform/cos-lite?ref=tf-cos-lite-3.0.0" + model_uuid = data.juju_model.cos-model.uuid + risk = "edge" + internal_tls = false + external_certificates_offer_url = "admin/${var.ca_model}.certificates" + external_ca_cert_offer_url = "admin/${var.ca_model}.send-ca-cert" +} diff --git a/tests/integration/cos_lite/tls_full/test_upgrade_cos_lite_tls_full.py b/tests/integration/cos_lite/tls_full/test_upgrade_cos_lite_tls_full.py index e834b153..7d97e8b3 100644 --- a/tests/integration/cos_lite/tls_full/test_upgrade_cos_lite_tls_full.py +++ b/tests/integration/cos_lite/tls_full/test_upgrade_cos_lite_tls_full.py @@ -10,6 +10,7 @@ from helpers import generic_assertions TRACK_2_TF_FILE = Path(__file__).parent.resolve() / "track-2.tf" +TRACK_3_TF_FILE = Path(__file__).parent.resolve() / "track-3.0.tf" TRACK_DEV_TF_FILE = Path(__file__).parent.resolve() / "track-dev.tf" @@ -22,6 +23,17 @@ def test_deploy_from_track_2( generic_assertions(cos_model, ca_model, tmp_path) +def test_deploy_to_track_3( + tmp_path, tf_manager, ca_model: jubilant.Juju, cos_model: jubilant.Juju +): + # WHEN upgraded to track 3.0 + tf_manager.init(TRACK_3_TF_FILE) + tf_manager.apply(ca_model=ca_model.model, cos_model=cos_model.model) + + # THEN the model is upgraded and is healthy + generic_assertions(cos_model, ca_model, tmp_path) + + def test_deploy_to_track_dev( tmp_path, tf_manager, ca_model: jubilant.Juju, cos_model: jubilant.Juju ): diff --git a/tests/integration/cos_lite/tls_full/track-3.0.tf b/tests/integration/cos_lite/tls_full/track-3.0.tf new file mode 100644 index 00000000..ac9ddbd5 --- /dev/null +++ b/tests/integration/cos_lite/tls_full/track-3.0.tf @@ -0,0 +1,41 @@ +terraform { + required_version = ">= 1.5" + required_providers { + juju = { + source = "juju/juju" + version = ">= 1.0" + } + } +} + +variable "ca_model" { + type = string +} + +variable "cos_model" { + type = string +} + +data "juju_model" "ca-model" { + name = var.ca_model + owner = "admin" +} + +data "juju_model" "cos-model" { + name = var.cos_model + owner = "admin" +} + +module "ssc" { + source = "git::https://github.com/canonical/self-signed-certificates-operator//terraform" + model_uuid = data.juju_model.ca-model.uuid +} + +module "cos-lite" { + source = "git::https://github.com/canonical/observability-stack//terraform/cos-lite?ref=tf-cos-lite-3.0.0" + model_uuid = data.juju_model.cos-model.uuid + risk = "edge" + internal_tls = true + external_certificates_offer_url = "admin/${var.ca_model}.certificates" + external_ca_cert_offer_url = "admin/${var.ca_model}.send-ca-cert" +} diff --git a/tests/integration/cos_lite/tls_internal/test_upgrade_cos_lite_tls_internal.py b/tests/integration/cos_lite/tls_internal/test_upgrade_cos_lite_tls_internal.py index b5d91db6..80c0b8c3 100644 --- a/tests/integration/cos_lite/tls_internal/test_upgrade_cos_lite_tls_internal.py +++ b/tests/integration/cos_lite/tls_internal/test_upgrade_cos_lite_tls_internal.py @@ -10,6 +10,7 @@ from helpers import generic_assertions TRACK_2_TF_FILE = Path(__file__).parent.resolve() / "track-2.tf" +TRACK_3_TF_FILE = Path(__file__).parent.resolve() / "track-3.0.tf" TRACK_DEV_TF_FILE = Path(__file__).parent.resolve() / "track-dev.tf" @@ -20,6 +21,15 @@ def test_deploy_from_track_2(tf_manager, cos_model: jubilant.Juju): generic_assertions(cos_model) +def test_deploy_to_track_3(tf_manager, cos_model: jubilant.Juju): + # WHEN upgraded to track 3.0 + tf_manager.init(TRACK_3_TF_FILE) + tf_manager.apply(model=cos_model.model) + + # THEN the model is upgraded and is healthy + generic_assertions(cos_model) + + def test_deploy_to_track_dev(tf_manager, cos_model: jubilant.Juju): # WHEN upgraded to track dev tf_manager.init(TRACK_DEV_TF_FILE) diff --git a/tests/integration/cos_lite/tls_internal/track-3.0.tf b/tests/integration/cos_lite/tls_internal/track-3.0.tf new file mode 100644 index 00000000..f365bfda --- /dev/null +++ b/tests/integration/cos_lite/tls_internal/track-3.0.tf @@ -0,0 +1,25 @@ +terraform { + required_version = ">= 1.5" + required_providers { + juju = { + source = "juju/juju" + version = ">= 1.0" + } + } +} + +variable "model" { + type = string +} + +data "juju_model" "model" { + name = var.model + owner = "admin" +} + +module "cos-lite" { + source = "git::https://github.com/canonical/observability-stack//terraform/cos-lite?ref=tf-cos-lite-3.0.0" + model_uuid = data.juju_model.model.uuid + risk = "edge" + internal_tls = true +} diff --git a/tests/integration/cos_lite/tls_none/test_upgrade_cos_lite_tls_none.py b/tests/integration/cos_lite/tls_none/test_upgrade_cos_lite_tls_none.py index 0d9eae1c..28a9bbbe 100644 --- a/tests/integration/cos_lite/tls_none/test_upgrade_cos_lite_tls_none.py +++ b/tests/integration/cos_lite/tls_none/test_upgrade_cos_lite_tls_none.py @@ -10,6 +10,7 @@ from helpers import generic_assertions TRACK_2_TF_FILE = Path(__file__).parent.resolve() / "track-2.tf" +TRACK_3_TF_FILE = Path(__file__).parent.resolve() / "track-3.0.tf" TRACK_DEV_TF_FILE = Path(__file__).parent.resolve() / "track-dev.tf" @@ -20,6 +21,15 @@ def test_deploy_from_track_2(tf_manager, cos_model: jubilant.Juju): generic_assertions(cos_model) +def test_deploy_to_track_3(tf_manager, cos_model: jubilant.Juju): + # WHEN upgraded to track 3.0 + tf_manager.init(TRACK_3_TF_FILE) + tf_manager.apply(model=cos_model.model) + + # THEN the model is upgraded and is healthy + generic_assertions(cos_model) + + def test_deploy_to_track_dev(tf_manager, cos_model: jubilant.Juju): # WHEN upgraded to track dev tf_manager.init(TRACK_DEV_TF_FILE) diff --git a/tests/integration/cos_lite/tls_none/track-3.0.tf b/tests/integration/cos_lite/tls_none/track-3.0.tf new file mode 100644 index 00000000..22feccd7 --- /dev/null +++ b/tests/integration/cos_lite/tls_none/track-3.0.tf @@ -0,0 +1,25 @@ +terraform { + required_version = ">= 1.5" + required_providers { + juju = { + source = "juju/juju" + version = ">= 1.0" + } + } +} + +variable "model" { + type = string +} + +data "juju_model" "model" { + name = var.model + owner = "admin" +} + +module "cos-lite" { + source = "git::https://github.com/canonical/observability-stack//terraform/cos-lite?ref=tf-cos-lite-3.0.0" + model_uuid = data.juju_model.model.uuid + risk = "edge" + internal_tls = false +} From 58b789379553aab2e7ef99ee64dc59899dcbcdb8 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Mon, 8 Jun 2026 10:55:48 -0400 Subject: [PATCH 02/41] chore: Default risks to stable --- terraform/cos-lite/variables.tf | 2 +- terraform/cos/variables.tf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/terraform/cos-lite/variables.tf b/terraform/cos-lite/variables.tf index fc47dbe5..b60c359a 100644 --- a/terraform/cos-lite/variables.tf +++ b/terraform/cos-lite/variables.tf @@ -8,7 +8,7 @@ variable "risk" { description = "Risk level that the applications are (unless overwritten by individual channels) deployed from" type = string - default = "edge" + default = "stable" } variable "base" { diff --git a/terraform/cos/variables.tf b/terraform/cos/variables.tf index 2ae191ef..71c06da1 100644 --- a/terraform/cos/variables.tf +++ b/terraform/cos/variables.tf @@ -8,7 +8,7 @@ variable "risk" { description = "Risk level that the applications are (unless overwritten by individual channels) deployed from" type = string - default = "edge" + default = "stable" } variable "base" { From 08d1ceef1d44d05f7df7fbf63ec8ef56d006f524 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Thu, 11 Jun 2026 14:44:50 -0400 Subject: [PATCH 03/41] feat: Risk upgrades --- .../test_track_dev_cos_lite_upgrade_risk.py | 27 +++++++++++ .../cos_lite/risk_upgrades/track-dev-risks.tf | 45 +++++++++++++++++++ 2 files changed, 72 insertions(+) create mode 100644 tests/integration/cos_lite/risk_upgrades/test_track_dev_cos_lite_upgrade_risk.py create mode 100644 tests/integration/cos_lite/risk_upgrades/track-dev-risks.tf diff --git a/tests/integration/cos_lite/risk_upgrades/test_track_dev_cos_lite_upgrade_risk.py b/tests/integration/cos_lite/risk_upgrades/test_track_dev_cos_lite_upgrade_risk.py new file mode 100644 index 00000000..18f3f89c --- /dev/null +++ b/tests/integration/cos_lite/risk_upgrades/test_track_dev_cos_lite_upgrade_risk.py @@ -0,0 +1,27 @@ +from pathlib import Path + +import jubilant +from helpers import generic_assertions + +TF_FILE = Path(__file__).parent.resolve() / "track-dev-risks.tf" + + +def test_deploy_from_track_2( + tf_manager, ca_model: jubilant.Juju, cos_model: jubilant.Juju, tmp_path +): + # GIVEN a module deployed with a "stable" risk + tf_manager.init(TF_FILE) + tf_manager.apply(ca_model=ca_model.model, cos_model=cos_model.model, risk="stable") + generic_assertions(cos_model, ca_model, tmp_path) + + +def test_upgrade_path( + tf_manager, ca_model: jubilant.Juju, cos_model: jubilant.Juju, tmp_path +): + # WHEN upgraded to higher risk + for risk in ["candidate", "beta", "edge"]: + tf_manager.init(TF_FILE) + tf_manager.apply(ca_model=ca_model.model, cos_model=cos_model.model, risk=risk) + + # THEN the model is upgraded and is healthy + generic_assertions(cos_model, ca_model, tmp_path) diff --git a/tests/integration/cos_lite/risk_upgrades/track-dev-risks.tf b/tests/integration/cos_lite/risk_upgrades/track-dev-risks.tf new file mode 100644 index 00000000..2e01d485 --- /dev/null +++ b/tests/integration/cos_lite/risk_upgrades/track-dev-risks.tf @@ -0,0 +1,45 @@ +terraform { + required_version = ">= 1.5" + required_providers { + juju = { + source = "juju/juju" + version = ">= 1.0" + } + } +} + +variable "risk" { + type = string +} + +variable "ca_model" { + type = string +} + +variable "cos_model" { + type = string +} + +data "juju_model" "ca-model" { + name = var.ca_model + owner = "admin" +} + +data "juju_model" "cos-model" { + name = var.cos_model + owner = "admin" +} + +module "ssc" { + source = "git::https://github.com/canonical/self-signed-certificates-operator//terraform" + model_uuid = data.juju_model.ca-model.uuid +} + +module "cos-lite" { + source = "git::https://github.com/canonical/observability-stack//terraform/cos-lite" + model = { uuid = data.juju_model.cos-model.uuid } + risk = var.risk + internal_tls = true + external_certificates_offer_url = "admin/${var.ca_model}.certificates" + external_ca_cert_offer_url = "admin/${var.ca_model}.send-ca-cert" +} From 9ef8e5e97e1e6e05a1f07e6601fc74bc91d22331 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Thu, 11 Jun 2026 19:30:05 -0400 Subject: [PATCH 04/41] chore --- .github/workflows/_integration.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/_integration.yml b/.github/workflows/_integration.yml index 26d82961..45a340f4 100644 --- a/.github/workflows/_integration.yml +++ b/.github/workflows/_integration.yml @@ -39,7 +39,7 @@ jobs: fail-fast: false matrix: juju-channel: ["3.6/stable"] - scenario: ["tls_full", "tls_external", "tls_internal", "tls_none"] + scenario: ["risk_upgrades", "tls_full", "tls_external", "tls_internal", "tls_none"] steps: - name: Checkout uses: actions/checkout@v4 From 06ea970e03df72315625b53c220ae2818d5316ef Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Thu, 11 Jun 2026 19:37:46 -0400 Subject: [PATCH 05/41] chore --- .github/workflows/terraform.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/terraform.yml b/.github/workflows/terraform.yml index 84d8ffc1..b4fc570d 100644 --- a/.github/workflows/terraform.yml +++ b/.github/workflows/terraform.yml @@ -60,7 +60,7 @@ jobs: test-integration-cos-lite: name: COS Lite Terraform integration needs: [test-unit] - uses: canonical/observability-stack/.github/workflows/_integration.yml@main + uses: canonical/observability-stack/.github/workflows/_integration.yml@feat/risk-upgrades with: product: cos_lite runner: self-hosted-linux-amd64-noble-large From c468eb637622e56ba7ed91b1ff952b784d1bd1a3 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Thu, 11 Jun 2026 19:49:28 -0400 Subject: [PATCH 06/41] chore --- .../risk_upgrades/test_track_dev_cos_lite_upgrade_risk.py | 4 ++-- .../cos_lite/risk_upgrades/{track-dev-risks.tf => track-2.tf} | 0 2 files changed, 2 insertions(+), 2 deletions(-) rename tests/integration/cos_lite/risk_upgrades/{track-dev-risks.tf => track-2.tf} (100%) diff --git a/tests/integration/cos_lite/risk_upgrades/test_track_dev_cos_lite_upgrade_risk.py b/tests/integration/cos_lite/risk_upgrades/test_track_dev_cos_lite_upgrade_risk.py index 18f3f89c..dc05bf5c 100644 --- a/tests/integration/cos_lite/risk_upgrades/test_track_dev_cos_lite_upgrade_risk.py +++ b/tests/integration/cos_lite/risk_upgrades/test_track_dev_cos_lite_upgrade_risk.py @@ -3,10 +3,10 @@ import jubilant from helpers import generic_assertions -TF_FILE = Path(__file__).parent.resolve() / "track-dev-risks.tf" +TF_FILE = Path(__file__).parent.resolve() / "track-2.tf" -def test_deploy_from_track_2( +def test_deploy_from_stable( tf_manager, ca_model: jubilant.Juju, cos_model: jubilant.Juju, tmp_path ): # GIVEN a module deployed with a "stable" risk diff --git a/tests/integration/cos_lite/risk_upgrades/track-dev-risks.tf b/tests/integration/cos_lite/risk_upgrades/track-2.tf similarity index 100% rename from tests/integration/cos_lite/risk_upgrades/track-dev-risks.tf rename to tests/integration/cos_lite/risk_upgrades/track-2.tf From 23d0ab73a69b6f3196a997c89b953719bc3245ee Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Fri, 12 Jun 2026 08:12:28 -0400 Subject: [PATCH 07/41] chore --- .github/workflows/_integration.yml | 3 +- .github/workflows/terraform.yml | 28 +++++++++---------- .../cos_lite/risk_upgrades/track-2.tf | 6 ++-- 3 files changed, 19 insertions(+), 18 deletions(-) diff --git a/.github/workflows/_integration.yml b/.github/workflows/_integration.yml index 45a340f4..482a31b5 100644 --- a/.github/workflows/_integration.yml +++ b/.github/workflows/_integration.yml @@ -39,7 +39,8 @@ jobs: fail-fast: false matrix: juju-channel: ["3.6/stable"] - scenario: ["risk_upgrades", "tls_full", "tls_external", "tls_internal", "tls_none"] + # scenario: ["risk_upgrades", "tls_full", "tls_external", "tls_internal", "tls_none"] + scenario: ["risk_upgrades"] steps: - name: Checkout uses: actions/checkout@v4 diff --git a/.github/workflows/terraform.yml b/.github/workflows/terraform.yml index b4fc570d..fcda6709 100644 --- a/.github/workflows/terraform.yml +++ b/.github/workflows/terraform.yml @@ -64,17 +64,17 @@ jobs: with: product: cos_lite runner: self-hosted-linux-amd64-noble-large - test-integration-cos: - name: COS Terraform integration - needs: [test-unit] - uses: canonical/observability-stack/.github/workflows/_integration.yml@main - with: - product: cos - runner: self-hosted-linux-amd64-noble-xlarge - test-integration-cos-dev: - name: COS Dev Terraform integration - needs: [test-unit] - uses: canonical/observability-stack/.github/workflows/_integration.yml@main - with: - product: cos_dev - runner: self-hosted-linux-amd64-noble-large + # test-integration-cos: + # name: COS Terraform integration + # needs: [test-unit] + # uses: canonical/observability-stack/.github/workflows/_integration.yml@main + # with: + # product: cos + # runner: self-hosted-linux-amd64-noble-xlarge + # test-integration-cos-dev: + # name: COS Dev Terraform integration + # needs: [test-unit] + # uses: canonical/observability-stack/.github/workflows/_integration.yml@main + # with: + # product: cos_dev + # runner: self-hosted-linux-amd64-noble-large diff --git a/tests/integration/cos_lite/risk_upgrades/track-2.tf b/tests/integration/cos_lite/risk_upgrades/track-2.tf index 2e01d485..1dd1afdb 100644 --- a/tests/integration/cos_lite/risk_upgrades/track-2.tf +++ b/tests/integration/cos_lite/risk_upgrades/track-2.tf @@ -36,9 +36,9 @@ module "ssc" { } module "cos-lite" { - source = "git::https://github.com/canonical/observability-stack//terraform/cos-lite" - model = { uuid = data.juju_model.cos-model.uuid } - risk = var.risk + source = "git::https://github.com/canonical/observability-stack//terraform/cos-lite?ref=track/2" + model_uuid = data.juju_model.cos-model.uuid + channel = "2/${var.risk}" internal_tls = true external_certificates_offer_url = "admin/${var.ca_model}.certificates" external_ca_cert_offer_url = "admin/${var.ca_model}.send-ca-cert" From 9cdbb79ee27d89c9e06b4e66a7df1ae4dda61aab Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Wed, 1 Jul 2026 12:19:53 -0400 Subject: [PATCH 08/41] chore --- terraform/cos-lite/README.md | 9 ++++----- terraform/cos/README.md | 7 +++---- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/terraform/cos-lite/README.md b/terraform/cos-lite/README.md index 220af241..8ba8e8f5 100644 --- a/terraform/cos-lite/README.md +++ b/terraform/cos-lite/README.md @@ -19,16 +19,15 @@ This is a Terraform module facilitating the deployment of the COS Lite solution, | [grafana](#module\_grafana) | git::https://github.com/canonical/grafana-k8s-operator//terraform | tf-12.4.0 | | [loki](#module\_loki) | git::https://github.com/canonical/loki-k8s-operator//terraform | tf-3.7.0 | | [prometheus](#module\_prometheus) | git::https://github.com/canonical/prometheus-k8s-operator//terraform | tf-3.11.0 | -| [ssc](#module\_ssc) | git::https://github.com/canonical/self-signed-certificates-operator//terraform | rev653 | +| [ssc](#module\_ssc) | git::https://github.com/canonical/self-signed-certificates-operator//terraform | n/a | | [traefik](#module\_traefik) | git::https://github.com/canonical/traefik-k8s-operator//terraform | rev301 | ## Inputs | 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@24.04. Check Charmhub for per-charm base support. | `string` | `"ubuntu@26.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 | +| [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")
resources = optional(map(string), {})
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")
resources = optional(map(string), {})
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 | | [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")
resources = optional(map(string), {})
revision = optional(number, null)
storage_directives = optional(map(string), {})
units = optional(number, 1)
})
| `{}` | no | @@ -38,7 +37,7 @@ This is a Terraform module facilitating the deployment of the COS Lite solution, | [model](#input\_model) | Model configuration. When `uuid` is set, an existing model is looked up; otherwise a new model is created with the given fields. For more details: https://registry.terraform.io/providers/juju/juju/latest/docs/resources/model |
object({
uuid = optional(string)
name = optional(string, "cos-lite")
cloud = optional(object({
name = string
region = optional(string)
}))
annotations = optional(map(string))
config = optional(map(string))
constraints = optional(string)
credential = optional(string)
target_controller = optional(string)
})
| `{}` | no | | [postgresql\_offer\_url](#input\_postgresql\_offer\_url) | A Juju offer URL (e.g. admin/postgresql.database) of a PostgreSQL service providing the 'postgresql\_client' integration for applications to connect to the database. | `string` | `null` | no | | [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")
resources = optional(map(string), {})
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 | +| [risk](#input\_risk) | Risk level that the applications are (unless overwritten by individual channels) deployed from | `string` | `"stable"` | 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")
resources = optional(map(string), {})
revision = optional(number, null)
storage_directives = optional(map(string), {})
units = optional(number, 1)
})
| `{}` | no | diff --git a/terraform/cos/README.md b/terraform/cos/README.md index 8cded71d..f894364e 100644 --- a/terraform/cos/README.md +++ b/terraform/cos/README.md @@ -23,7 +23,7 @@ This is a Terraform module facilitating the deployment of the COS solution, usin | [loki](#module\_loki) | git::https://github.com/canonical/loki-operators//terraform | tf-3.7.0 | | [mimir](#module\_mimir) | git::https://github.com/canonical/mimir-operators//terraform | tf-2.17.0 | | [opentelemetry\_collector](#module\_opentelemetry\_collector) | git::https://github.com/canonical/opentelemetry-collector-k8s-operator//terraform | tf-0.130.0 | -| [ssc](#module\_ssc) | git::https://github.com/canonical/self-signed-certificates-operator//terraform | rev653 | +| [ssc](#module\_ssc) | git::https://github.com/canonical/self-signed-certificates-operator//terraform | n/a | | [tempo](#module\_tempo) | git::https://github.com/canonical/tempo-operators//terraform | tf-2.10.0 | | [traefik](#module\_traefik) | git::https://github.com/canonical/traefik-k8s-operator//terraform | rev301 | @@ -33,8 +33,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")
resources = optional(map(string), {})
revision = optional(number, null)
storage_directives = optional(map(string), {})
units = optional(number, 3)
})
| `{}` | 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@24.04. Check Charmhub for per-charm base support. | `string` | `"ubuntu@26.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 | +| [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")
resources = optional(map(string), {})
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 | | [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 | @@ -50,7 +49,7 @@ This is a Terraform module facilitating the deployment of the COS solution, usin | [model](#input\_model) | Model configuration. When `uuid` is set, an existing model is looked up; otherwise a new model is created with the given fields. For more details: https://registry.terraform.io/providers/juju/juju/latest/docs/resources/model |
object({
uuid = optional(string)
name = optional(string, "cos")
cloud = optional(object({
name = string
region = optional(string)
}))
annotations = optional(map(string))
config = optional(map(string))
constraints = optional(string)
credential = optional(string)
target_controller = optional(string)
})
| `{}` | no | | [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")
resources = optional(map(string), {})
revision = optional(number, null)
storage_directives = optional(map(string), {})
units = optional(number, 1)
})
| `{}` | no | | [postgresql\_offer\_url](#input\_postgresql\_offer\_url) | A Juju offer URL (e.g. admin/postgresql.database) of a PostgreSQL service providing the 'postgresql\_client' integration for applications to connect to the database. | `string` | `null` | no | -| [risk](#input\_risk) | Risk level that the applications are (unless overwritten by individual channels) deployed from | `string` | `"edge"` | no | +| [risk](#input\_risk) | Risk level that the applications are (unless overwritten by individual channels) deployed from | `string` | `"stable"` | 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({
config = optional(map(string), {})
constraints = optional(string, "arch=amd64")
resources = optional(map(string), {})
revision = optional(number, null)
storage_directives = optional(map(string), {})
units = optional(number, 1)
})
| `{}` | no | From e2dd11bce5d290a956ba561a1f22f68f84815c68 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Wed, 1 Jul 2026 14:53:24 -0400 Subject: [PATCH 09/41] chore --- terraform/cos-lite/applications.tf | 14 +++++++------- terraform/cos/applications.tf | 14 +++++++------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/terraform/cos-lite/applications.tf b/terraform/cos-lite/applications.tf index 1d90afa9..071e1fbb 100644 --- a/terraform/cos-lite/applications.tf +++ b/terraform/cos-lite/applications.tf @@ -1,5 +1,5 @@ module "alertmanager" { - source = "git::https://github.com/canonical/alertmanager-k8s-operator//terraform?ref=tf-0.31.0" + source = "git::https://github.com/canonical/alertmanager-k8s-operator//terraform?ref=tf-0.31.1" app_name = var.alertmanager.app_name channel = local.channels.alertmanager @@ -13,7 +13,7 @@ module "alertmanager" { } module "catalogue" { - source = "git::https://github.com/canonical/catalogue-k8s-operator//terraform?ref=tf-3.0.0" + source = "git::https://github.com/canonical/catalogue-k8s-operator//terraform?ref=tf-3.0.1" app_name = var.catalogue.app_name channel = local.channels.catalogue @@ -27,7 +27,7 @@ module "catalogue" { } module "grafana" { - source = "git::https://github.com/canonical/grafana-k8s-operator//terraform?ref=tf-12.4.0" + source = "git::https://github.com/canonical/grafana-k8s-operator//terraform?ref=tf-12.4.1" replace_triggers = [terraform_data.grafana_litestream_resource.id] app_name = var.grafana.app_name @@ -42,7 +42,7 @@ module "grafana" { } module "loki" { - source = "git::https://github.com/canonical/loki-k8s-operator//terraform?ref=tf-3.7.0" + source = "git::https://github.com/canonical/loki-k8s-operator//terraform?ref=tf-3.7.1" app_name = var.loki.app_name channel = local.channels.loki @@ -56,7 +56,7 @@ module "loki" { } module "prometheus" { - source = "git::https://github.com/canonical/prometheus-k8s-operator//terraform?ref=tf-3.11.0" + source = "git::https://github.com/canonical/prometheus-k8s-operator//terraform?ref=tf-3.11.1" app_name = var.prometheus.app_name channel = local.channels.prometheus @@ -70,7 +70,7 @@ module "prometheus" { } module "ssc" { - source = "git::https://github.com/canonical/self-signed-certificates-operator//terraform" + source = "git::https://github.com/canonical/self-signed-certificates-operator//terraform?ref=rev653" count = var.internal_tls ? 1 : 0 app_name = var.ssc.app_name @@ -83,7 +83,7 @@ module "ssc" { } module "traefik" { - source = "git::https://github.com/canonical/traefik-k8s-operator//terraform?ref=rev301" + source = "git::https://github.com/canonical/traefik-k8s-operator//terraform?ref=traefik-k8s-rev345" count = local.traefik_enabled ? 1 : 0 app_name = var.traefik.app_name diff --git a/terraform/cos/applications.tf b/terraform/cos/applications.tf index eab00c97..675b74f7 100644 --- a/terraform/cos/applications.tf +++ b/terraform/cos/applications.tf @@ -1,5 +1,5 @@ module "alertmanager" { - source = "git::https://github.com/canonical/alertmanager-k8s-operator//terraform?ref=tf-0.31.0" + source = "git::https://github.com/canonical/alertmanager-k8s-operator//terraform?ref=tf-0.31.1" app_name = var.alertmanager.app_name channel = local.channels.alertmanager @@ -13,7 +13,7 @@ module "alertmanager" { } module "catalogue" { - source = "git::https://github.com/canonical/catalogue-k8s-operator//terraform?ref=tf-3.0.0" + source = "git::https://github.com/canonical/catalogue-k8s-operator//terraform?ref=tf-3.0.1" app_name = var.catalogue.app_name channel = local.channels.catalogue @@ -27,7 +27,7 @@ module "catalogue" { } module "grafana" { - source = "git::https://github.com/canonical/grafana-k8s-operator//terraform?ref=tf-12.4.0" + source = "git::https://github.com/canonical/grafana-k8s-operator//terraform?ref=tf-12.4.1" app_name = var.grafana.app_name channel = local.channels.grafana @@ -42,7 +42,7 @@ module "grafana" { } module "loki" { - source = "git::https://github.com/canonical/loki-operators//terraform?ref=tf-3.7.0" + source = "git::https://github.com/canonical/loki-operators//terraform?ref=tf-3.7.1" anti_affinity = var.anti_affinity channel = local.channels.loki @@ -114,7 +114,7 @@ module "mimir" { } module "opentelemetry_collector" { - source = "git::https://github.com/canonical/opentelemetry-collector-k8s-operator//terraform?ref=tf-0.130.0" + source = "git::https://github.com/canonical/opentelemetry-collector-k8s-operator//terraform?ref=tf-0.130.1" app_name = var.opentelemetry_collector.app_name channel = local.channels.otelcol @@ -128,7 +128,7 @@ module "opentelemetry_collector" { } module "ssc" { - source = "git::https://github.com/canonical/self-signed-certificates-operator//terraform" + source = "git::https://github.com/canonical/self-signed-certificates-operator//terraform?ref=rev653" count = var.internal_tls ? 1 : 0 app_name = var.ssc.app_name @@ -186,7 +186,7 @@ module "tempo" { } module "traefik" { - source = "git::https://github.com/canonical/traefik-k8s-operator//terraform?ref=rev301" + source = "git::https://github.com/canonical/traefik-k8s-operator//terraform?ref=traefik-k8s-rev345" count = local.traefik_enabled ? 1 : 0 app_name = var.traefik.app_name From d6e84686a5f4a8483acb2671e079bc1cd199d266 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Wed, 1 Jul 2026 14:45:41 -0400 Subject: [PATCH 10/41] fix: Add base inputs to applications (#432) --- terraform/cos-lite/applications.tf | 10 +++++++++- terraform/cos/applications.tf | 15 ++++++++++++++- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/terraform/cos-lite/applications.tf b/terraform/cos-lite/applications.tf index 071e1fbb..e56e96a6 100644 --- a/terraform/cos-lite/applications.tf +++ b/terraform/cos-lite/applications.tf @@ -2,6 +2,7 @@ module "alertmanager" { source = "git::https://github.com/canonical/alertmanager-k8s-operator//terraform?ref=tf-0.31.1" app_name = var.alertmanager.app_name + base = local.bases.o11y channel = local.channels.alertmanager config = var.alertmanager.config constraints = var.alertmanager.constraints @@ -16,6 +17,7 @@ module "catalogue" { source = "git::https://github.com/canonical/catalogue-k8s-operator//terraform?ref=tf-3.0.1" app_name = var.catalogue.app_name + base = local.bases.o11y channel = local.channels.catalogue config = var.catalogue.config constraints = var.catalogue.constraints @@ -31,6 +33,7 @@ module "grafana" { replace_triggers = [terraform_data.grafana_litestream_resource.id] app_name = var.grafana.app_name + base = local.bases.o11y channel = local.channels.grafana config = var.grafana.config constraints = var.grafana.constraints @@ -45,6 +48,7 @@ module "loki" { source = "git::https://github.com/canonical/loki-k8s-operator//terraform?ref=tf-3.7.1" app_name = var.loki.app_name + base = local.bases.o11y channel = local.channels.loki config = var.loki.config constraints = var.loki.constraints @@ -59,6 +63,7 @@ module "prometheus" { source = "git::https://github.com/canonical/prometheus-k8s-operator//terraform?ref=tf-3.11.1" app_name = var.prometheus.app_name + base = local.bases.o11y channel = local.channels.prometheus config = var.prometheus.config constraints = var.prometheus.constraints @@ -74,6 +79,7 @@ module "ssc" { count = var.internal_tls ? 1 : 0 app_name = var.ssc.app_name + base = local.bases.ssc channel = local.channels.ssc config = var.ssc.config constraints = var.ssc.constraints @@ -86,7 +92,9 @@ module "traefik" { source = "git::https://github.com/canonical/traefik-k8s-operator//terraform?ref=traefik-k8s-rev345" count = local.traefik_enabled ? 1 : 0 - app_name = var.traefik.app_name + app_name = var.traefik.app_name + # FIXME: Once Traefik TF module supports a base var, add it here + # base = local.bases.traefik channel = local.channels.traefik config = var.traefik.config constraints = var.traefik.constraints diff --git a/terraform/cos/applications.tf b/terraform/cos/applications.tf index 675b74f7..ca74f5d9 100644 --- a/terraform/cos/applications.tf +++ b/terraform/cos/applications.tf @@ -2,6 +2,7 @@ module "alertmanager" { source = "git::https://github.com/canonical/alertmanager-k8s-operator//terraform?ref=tf-0.31.1" app_name = var.alertmanager.app_name + base = local.bases.o11y channel = local.channels.alertmanager config = var.alertmanager.config constraints = var.alertmanager.constraints @@ -16,6 +17,7 @@ module "catalogue" { source = "git::https://github.com/canonical/catalogue-k8s-operator//terraform?ref=tf-3.0.1" app_name = var.catalogue.app_name + base = local.bases.o11y channel = local.channels.catalogue config = var.catalogue.config constraints = var.catalogue.constraints @@ -30,6 +32,7 @@ module "grafana" { source = "git::https://github.com/canonical/grafana-k8s-operator//terraform?ref=tf-12.4.1" app_name = var.grafana.app_name + base = local.bases.o11y channel = local.channels.grafana config = var.grafana.config constraints = var.grafana.constraints @@ -45,12 +48,14 @@ module "loki" { source = "git::https://github.com/canonical/loki-operators//terraform?ref=tf-3.7.1" anti_affinity = var.anti_affinity + base = local.bases.o11y channel = local.channels.loki model_uuid = local.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_base = local.bases.s3_integrator s3_integrator_channel = local.channels.s3_integrator s3_integrator_config = var.s3_integrator.config s3_integrator_constraints = var.s3_integrator.constraints @@ -81,12 +86,14 @@ module "mimir" { source = "git::https://github.com/canonical/mimir-operators//terraform?ref=tf-2.17.0" anti_affinity = var.anti_affinity + base = local.bases.o11y channel = local.channels.mimir model_uuid = local.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_base = local.bases.s3_integrator s3_integrator_channel = local.channels.s3_integrator s3_integrator_config = var.s3_integrator.config s3_integrator_constraints = var.s3_integrator.constraints @@ -117,6 +124,7 @@ module "opentelemetry_collector" { source = "git::https://github.com/canonical/opentelemetry-collector-k8s-operator//terraform?ref=tf-0.130.1" app_name = var.opentelemetry_collector.app_name + base = local.bases.o11y channel = local.channels.otelcol config = var.opentelemetry_collector.config constraints = var.opentelemetry_collector.constraints @@ -132,6 +140,7 @@ module "ssc" { count = var.internal_tls ? 1 : 0 app_name = var.ssc.app_name + base = local.bases.ssc channel = local.channels.ssc config = var.ssc.config constraints = var.ssc.constraints @@ -144,12 +153,14 @@ module "tempo" { source = "git::https://github.com/canonical/tempo-operators//terraform?ref=tf-2.10.0" anti_affinity = var.anti_affinity + base = local.bases.o11y channel = local.channels.tempo model_uuid = local.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_base = local.bases.s3_integrator s3_integrator_channel = local.channels.s3_integrator s3_integrator_config = var.s3_integrator.config s3_integrator_constraints = var.s3_integrator.constraints @@ -189,7 +200,9 @@ module "traefik" { source = "git::https://github.com/canonical/traefik-k8s-operator//terraform?ref=traefik-k8s-rev345" count = local.traefik_enabled ? 1 : 0 - app_name = var.traefik.app_name + app_name = var.traefik.app_name + # FIXME: Once Traefik TF module supports a base var, add it here + # base = local.bases.traefik 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 From 871d04a50845667b6fcdc6f9e116cf72fbd06d3f Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Wed, 1 Jul 2026 15:04:22 -0400 Subject: [PATCH 11/41] chore --- terraform/cos-lite/README.md | 14 +++++++------- terraform/cos/README.md | 14 +++++++------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/terraform/cos-lite/README.md b/terraform/cos-lite/README.md index 8ba8e8f5..95fdf74d 100644 --- a/terraform/cos-lite/README.md +++ b/terraform/cos-lite/README.md @@ -14,13 +14,13 @@ This is a Terraform module facilitating the deployment of the COS Lite solution, | Name | Source | Version | |------|--------|---------| -| [alertmanager](#module\_alertmanager) | git::https://github.com/canonical/alertmanager-k8s-operator//terraform | tf-0.31.0 | -| [catalogue](#module\_catalogue) | git::https://github.com/canonical/catalogue-k8s-operator//terraform | tf-3.0.0 | -| [grafana](#module\_grafana) | git::https://github.com/canonical/grafana-k8s-operator//terraform | tf-12.4.0 | -| [loki](#module\_loki) | git::https://github.com/canonical/loki-k8s-operator//terraform | tf-3.7.0 | -| [prometheus](#module\_prometheus) | git::https://github.com/canonical/prometheus-k8s-operator//terraform | tf-3.11.0 | -| [ssc](#module\_ssc) | git::https://github.com/canonical/self-signed-certificates-operator//terraform | n/a | -| [traefik](#module\_traefik) | git::https://github.com/canonical/traefik-k8s-operator//terraform | rev301 | +| [alertmanager](#module\_alertmanager) | git::https://github.com/canonical/alertmanager-k8s-operator//terraform | tf-0.31.1 | +| [catalogue](#module\_catalogue) | git::https://github.com/canonical/catalogue-k8s-operator//terraform | tf-3.0.1 | +| [grafana](#module\_grafana) | git::https://github.com/canonical/grafana-k8s-operator//terraform | tf-12.4.1 | +| [loki](#module\_loki) | git::https://github.com/canonical/loki-k8s-operator//terraform | tf-3.7.1 | +| [prometheus](#module\_prometheus) | git::https://github.com/canonical/prometheus-k8s-operator//terraform | tf-3.11.1 | +| [ssc](#module\_ssc) | git::https://github.com/canonical/self-signed-certificates-operator//terraform | rev653 | +| [traefik](#module\_traefik) | git::https://github.com/canonical/traefik-k8s-operator//terraform | traefik-k8s-rev345 | ## Inputs diff --git a/terraform/cos/README.md b/terraform/cos/README.md index f894364e..617f6b13 100644 --- a/terraform/cos/README.md +++ b/terraform/cos/README.md @@ -17,15 +17,15 @@ This is a Terraform module facilitating the deployment of the COS solution, usin | Name | Source | Version | |------|--------|---------| -| [alertmanager](#module\_alertmanager) | git::https://github.com/canonical/alertmanager-k8s-operator//terraform | tf-0.31.0 | -| [catalogue](#module\_catalogue) | git::https://github.com/canonical/catalogue-k8s-operator//terraform | tf-3.0.0 | -| [grafana](#module\_grafana) | git::https://github.com/canonical/grafana-k8s-operator//terraform | tf-12.4.0 | -| [loki](#module\_loki) | git::https://github.com/canonical/loki-operators//terraform | tf-3.7.0 | +| [alertmanager](#module\_alertmanager) | git::https://github.com/canonical/alertmanager-k8s-operator//terraform | tf-0.31.1 | +| [catalogue](#module\_catalogue) | git::https://github.com/canonical/catalogue-k8s-operator//terraform | tf-3.0.1 | +| [grafana](#module\_grafana) | git::https://github.com/canonical/grafana-k8s-operator//terraform | tf-12.4.1 | +| [loki](#module\_loki) | git::https://github.com/canonical/loki-operators//terraform | tf-3.7.1 | | [mimir](#module\_mimir) | git::https://github.com/canonical/mimir-operators//terraform | tf-2.17.0 | -| [opentelemetry\_collector](#module\_opentelemetry\_collector) | git::https://github.com/canonical/opentelemetry-collector-k8s-operator//terraform | tf-0.130.0 | -| [ssc](#module\_ssc) | git::https://github.com/canonical/self-signed-certificates-operator//terraform | n/a | +| [opentelemetry\_collector](#module\_opentelemetry\_collector) | git::https://github.com/canonical/opentelemetry-collector-k8s-operator//terraform | tf-0.130.1 | +| [ssc](#module\_ssc) | git::https://github.com/canonical/self-signed-certificates-operator//terraform | rev653 | | [tempo](#module\_tempo) | git::https://github.com/canonical/tempo-operators//terraform | tf-2.10.0 | -| [traefik](#module\_traefik) | git::https://github.com/canonical/traefik-k8s-operator//terraform | rev301 | +| [traefik](#module\_traefik) | git::https://github.com/canonical/traefik-k8s-operator//terraform | traefik-k8s-rev345 | ## Inputs From 56344cfa46850301d1e014c82129f925795d6cc7 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Wed, 1 Jul 2026 15:07:46 -0400 Subject: [PATCH 12/41] chore --- tests/integration/cos_lite/tls_full/track-3.0.tf | 2 +- tests/integration/cos_lite/tls_internal/track-3.0.tf | 2 +- tests/integration/cos_lite/tls_none/track-3.0.tf | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/integration/cos_lite/tls_full/track-3.0.tf b/tests/integration/cos_lite/tls_full/track-3.0.tf index ac9ddbd5..ff53144a 100644 --- a/tests/integration/cos_lite/tls_full/track-3.0.tf +++ b/tests/integration/cos_lite/tls_full/track-3.0.tf @@ -32,7 +32,7 @@ module "ssc" { } module "cos-lite" { - source = "git::https://github.com/canonical/observability-stack//terraform/cos-lite?ref=tf-cos-lite-3.0.0" + source = "git::https://github.com/canonical/observability-stack//terraform/cos-lite?ref=track/3.0" model_uuid = data.juju_model.cos-model.uuid risk = "edge" internal_tls = true diff --git a/tests/integration/cos_lite/tls_internal/track-3.0.tf b/tests/integration/cos_lite/tls_internal/track-3.0.tf index f365bfda..4563971a 100644 --- a/tests/integration/cos_lite/tls_internal/track-3.0.tf +++ b/tests/integration/cos_lite/tls_internal/track-3.0.tf @@ -18,7 +18,7 @@ data "juju_model" "model" { } module "cos-lite" { - source = "git::https://github.com/canonical/observability-stack//terraform/cos-lite?ref=tf-cos-lite-3.0.0" + source = "git::https://github.com/canonical/observability-stack//terraform/cos-lite?ref=track/3.0" model_uuid = data.juju_model.model.uuid risk = "edge" internal_tls = true diff --git a/tests/integration/cos_lite/tls_none/track-3.0.tf b/tests/integration/cos_lite/tls_none/track-3.0.tf index 22feccd7..5b4793a3 100644 --- a/tests/integration/cos_lite/tls_none/track-3.0.tf +++ b/tests/integration/cos_lite/tls_none/track-3.0.tf @@ -18,7 +18,7 @@ data "juju_model" "model" { } module "cos-lite" { - source = "git::https://github.com/canonical/observability-stack//terraform/cos-lite?ref=tf-cos-lite-3.0.0" + source = "git::https://github.com/canonical/observability-stack//terraform/cos-lite?ref=track/3.0" model_uuid = data.juju_model.model.uuid risk = "edge" internal_tls = false From 08421ec8cb92880903be3a3caa9399d8bae28bd1 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Wed, 1 Jul 2026 15:08:02 -0400 Subject: [PATCH 13/41] chore --- tests/integration/cos/tls_external/track-3.0.tf | 2 +- tests/integration/cos/tls_full/track-3.0.tf | 2 +- tests/integration/cos/tls_internal/track-3.0.tf | 2 +- tests/integration/cos/tls_none/track-3.0.tf | 2 +- tests/integration/cos_lite/tls_external/track-3.0.tf | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/integration/cos/tls_external/track-3.0.tf b/tests/integration/cos/tls_external/track-3.0.tf index 49681537..69a4da30 100644 --- a/tests/integration/cos/tls_external/track-3.0.tf +++ b/tests/integration/cos/tls_external/track-3.0.tf @@ -44,7 +44,7 @@ module "ssc" { } module "cos" { - source = "git::https://github.com/canonical/observability-stack//terraform/cos?ref=tf-cos-3.0.0" + source = "git::https://github.com/canonical/observability-stack//terraform/cos?ref=track/3.0" model_uuid = data.juju_model.cos-model.uuid risk = "edge" internal_tls = false diff --git a/tests/integration/cos/tls_full/track-3.0.tf b/tests/integration/cos/tls_full/track-3.0.tf index 2f457056..6ecdc487 100644 --- a/tests/integration/cos/tls_full/track-3.0.tf +++ b/tests/integration/cos/tls_full/track-3.0.tf @@ -44,7 +44,7 @@ module "ssc" { } module "cos" { - source = "git::https://github.com/canonical/observability-stack//terraform/cos?ref=tf-cos-3.0.0" + source = "git::https://github.com/canonical/observability-stack//terraform/cos?ref=track/3.0" model_uuid = data.juju_model.cos-model.uuid risk = "edge" internal_tls = true diff --git a/tests/integration/cos/tls_internal/track-3.0.tf b/tests/integration/cos/tls_internal/track-3.0.tf index 920a1916..ffcafd32 100644 --- a/tests/integration/cos/tls_internal/track-3.0.tf +++ b/tests/integration/cos/tls_internal/track-3.0.tf @@ -30,7 +30,7 @@ variable "s3_access_key" { } module "cos" { - source = "git::https://github.com/canonical/observability-stack//terraform/cos?ref=tf-cos-3.0.0" + source = "git::https://github.com/canonical/observability-stack//terraform/cos?ref=track/3.0" model_uuid = data.juju_model.model.uuid risk = "edge" internal_tls = true diff --git a/tests/integration/cos/tls_none/track-3.0.tf b/tests/integration/cos/tls_none/track-3.0.tf index d387e924..4326a4ce 100644 --- a/tests/integration/cos/tls_none/track-3.0.tf +++ b/tests/integration/cos/tls_none/track-3.0.tf @@ -30,7 +30,7 @@ variable "s3_access_key" { } module "cos" { - source = "git::https://github.com/canonical/observability-stack//terraform/cos?ref=tf-cos-3.0.0" + source = "git::https://github.com/canonical/observability-stack//terraform/cos?ref=track/3.0" model_uuid = data.juju_model.model.uuid risk = "edge" internal_tls = false diff --git a/tests/integration/cos_lite/tls_external/track-3.0.tf b/tests/integration/cos_lite/tls_external/track-3.0.tf index 24c354ad..080bdaf7 100644 --- a/tests/integration/cos_lite/tls_external/track-3.0.tf +++ b/tests/integration/cos_lite/tls_external/track-3.0.tf @@ -32,7 +32,7 @@ module "ssc" { } module "cos-lite" { - source = "git::https://github.com/canonical/observability-stack//terraform/cos-lite?ref=tf-cos-lite-3.0.0" + source = "git::https://github.com/canonical/observability-stack//terraform/cos-lite?ref=track/3.0" model_uuid = data.juju_model.cos-model.uuid risk = "edge" internal_tls = false From 20c71ddeabafcf89f666577c8399f9546cac71e0 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Wed, 1 Jul 2026 15:11:15 -0400 Subject: [PATCH 14/41] chore --- terraform/cos-lite/locals.tf | 1 - terraform/cos/locals.tf | 1 - 2 files changed, 2 deletions(-) diff --git a/terraform/cos-lite/locals.tf b/terraform/cos-lite/locals.tf index 305876cc..ed5f1ff5 100644 --- a/terraform/cos-lite/locals.tf +++ b/terraform/cos-lite/locals.tf @@ -6,7 +6,6 @@ locals { storage_directives_warning = "is unset, so it will use the default 1G volume. Set a size before deploying to production; resizing a persistent volume after deployment requires manual steps. See https://documentation.ubuntu.com/observability/latest/how-to/configure-and-tune/customize-storage-options/" tls_termination = var.external_certificates_offer_url != null ? true : false traefik_enabled = local.reverse_proxy_enabled - traefik_base = "ubuntu@20.04" bases = { o11y = "ubuntu@26.04" ssc = "ubuntu@24.04" diff --git a/terraform/cos/locals.tf b/terraform/cos/locals.tf index b075ab56..daf173e5 100644 --- a/terraform/cos/locals.tf +++ b/terraform/cos/locals.tf @@ -7,7 +7,6 @@ locals { storage_directives_warning = "is unset, so it will use the default 1G volume. Set a size before deploying to production; resizing a persistent volume after deployment requires manual steps. See https://documentation.ubuntu.com/observability/latest/how-to/configure-and-tune/customize-storage-options/" tls_termination = var.external_certificates_offer_url != null ? true : false traefik_enabled = local.reverse_proxy_enabled - traefik_base = "ubuntu@20.04" bases = { o11y = "ubuntu@26.04" s3_integrator = "ubuntu@24.04" From 61b9849a0e194e9e0d97970b5ca48d48e2b39f5e Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Wed, 1 Jul 2026 15:26:13 -0400 Subject: [PATCH 15/41] chore --- tests/integration/cos/tls_external/track-3.0.tf | 2 ++ tests/integration/cos/tls_full/track-3.0.tf | 2 ++ tests/integration/cos/tls_internal/track-3.0.tf | 2 ++ tests/integration/cos/tls_none/track-3.0.tf | 2 ++ 4 files changed, 8 insertions(+) diff --git a/tests/integration/cos/tls_external/track-3.0.tf b/tests/integration/cos/tls_external/track-3.0.tf index 69a4da30..361b37d1 100644 --- a/tests/integration/cos/tls_external/track-3.0.tf +++ b/tests/integration/cos/tls_external/track-3.0.tf @@ -55,6 +55,8 @@ module "cos" { s3_secret_key = var.s3_secret_key s3_access_key = var.s3_access_key + alertmanager = { units = 1 } + grafana = { units = 1 } loki_coordinator = { units = 1 } loki_worker = { backend_units = 1, read_units = 1, write_units = 1 } mimir_coordinator = { units = 1 } diff --git a/tests/integration/cos/tls_full/track-3.0.tf b/tests/integration/cos/tls_full/track-3.0.tf index 6ecdc487..739e779b 100644 --- a/tests/integration/cos/tls_full/track-3.0.tf +++ b/tests/integration/cos/tls_full/track-3.0.tf @@ -55,6 +55,8 @@ module "cos" { s3_secret_key = var.s3_secret_key s3_access_key = var.s3_access_key + alertmanager = { units = 1 } + grafana = { units = 1 } loki_coordinator = { units = 1 } loki_worker = { backend_units = 1, read_units = 1, write_units = 1 } mimir_coordinator = { units = 1 } diff --git a/tests/integration/cos/tls_internal/track-3.0.tf b/tests/integration/cos/tls_internal/track-3.0.tf index ffcafd32..16df7d61 100644 --- a/tests/integration/cos/tls_internal/track-3.0.tf +++ b/tests/integration/cos/tls_internal/track-3.0.tf @@ -39,6 +39,8 @@ module "cos" { s3_secret_key = var.s3_secret_key s3_access_key = var.s3_access_key + alertmanager = { units = 1 } + grafana = { units = 1 } loki_coordinator = { units = 1 } loki_worker = { backend_units = 1, read_units = 1, write_units = 1 } mimir_coordinator = { units = 1 } diff --git a/tests/integration/cos/tls_none/track-3.0.tf b/tests/integration/cos/tls_none/track-3.0.tf index 4326a4ce..b0b9dc41 100644 --- a/tests/integration/cos/tls_none/track-3.0.tf +++ b/tests/integration/cos/tls_none/track-3.0.tf @@ -39,6 +39,8 @@ module "cos" { s3_secret_key = var.s3_secret_key s3_access_key = var.s3_access_key + alertmanager = { units = 1 } + grafana = { units = 1 } loki_coordinator = { units = 1 } loki_worker = { backend_units = 1, read_units = 1, write_units = 1 } mimir_coordinator = { units = 1 } From 08a325f1795d4be805a388534ca27dba8f53a91f Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Wed, 1 Jul 2026 16:05:12 -0400 Subject: [PATCH 16/41] chore --- terraform/cos/applications.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/terraform/cos/applications.tf b/terraform/cos/applications.tf index ca74f5d9..85293126 100644 --- a/terraform/cos/applications.tf +++ b/terraform/cos/applications.tf @@ -83,7 +83,7 @@ module "loki" { } module "mimir" { - source = "git::https://github.com/canonical/mimir-operators//terraform?ref=tf-2.17.0" + source = "git::https://github.com/canonical/mimir-operators//terraform?ref=tf-2.17.1" anti_affinity = var.anti_affinity base = local.bases.o11y From 7af28c5b98fafc631a488dbeada8d0d8baa9e4c7 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Wed, 1 Jul 2026 16:46:48 -0400 Subject: [PATCH 17/41] chore --- terraform/cos-lite/applications.tf | 10 +++++----- terraform/cos/applications.tf | 14 +++++++------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/terraform/cos-lite/applications.tf b/terraform/cos-lite/applications.tf index e56e96a6..37b2c486 100644 --- a/terraform/cos-lite/applications.tf +++ b/terraform/cos-lite/applications.tf @@ -1,5 +1,5 @@ module "alertmanager" { - source = "git::https://github.com/canonical/alertmanager-k8s-operator//terraform?ref=tf-0.31.1" + source = "git::https://github.com/canonical/alertmanager-k8s-operator//terraform?ref=tf-0.31.2" app_name = var.alertmanager.app_name base = local.bases.o11y @@ -14,7 +14,7 @@ module "alertmanager" { } module "catalogue" { - source = "git::https://github.com/canonical/catalogue-k8s-operator//terraform?ref=tf-3.0.1" + source = "git::https://github.com/canonical/catalogue-k8s-operator//terraform?ref=tf-3.0.2" app_name = var.catalogue.app_name base = local.bases.o11y @@ -29,7 +29,7 @@ module "catalogue" { } module "grafana" { - source = "git::https://github.com/canonical/grafana-k8s-operator//terraform?ref=tf-12.4.1" + source = "git::https://github.com/canonical/grafana-k8s-operator//terraform?ref=tf-12.4.2" replace_triggers = [terraform_data.grafana_litestream_resource.id] app_name = var.grafana.app_name @@ -45,7 +45,7 @@ module "grafana" { } module "loki" { - source = "git::https://github.com/canonical/loki-k8s-operator//terraform?ref=tf-3.7.1" + source = "git::https://github.com/canonical/loki-k8s-operator//terraform?ref=tf-3.7.2" app_name = var.loki.app_name base = local.bases.o11y @@ -60,7 +60,7 @@ module "loki" { } module "prometheus" { - source = "git::https://github.com/canonical/prometheus-k8s-operator//terraform?ref=tf-3.11.1" + source = "git::https://github.com/canonical/prometheus-k8s-operator//terraform?ref=tf-3.11.2" app_name = var.prometheus.app_name base = local.bases.o11y diff --git a/terraform/cos/applications.tf b/terraform/cos/applications.tf index 85293126..24cea54e 100644 --- a/terraform/cos/applications.tf +++ b/terraform/cos/applications.tf @@ -1,5 +1,5 @@ module "alertmanager" { - source = "git::https://github.com/canonical/alertmanager-k8s-operator//terraform?ref=tf-0.31.1" + source = "git::https://github.com/canonical/alertmanager-k8s-operator//terraform?ref=tf-0.31.2" app_name = var.alertmanager.app_name base = local.bases.o11y @@ -14,7 +14,7 @@ module "alertmanager" { } module "catalogue" { - source = "git::https://github.com/canonical/catalogue-k8s-operator//terraform?ref=tf-3.0.1" + source = "git::https://github.com/canonical/catalogue-k8s-operator//terraform?ref=tf-3.0.2" app_name = var.catalogue.app_name base = local.bases.o11y @@ -29,7 +29,7 @@ module "catalogue" { } module "grafana" { - source = "git::https://github.com/canonical/grafana-k8s-operator//terraform?ref=tf-12.4.1" + source = "git::https://github.com/canonical/grafana-k8s-operator//terraform?ref=tf-12.4.2" app_name = var.grafana.app_name base = local.bases.o11y @@ -45,7 +45,7 @@ module "grafana" { } module "loki" { - source = "git::https://github.com/canonical/loki-operators//terraform?ref=tf-3.7.1" + source = "git::https://github.com/canonical/loki-operators//terraform?ref=tf-3.7.3" anti_affinity = var.anti_affinity base = local.bases.o11y @@ -83,7 +83,7 @@ module "loki" { } module "mimir" { - source = "git::https://github.com/canonical/mimir-operators//terraform?ref=tf-2.17.1" + source = "git::https://github.com/canonical/mimir-operators//terraform?ref=tf-2.17.2" anti_affinity = var.anti_affinity base = local.bases.o11y @@ -121,7 +121,7 @@ module "mimir" { } module "opentelemetry_collector" { - source = "git::https://github.com/canonical/opentelemetry-collector-k8s-operator//terraform?ref=tf-0.130.1" + source = "git::https://github.com/canonical/opentelemetry-collector-k8s-operator//terraform?ref=tf-0.130.2" app_name = var.opentelemetry_collector.app_name base = local.bases.o11y @@ -150,7 +150,7 @@ module "ssc" { } module "tempo" { - source = "git::https://github.com/canonical/tempo-operators//terraform?ref=tf-2.10.0" + source = "git::https://github.com/canonical/tempo-operators//terraform?ref=tf-2.10.1" anti_affinity = var.anti_affinity base = local.bases.o11y From 5bc266c2f9f35b06531bd7baddd6b5ded85358f2 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Wed, 1 Jul 2026 18:44:16 -0400 Subject: [PATCH 18/41] chore --- terraform/cos-lite/README.md | 10 +++++----- terraform/cos/README.md | 14 +++++++------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/terraform/cos-lite/README.md b/terraform/cos-lite/README.md index 95fdf74d..c8f2799c 100644 --- a/terraform/cos-lite/README.md +++ b/terraform/cos-lite/README.md @@ -14,11 +14,11 @@ This is a Terraform module facilitating the deployment of the COS Lite solution, | Name | Source | Version | |------|--------|---------| -| [alertmanager](#module\_alertmanager) | git::https://github.com/canonical/alertmanager-k8s-operator//terraform | tf-0.31.1 | -| [catalogue](#module\_catalogue) | git::https://github.com/canonical/catalogue-k8s-operator//terraform | tf-3.0.1 | -| [grafana](#module\_grafana) | git::https://github.com/canonical/grafana-k8s-operator//terraform | tf-12.4.1 | -| [loki](#module\_loki) | git::https://github.com/canonical/loki-k8s-operator//terraform | tf-3.7.1 | -| [prometheus](#module\_prometheus) | git::https://github.com/canonical/prometheus-k8s-operator//terraform | tf-3.11.1 | +| [alertmanager](#module\_alertmanager) | git::https://github.com/canonical/alertmanager-k8s-operator//terraform | tf-0.31.2 | +| [catalogue](#module\_catalogue) | git::https://github.com/canonical/catalogue-k8s-operator//terraform | tf-3.0.2 | +| [grafana](#module\_grafana) | git::https://github.com/canonical/grafana-k8s-operator//terraform | tf-12.4.2 | +| [loki](#module\_loki) | git::https://github.com/canonical/loki-k8s-operator//terraform | tf-3.7.2 | +| [prometheus](#module\_prometheus) | git::https://github.com/canonical/prometheus-k8s-operator//terraform | tf-3.11.2 | | [ssc](#module\_ssc) | git::https://github.com/canonical/self-signed-certificates-operator//terraform | rev653 | | [traefik](#module\_traefik) | git::https://github.com/canonical/traefik-k8s-operator//terraform | traefik-k8s-rev345 | diff --git a/terraform/cos/README.md b/terraform/cos/README.md index 617f6b13..0f99144e 100644 --- a/terraform/cos/README.md +++ b/terraform/cos/README.md @@ -17,14 +17,14 @@ This is a Terraform module facilitating the deployment of the COS solution, usin | Name | Source | Version | |------|--------|---------| -| [alertmanager](#module\_alertmanager) | git::https://github.com/canonical/alertmanager-k8s-operator//terraform | tf-0.31.1 | -| [catalogue](#module\_catalogue) | git::https://github.com/canonical/catalogue-k8s-operator//terraform | tf-3.0.1 | -| [grafana](#module\_grafana) | git::https://github.com/canonical/grafana-k8s-operator//terraform | tf-12.4.1 | -| [loki](#module\_loki) | git::https://github.com/canonical/loki-operators//terraform | tf-3.7.1 | -| [mimir](#module\_mimir) | git::https://github.com/canonical/mimir-operators//terraform | tf-2.17.0 | -| [opentelemetry\_collector](#module\_opentelemetry\_collector) | git::https://github.com/canonical/opentelemetry-collector-k8s-operator//terraform | tf-0.130.1 | +| [alertmanager](#module\_alertmanager) | git::https://github.com/canonical/alertmanager-k8s-operator//terraform | tf-0.31.2 | +| [catalogue](#module\_catalogue) | git::https://github.com/canonical/catalogue-k8s-operator//terraform | tf-3.0.2 | +| [grafana](#module\_grafana) | git::https://github.com/canonical/grafana-k8s-operator//terraform | tf-12.4.2 | +| [loki](#module\_loki) | git::https://github.com/canonical/loki-operators//terraform | tf-3.7.3 | +| [mimir](#module\_mimir) | git::https://github.com/canonical/mimir-operators//terraform | tf-2.17.2 | +| [opentelemetry\_collector](#module\_opentelemetry\_collector) | git::https://github.com/canonical/opentelemetry-collector-k8s-operator//terraform | tf-0.130.2 | | [ssc](#module\_ssc) | git::https://github.com/canonical/self-signed-certificates-operator//terraform | rev653 | -| [tempo](#module\_tempo) | git::https://github.com/canonical/tempo-operators//terraform | tf-2.10.0 | +| [tempo](#module\_tempo) | git::https://github.com/canonical/tempo-operators//terraform | tf-2.10.1 | | [traefik](#module\_traefik) | git::https://github.com/canonical/traefik-k8s-operator//terraform | traefik-k8s-rev345 | ## Inputs From 23ed0a56b0c340fb03276e25b85bd961a269c5e6 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Wed, 1 Jul 2026 19:03:40 -0400 Subject: [PATCH 19/41] chore --- tests/integration/cos/tls_external/track-3.0.tf | 2 +- tests/integration/cos/tls_full/track-3.0.tf | 2 +- tests/integration/cos/tls_internal/track-3.0.tf | 2 +- tests/integration/cos/tls_none/track-3.0.tf | 2 +- tests/integration/cos_lite/tls_external/track-3.0.tf | 2 +- tests/integration/cos_lite/tls_full/track-3.0.tf | 2 +- tests/integration/cos_lite/tls_internal/track-3.0.tf | 2 +- tests/integration/cos_lite/tls_none/track-3.0.tf | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/integration/cos/tls_external/track-3.0.tf b/tests/integration/cos/tls_external/track-3.0.tf index 361b37d1..adf781e5 100644 --- a/tests/integration/cos/tls_external/track-3.0.tf +++ b/tests/integration/cos/tls_external/track-3.0.tf @@ -45,7 +45,7 @@ module "ssc" { module "cos" { source = "git::https://github.com/canonical/observability-stack//terraform/cos?ref=track/3.0" - model_uuid = data.juju_model.cos-model.uuid + model = { uuid = data.juju_model.cos-model.uuid } risk = "edge" internal_tls = false external_certificates_offer_url = "admin/${var.ca_model}.certificates" diff --git a/tests/integration/cos/tls_full/track-3.0.tf b/tests/integration/cos/tls_full/track-3.0.tf index 739e779b..53dd53e6 100644 --- a/tests/integration/cos/tls_full/track-3.0.tf +++ b/tests/integration/cos/tls_full/track-3.0.tf @@ -45,7 +45,7 @@ module "ssc" { module "cos" { source = "git::https://github.com/canonical/observability-stack//terraform/cos?ref=track/3.0" - model_uuid = data.juju_model.cos-model.uuid + model = { uuid = data.juju_model.cos-model.uuid } risk = "edge" internal_tls = true external_certificates_offer_url = "admin/${var.ca_model}.certificates" diff --git a/tests/integration/cos/tls_internal/track-3.0.tf b/tests/integration/cos/tls_internal/track-3.0.tf index 16df7d61..74b90cc2 100644 --- a/tests/integration/cos/tls_internal/track-3.0.tf +++ b/tests/integration/cos/tls_internal/track-3.0.tf @@ -31,7 +31,7 @@ variable "s3_access_key" { module "cos" { source = "git::https://github.com/canonical/observability-stack//terraform/cos?ref=track/3.0" - model_uuid = data.juju_model.model.uuid + model = { uuid = data.juju_model.model.uuid } risk = "edge" internal_tls = true diff --git a/tests/integration/cos/tls_none/track-3.0.tf b/tests/integration/cos/tls_none/track-3.0.tf index b0b9dc41..538fbd6f 100644 --- a/tests/integration/cos/tls_none/track-3.0.tf +++ b/tests/integration/cos/tls_none/track-3.0.tf @@ -31,7 +31,7 @@ variable "s3_access_key" { module "cos" { source = "git::https://github.com/canonical/observability-stack//terraform/cos?ref=track/3.0" - model_uuid = data.juju_model.model.uuid + model = { uuid = data.juju_model.model.uuid } risk = "edge" internal_tls = false diff --git a/tests/integration/cos_lite/tls_external/track-3.0.tf b/tests/integration/cos_lite/tls_external/track-3.0.tf index 080bdaf7..40e26726 100644 --- a/tests/integration/cos_lite/tls_external/track-3.0.tf +++ b/tests/integration/cos_lite/tls_external/track-3.0.tf @@ -33,7 +33,7 @@ module "ssc" { module "cos-lite" { source = "git::https://github.com/canonical/observability-stack//terraform/cos-lite?ref=track/3.0" - model_uuid = data.juju_model.cos-model.uuid + model = { uuid = data.juju_model.cos-model.uuid } risk = "edge" internal_tls = false external_certificates_offer_url = "admin/${var.ca_model}.certificates" diff --git a/tests/integration/cos_lite/tls_full/track-3.0.tf b/tests/integration/cos_lite/tls_full/track-3.0.tf index ff53144a..13f2e83f 100644 --- a/tests/integration/cos_lite/tls_full/track-3.0.tf +++ b/tests/integration/cos_lite/tls_full/track-3.0.tf @@ -33,7 +33,7 @@ module "ssc" { module "cos-lite" { source = "git::https://github.com/canonical/observability-stack//terraform/cos-lite?ref=track/3.0" - model_uuid = data.juju_model.cos-model.uuid + model = { uuid = data.juju_model.cos-model.uuid } risk = "edge" internal_tls = true external_certificates_offer_url = "admin/${var.ca_model}.certificates" diff --git a/tests/integration/cos_lite/tls_internal/track-3.0.tf b/tests/integration/cos_lite/tls_internal/track-3.0.tf index 4563971a..3c12880c 100644 --- a/tests/integration/cos_lite/tls_internal/track-3.0.tf +++ b/tests/integration/cos_lite/tls_internal/track-3.0.tf @@ -19,7 +19,7 @@ data "juju_model" "model" { module "cos-lite" { source = "git::https://github.com/canonical/observability-stack//terraform/cos-lite?ref=track/3.0" - model_uuid = data.juju_model.model.uuid + model = { uuid = data.juju_model.model.uuid } risk = "edge" internal_tls = true } diff --git a/tests/integration/cos_lite/tls_none/track-3.0.tf b/tests/integration/cos_lite/tls_none/track-3.0.tf index 5b4793a3..9d28053b 100644 --- a/tests/integration/cos_lite/tls_none/track-3.0.tf +++ b/tests/integration/cos_lite/tls_none/track-3.0.tf @@ -19,7 +19,7 @@ data "juju_model" "model" { module "cos-lite" { source = "git::https://github.com/canonical/observability-stack//terraform/cos-lite?ref=track/3.0" - model_uuid = data.juju_model.model.uuid + model = { uuid = data.juju_model.model.uuid } risk = "edge" internal_tls = false } From d58081400d6124c7d37a78ee43897cd33e7f5e0b Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Mon, 6 Jul 2026 10:06:49 -0400 Subject: [PATCH 20/41] chore --- terraform/cos-lite/applications.tf | 2 +- terraform/cos/applications.tf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/terraform/cos-lite/applications.tf b/terraform/cos-lite/applications.tf index 37b2c486..649beb01 100644 --- a/terraform/cos-lite/applications.tf +++ b/terraform/cos-lite/applications.tf @@ -14,7 +14,7 @@ module "alertmanager" { } module "catalogue" { - source = "git::https://github.com/canonical/catalogue-k8s-operator//terraform?ref=tf-3.0.2" + source = "git::https://github.com/canonical/catalogue-k8s-operator//terraform?ref=tf-3.0.3" app_name = var.catalogue.app_name base = local.bases.o11y diff --git a/terraform/cos/applications.tf b/terraform/cos/applications.tf index 24cea54e..2e090787 100644 --- a/terraform/cos/applications.tf +++ b/terraform/cos/applications.tf @@ -14,7 +14,7 @@ module "alertmanager" { } module "catalogue" { - source = "git::https://github.com/canonical/catalogue-k8s-operator//terraform?ref=tf-3.0.2" + source = "git::https://github.com/canonical/catalogue-k8s-operator//terraform?ref=tf-3.0.3" app_name = var.catalogue.app_name base = local.bases.o11y From 1bc80ab049c98ed6daae802c7a00f00f476043ac Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Mon, 6 Jul 2026 10:07:51 -0400 Subject: [PATCH 21/41] chore --- terraform/cos-lite/README.md | 2 +- terraform/cos/README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/terraform/cos-lite/README.md b/terraform/cos-lite/README.md index c8f2799c..eaef3186 100644 --- a/terraform/cos-lite/README.md +++ b/terraform/cos-lite/README.md @@ -15,7 +15,7 @@ This is a Terraform module facilitating the deployment of the COS Lite solution, | Name | Source | Version | |------|--------|---------| | [alertmanager](#module\_alertmanager) | git::https://github.com/canonical/alertmanager-k8s-operator//terraform | tf-0.31.2 | -| [catalogue](#module\_catalogue) | git::https://github.com/canonical/catalogue-k8s-operator//terraform | tf-3.0.2 | +| [catalogue](#module\_catalogue) | git::https://github.com/canonical/catalogue-k8s-operator//terraform | tf-3.0.3 | | [grafana](#module\_grafana) | git::https://github.com/canonical/grafana-k8s-operator//terraform | tf-12.4.2 | | [loki](#module\_loki) | git::https://github.com/canonical/loki-k8s-operator//terraform | tf-3.7.2 | | [prometheus](#module\_prometheus) | git::https://github.com/canonical/prometheus-k8s-operator//terraform | tf-3.11.2 | diff --git a/terraform/cos/README.md b/terraform/cos/README.md index 0f99144e..b73a6d43 100644 --- a/terraform/cos/README.md +++ b/terraform/cos/README.md @@ -18,7 +18,7 @@ This is a Terraform module facilitating the deployment of the COS solution, usin | Name | Source | Version | |------|--------|---------| | [alertmanager](#module\_alertmanager) | git::https://github.com/canonical/alertmanager-k8s-operator//terraform | tf-0.31.2 | -| [catalogue](#module\_catalogue) | git::https://github.com/canonical/catalogue-k8s-operator//terraform | tf-3.0.2 | +| [catalogue](#module\_catalogue) | git::https://github.com/canonical/catalogue-k8s-operator//terraform | tf-3.0.3 | | [grafana](#module\_grafana) | git::https://github.com/canonical/grafana-k8s-operator//terraform | tf-12.4.2 | | [loki](#module\_loki) | git::https://github.com/canonical/loki-operators//terraform | tf-3.7.3 | | [mimir](#module\_mimir) | git::https://github.com/canonical/mimir-operators//terraform | tf-2.17.2 | From b919e357f51084d9691dab074df755d6c8025088 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Mon, 6 Jul 2026 10:15:09 -0400 Subject: [PATCH 22/41] chore --- terraform/cos-dev/applications.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/terraform/cos-dev/applications.tf b/terraform/cos-dev/applications.tf index 612af09b..dfd08c10 100644 --- a/terraform/cos-dev/applications.tf +++ b/terraform/cos-dev/applications.tf @@ -13,7 +13,7 @@ module "alertmanager" { } module "catalogue" { - source = "git::https://github.com/canonical/catalogue-k8s-operator//terraform" + source = "git::https://github.com/canonical/catalogue-k8s-operator//charm/terraform" app_name = var.catalogue.app_name channel = local.channels.catalogue From 425095f9a4e7f6513b7677a96404cae3b2b85e7c Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Mon, 6 Jul 2026 10:23:44 -0400 Subject: [PATCH 23/41] chore --- terraform/cos-lite/applications.tf | 2 +- terraform/cos/applications.tf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/terraform/cos-lite/applications.tf b/terraform/cos-lite/applications.tf index 649beb01..1859970b 100644 --- a/terraform/cos-lite/applications.tf +++ b/terraform/cos-lite/applications.tf @@ -14,7 +14,7 @@ module "alertmanager" { } module "catalogue" { - source = "git::https://github.com/canonical/catalogue-k8s-operator//terraform?ref=tf-3.0.3" + source = "git::https://github.com/canonical/catalogue-k8s-operator//charm/terraform?ref=tf-3.0.3" app_name = var.catalogue.app_name base = local.bases.o11y diff --git a/terraform/cos/applications.tf b/terraform/cos/applications.tf index 2e090787..b2464b66 100644 --- a/terraform/cos/applications.tf +++ b/terraform/cos/applications.tf @@ -14,7 +14,7 @@ module "alertmanager" { } module "catalogue" { - source = "git::https://github.com/canonical/catalogue-k8s-operator//terraform?ref=tf-3.0.3" + source = "git::https://github.com/canonical/catalogue-k8s-operator//charm/terraform?ref=tf-3.0.3" app_name = var.catalogue.app_name base = local.bases.o11y From 1172963854632850f140ee19ebddc06719cc6dc7 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Mon, 6 Jul 2026 10:28:21 -0400 Subject: [PATCH 24/41] chore --- terraform/cos-dev/README.md | 2 +- terraform/cos-lite/README.md | 2 +- terraform/cos/README.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/terraform/cos-dev/README.md b/terraform/cos-dev/README.md index 51cf8e8c..cfef1c6a 100644 --- a/terraform/cos-dev/README.md +++ b/terraform/cos-dev/README.md @@ -17,7 +17,7 @@ This module is intended for development and testing environments where full HA i | Name | Source | Version | |------|--------|---------| | [alertmanager](#module\_alertmanager) | git::https://github.com/canonical/alertmanager-k8s-operator//terraform | n/a | -| [catalogue](#module\_catalogue) | git::https://github.com/canonical/catalogue-k8s-operator//terraform | n/a | +| [catalogue](#module\_catalogue) | git::https://github.com/canonical/catalogue-k8s-operator//charm/terraform | n/a | | [grafana](#module\_grafana) | git::https://github.com/canonical/grafana-k8s-operator//terraform | n/a | | [loki\_coordinator](#module\_loki\_coordinator) | git::https://github.com/canonical/loki-operators//coordinator/terraform | n/a | | [loki\_worker](#module\_loki\_worker) | git::https://github.com/canonical/loki-operators//worker/terraform | n/a | diff --git a/terraform/cos-lite/README.md b/terraform/cos-lite/README.md index eaef3186..fed20180 100644 --- a/terraform/cos-lite/README.md +++ b/terraform/cos-lite/README.md @@ -15,7 +15,7 @@ This is a Terraform module facilitating the deployment of the COS Lite solution, | Name | Source | Version | |------|--------|---------| | [alertmanager](#module\_alertmanager) | git::https://github.com/canonical/alertmanager-k8s-operator//terraform | tf-0.31.2 | -| [catalogue](#module\_catalogue) | git::https://github.com/canonical/catalogue-k8s-operator//terraform | tf-3.0.3 | +| [catalogue](#module\_catalogue) | git::https://github.com/canonical/catalogue-k8s-operator//charm/terraform | tf-3.0.3 | | [grafana](#module\_grafana) | git::https://github.com/canonical/grafana-k8s-operator//terraform | tf-12.4.2 | | [loki](#module\_loki) | git::https://github.com/canonical/loki-k8s-operator//terraform | tf-3.7.2 | | [prometheus](#module\_prometheus) | git::https://github.com/canonical/prometheus-k8s-operator//terraform | tf-3.11.2 | diff --git a/terraform/cos/README.md b/terraform/cos/README.md index b73a6d43..3191db41 100644 --- a/terraform/cos/README.md +++ b/terraform/cos/README.md @@ -18,7 +18,7 @@ This is a Terraform module facilitating the deployment of the COS solution, usin | Name | Source | Version | |------|--------|---------| | [alertmanager](#module\_alertmanager) | git::https://github.com/canonical/alertmanager-k8s-operator//terraform | tf-0.31.2 | -| [catalogue](#module\_catalogue) | git::https://github.com/canonical/catalogue-k8s-operator//terraform | tf-3.0.3 | +| [catalogue](#module\_catalogue) | git::https://github.com/canonical/catalogue-k8s-operator//charm/terraform | tf-3.0.3 | | [grafana](#module\_grafana) | git::https://github.com/canonical/grafana-k8s-operator//terraform | tf-12.4.2 | | [loki](#module\_loki) | git::https://github.com/canonical/loki-operators//terraform | tf-3.7.3 | | [mimir](#module\_mimir) | git::https://github.com/canonical/mimir-operators//terraform | tf-2.17.2 | From 12e92dedcd8b3e9f9f1712c143bd49c13866c6ef Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Mon, 6 Jul 2026 10:43:33 -0400 Subject: [PATCH 25/41] chore --- terraform/cos-dev/README.md | 118 --- terraform/cos-dev/applications.tf | 515 ---------- terraform/cos-dev/integrations.tf | 879 ------------------ terraform/cos-dev/locals.tf | 55 -- terraform/cos-dev/offers.tf | 36 - terraform/cos-dev/outputs.tf | 45 - terraform/cos-dev/terraform.tf | 9 - .../tests/conditional_ingress.tftest.hcl | 70 -- .../cos-dev/tests/external_tls.tftest.hcl | 54 -- .../cos-dev/tests/internal_tls.tftest.hcl | 50 - .../cos-dev/tests/revision_pin.tftest.hcl | 175 ---- .../tests/topology_and_storage.tftest.hcl | 408 -------- terraform/cos-dev/upgrades.tf | 105 --- terraform/cos-dev/variables.tf | 361 ------- .../tls_external/test_cos_dev_tls_external.py | 31 - .../cos_dev/tls_external/track-dev.tf | 41 - .../cos_dev/tls_full/test_cos_dev_tls_full.py | 31 - .../integration/cos_dev/tls_full/track-dev.tf | 41 - .../tls_internal/test_cos_dev_tls_internal.py | 28 - .../cos_dev/tls_internal/track-dev.tf | 25 - .../cos_dev/tls_none/test_cos_dev_tls_none.py | 28 - .../integration/cos_dev/tls_none/track-dev.tf | 25 - 22 files changed, 3130 deletions(-) delete mode 100644 terraform/cos-dev/README.md delete mode 100644 terraform/cos-dev/applications.tf delete mode 100644 terraform/cos-dev/integrations.tf delete mode 100644 terraform/cos-dev/locals.tf delete mode 100644 terraform/cos-dev/offers.tf delete mode 100644 terraform/cos-dev/outputs.tf delete mode 100644 terraform/cos-dev/terraform.tf delete mode 100644 terraform/cos-dev/tests/conditional_ingress.tftest.hcl delete mode 100644 terraform/cos-dev/tests/external_tls.tftest.hcl delete mode 100644 terraform/cos-dev/tests/internal_tls.tftest.hcl delete mode 100644 terraform/cos-dev/tests/revision_pin.tftest.hcl delete mode 100644 terraform/cos-dev/tests/topology_and_storage.tftest.hcl delete mode 100644 terraform/cos-dev/upgrades.tf delete mode 100644 terraform/cos-dev/variables.tf delete mode 100644 tests/integration/cos_dev/tls_external/test_cos_dev_tls_external.py delete mode 100644 tests/integration/cos_dev/tls_external/track-dev.tf delete mode 100644 tests/integration/cos_dev/tls_full/test_cos_dev_tls_full.py delete mode 100644 tests/integration/cos_dev/tls_full/track-dev.tf delete mode 100644 tests/integration/cos_dev/tls_internal/test_cos_dev_tls_internal.py delete mode 100644 tests/integration/cos_dev/tls_internal/track-dev.tf delete mode 100644 tests/integration/cos_dev/tls_none/test_cos_dev_tls_none.py delete mode 100644 tests/integration/cos_dev/tls_none/track-dev.tf diff --git a/terraform/cos-dev/README.md b/terraform/cos-dev/README.md deleted file mode 100644 index cfef1c6a..00000000 --- a/terraform/cos-dev/README.md +++ /dev/null @@ -1,118 +0,0 @@ -# Terraform module for the COS Dev solution - -This is a Terraform module facilitating the deployment of the COS Dev solution, using the [Terraform juju provider](https://github.com/juju/terraform-provider-juju/). For more information, refer to the provider [documentation](https://registry.terraform.io/providers/juju/juju/latest/docs). This Terraform module deploys a lightweight COS stack supporting both **monolithic** and **distributed** topologies, and either [SeaweedFS](https://github.com/seaweedfs/seaweedfs) or an external S3-compatible store (via `s3-integrator`) as the storage backend. - -This module is intended for development and testing environments where full HA is not required. It uses the individual coordinator and worker charm modules, rather than the bundled operator modules used by the main COS module. - - -## Providers - -| Name | Version | -|------|---------| -| [juju](#provider\_juju) | >= 1.0 | -| [terraform](#provider\_terraform) | n/a | - -## Modules - -| Name | Source | Version | -|------|--------|---------| -| [alertmanager](#module\_alertmanager) | git::https://github.com/canonical/alertmanager-k8s-operator//terraform | n/a | -| [catalogue](#module\_catalogue) | git::https://github.com/canonical/catalogue-k8s-operator//charm/terraform | n/a | -| [grafana](#module\_grafana) | git::https://github.com/canonical/grafana-k8s-operator//terraform | n/a | -| [loki\_coordinator](#module\_loki\_coordinator) | git::https://github.com/canonical/loki-operators//coordinator/terraform | n/a | -| [loki\_worker](#module\_loki\_worker) | git::https://github.com/canonical/loki-operators//worker/terraform | n/a | -| [loki\_worker\_backend](#module\_loki\_worker\_backend) | git::https://github.com/canonical/loki-operators//worker/terraform | n/a | -| [loki\_worker\_read](#module\_loki\_worker\_read) | git::https://github.com/canonical/loki-operators//worker/terraform | n/a | -| [loki\_worker\_write](#module\_loki\_worker\_write) | git::https://github.com/canonical/loki-operators//worker/terraform | n/a | -| [mimir\_coordinator](#module\_mimir\_coordinator) | git::https://github.com/canonical/mimir-operators//coordinator/terraform | n/a | -| [mimir\_worker](#module\_mimir\_worker) | git::https://github.com/canonical/mimir-operators//worker/terraform | n/a | -| [mimir\_worker\_backend](#module\_mimir\_worker\_backend) | git::https://github.com/canonical/mimir-operators//worker/terraform | n/a | -| [mimir\_worker\_read](#module\_mimir\_worker\_read) | git::https://github.com/canonical/mimir-operators//worker/terraform | n/a | -| [mimir\_worker\_write](#module\_mimir\_worker\_write) | git::https://github.com/canonical/mimir-operators//worker/terraform | n/a | -| [opentelemetry\_collector](#module\_opentelemetry\_collector) | git::https://github.com/canonical/opentelemetry-collector-k8s-operator//terraform | n/a | -| [seaweedfs](#module\_seaweedfs) | git::https://github.com/canonical/observability-stack//terraform/seaweedfs | n/a | -| [ssc](#module\_ssc) | git::https://github.com/canonical/self-signed-certificates-operator//terraform | n/a | -| [tempo\_coordinator](#module\_tempo\_coordinator) | git::https://github.com/canonical/tempo-operators//coordinator/terraform | n/a | -| [tempo\_worker](#module\_tempo\_worker) | git::https://github.com/canonical/tempo-operators//worker/terraform | n/a | -| [tempo\_worker\_compactor](#module\_tempo\_worker\_compactor) | git::https://github.com/canonical/tempo-operators//worker/terraform | n/a | -| [tempo\_worker\_distributor](#module\_tempo\_worker\_distributor) | git::https://github.com/canonical/tempo-operators//worker/terraform | n/a | -| [tempo\_worker\_ingester](#module\_tempo\_worker\_ingester) | git::https://github.com/canonical/tempo-operators//worker/terraform | n/a | -| [tempo\_worker\_metrics\_generator](#module\_tempo\_worker\_metrics\_generator) | git::https://github.com/canonical/tempo-operators//worker/terraform | n/a | -| [tempo\_worker\_querier](#module\_tempo\_worker\_querier) | git::https://github.com/canonical/tempo-operators//worker/terraform | n/a | -| [tempo\_worker\_query\_frontend](#module\_tempo\_worker\_query\_frontend) | git::https://github.com/canonical/tempo-operators//worker/terraform | n/a | -| [traefik](#module\_traefik) | git::https://github.com/canonical/traefik-k8s-operator//terraform | n/a | - -## Inputs - -| 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")
resources = optional(map(string), {})
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")
resources = optional(map(string), {})
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 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")
resources = optional(map(string), {})
revision = optional(number, null)
storage_directives = optional(map(string), {})
units = optional(number, 1)
})
| `{}` | no | -| [ingress](#input\_ingress) | Per-component toggle for ingress integrations |
object({
alertmanager = optional(bool, true)
catalogue = optional(bool, true)
grafana = optional(bool, true)
loki = optional(bool, true)
mimir = optional(bool, true)
opentelemetry_collector = optional(bool, true)
tempo = optional(bool, true)
})
| `{}` | no | -| [internal\_tls](#input\_internal\_tls) | Specify whether to use TLS or not for internal COS communication. By default, TLS is enabled using self-signed-certificates | `bool` | `true` | no | -| [loki\_bucket](#input\_loki\_bucket) | Loki S3 bucket name | `string` | `"loki"` | no | -| [loki\_coordinator](#input\_loki\_coordinator) | Application configuration for the Loki coordinator. 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")
resources = optional(map(string), {})
revision = optional(number, null)
storage_directives = optional(map(string), {})
units = optional(number, 1)
})
| `{}` | no | -| [loki\_worker](#input\_loki\_worker) | Application configuration for the Loki worker(s). For more details: https://registry.terraform.io/providers/juju/juju/latest/docs/resources/application |
object({
app_name = optional(string, "loki-worker")
constraints = optional(string, "arch=amd64")
resources = optional(map(string), {})
revision = optional(number, null)
# Monolithic mode (role-all)
config = optional(map(string), {})
storage_directives = optional(map(string), {})
units = optional(number, 1)
# Distributed mode
backend_config = optional(map(string), {})
read_config = optional(map(string), {})
write_config = optional(map(string), {})
backend_storage_directives = optional(map(string), {})
read_storage_directives = optional(map(string), {})
write_storage_directives = optional(map(string), {})
backend_units = optional(number, 1)
read_units = optional(number, 1)
write_units = optional(number, 1)
})
| `{}` | no | -| [mimir\_bucket](#input\_mimir\_bucket) | Mimir S3 bucket name | `string` | `"mimir"` | no | -| [mimir\_coordinator](#input\_mimir\_coordinator) | Application configuration for the Mimir coordinator. For more details: https://registry.terraform.io/providers/juju/juju/latest/docs/resources/application |
object({
app_name = optional(string, "mimir")
config = optional(map(string), {})
constraints = optional(string, "arch=amd64")
resources = optional(map(string), {})
revision = optional(number, null)
storage_directives = optional(map(string), {})
units = optional(number, 1)
})
| `{}` | no | -| [mimir\_worker](#input\_mimir\_worker) | Application configuration for the Mimir worker(s). For more details: https://registry.terraform.io/providers/juju/juju/latest/docs/resources/application |
object({
app_name = optional(string, "mimir-worker")
constraints = optional(string, "arch=amd64")
resources = optional(map(string), {})
revision = optional(number, null)
# Monolithic mode (role-all)
config = optional(map(string), {})
storage_directives = optional(map(string), {})
units = optional(number, 1)
# Distributed mode
backend_config = optional(map(string), {})
read_config = optional(map(string), {})
write_config = optional(map(string), {})
backend_storage_directives = optional(map(string), {})
read_storage_directives = optional(map(string), {})
write_storage_directives = optional(map(string), {})
backend_units = optional(number, 1)
read_units = optional(number, 1)
write_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 | -| [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")
resources = optional(map(string), {})
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. Required when storage\_backend is 's3'. | `string` | `null` | no | -| [s3\_endpoint](#input\_s3\_endpoint) | S3 endpoint URL. Required when storage\_backend is 's3'. | `string` | `null` | no | -| [s3\_integrator](#input\_s3\_integrator) | Application configuration shared by all S3-integrators (one deployed per coordinated worker). 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. Required when storage\_backend is 's3'. | `string` | `null` | no | -| [seaweedfs](#input\_seaweedfs) | Application configuration for SeaweedFS. For more details: https://registry.terraform.io/providers/juju/juju/latest/docs/resources/application |
object({
app_name = optional(string, "seaweedfs")
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 | -| [storage\_backend](#input\_storage\_backend) | Storage backend: 'seaweedfs' (built-in S3-compatible storage) or 's3' (external S3/Ceph via s3-integrator). | `string` | `"seaweedfs"` | no | -| [tempo\_bucket](#input\_tempo\_bucket) | Tempo S3 bucket name | `string` | `"tempo"` | no | -| [tempo\_coordinator](#input\_tempo\_coordinator) | Application configuration for the Tempo coordinator. For more details: https://registry.terraform.io/providers/juju/juju/latest/docs/resources/application |
object({
app_name = optional(string, "tempo")
config = optional(map(string), {})
constraints = optional(string, "arch=amd64")
resources = optional(map(string), {})
revision = optional(number, null)
storage_directives = optional(map(string), {})
units = optional(number, 1)
})
| `{}` | no | -| [tempo\_worker](#input\_tempo\_worker) | Application configuration for the Tempo worker(s). For more details: https://registry.terraform.io/providers/juju/juju/latest/docs/resources/application |
object({
app_name = optional(string, "tempo-worker")
constraints = optional(string, "arch=amd64")
resources = optional(map(string), {})
revision = optional(number, null)
# Monolithic mode (role-all)
config = optional(map(string), {})
storage_directives = optional(map(string), {})
units = optional(number, 1)
# Distributed mode
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), {})
querier_storage_directives = optional(map(string), {})
query_frontend_storage_directives = optional(map(string), {})
ingester_storage_directives = optional(map(string), {})
distributor_storage_directives = optional(map(string), {})
compactor_storage_directives = optional(map(string), {})
metrics_generator_storage_directives = optional(map(string), {})
querier_units = optional(number, 1)
query_frontend_units = optional(number, 1)
ingester_units = optional(number, 1)
distributor_units = optional(number, 1)
compactor_units = optional(number, 1)
metrics_generator_units = optional(number, 1)
})
| `{}` | no | -| [topology](#input\_topology) | Deployment topology: 'monolithic' (single role-all worker per component) or 'distributed' (separate workers per role). | `string` | `"monolithic"` | 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")
resources = optional(map(string), {})
revision = optional(number, null)
storage_directives = optional(map(string), {})
units = optional(number, 1)
})
| `{}` | no | - -## Outputs - -| Name | Description | -|------|-------------| -| [components](#output\_components) | All Terraform charm modules which make up this product module | -| [offers](#output\_offers) | All Juju offers which are exposed by this product module | - - -## Usage - -### Basic usage - -To deploy the COS Dev solution in a model named `cos-dev`, create this root module: - -```hcl -terraform { - required_version = ">= 1.5" - required_providers { - juju = { - source = "juju/juju" - version = "~> 1.0" - } - } -} - -resource "juju_model" "cos-dev" { - name = "cos-dev" -} - -module "cos-dev" { - source = "git::https://github.com/canonical/observability-stack//terraform/cos-dev" - model_uuid = juju_model.cos-dev.uuid -} -``` - -Then, use terraform to deploy the module: - -```shell -terraform init -terraform apply -``` diff --git a/terraform/cos-dev/applications.tf b/terraform/cos-dev/applications.tf deleted file mode 100644 index dfd08c10..00000000 --- a/terraform/cos-dev/applications.tf +++ /dev/null @@ -1,515 +0,0 @@ -module "alertmanager" { - source = "git::https://github.com/canonical/alertmanager-k8s-operator//terraform" - - app_name = var.alertmanager.app_name - channel = local.channels.alertmanager - config = var.alertmanager.config - constraints = var.alertmanager.constraints - model_uuid = var.model_uuid - resources = var.alertmanager.resources - revision = local.revisions.alertmanager - storage_directives = var.alertmanager.storage_directives - units = var.alertmanager.units -} - -module "catalogue" { - source = "git::https://github.com/canonical/catalogue-k8s-operator//charm/terraform" - - app_name = var.catalogue.app_name - channel = local.channels.catalogue - config = var.catalogue.config - constraints = var.catalogue.constraints - model_uuid = var.model_uuid - resources = var.catalogue.resources - revision = local.revisions.catalogue - storage_directives = var.catalogue.storage_directives - units = var.catalogue.units -} - -module "grafana" { - source = "git::https://github.com/canonical/grafana-k8s-operator//terraform" - - app_name = var.grafana.app_name - channel = local.channels.grafana - config = var.grafana.config - constraints = var.grafana.constraints - model_uuid = var.model_uuid - resources = var.grafana.resources - revision = local.revisions.grafana - storage_directives = var.grafana.storage_directives - units = var.grafana.units - replace_triggers = [terraform_data.grafana_litestream_resource.id] -} - -module "loki_coordinator" { - source = "git::https://github.com/canonical/loki-operators//coordinator/terraform" - - app_name = var.loki_coordinator.app_name - channel = local.channels.loki - config = var.loki_coordinator.config - constraints = var.loki_coordinator.constraints - model_uuid = var.model_uuid - resources = var.loki_coordinator.resources - revision = local.revisions.loki_coordinator - storage_directives = var.loki_coordinator.storage_directives - units = var.loki_coordinator.units -} - -# Monolithic: single all-in-one worker -module "loki_worker" { - source = "git::https://github.com/canonical/loki-operators//worker/terraform" - count = var.topology == "monolithic" ? 1 : 0 - depends_on = [module.loki_coordinator] - - app_name = var.loki_worker.app_name - channel = local.channels.loki - config = merge({ "role-all" = "true" }, var.loki_worker.config) - constraints = var.loki_worker.constraints - model_uuid = var.model_uuid - resources = var.loki_worker.resources - revision = local.revisions.loki_worker - storage_directives = var.loki_worker.storage_directives - units = var.loki_worker.units -} - -# Distributed: separate backend, read, and write workers -module "loki_worker_backend" { - source = "git::https://github.com/canonical/loki-operators//worker/terraform" - count = var.topology == "distributed" ? 1 : 0 - depends_on = [module.loki_coordinator] - - app_name = "${var.loki_worker.app_name}-backend" - channel = local.channels.loki - config = merge({ "role-backend" = "true" }, var.loki_worker.backend_config) - constraints = var.loki_worker.constraints - model_uuid = var.model_uuid - resources = var.loki_worker.resources - revision = local.revisions.loki_worker - storage_directives = var.loki_worker.backend_storage_directives - units = var.loki_worker.backend_units -} - -module "loki_worker_read" { - source = "git::https://github.com/canonical/loki-operators//worker/terraform" - count = var.topology == "distributed" ? 1 : 0 - depends_on = [module.loki_coordinator] - - app_name = "${var.loki_worker.app_name}-read" - channel = local.channels.loki - config = merge({ "role-read" = "true" }, var.loki_worker.read_config) - constraints = var.loki_worker.constraints - model_uuid = var.model_uuid - resources = var.loki_worker.resources - revision = local.revisions.loki_worker - storage_directives = var.loki_worker.read_storage_directives - units = var.loki_worker.read_units -} - -module "loki_worker_write" { - source = "git::https://github.com/canonical/loki-operators//worker/terraform" - count = var.topology == "distributed" ? 1 : 0 - depends_on = [module.loki_coordinator] - - app_name = "${var.loki_worker.app_name}-write" - channel = local.channels.loki - config = merge({ "role-write" = "true" }, var.loki_worker.write_config) - constraints = var.loki_worker.constraints - model_uuid = var.model_uuid - resources = var.loki_worker.resources - revision = local.revisions.loki_worker - storage_directives = var.loki_worker.write_storage_directives - units = var.loki_worker.write_units -} - -module "mimir_coordinator" { - source = "git::https://github.com/canonical/mimir-operators//coordinator/terraform" - - app_name = var.mimir_coordinator.app_name - channel = local.channels.mimir - config = var.mimir_coordinator.config - constraints = var.mimir_coordinator.constraints - model_uuid = var.model_uuid - resources = var.mimir_coordinator.resources - revision = local.revisions.mimir_coordinator - storage_directives = var.mimir_coordinator.storage_directives - units = var.mimir_coordinator.units -} - -# Monolithic: single all-in-one worker -module "mimir_worker" { - source = "git::https://github.com/canonical/mimir-operators//worker/terraform" - count = var.topology == "monolithic" ? 1 : 0 - depends_on = [module.mimir_coordinator] - - app_name = var.mimir_worker.app_name - channel = local.channels.mimir - config = merge({ "role-all" = "true" }, var.mimir_worker.config) - constraints = var.mimir_worker.constraints - model_uuid = var.model_uuid - resources = var.mimir_worker.resources - revision = local.revisions.mimir_worker - storage_directives = var.mimir_worker.storage_directives - units = var.mimir_worker.units -} - -# Distributed: separate backend, read, and write workers -module "mimir_worker_backend" { - source = "git::https://github.com/canonical/mimir-operators//worker/terraform" - count = var.topology == "distributed" ? 1 : 0 - depends_on = [module.mimir_coordinator] - - app_name = "${var.mimir_worker.app_name}-backend" - channel = local.channels.mimir - config = merge({ "role-backend" = "true" }, var.mimir_worker.backend_config) - constraints = var.mimir_worker.constraints - model_uuid = var.model_uuid - resources = var.mimir_worker.resources - revision = local.revisions.mimir_worker - storage_directives = var.mimir_worker.backend_storage_directives - units = var.mimir_worker.backend_units -} - -module "mimir_worker_read" { - source = "git::https://github.com/canonical/mimir-operators//worker/terraform" - count = var.topology == "distributed" ? 1 : 0 - depends_on = [module.mimir_coordinator] - - app_name = "${var.mimir_worker.app_name}-read" - channel = local.channels.mimir - config = merge({ "role-read" = "true" }, var.mimir_worker.read_config) - constraints = var.mimir_worker.constraints - model_uuid = var.model_uuid - resources = var.mimir_worker.resources - revision = local.revisions.mimir_worker - storage_directives = var.mimir_worker.read_storage_directives - units = var.mimir_worker.read_units -} - -module "mimir_worker_write" { - source = "git::https://github.com/canonical/mimir-operators//worker/terraform" - count = var.topology == "distributed" ? 1 : 0 - depends_on = [module.mimir_coordinator] - - app_name = "${var.mimir_worker.app_name}-write" - channel = local.channels.mimir - config = merge({ "role-write" = "true" }, var.mimir_worker.write_config) - constraints = var.mimir_worker.constraints - model_uuid = var.model_uuid - resources = var.mimir_worker.resources - revision = local.revisions.mimir_worker - storage_directives = var.mimir_worker.write_storage_directives - units = var.mimir_worker.write_units -} - -module "opentelemetry_collector" { - source = "git::https://github.com/canonical/opentelemetry-collector-k8s-operator//terraform" - - app_name = var.opentelemetry_collector.app_name - channel = local.channels.otelcol - config = var.opentelemetry_collector.config - constraints = var.opentelemetry_collector.constraints - model_uuid = var.model_uuid - resources = var.opentelemetry_collector.resources - revision = local.revisions.otelcol - storage_directives = var.opentelemetry_collector.storage_directives - units = var.opentelemetry_collector.units -} - -module "seaweedfs" { - source = "git::https://github.com/canonical/observability-stack//terraform/seaweedfs" - count = var.storage_backend == "seaweedfs" ? 1 : 0 - - app_name = var.seaweedfs.app_name - channel = local.channels.seaweedfs - config = var.seaweedfs.config - constraints = var.seaweedfs.constraints - model_uuid = var.model_uuid - revision = local.revisions.seaweedfs - storage_directives = var.seaweedfs.storage_directives - units = var.seaweedfs.units -} - -module "ssc" { - source = "git::https://github.com/canonical/self-signed-certificates-operator//terraform" - count = var.internal_tls ? 1 : 0 - - app_name = var.ssc.app_name - channel = local.channels.ssc - config = var.ssc.config - constraints = var.ssc.constraints - model_uuid = var.model_uuid - revision = local.revisions.ssc - units = var.ssc.units -} - -module "tempo_coordinator" { - source = "git::https://github.com/canonical/tempo-operators//coordinator/terraform" - - app_name = var.tempo_coordinator.app_name - channel = local.channels.tempo - config = var.tempo_coordinator.config - constraints = var.tempo_coordinator.constraints - model_uuid = var.model_uuid - resources = var.tempo_coordinator.resources - revision = local.revisions.tempo_coordinator - storage_directives = var.tempo_coordinator.storage_directives - units = var.tempo_coordinator.units -} - -# Monolithic: single all-in-one worker -module "tempo_worker" { - source = "git::https://github.com/canonical/tempo-operators//worker/terraform" - count = var.topology == "monolithic" ? 1 : 0 - depends_on = [module.tempo_coordinator] - - app_name = var.tempo_worker.app_name - channel = local.channels.tempo - config = merge({ "role-all" = "true" }, var.tempo_worker.config) - constraints = var.tempo_worker.constraints - model_uuid = var.model_uuid - resources = var.tempo_worker.resources - revision = local.revisions.tempo_worker - storage_directives = var.tempo_worker.storage_directives - units = var.tempo_worker.units -} - -# Distributed: separate workers per role -module "tempo_worker_querier" { - source = "git::https://github.com/canonical/tempo-operators//worker/terraform" - count = var.topology == "distributed" ? 1 : 0 - depends_on = [module.tempo_coordinator] - - app_name = "${var.tempo_worker.app_name}-querier" - channel = local.channels.tempo - config = merge({ "role-all" = "false", "role-querier" = "true" }, var.tempo_worker.querier_config) - constraints = var.tempo_worker.constraints - model_uuid = var.model_uuid - resources = var.tempo_worker.resources - revision = local.revisions.tempo_worker - storage_directives = var.tempo_worker.querier_storage_directives - units = var.tempo_worker.querier_units -} - -module "tempo_worker_query_frontend" { - source = "git::https://github.com/canonical/tempo-operators//worker/terraform" - count = var.topology == "distributed" ? 1 : 0 - depends_on = [module.tempo_coordinator] - - app_name = "${var.tempo_worker.app_name}-query-frontend" - channel = local.channels.tempo - config = merge({ "role-all" = "false", "role-query-frontend" = "true" }, var.tempo_worker.query_frontend_config) - constraints = var.tempo_worker.constraints - model_uuid = var.model_uuid - resources = var.tempo_worker.resources - revision = local.revisions.tempo_worker - storage_directives = var.tempo_worker.query_frontend_storage_directives - units = var.tempo_worker.query_frontend_units -} - -module "tempo_worker_ingester" { - source = "git::https://github.com/canonical/tempo-operators//worker/terraform" - count = var.topology == "distributed" ? 1 : 0 - depends_on = [module.tempo_coordinator] - - app_name = "${var.tempo_worker.app_name}-ingester" - channel = local.channels.tempo - config = merge({ "role-all" = "false", "role-ingester" = "true" }, var.tempo_worker.ingester_config) - constraints = var.tempo_worker.constraints - model_uuid = var.model_uuid - resources = var.tempo_worker.resources - revision = local.revisions.tempo_worker - storage_directives = var.tempo_worker.ingester_storage_directives - units = var.tempo_worker.ingester_units -} - -module "tempo_worker_distributor" { - source = "git::https://github.com/canonical/tempo-operators//worker/terraform" - count = var.topology == "distributed" ? 1 : 0 - depends_on = [module.tempo_coordinator] - - app_name = "${var.tempo_worker.app_name}-distributor" - channel = local.channels.tempo - config = merge({ "role-all" = "false", "role-distributor" = "true" }, var.tempo_worker.distributor_config) - constraints = var.tempo_worker.constraints - model_uuid = var.model_uuid - resources = var.tempo_worker.resources - revision = local.revisions.tempo_worker - storage_directives = var.tempo_worker.distributor_storage_directives - units = var.tempo_worker.distributor_units -} - -module "tempo_worker_compactor" { - source = "git::https://github.com/canonical/tempo-operators//worker/terraform" - count = var.topology == "distributed" ? 1 : 0 - depends_on = [module.tempo_coordinator] - - app_name = "${var.tempo_worker.app_name}-compactor" - channel = local.channels.tempo - config = merge({ "role-all" = "false", "role-compactor" = "true" }, var.tempo_worker.compactor_config) - constraints = var.tempo_worker.constraints - model_uuid = var.model_uuid - resources = var.tempo_worker.resources - revision = local.revisions.tempo_worker - storage_directives = var.tempo_worker.compactor_storage_directives - units = var.tempo_worker.compactor_units -} - -module "tempo_worker_metrics_generator" { - source = "git::https://github.com/canonical/tempo-operators//worker/terraform" - count = var.topology == "distributed" ? 1 : 0 - depends_on = [module.tempo_coordinator] - - app_name = "${var.tempo_worker.app_name}-metrics-generator" - channel = local.channels.tempo - config = merge({ "role-all" = "false", "role-metrics-generator" = "true" }, var.tempo_worker.metrics_generator_config) - constraints = var.tempo_worker.constraints - model_uuid = var.model_uuid - resources = var.tempo_worker.resources - revision = local.revisions.tempo_worker - storage_directives = var.tempo_worker.metrics_generator_storage_directives - units = var.tempo_worker.metrics_generator_units -} - -module "traefik" { - source = "git::https://github.com/canonical/traefik-k8s-operator//terraform" - count = local.traefik_enabled ? 1 : 0 - - app_name = var.traefik.app_name - channel = local.channels.traefik - config = var.traefik.config - constraints = var.traefik.constraints - model_uuid = var.model_uuid - resources = var.traefik.resources - revision = local.revisions.traefik - storage_directives = var.traefik.storage_directives - units = var.traefik.units -} - -# -------------- # S3-integrator resources (storage_backend = "s3") -------------- - -resource "juju_secret" "loki_s3_credentials" { - count = var.storage_backend == "s3" ? 1 : 0 - - model_uuid = var.model_uuid - name = "loki-s3-credentials" - value = { - access-key = var.s3_access_key - secret-key = var.s3_secret_key - } - info = "S3 credentials for Loki" -} - -resource "juju_access_secret" "loki_s3_credentials_access" { - count = var.storage_backend == "s3" ? 1 : 0 - - model_uuid = var.model_uuid - applications = [juju_application.s3_integrator_loki[0].name] - secret_id = juju_secret.loki_s3_credentials[0].secret_id -} - -# TODO: Replace with a remote terraform module once the s3-integrator charm exposes one. -resource "juju_application" "s3_integrator_loki" { - count = var.storage_backend == "s3" ? 1 : 0 - - config = merge({ - endpoint = var.s3_endpoint - bucket = var.loki_bucket - credentials = "secret:${juju_secret.loki_s3_credentials[0].secret_id}" - }, var.s3_integrator.config) - constraints = var.s3_integrator.constraints - model_uuid = var.model_uuid - name = "${var.loki_coordinator.app_name}-s3-integrator" - storage_directives = var.s3_integrator.storage_directives - trust = true - units = var.s3_integrator.units - - charm { - name = "s3-integrator" - channel = local.channels.s3_integrator - revision = local.revisions.s3_integrator - } -} - -resource "juju_secret" "mimir_s3_credentials" { - count = var.storage_backend == "s3" ? 1 : 0 - - model_uuid = var.model_uuid - name = "mimir-s3-credentials" - value = { - access-key = var.s3_access_key - secret-key = var.s3_secret_key - } - info = "S3 credentials for Mimir" -} - -resource "juju_access_secret" "mimir_s3_credentials_access" { - count = var.storage_backend == "s3" ? 1 : 0 - - model_uuid = var.model_uuid - applications = [juju_application.s3_integrator_mimir[0].name] - secret_id = juju_secret.mimir_s3_credentials[0].secret_id -} - -resource "juju_application" "s3_integrator_mimir" { - count = var.storage_backend == "s3" ? 1 : 0 - - config = merge({ - endpoint = var.s3_endpoint - bucket = var.mimir_bucket - credentials = "secret:${juju_secret.mimir_s3_credentials[0].secret_id}" - }, var.s3_integrator.config) - constraints = var.s3_integrator.constraints - model_uuid = var.model_uuid - name = "${var.mimir_coordinator.app_name}-s3-integrator" - storage_directives = var.s3_integrator.storage_directives - trust = true - units = var.s3_integrator.units - - charm { - name = "s3-integrator" - channel = local.channels.s3_integrator - revision = local.revisions.s3_integrator - } -} - -resource "juju_secret" "tempo_s3_credentials" { - count = var.storage_backend == "s3" ? 1 : 0 - - model_uuid = var.model_uuid - name = "tempo-s3-credentials" - value = { - access-key = var.s3_access_key - secret-key = var.s3_secret_key - } - info = "S3 credentials for Tempo" -} - -resource "juju_access_secret" "tempo_s3_credentials_access" { - count = var.storage_backend == "s3" ? 1 : 0 - - model_uuid = var.model_uuid - applications = [juju_application.s3_integrator_tempo[0].name] - secret_id = juju_secret.tempo_s3_credentials[0].secret_id -} - -resource "juju_application" "s3_integrator_tempo" { - count = var.storage_backend == "s3" ? 1 : 0 - - config = merge({ - endpoint = var.s3_endpoint - bucket = var.tempo_bucket - credentials = "secret:${juju_secret.tempo_s3_credentials[0].secret_id}" - }, var.s3_integrator.config) - constraints = var.s3_integrator.constraints - model_uuid = var.model_uuid - name = "${var.tempo_coordinator.app_name}-s3-integrator" - storage_directives = var.s3_integrator.storage_directives - trust = true - units = var.s3_integrator.units - - charm { - name = "s3-integrator" - channel = local.channels.s3_integrator - revision = local.revisions.s3_integrator - } -} diff --git a/terraform/cos-dev/integrations.tf b/terraform/cos-dev/integrations.tf deleted file mode 100644 index f62ab0c4..00000000 --- a/terraform/cos-dev/integrations.tf +++ /dev/null @@ -1,879 +0,0 @@ -# -------------- # Cluster integrations --------------------- - -# Monolithic: coordinator ↔ single all-in-one worker -resource "juju_integration" "loki_cluster" { - count = var.topology == "monolithic" ? 1 : 0 - - model_uuid = var.model_uuid - - application { - name = module.loki_coordinator.app_name - endpoint = module.loki_coordinator.provides.loki_cluster - } - - application { - name = module.loki_worker[0].app_name - endpoint = module.loki_worker[0].requires.loki_cluster - } -} - -# Distributed: coordinator ↔ separate backend, read, write workers -resource "juju_integration" "loki_cluster_backend" { - count = var.topology == "distributed" ? 1 : 0 - - model_uuid = var.model_uuid - - application { - name = module.loki_coordinator.app_name - endpoint = module.loki_coordinator.provides.loki_cluster - } - - application { - name = module.loki_worker_backend[0].app_name - endpoint = module.loki_worker_backend[0].requires.loki_cluster - } -} - -resource "juju_integration" "loki_cluster_read" { - count = var.topology == "distributed" ? 1 : 0 - - model_uuid = var.model_uuid - - application { - name = module.loki_coordinator.app_name - endpoint = module.loki_coordinator.provides.loki_cluster - } - - application { - name = module.loki_worker_read[0].app_name - endpoint = module.loki_worker_read[0].requires.loki_cluster - } -} - -resource "juju_integration" "loki_cluster_write" { - count = var.topology == "distributed" ? 1 : 0 - - model_uuid = var.model_uuid - - application { - name = module.loki_coordinator.app_name - endpoint = module.loki_coordinator.provides.loki_cluster - } - - application { - name = module.loki_worker_write[0].app_name - endpoint = module.loki_worker_write[0].requires.loki_cluster - } -} - -resource "juju_integration" "mimir_cluster" { - count = var.topology == "monolithic" ? 1 : 0 - - model_uuid = var.model_uuid - - application { - name = module.mimir_coordinator.app_name - endpoint = module.mimir_coordinator.provides.mimir_cluster - } - - application { - name = module.mimir_worker[0].app_name - endpoint = module.mimir_worker[0].requires.mimir_cluster - } -} - -resource "juju_integration" "mimir_cluster_backend" { - count = var.topology == "distributed" ? 1 : 0 - - model_uuid = var.model_uuid - - application { - name = module.mimir_coordinator.app_name - endpoint = module.mimir_coordinator.provides.mimir_cluster - } - - application { - name = module.mimir_worker_backend[0].app_name - endpoint = module.mimir_worker_backend[0].requires.mimir_cluster - } -} - -resource "juju_integration" "mimir_cluster_read" { - count = var.topology == "distributed" ? 1 : 0 - - model_uuid = var.model_uuid - - application { - name = module.mimir_coordinator.app_name - endpoint = module.mimir_coordinator.provides.mimir_cluster - } - - application { - name = module.mimir_worker_read[0].app_name - endpoint = module.mimir_worker_read[0].requires.mimir_cluster - } -} - -resource "juju_integration" "mimir_cluster_write" { - count = var.topology == "distributed" ? 1 : 0 - - model_uuid = var.model_uuid - - application { - name = module.mimir_coordinator.app_name - endpoint = module.mimir_coordinator.provides.mimir_cluster - } - - application { - name = module.mimir_worker_write[0].app_name - endpoint = module.mimir_worker_write[0].requires.mimir_cluster - } -} - -resource "juju_integration" "tempo_cluster" { - count = var.topology == "monolithic" ? 1 : 0 - - model_uuid = var.model_uuid - - application { - name = module.tempo_coordinator.app_name - endpoint = module.tempo_coordinator.provides.tempo_cluster - } - - application { - name = module.tempo_worker[0].app_name - endpoint = module.tempo_worker[0].requires.tempo_cluster - } -} - -resource "juju_integration" "tempo_cluster_querier" { - count = var.topology == "distributed" ? 1 : 0 - - model_uuid = var.model_uuid - - application { - name = module.tempo_coordinator.app_name - endpoint = "tempo-cluster" - } - - application { - name = module.tempo_worker_querier[0].app_name - endpoint = "tempo-cluster" - } -} - -resource "juju_integration" "tempo_cluster_query_frontend" { - count = var.topology == "distributed" ? 1 : 0 - - model_uuid = var.model_uuid - - application { - name = module.tempo_coordinator.app_name - endpoint = "tempo-cluster" - } - - application { - name = module.tempo_worker_query_frontend[0].app_name - endpoint = "tempo-cluster" - } -} - -resource "juju_integration" "tempo_cluster_ingester" { - count = var.topology == "distributed" ? 1 : 0 - - model_uuid = var.model_uuid - - application { - name = module.tempo_coordinator.app_name - endpoint = "tempo-cluster" - } - - application { - name = module.tempo_worker_ingester[0].app_name - endpoint = "tempo-cluster" - } -} - -resource "juju_integration" "tempo_cluster_distributor" { - count = var.topology == "distributed" ? 1 : 0 - - model_uuid = var.model_uuid - - application { - name = module.tempo_coordinator.app_name - endpoint = "tempo-cluster" - } - - application { - name = module.tempo_worker_distributor[0].app_name - endpoint = "tempo-cluster" - } -} - -resource "juju_integration" "tempo_cluster_compactor" { - count = var.topology == "distributed" ? 1 : 0 - - model_uuid = var.model_uuid - - application { - name = module.tempo_coordinator.app_name - endpoint = "tempo-cluster" - } - - application { - name = module.tempo_worker_compactor[0].app_name - endpoint = "tempo-cluster" - } -} - -resource "juju_integration" "tempo_cluster_metrics_generator" { - count = var.topology == "distributed" ? 1 : 0 - - model_uuid = var.model_uuid - - application { - name = module.tempo_coordinator.app_name - endpoint = "tempo-cluster" - } - - application { - name = module.tempo_worker_metrics_generator[0].app_name - endpoint = "tempo-cluster" - } -} - -# -------------- # SeaweedFS S3 storage ------------------- - -resource "juju_integration" "seaweedfs_loki" { - count = var.storage_backend == "seaweedfs" ? 1 : 0 - - model_uuid = var.model_uuid - - application { - name = module.seaweedfs[0].app_name - endpoint = module.seaweedfs[0].provides.s3 - } - - application { - name = module.loki_coordinator.app_name - endpoint = "s3" - } -} - -resource "juju_integration" "seaweedfs_mimir" { - count = var.storage_backend == "seaweedfs" ? 1 : 0 - - model_uuid = var.model_uuid - - application { - name = module.seaweedfs[0].app_name - endpoint = module.seaweedfs[0].provides.s3 - } - - application { - name = module.mimir_coordinator.app_name - endpoint = "s3" - } -} - -resource "juju_integration" "seaweedfs_tempo" { - count = var.storage_backend == "seaweedfs" ? 1 : 0 - - model_uuid = var.model_uuid - - application { - name = module.seaweedfs[0].app_name - endpoint = module.seaweedfs[0].provides.s3 - } - - application { - name = module.tempo_coordinator.app_name - endpoint = module.tempo_coordinator.requires.s3 - } -} - -# -------------- # S3-integrator storage ------------------- - -resource "juju_integration" "s3_integrator_loki" { - count = var.storage_backend == "s3" ? 1 : 0 - - model_uuid = var.model_uuid - - application { - name = juju_application.s3_integrator_loki[0].name - endpoint = "s3-credentials" - } - - application { - name = module.loki_coordinator.app_name - endpoint = "s3" - } -} - -resource "juju_integration" "s3_integrator_mimir" { - count = var.storage_backend == "s3" ? 1 : 0 - - model_uuid = var.model_uuid - - application { - name = juju_application.s3_integrator_mimir[0].name - endpoint = "s3-credentials" - } - - application { - name = module.mimir_coordinator.app_name - endpoint = "s3" - } -} - -resource "juju_integration" "s3_integrator_tempo" { - count = var.storage_backend == "s3" ? 1 : 0 - - model_uuid = var.model_uuid - - application { - name = juju_application.s3_integrator_tempo[0].name - endpoint = "s3-credentials" - } - - application { - name = module.tempo_coordinator.app_name - endpoint = module.tempo_coordinator.requires.s3 - } -} - -# -------------- # Grafana Dashboard --------------------- - -resource "juju_integration" "grafana_dashboards" { - for_each = { - alertmanager = { - app_name = module.alertmanager.app_name - endpoint = module.alertmanager.provides.grafana_dashboard - } - loki = { - app_name = module.loki_coordinator.app_name - endpoint = "grafana-dashboards-provider" - } - mimir = { - app_name = module.mimir_coordinator.app_name - endpoint = "grafana-dashboards-provider" - } - otelcol = { - app_name = module.opentelemetry_collector.app_name - endpoint = module.opentelemetry_collector.provides.grafana_dashboards_provider - } - tempo = { - app_name = module.tempo_coordinator.app_name - endpoint = module.tempo_coordinator.provides.grafana_dashboard - } - } - - model_uuid = var.model_uuid - - application { - name = each.value.app_name - endpoint = each.value.endpoint - } - - application { - name = module.grafana.app_name - endpoint = module.grafana.requires.grafana_dashboard - } - - lifecycle { replace_triggered_by = [terraform_data.grafana_litestream_resource] } -} - -# -------------- # Charm Tracing ------------------------ - -resource "juju_integration" "charm_tracing" { - for_each = { - loki = { - app_name = module.loki_coordinator.app_name - endpoint = "charm-tracing" - } - mimir = { - app_name = module.mimir_coordinator.app_name - endpoint = "charm-tracing" - } - } - - model_uuid = var.model_uuid - - application { - name = each.value.app_name - endpoint = each.value.endpoint - } - - application { - name = module.opentelemetry_collector.app_name - endpoint = module.opentelemetry_collector.provides.receive_traces - } -} - -resource "juju_integration" "charm_tracing_grafana" { - model_uuid = var.model_uuid - - application { - name = module.grafana.app_name - endpoint = module.grafana.requires.charm_tracing - } - - application { - name = module.opentelemetry_collector.app_name - endpoint = module.opentelemetry_collector.provides.receive_traces - } - - lifecycle { replace_triggered_by = [terraform_data.grafana_litestream_resource] } -} - -# -------------- # Metrics Endpoint ---------------------- - -resource "juju_integration" "otelcol_metrics_endpoint" { - for_each = { - alertmanager = { - app_name = module.alertmanager.app_name - endpoint = module.alertmanager.provides.self_metrics_endpoint - } - loki = { - app_name = module.loki_coordinator.app_name - endpoint = "self-metrics-endpoint" - } - mimir = { - app_name = module.mimir_coordinator.app_name - endpoint = "self-metrics-endpoint" - } - tempo = { - app_name = module.tempo_coordinator.app_name - endpoint = module.tempo_coordinator.provides.metrics_endpoint - } - } - - model_uuid = var.model_uuid - - application { - name = each.value.app_name - endpoint = each.value.endpoint - } - - application { - name = module.opentelemetry_collector.app_name - endpoint = module.opentelemetry_collector.requires.metrics_endpoint - } -} - -# -------------- # Grafana Source Integrations -------------- - -resource "juju_integration" "grafana_sources" { - for_each = { - alertmanager = { - app_name = module.alertmanager.app_name - endpoint = module.alertmanager.provides.grafana_source - } - loki = { - app_name = module.loki_coordinator.app_name - endpoint = "grafana-source" - } - mimir = { - app_name = module.mimir_coordinator.app_name - endpoint = "grafana-source" - } - tempo = { - app_name = module.tempo_coordinator.app_name - endpoint = module.tempo_coordinator.provides.grafana_source - } - } - - model_uuid = var.model_uuid - - application { - name = each.value.app_name - endpoint = each.value.endpoint - } - - application { - name = module.grafana.app_name - endpoint = module.grafana.requires.grafana_source - } - - lifecycle { replace_triggered_by = [terraform_data.grafana_litestream_resource] } -} - -# -------------- # Receive Loki Logs --------------------- - -resource "juju_integration" "otelcol_logging_provider" { - for_each = { - loki = { - app_name = module.loki_coordinator.app_name - endpoint = "logging-consumer" - } - mimir = { - app_name = module.mimir_coordinator.app_name - endpoint = "logging-consumer" - } - tempo = { - app_name = module.tempo_coordinator.app_name - endpoint = module.tempo_coordinator.requires.logging - } - } - - model_uuid = var.model_uuid - - application { - name = each.value.app_name - endpoint = each.value.endpoint - } - - application { - name = module.opentelemetry_collector.app_name - endpoint = module.opentelemetry_collector.provides.receive_loki_logs - } -} - -# -------------- # Alertmanager integrations -------------- - -resource "juju_integration" "alerting" { - for_each = { - loki = { - app_name = module.loki_coordinator.app_name - endpoint = "alertmanager" - } - mimir = { - app_name = module.mimir_coordinator.app_name - endpoint = "alertmanager" - } - } - - model_uuid = var.model_uuid - - application { - name = each.value.app_name - endpoint = each.value.endpoint - } - - application { - name = module.alertmanager.app_name - endpoint = module.alertmanager.provides.alerting - } -} - -# -------------- # Provided by Loki -------------- - -resource "juju_integration" "loki_logging_otelcol_logging_consumer" { - model_uuid = var.model_uuid - - application { - name = module.loki_coordinator.app_name - endpoint = "logging" - } - - application { - name = module.opentelemetry_collector.app_name - endpoint = module.opentelemetry_collector.requires.send_loki_logs - } -} - -# -------------- # Provided by Tempo -------------- - -resource "juju_integration" "tempo_tracing_otelcol_tracing" { - model_uuid = var.model_uuid - - application { - name = module.tempo_coordinator.app_name - endpoint = module.tempo_coordinator.provides.tracing - } - - application { - name = module.opentelemetry_collector.app_name - endpoint = module.opentelemetry_collector.requires.send_traces - } -} - -resource "juju_integration" "tempo_send_remote_write_mimir_receive_remote_write" { - model_uuid = var.model_uuid - - application { - name = module.tempo_coordinator.app_name - endpoint = module.tempo_coordinator.requires.send_remote_write - } - - application { - name = module.mimir_coordinator.app_name - endpoint = "receive-remote-write" - } -} - -# -------------- # Catalogue Integrations -------------- - -resource "juju_integration" "catalogue_integrations" { - for_each = { - alertmanager = { - app_name = module.alertmanager.app_name - endpoint = module.alertmanager.requires.catalogue - } - mimir = { - app_name = module.mimir_coordinator.app_name - endpoint = "catalogue" - } - tempo = { - app_name = module.tempo_coordinator.app_name - endpoint = module.tempo_coordinator.requires.catalogue - } - } - - model_uuid = var.model_uuid - - application { - name = module.catalogue.app_name - endpoint = module.catalogue.provides.catalogue - } - - application { - name = each.value.app_name - endpoint = each.value.endpoint - } -} - -resource "juju_integration" "catalogue_integration_grafana" { - model_uuid = var.model_uuid - - application { - name = module.catalogue.app_name - endpoint = module.catalogue.provides.catalogue - } - - application { - name = module.grafana.app_name - endpoint = module.grafana.requires.catalogue - } - - lifecycle { replace_triggered_by = [terraform_data.grafana_litestream_resource] } -} - -# -------------- # Ingress -------------------------- - -resource "juju_integration" "ingress" { - for_each = { - for k, v in { - alertmanager = { - app_name = module.alertmanager.app_name - endpoint = module.alertmanager.requires.ingress - } - catalogue = { - app_name = module.catalogue.app_name - endpoint = module.catalogue.requires.ingress - } - loki = { - app_name = module.loki_coordinator.app_name - endpoint = "ingress" - } - mimir = { - app_name = module.mimir_coordinator.app_name - endpoint = "ingress" - } - } : k => v if local.traefik_enabled && var.ingress[k] - } - - model_uuid = var.model_uuid - - application { - name = module.traefik[0].app_name - endpoint = module.traefik[0].endpoints.ingress - } - - application { - name = each.value.app_name - endpoint = each.value.endpoint - } -} - -resource "juju_integration" "grafana_ingress" { - count = local.traefik_enabled && var.ingress.grafana ? 1 : 0 - - model_uuid = var.model_uuid - - application { - name = module.grafana.app_name - endpoint = module.grafana.requires.ingress - } - - application { - name = module.traefik[0].app_name - endpoint = module.traefik[0].endpoints.ingress - } - - lifecycle { replace_triggered_by = [terraform_data.grafana_ingress_interface, terraform_data.grafana_litestream_resource] } -} - -resource "juju_integration" "traefik_route" { - for_each = { - for k, v in { - opentelemetry_collector = { - app_name = module.opentelemetry_collector.app_name - endpoint = module.opentelemetry_collector.requires.ingress - } - tempo = { - app_name = module.tempo_coordinator.app_name - endpoint = module.tempo_coordinator.requires.ingress - } - } : k => v if local.traefik_enabled && var.ingress[k] - } - - model_uuid = var.model_uuid - - application { - name = module.traefik[0].app_name - endpoint = module.traefik[0].endpoints.traefik_route - } - - application { - name = each.value.app_name - endpoint = each.value.endpoint - } -} - -# -------------- # Provided by OpenTelemetry Collector -------------- - -resource "juju_integration" "opentelemetry_collector_mimir_metrics" { - model_uuid = var.model_uuid - - application { - name = module.mimir_coordinator.app_name - endpoint = "receive-remote-write" - } - - application { - name = module.opentelemetry_collector.app_name - endpoint = module.opentelemetry_collector.requires.send_remote_write - } -} - -# -------------- # Certificate Integrations -------------- - -resource "juju_integration" "internal_certificates" { - for_each = var.internal_tls ? { - alertmanager = { - app_name = module.alertmanager.app_name - endpoint = module.alertmanager.requires.certificates - } - catalogue = { - app_name = module.catalogue.app_name - endpoint = module.catalogue.requires.certificates - } - grafana = { - app_name = module.grafana.app_name - endpoint = module.grafana.requires.certificates - } - loki = { - app_name = module.loki_coordinator.app_name - endpoint = "certificates" - } - mimir = { - app_name = module.mimir_coordinator.app_name - endpoint = "certificates" - } - opentelemetry_collector = { - app_name = module.opentelemetry_collector.app_name - endpoint = module.opentelemetry_collector.requires.receive_server_cert - } - tempo = { - app_name = module.tempo_coordinator.app_name - endpoint = module.tempo_coordinator.requires.certificates - } - } : {} - - model_uuid = var.model_uuid - - application { - name = module.ssc[0].app_name - endpoint = module.ssc[0].provides.certificates - } - - application { - name = each.value.app_name - endpoint = each.value.endpoint - } -} - -resource "juju_integration" "traefik_receive_ca_certificate" { - count = local.traefik_enabled && var.internal_tls ? 1 : 0 - - model_uuid = var.model_uuid - - application { - name = module.ssc[0].app_name - endpoint = module.ssc[0].provides.send-ca-cert - } - - application { - name = module.traefik[0].app_name - endpoint = module.traefik[0].endpoints.receive_ca_cert - } -} - -# -------------- # Provided by an external CA -------------- - -resource "juju_integration" "external_traefik_certificates" { - count = local.traefik_enabled && local.tls_termination ? 1 : 0 - - model_uuid = var.model_uuid - - application { offer_url = var.external_certificates_offer_url } - application { - name = module.traefik[0].app_name - endpoint = module.traefik[0].endpoints.certificates - } -} - -resource "juju_integration" "external_grafana_ca_cert" { - count = local.tls_termination ? 1 : 0 - - model_uuid = var.model_uuid - - application { offer_url = var.external_ca_cert_offer_url } - application { - name = module.grafana.app_name - endpoint = module.grafana.requires.receive_ca_cert - } -} - -resource "juju_integration" "external_otelcol_ca_cert" { - count = local.tls_termination ? 1 : 0 - - model_uuid = var.model_uuid - - application { offer_url = var.external_ca_cert_offer_url } - application { - name = module.opentelemetry_collector.app_name - endpoint = module.opentelemetry_collector.requires.receive_ca_cert - } -} - -# -------------- # Telemetry correlations --------------------- - -resource "juju_integration" "traces_and_logs_correlation" { - model_uuid = var.model_uuid - - application { - name = module.tempo_coordinator.app_name - endpoint = module.tempo_coordinator.requires.receive_datasource - } - - application { - name = module.loki_coordinator.app_name - endpoint = "send-datasource" - } -} - -resource "juju_integration" "traces_and_metrics_correlation" { - model_uuid = var.model_uuid - - application { - name = module.tempo_coordinator.app_name - endpoint = module.tempo_coordinator.requires.receive_datasource - } - - application { - name = module.mimir_coordinator.app_name - endpoint = "send-datasource" - } -} diff --git a/terraform/cos-dev/locals.tf b/terraform/cos-dev/locals.tf deleted file mode 100644 index ffc1daf4..00000000 --- a/terraform/cos-dev/locals.tf +++ /dev/null @@ -1,55 +0,0 @@ -locals { - tls_termination = var.external_certificates_offer_url != null ? true : false - reverse_proxy_enabled = anytrue(values(var.ingress)) - traefik_enabled = local.reverse_proxy_enabled - bases = { - o11y = "ubuntu@26.04" - s3_integrator = "ubuntu@24.04" - ssc = "ubuntu@24.04" - swfs = "ubuntu@24.04" - traefik = "ubuntu@26.04" - } - 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}" - seaweedfs = "${local.tracks.seaweedfs}/${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.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 - seaweedfs = var.seaweedfs.revision != null ? var.seaweedfs.revision : data.juju_charm.seaweedfs_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 - } - tracks = { - alertmanager = "dev" - catalogue = "dev" - grafana = "dev" - loki = "dev" - mimir = "dev" - otelcol = "dev" - tempo = "dev" - # external charms - s3_integrator = "2" - seaweedfs = "latest" - ssc = "1" - traefik = "latest" - } -} diff --git a/terraform/cos-dev/offers.tf b/terraform/cos-dev/offers.tf deleted file mode 100644 index a5937c88..00000000 --- a/terraform/cos-dev/offers.tf +++ /dev/null @@ -1,36 +0,0 @@ -resource "juju_offer" "alertmanager_karma_dashboard" { - name = "alertmanager-karma-dashboard" - model_uuid = var.model_uuid - application_name = module.alertmanager.app_name - endpoints = [module.alertmanager.provides.karma_dashboard] -} - -resource "juju_offer" "grafana_dashboards" { - name = "grafana-dashboards" - model_uuid = var.model_uuid - application_name = module.grafana.app_name - endpoints = [module.grafana.requires.grafana_dashboard] - - lifecycle { replace_triggered_by = [terraform_data.grafana_litestream_resource] } -} - -resource "juju_offer" "loki_logging" { - name = "loki-logging" - model_uuid = var.model_uuid - application_name = module.loki_coordinator.app_name - endpoints = ["logging"] -} - -resource "juju_offer" "mimir_receive_remote_write" { - name = "mimir-receive-remote-write" - model_uuid = var.model_uuid - application_name = module.mimir_coordinator.app_name - endpoints = ["receive-remote-write"] -} - -resource "juju_offer" "tempo_tracing" { - name = "tempo-tracing" - model_uuid = var.model_uuid - application_name = module.tempo_coordinator.app_name - endpoints = [module.tempo_coordinator.provides.tracing] -} diff --git a/terraform/cos-dev/outputs.tf b/terraform/cos-dev/outputs.tf deleted file mode 100644 index 11f50d6d..00000000 --- a/terraform/cos-dev/outputs.tf +++ /dev/null @@ -1,45 +0,0 @@ -# -------------- # Integration offers -------------- # - -output "offers" { - value = { - alertmanager_karma_dashboard = juju_offer.alertmanager_karma_dashboard - grafana_dashboards = juju_offer.grafana_dashboards - loki_logging = juju_offer.loki_logging - mimir_receive_remote_write = juju_offer.mimir_receive_remote_write - tempo_tracing = juju_offer.tempo_tracing - } - description = "All Juju offers which are exposed by this product module" -} - -# -------------- # Submodules -------------- # - -output "components" { - value = { - alertmanager = module.alertmanager - catalogue = module.catalogue - grafana = module.grafana - loki_coordinator = module.loki_coordinator - loki_worker = try(module.loki_worker[0], null) - loki_worker_backend = try(module.loki_worker_backend[0], null) - loki_worker_read = try(module.loki_worker_read[0], null) - loki_worker_write = try(module.loki_worker_write[0], null) - mimir_coordinator = module.mimir_coordinator - mimir_worker = try(module.mimir_worker[0], null) - mimir_worker_backend = try(module.mimir_worker_backend[0], null) - mimir_worker_read = try(module.mimir_worker_read[0], null) - mimir_worker_write = try(module.mimir_worker_write[0], null) - opentelemetry_collector = module.opentelemetry_collector - seaweedfs = try(module.seaweedfs[0], null) - ssc = try(module.ssc[0], null) - tempo_coordinator = module.tempo_coordinator - tempo_worker = try(module.tempo_worker[0], null) - tempo_worker_querier = try(module.tempo_worker_querier[0], null) - tempo_worker_query_frontend = try(module.tempo_worker_query_frontend[0], null) - tempo_worker_ingester = try(module.tempo_worker_ingester[0], null) - tempo_worker_distributor = try(module.tempo_worker_distributor[0], null) - tempo_worker_compactor = try(module.tempo_worker_compactor[0], null) - tempo_worker_metrics_generator = try(module.tempo_worker_metrics_generator[0], null) - traefik = try(module.traefik[0], null) - } - description = "All Terraform charm modules which make up this product module" -} diff --git a/terraform/cos-dev/terraform.tf b/terraform/cos-dev/terraform.tf deleted file mode 100644 index bfe432d4..00000000 --- a/terraform/cos-dev/terraform.tf +++ /dev/null @@ -1,9 +0,0 @@ -terraform { - required_version = ">= 1.5" - required_providers { - juju = { - source = "juju/juju" - version = ">= 1.0" - } - } -} diff --git a/terraform/cos-dev/tests/conditional_ingress.tftest.hcl b/terraform/cos-dev/tests/conditional_ingress.tftest.hcl deleted file mode 100644 index 3530c4a5..00000000 --- a/terraform/cos-dev/tests/conditional_ingress.tftest.hcl +++ /dev/null @@ -1,70 +0,0 @@ -mock_provider "juju" {} - -variables { - model_uuid = "00000000-0000-0000-0000-000000000000" - opentelemetry_collector = { storage_directives = { "foo" = "1G" } } -} - -# --- traefik: all ingress enabled by default --- - -run "traefik_ingress_enabled" { - command = plan - - assert { - condition = length(module.traefik) == 1 - error_message = "Expected a traefik module when ingress is enabled" - } - - assert { - condition = length(juju_integration.ingress) == 4 - error_message = "Unexpected ingress integrations when ingress is enabled" - } - - assert { - condition = length(juju_integration.grafana_ingress) == 1 - error_message = "Unexpected grafana_ingress integrations when ingress is enabled" - } - - assert { - condition = length(juju_integration.traefik_route) == 2 - error_message = "Unexpected traefik_route integrations when ingress is enabled" - } -} - -# --- traefik: all ingress disabled --- - -run "traefik_ingress_disabled" { - command = plan - - variables { - ingress = { - alertmanager = false - catalogue = false - grafana = false - loki = false - mimir = false - opentelemetry_collector = false - tempo = false - } - } - - assert { - condition = length(module.traefik) == 0 - error_message = "Expected no traefik module when ingress is disabled" - } - - assert { - condition = length(juju_integration.ingress) == 0 - error_message = "Unexpected ingress integrations when ingress is disabled" - } - - assert { - condition = length(juju_integration.grafana_ingress) == 0 - error_message = "Unexpected grafana_ingress integrations when ingress is disabled" - } - - assert { - condition = length(juju_integration.traefik_route) == 0 - error_message = "Unexpected traefik_route integrations when ingress is disabled" - } -} diff --git a/terraform/cos-dev/tests/external_tls.tftest.hcl b/terraform/cos-dev/tests/external_tls.tftest.hcl deleted file mode 100644 index 30925f62..00000000 --- a/terraform/cos-dev/tests/external_tls.tftest.hcl +++ /dev/null @@ -1,54 +0,0 @@ -mock_provider "juju" {} - -variables { - model_uuid = "00000000-0000-0000-0000-000000000000" - opentelemetry_collector = { storage_directives = { "foo" = "1G" } } -} - -# --- external cert URLs both null: no validation error --- - -run "external_cert_urls_both_null" { - command = plan - - variables { - external_certificates_offer_url = null - external_ca_cert_offer_url = null - } -} - -# --- external cert URLs both set: no validation error --- - -run "external_cert_urls_both_set" { - command = plan - - variables { - external_certificates_offer_url = "admin/external-ca.tls-certificates" - external_ca_cert_offer_url = "admin/external-ca.send-ca-cert" - } -} - -# --- only external_certificates_offer_url set: validation error --- - -run "external_certificates_offer_url_only_fails" { - command = plan - - variables { - external_certificates_offer_url = "admin/external-ca.tls-certificates" - external_ca_cert_offer_url = null - } - - expect_failures = [var.external_certificates_offer_url] -} - -# --- only external_ca_cert_offer_url set: validation error --- - -run "external_ca_cert_offer_url_only_fails" { - command = plan - - variables { - external_certificates_offer_url = null - external_ca_cert_offer_url = "admin/external-ca.send-ca-cert" - } - - expect_failures = [var.external_certificates_offer_url] -} diff --git a/terraform/cos-dev/tests/internal_tls.tftest.hcl b/terraform/cos-dev/tests/internal_tls.tftest.hcl deleted file mode 100644 index 687f426e..00000000 --- a/terraform/cos-dev/tests/internal_tls.tftest.hcl +++ /dev/null @@ -1,50 +0,0 @@ -mock_provider "juju" {} - -variables { - model_uuid = "00000000-0000-0000-0000-000000000000" - opentelemetry_collector = { storage_directives = { "foo" = "1G" } } -} - -# --- default: internal_tls enabled --- - -run "internal_tls_enabled" { - command = plan - - assert { - condition = length(module.ssc) == 1 - error_message = "Expected ssc module when internal_tls is enabled" - } - - assert { - condition = length(juju_integration.internal_certificates) == 7 - error_message = "Unexpected internal_certificates integrations when internal_tls is enabled" - } - - assert { - condition = length(juju_integration.traefik_receive_ca_certificate) == 1 - error_message = "Unexpected traefik_receive_ca_certificate integrations when internal_tls is enabled" - } -} - -# --- internal_tls disabled: no ingress via traefik --- - -run "internal_tls_disabled" { - command = plan - - variables { internal_tls = false } - - assert { - condition = length(module.ssc) == 0 - error_message = "Expected no self-signed-certificates module when internal_tls is disabled" - } - - assert { - condition = length(juju_integration.internal_certificates) == 0 - error_message = "Unexpected internal_certificates integrations when internal_tls is disabled" - } - - assert { - condition = length(juju_integration.traefik_receive_ca_certificate) == 0 - error_message = "Unexpected traefik_receive_ca_certificate integrations when internal_tls is disabled" - } -} diff --git a/terraform/cos-dev/tests/revision_pin.tftest.hcl b/terraform/cos-dev/tests/revision_pin.tftest.hcl deleted file mode 100644 index f90c1945..00000000 --- a/terraform/cos-dev/tests/revision_pin.tftest.hcl +++ /dev/null @@ -1,175 +0,0 @@ -mock_provider "juju" {} - -variables { - model_uuid = "00000000-0000-0000-0000-000000000000" - opentelemetry_collector = { storage_directives = { "foo" = "1G" } } -} - -# --- 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 = 2 } - grafana = { revision = 3 } - loki_coordinator = { revision = 4 } - loki_worker = { revision = 5 } - mimir_coordinator = { revision = 6 } - mimir_worker = { revision = 7 } - opentelemetry_collector = { revision = 8, storage_directives = { "foo" = "1G" } } - seaweedfs = { revision = 9 } - s3_integrator = { revision = 14 } - ssc = { revision = 10 } - tempo_coordinator = { revision = 11 } - tempo_worker = { revision = 12 } - traefik = { revision = 13 } - } - - assert { - condition = local.revisions.alertmanager == 1 - error_message = "Expected alertmanager revision 1, got ${local.revisions.alertmanager}" - } - - assert { - condition = local.revisions.catalogue == 2 - error_message = "Expected catalogue revision 2, got ${local.revisions.catalogue}" - } - - assert { - condition = local.revisions.grafana == 3 - error_message = "Expected grafana revision 3, got ${local.revisions.grafana}" - } - - assert { - condition = local.revisions.loki_coordinator == 4 - error_message = "Expected loki_coordinator revision 4, got ${local.revisions.loki_coordinator}" - } - - assert { - condition = local.revisions.loki_worker == 5 - error_message = "Expected loki_worker revision 5, got ${local.revisions.loki_worker}" - } - - assert { - condition = local.revisions.mimir_coordinator == 6 - error_message = "Expected mimir_coordinator revision 6, got ${local.revisions.mimir_coordinator}" - } - - assert { - condition = local.revisions.mimir_worker == 7 - error_message = "Expected mimir_worker revision 7, got ${local.revisions.mimir_worker}" - } - - assert { - condition = local.revisions.otelcol == 8 - error_message = "Expected otelcol revision 8, got ${local.revisions.otelcol}" - } - - assert { - condition = local.revisions.seaweedfs == 9 - error_message = "Expected seaweedfs revision 9, got ${local.revisions.seaweedfs}" - } - - assert { - condition = local.revisions.s3_integrator == 14 - error_message = "Expected s3_integrator revision 14, got ${local.revisions.s3_integrator}" - } - - assert { - condition = local.revisions.ssc == 10 - error_message = "Expected ssc revision 10, got ${local.revisions.ssc}" - } - - assert { - condition = local.revisions.tempo_coordinator == 11 - error_message = "Expected tempo_coordinator revision 11, got ${local.revisions.tempo_coordinator}" - } - - assert { - condition = local.revisions.tempo_worker == 12 - error_message = "Expected tempo_worker revision 12, got ${local.revisions.tempo_worker}" - } - - assert { - 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.seaweedfs == data.juju_charm.seaweedfs_info.revision - error_message = "seaweedfs 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.ssc == data.juju_charm.ssc_info.revision - error_message = "ssc 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-dev/tests/topology_and_storage.tftest.hcl b/terraform/cos-dev/tests/topology_and_storage.tftest.hcl deleted file mode 100644 index bd10af26..00000000 --- a/terraform/cos-dev/tests/topology_and_storage.tftest.hcl +++ /dev/null @@ -1,408 +0,0 @@ -mock_provider "juju" {} - -variables { - model_uuid = "00000000-0000-0000-0000-000000000000" - opentelemetry_collector = { storage_directives = { "foo" = "1G" } } -} - -# --- Default: monolithic topology with seaweedfs --- - -run "default_monolithic_seaweedfs" { - command = plan - - assert { - condition = length(module.seaweedfs) == 1 - error_message = "Expected seaweedfs module to be deployed with seaweedfs storage backend" - } - - assert { - condition = alltrue([ - length(juju_integration.seaweedfs_loki) == 1, - length(juju_integration.seaweedfs_mimir) == 1, - length(juju_integration.seaweedfs_tempo) == 1, - ]) - error_message = "Expected seaweedfs integrations to all coordinators" - } - - assert { - condition = alltrue([ - length(module.loki_worker) == 1, - length(module.mimir_worker) == 1, - length(module.tempo_worker) == 1, - ]) - error_message = "Expected all monolithic workers to be deployed" - } - - assert { - condition = !anytrue([ - length(module.loki_worker_backend) > 0, - length(module.loki_worker_read) > 0, - length(module.loki_worker_write) > 0, - ]) - error_message = "Expected no distributed loki workers in monolithic mode" - } - - assert { - condition = !anytrue([ - length(module.mimir_worker_backend) > 0, - length(module.mimir_worker_read) > 0, - length(module.mimir_worker_write) > 0, - ]) - error_message = "Expected no distributed mimir workers in monolithic mode" - } - - assert { - condition = !anytrue([ - length(module.tempo_worker_querier) > 0, - length(module.tempo_worker_query_frontend) > 0, - length(module.tempo_worker_ingester) > 0, - length(module.tempo_worker_distributor) > 0, - length(module.tempo_worker_compactor) > 0, - length(module.tempo_worker_metrics_generator) > 0, - ]) - error_message = "Expected no distributed tempo workers in monolithic mode" - } - - assert { - condition = alltrue([ - length(juju_integration.loki_cluster) == 1, - length(juju_integration.mimir_cluster) == 1, - length(juju_integration.tempo_cluster) == 1, - ]) - error_message = "Expected monolithic cluster integrations for all coordinators" - } - - assert { - condition = !anytrue([ - length(juju_integration.loki_cluster_backend) > 0, - length(juju_integration.loki_cluster_read) > 0, - length(juju_integration.loki_cluster_write) > 0, - ]) - error_message = "Expected no distributed loki cluster integrations in monolithic mode" - } - - assert { - condition = !anytrue([ - length(juju_integration.mimir_cluster_backend) > 0, - length(juju_integration.mimir_cluster_read) > 0, - length(juju_integration.mimir_cluster_write) > 0, - ]) - error_message = "Expected no distributed mimir cluster integrations in monolithic mode" - } - - assert { - condition = !anytrue([ - length(juju_integration.tempo_cluster_querier) > 0, - length(juju_integration.tempo_cluster_query_frontend) > 0, - length(juju_integration.tempo_cluster_ingester) > 0, - length(juju_integration.tempo_cluster_distributor) > 0, - length(juju_integration.tempo_cluster_compactor) > 0, - length(juju_integration.tempo_cluster_metrics_generator) > 0, - ]) - error_message = "Expected no distributed tempo cluster integrations in monolithic mode" - } -} - -# --- Distributed topology with seaweedfs --- - -run "distributed_seaweedfs" { - command = plan - - variables { - topology = "distributed" - } - - assert { - condition = length(module.seaweedfs) == 1 - error_message = "Expected seaweedfs module to be deployed with seaweedfs storage backend" - } - - assert { - condition = alltrue([ - length(juju_integration.seaweedfs_loki) == 1, - length(juju_integration.seaweedfs_mimir) == 1, - length(juju_integration.seaweedfs_tempo) == 1, - ]) - error_message = "Expected seaweedfs integrations to all coordinators" - } - - assert { - condition = !anytrue([ - length(module.loki_worker) > 0, - length(module.mimir_worker) > 0, - length(module.tempo_worker) > 0, - ]) - error_message = "Expected no monolithic workers in distributed mode" - } - - assert { - condition = alltrue([ - length(module.loki_worker_backend) == 1, - length(module.loki_worker_read) == 1, - length(module.loki_worker_write) == 1, - ]) - error_message = "Expected all distributed loki workers (backend, read, write)" - } - - assert { - condition = alltrue([ - length(module.mimir_worker_backend) == 1, - length(module.mimir_worker_read) == 1, - length(module.mimir_worker_write) == 1, - ]) - error_message = "Expected all distributed mimir workers (backend, read, write)" - } - - assert { - condition = alltrue([ - length(module.tempo_worker_querier) == 1, - length(module.tempo_worker_query_frontend) == 1, - length(module.tempo_worker_ingester) == 1, - length(module.tempo_worker_distributor) == 1, - length(module.tempo_worker_compactor) == 1, - length(module.tempo_worker_metrics_generator) == 1, - ]) - error_message = "Expected all distributed tempo workers (querier, query_frontend, ingester, distributor, compactor, metrics_generator)" - } - - assert { - condition = !anytrue([ - length(juju_integration.loki_cluster) > 0, - length(juju_integration.mimir_cluster) > 0, - length(juju_integration.tempo_cluster) > 0, - ]) - error_message = "Expected no monolithic cluster integrations in distributed mode" - } - - assert { - condition = alltrue([ - length(juju_integration.loki_cluster_backend) == 1, - length(juju_integration.loki_cluster_read) == 1, - length(juju_integration.loki_cluster_write) == 1, - ]) - error_message = "Expected all distributed loki cluster integrations (backend, read, write)" - } - - assert { - condition = alltrue([ - length(juju_integration.mimir_cluster_backend) == 1, - length(juju_integration.mimir_cluster_read) == 1, - length(juju_integration.mimir_cluster_write) == 1, - ]) - error_message = "Expected all distributed mimir cluster integrations (backend, read, write)" - } - - assert { - condition = alltrue([ - length(juju_integration.tempo_cluster_querier) == 1, - length(juju_integration.tempo_cluster_query_frontend) == 1, - length(juju_integration.tempo_cluster_ingester) == 1, - length(juju_integration.tempo_cluster_distributor) == 1, - length(juju_integration.tempo_cluster_compactor) == 1, - length(juju_integration.tempo_cluster_metrics_generator) == 1, - ]) - error_message = "Expected all distributed tempo cluster integrations" - } -} - -# --- Monolithic topology with s3-integrator --- - -run "monolithic_s3" { - command = plan - - variables { - storage_backend = "s3" - s3_endpoint = "https://s3.example.com" - s3_access_key = "access-key" - s3_secret_key = "secret-key" - loki_bucket = "loki" - mimir_bucket = "mimir" - tempo_bucket = "tempo" - } - - assert { - condition = length(module.seaweedfs) == 0 - error_message = "Expected no seaweedfs module with s3 storage backend" - } - - assert { - condition = alltrue([ - length(juju_application.s3_integrator_loki) == 1, - length(juju_application.s3_integrator_mimir) == 1, - length(juju_application.s3_integrator_tempo) == 1, - ]) - error_message = "Expected s3-integrator applications for all coordinators" - } - - assert { - condition = alltrue([ - length(juju_integration.s3_integrator_loki) == 1, - length(juju_integration.s3_integrator_mimir) == 1, - length(juju_integration.s3_integrator_tempo) == 1, - ]) - error_message = "Expected s3-integrator integrations for all coordinators" - } - - assert { - condition = !anytrue([ - length(juju_integration.seaweedfs_loki) > 0, - length(juju_integration.seaweedfs_mimir) > 0, - length(juju_integration.seaweedfs_tempo) > 0, - ]) - error_message = "Expected no seaweedfs integrations with s3 storage backend" - } - - assert { - condition = alltrue([ - length(module.loki_worker) == 1, - length(module.mimir_worker) == 1, - length(module.tempo_worker) == 1, - ]) - error_message = "Expected all monolithic workers in monolithic mode" - } - - assert { - condition = !anytrue([ - length(module.loki_worker_backend) > 0, - length(module.loki_worker_read) > 0, - length(module.loki_worker_write) > 0, - length(module.mimir_worker_backend) > 0, - length(module.mimir_worker_read) > 0, - length(module.mimir_worker_write) > 0, - length(module.tempo_worker_querier) > 0, - length(module.tempo_worker_query_frontend) > 0, - length(module.tempo_worker_ingester) > 0, - length(module.tempo_worker_distributor) > 0, - length(module.tempo_worker_compactor) > 0, - length(module.tempo_worker_metrics_generator) > 0, - ]) - error_message = "Expected no distributed workers in monolithic mode" - } -} - -# --- Distributed topology with s3-integrator --- - -run "distributed_s3" { - command = plan - - variables { - topology = "distributed" - storage_backend = "s3" - s3_endpoint = "https://s3.example.com" - s3_access_key = "access-key" - s3_secret_key = "secret-key" - loki_bucket = "loki" - mimir_bucket = "mimir" - tempo_bucket = "tempo" - } - - assert { - condition = length(module.seaweedfs) == 0 - error_message = "Expected no seaweedfs module with s3 storage backend" - } - - assert { - condition = alltrue([ - length(juju_application.s3_integrator_loki) == 1, - length(juju_application.s3_integrator_mimir) == 1, - length(juju_application.s3_integrator_tempo) == 1, - ]) - error_message = "Expected s3-integrator applications for all coordinators" - } - - assert { - condition = alltrue([ - length(juju_integration.s3_integrator_loki) == 1, - length(juju_integration.s3_integrator_mimir) == 1, - length(juju_integration.s3_integrator_tempo) == 1, - ]) - error_message = "Expected s3-integrator integrations for all coordinators" - } - - assert { - condition = !anytrue([ - length(juju_integration.seaweedfs_loki) > 0, - length(juju_integration.seaweedfs_mimir) > 0, - length(juju_integration.seaweedfs_tempo) > 0, - ]) - error_message = "Expected no seaweedfs integrations with s3 storage backend" - } - - assert { - condition = !anytrue([ - length(module.loki_worker) > 0, - length(module.mimir_worker) > 0, - length(module.tempo_worker) > 0, - ]) - error_message = "Expected no monolithic workers in distributed mode" - } - - assert { - condition = alltrue([ - length(module.loki_worker_backend) == 1, - length(module.loki_worker_read) == 1, - length(module.loki_worker_write) == 1, - ]) - error_message = "Expected all distributed loki workers (backend, read, write)" - } - - assert { - condition = alltrue([ - length(module.mimir_worker_backend) == 1, - length(module.mimir_worker_read) == 1, - length(module.mimir_worker_write) == 1, - ]) - error_message = "Expected all distributed mimir workers (backend, read, write)" - } - - assert { - condition = alltrue([ - length(module.tempo_worker_querier) == 1, - length(module.tempo_worker_query_frontend) == 1, - length(module.tempo_worker_ingester) == 1, - length(module.tempo_worker_distributor) == 1, - length(module.tempo_worker_compactor) == 1, - length(module.tempo_worker_metrics_generator) == 1, - ]) - error_message = "Expected all distributed tempo workers" - } - - assert { - condition = !anytrue([ - length(juju_integration.loki_cluster) > 0, - length(juju_integration.mimir_cluster) > 0, - length(juju_integration.tempo_cluster) > 0, - ]) - error_message = "Expected no monolithic cluster integrations in distributed mode" - } - - assert { - condition = alltrue([ - length(juju_integration.loki_cluster_backend) == 1, - length(juju_integration.loki_cluster_read) == 1, - length(juju_integration.loki_cluster_write) == 1, - ]) - error_message = "Expected all distributed loki cluster integrations" - } - - assert { - condition = alltrue([ - length(juju_integration.mimir_cluster_backend) == 1, - length(juju_integration.mimir_cluster_read) == 1, - length(juju_integration.mimir_cluster_write) == 1, - ]) - error_message = "Expected all distributed mimir cluster integrations" - } - - assert { - condition = alltrue([ - length(juju_integration.tempo_cluster_querier) == 1, - length(juju_integration.tempo_cluster_query_frontend) == 1, - length(juju_integration.tempo_cluster_ingester) == 1, - length(juju_integration.tempo_cluster_distributor) == 1, - length(juju_integration.tempo_cluster_compactor) == 1, - length(juju_integration.tempo_cluster_metrics_generator) == 1, - ]) - error_message = "Expected all distributed tempo cluster integrations" - } -} diff --git a/terraform/cos-dev/upgrades.tf b/terraform/cos-dev/upgrades.tf deleted file mode 100644 index 1a03c4a8..00000000 --- a/terraform/cos-dev/upgrades.tf +++ /dev/null @@ -1,105 +0,0 @@ -# -------------- # Replace triggers -------------- # - -# -- Grafana -- # - -# [application] Removed the litestream-image resource -# Given a Juju bug, we need to trigger application replacement, otherwise the upgrade will fail -# https://github.com/juju/juju/issues/21648 -# https://github.com/juju/juju/issues/22071 -resource "terraform_data" "grafana_litestream_resource" { - triggers_replace = contains(keys(data.juju_charm.grafana_info.resources), "litestream-image") -} - -# [integration] Ingress interface changed -# The ingress endpoint interface changes from traefik_route to ingress_per_app so we need to -# trigger integration replacement, otherwise the upgrade will fail -# https://github.com/canonical/observability-stack/issues/165 -resource "terraform_data" "grafana_ingress_interface" { - triggers_replace = lookup(data.juju_charm.grafana_info.requires, "ingress", "") -} - -# -------------- # CharmHub API -------------- # - -data "juju_charm" "alertmanager_info" { - charm = "alertmanager-k8s" - channel = local.channels.alertmanager - base = local.bases.o11y -} - -data "juju_charm" "catalogue_info" { - charm = "catalogue-k8s" - channel = local.channels.catalogue - base = local.bases.o11y -} - -data "juju_charm" "grafana_info" { - charm = "grafana-k8s" - channel = local.channels.grafana - base = local.bases.o11y -} - -data "juju_charm" "loki_coordinator_info" { - charm = "loki-coordinator-k8s" - channel = local.channels.loki - base = local.bases.o11y -} - -data "juju_charm" "loki_worker_info" { - charm = "loki-worker-k8s" - channel = local.channels.loki - base = local.bases.o11y -} - -data "juju_charm" "mimir_coordinator_info" { - charm = "mimir-coordinator-k8s" - channel = local.channels.mimir - base = local.bases.o11y -} - -data "juju_charm" "mimir_worker_info" { - charm = "mimir-worker-k8s" - channel = local.channels.mimir - base = local.bases.o11y -} - -data "juju_charm" "otelcol_info" { - charm = "opentelemetry-collector-k8s" - channel = local.channels.otelcol - base = local.bases.o11y -} - -data "juju_charm" "seaweedfs_info" { - charm = "seaweedfs-k8s" - channel = local.channels.seaweedfs - base = local.bases.swfs -} - -data "juju_charm" "ssc_info" { - charm = "self-signed-certificates" - channel = local.channels.ssc - base = local.bases.ssc -} - -data "juju_charm" "tempo_coordinator_info" { - charm = "tempo-coordinator-k8s" - channel = local.channels.tempo - base = local.bases.o11y -} - -data "juju_charm" "tempo_worker_info" { - charm = "tempo-worker-k8s" - channel = local.channels.tempo - base = local.bases.o11y -} - -data "juju_charm" "s3_integrator_info" { - charm = "s3-integrator" - channel = local.channels.s3_integrator - base = local.bases.s3_integrator -} - -data "juju_charm" "traefik_info" { - charm = "traefik-k8s" - channel = local.channels.traefik - base = local.bases.traefik -} diff --git a/terraform/cos-dev/variables.tf b/terraform/cos-dev/variables.tf deleted file mode 100644 index a6d79628..00000000 --- a/terraform/cos-dev/variables.tf +++ /dev/null @@ -1,361 +0,0 @@ -# We use constraints to set AntiAffinity in K8s -# https://discourse.charmhub.io/t/pod-priority-and-affinity-in-juju-charms/4091/13?u=jose - -# FIXME: Passing an empty constraints value to the Juju Terraform provider currently -# 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. - -variable "risk" { - description = "Risk level that the applications are (unless overwritten by individual channels) deployed from" - type = string - default = "edge" -} - -variable "model_uuid" { - description = "Reference to an existing model resource or data source for the model to deploy to" - type = string -} - -# -------------- # Topology configuration -------------- - -variable "topology" { - description = "Deployment topology: 'monolithic' (single role-all worker per component) or 'distributed' (separate workers per role)." - type = string - default = "monolithic" - validation { - condition = contains(["monolithic", "distributed"], var.topology) - error_message = "topology must be either 'monolithic' or 'distributed'." - } -} - -# -------------- # Storage backend configuration -------------- - -variable "storage_backend" { - description = "Storage backend: 'seaweedfs' (built-in S3-compatible storage) or 's3' (external S3/Ceph via s3-integrator)." - type = string - default = "seaweedfs" - validation { - condition = contains(["seaweedfs", "s3"], var.storage_backend) - error_message = "storage_backend must be either 'seaweedfs' or 's3'." - } -} - -# -------------- # Network configurations -------------- - -variable "internal_tls" { - description = "Specify whether to use TLS or not for internal COS communication. By default, TLS is enabled using self-signed-certificates" - type = bool - default = true -} - -variable "external_certificates_offer_url" { - description = "A Juju offer URL of a CA providing the 'tls_certificates' integration for Traefik to supply it with server certificates" - type = string - default = null - - validation { - condition = ( - (var.external_certificates_offer_url == null && var.external_ca_cert_offer_url == null) || - (var.external_certificates_offer_url != null && var.external_ca_cert_offer_url != null) - ) - error_message = "external_certificates_offer_url and external_ca_cert_offer_url must be supplied together (either both set or both null)." - } -} - -variable "external_ca_cert_offer_url" { - description = "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." - type = string - default = null -} - -# -------------- # Ingress configurations -------------- - -variable "ingress" { - description = "Per-component toggle for ingress integrations" - type = object({ - alertmanager = optional(bool, true) - catalogue = optional(bool, true) - grafana = optional(bool, true) - loki = optional(bool, true) - mimir = optional(bool, true) - opentelemetry_collector = optional(bool, true) - tempo = optional(bool, true) - }) - default = {} -} - -# -------------- # S3 storage configuration (required when storage_backend = "s3") -------------- - -variable "s3_endpoint" { - description = "S3 endpoint URL. Required when storage_backend is 's3'." - type = string - default = null -} - -variable "s3_access_key" { - description = "S3 access-key credential. Required when storage_backend is 's3'." - type = string - sensitive = true - default = null -} - -variable "s3_secret_key" { - description = "S3 secret-key credential. Required when storage_backend is 's3'." - type = string - sensitive = true - default = null -} - -variable "loki_bucket" { - description = "Loki S3 bucket name" - type = string - default = "loki" -} - -variable "mimir_bucket" { - description = "Mimir S3 bucket name" - type = string - default = "mimir" -} - -variable "tempo_bucket" { - description = "Tempo S3 bucket name" - type = string - default = "tempo" -} - -# -------------- # Application configurations -------------- - -variable "alertmanager" { - type = object({ - app_name = optional(string, "alertmanager") - config = optional(map(string), {}) - constraints = optional(string, "arch=amd64") - resources = optional(map(string), {}) - revision = optional(number, null) - storage_directives = optional(map(string), {}) - units = optional(number, 1) - }) - default = {} - description = "Application configuration for Alertmanager. For more details: https://registry.terraform.io/providers/juju/juju/latest/docs/resources/application" -} - -variable "catalogue" { - type = object({ - app_name = optional(string, "catalogue") - config = optional(map(string), {}) - constraints = optional(string, "arch=amd64") - resources = optional(map(string), {}) - revision = optional(number, null) - storage_directives = optional(map(string), {}) - units = optional(number, 1) - }) - default = {} - description = "Application configuration for Catalogue. For more details: https://registry.terraform.io/providers/juju/juju/latest/docs/resources/application" -} - -variable "grafana" { - type = object({ - app_name = optional(string, "grafana") - config = optional(map(string), {}) - constraints = optional(string, "arch=amd64") - resources = optional(map(string), {}) - revision = optional(number, null) - storage_directives = optional(map(string), {}) - units = optional(number, 1) - }) - default = {} - description = "Application configuration for Grafana. For more details: https://registry.terraform.io/providers/juju/juju/latest/docs/resources/application" -} - -variable "loki_coordinator" { - type = object({ - app_name = optional(string, "loki") - config = optional(map(string), {}) - constraints = optional(string, "arch=amd64") - resources = optional(map(string), {}) - revision = optional(number, null) - storage_directives = optional(map(string), {}) - units = optional(number, 1) - }) - default = {} - description = "Application configuration for the Loki coordinator. For more details: https://registry.terraform.io/providers/juju/juju/latest/docs/resources/application" -} - -variable "loki_worker" { - type = object({ - app_name = optional(string, "loki-worker") - constraints = optional(string, "arch=amd64") - resources = optional(map(string), {}) - revision = optional(number, null) - # Monolithic mode (role-all) - config = optional(map(string), {}) - storage_directives = optional(map(string), {}) - units = optional(number, 1) - # Distributed mode - backend_config = optional(map(string), {}) - read_config = optional(map(string), {}) - write_config = optional(map(string), {}) - backend_storage_directives = optional(map(string), {}) - read_storage_directives = optional(map(string), {}) - write_storage_directives = optional(map(string), {}) - backend_units = optional(number, 1) - read_units = optional(number, 1) - write_units = optional(number, 1) - }) - default = {} - description = "Application configuration for the Loki worker(s). For more details: https://registry.terraform.io/providers/juju/juju/latest/docs/resources/application" -} - -variable "mimir_coordinator" { - type = object({ - app_name = optional(string, "mimir") - config = optional(map(string), {}) - constraints = optional(string, "arch=amd64") - resources = optional(map(string), {}) - revision = optional(number, null) - storage_directives = optional(map(string), {}) - units = optional(number, 1) - }) - default = {} - description = "Application configuration for the Mimir coordinator. For more details: https://registry.terraform.io/providers/juju/juju/latest/docs/resources/application" -} - -variable "mimir_worker" { - type = object({ - app_name = optional(string, "mimir-worker") - constraints = optional(string, "arch=amd64") - resources = optional(map(string), {}) - revision = optional(number, null) - # Monolithic mode (role-all) - config = optional(map(string), {}) - storage_directives = optional(map(string), {}) - units = optional(number, 1) - # Distributed mode - backend_config = optional(map(string), {}) - read_config = optional(map(string), {}) - write_config = optional(map(string), {}) - backend_storage_directives = optional(map(string), {}) - read_storage_directives = optional(map(string), {}) - write_storage_directives = optional(map(string), {}) - backend_units = optional(number, 1) - read_units = optional(number, 1) - write_units = optional(number, 1) - }) - default = {} - description = "Application configuration for the Mimir worker(s). For more details: https://registry.terraform.io/providers/juju/juju/latest/docs/resources/application" -} - -variable "opentelemetry_collector" { - type = object({ - app_name = optional(string, "otelcol") - config = optional(map(string), {}) - constraints = optional(string, "arch=amd64") - resources = optional(map(string), {}) - revision = optional(number, null) - storage_directives = optional(map(string), {}) - units = optional(number, 1) - }) - default = {} - description = "Application configuration for OpenTelemetry Collector. For more details: https://registry.terraform.io/providers/juju/juju/latest/docs/resources/application" -} - -variable "seaweedfs" { - type = object({ - app_name = optional(string, "seaweedfs") - config = optional(map(string), {}) - constraints = optional(string, "arch=amd64") - revision = optional(number, null) - storage_directives = optional(map(string), {}) - units = optional(number, 1) - }) - default = {} - description = "Application configuration for SeaweedFS. For more details: https://registry.terraform.io/providers/juju/juju/latest/docs/resources/application" -} - -variable "ssc" { - type = 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) - }) - default = {} - description = "Application configuration for Self-signed-certificates. For more details: https://registry.terraform.io/providers/juju/juju/latest/docs/resources/application" -} - -variable "s3_integrator" { - type = object({ - config = optional(map(string), {}) - constraints = optional(string, "arch=amd64") - revision = optional(number, null) - storage_directives = optional(map(string), {}) - units = optional(number, 1) - }) - default = {} - description = "Application configuration shared by all S3-integrators (one deployed per coordinated worker). For more details: https://registry.terraform.io/providers/juju/juju/latest/docs/resources/application" -} - -variable "tempo_coordinator" { - type = object({ - app_name = optional(string, "tempo") - config = optional(map(string), {}) - constraints = optional(string, "arch=amd64") - resources = optional(map(string), {}) - revision = optional(number, null) - storage_directives = optional(map(string), {}) - units = optional(number, 1) - }) - default = {} - description = "Application configuration for the Tempo coordinator. For more details: https://registry.terraform.io/providers/juju/juju/latest/docs/resources/application" -} - -variable "tempo_worker" { - type = object({ - app_name = optional(string, "tempo-worker") - constraints = optional(string, "arch=amd64") - resources = optional(map(string), {}) - revision = optional(number, null) - # Monolithic mode (role-all) - config = optional(map(string), {}) - storage_directives = optional(map(string), {}) - units = optional(number, 1) - # Distributed mode - 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), {}) - querier_storage_directives = optional(map(string), {}) - query_frontend_storage_directives = optional(map(string), {}) - ingester_storage_directives = optional(map(string), {}) - distributor_storage_directives = optional(map(string), {}) - compactor_storage_directives = optional(map(string), {}) - metrics_generator_storage_directives = optional(map(string), {}) - querier_units = optional(number, 1) - query_frontend_units = optional(number, 1) - ingester_units = optional(number, 1) - distributor_units = optional(number, 1) - compactor_units = optional(number, 1) - metrics_generator_units = optional(number, 1) - }) - default = {} - description = "Application configuration for the Tempo worker(s). For more details: https://registry.terraform.io/providers/juju/juju/latest/docs/resources/application" -} - -variable "traefik" { - type = object({ - app_name = optional(string, "traefik") - config = optional(map(string), {}) - constraints = optional(string, "arch=amd64") - resources = optional(map(string), {}) - revision = optional(number, null) - storage_directives = optional(map(string), {}) - units = optional(number, 1) - }) - default = {} - description = "Application configuration for Traefik. For more details: https://registry.terraform.io/providers/juju/juju/latest/docs/resources/application" -} diff --git a/tests/integration/cos_dev/tls_external/test_cos_dev_tls_external.py b/tests/integration/cos_dev/tls_external/test_cos_dev_tls_external.py deleted file mode 100644 index 44e9696e..00000000 --- a/tests/integration/cos_dev/tls_external/test_cos_dev_tls_external.py +++ /dev/null @@ -1,31 +0,0 @@ -"""There are 2 sections of the COS Dev deployment (internal and external) which can implement TLS -communication. This python test file deploys COS Dev with external TLS, and without internal TLS. - -For more further TLS configuration details, refer to our documentation: -https://documentation.ubuntu.com/observability/latest/how-to/configure-tls-encryption/""" - -from pathlib import Path - -import jubilant -from helpers import ( - catalogue_apps_are_reachable, - get_tls_context, - no_errors_in_otelcol_logs, - wait_for_active_idle_without_error, - xfail_otelcol_logs, -) - -TRACK_DEV_TF_FILE = Path(__file__).parent.resolve() / "track-dev.tf" - - -def test_deploy(tmp_path, tf_manager, ca_model: jubilant.Juju, cos_model: jubilant.Juju): - tf_manager.init(TRACK_DEV_TF_FILE) - tf_manager.apply(ca_model=ca_model.model, cos_model=cos_model.model) - wait_for_active_idle_without_error([ca_model, cos_model]) - tls_ctx = get_tls_context(tmp_path, ca_model, "self-signed-certificates") - catalogue_apps_are_reachable(cos_model, tls_ctx) - - -@xfail_otelcol_logs -def test_no_errors_in_otelcol_logs_dev(cos_model: jubilant.Juju): - no_errors_in_otelcol_logs(cos_model) diff --git a/tests/integration/cos_dev/tls_external/track-dev.tf b/tests/integration/cos_dev/tls_external/track-dev.tf deleted file mode 100644 index 45d0913d..00000000 --- a/tests/integration/cos_dev/tls_external/track-dev.tf +++ /dev/null @@ -1,41 +0,0 @@ -terraform { - required_version = ">= 1.5" - required_providers { - juju = { - source = "juju/juju" - version = ">= 1.0" - } - } -} - -variable "ca_model" { - type = string -} - -variable "cos_model" { - type = string -} - -data "juju_model" "ca-model" { - name = var.ca_model - owner = "admin" -} - -data "juju_model" "cos-model" { - name = var.cos_model - owner = "admin" -} - -module "ssc" { - source = "git::https://github.com/canonical/self-signed-certificates-operator//terraform" - model_uuid = data.juju_model.ca-model.uuid -} - -module "cos-dev" { - source = "git::https://github.com/canonical/observability-stack//terraform/cos-dev" - model_uuid = data.juju_model.cos-model.uuid - risk = "edge" - internal_tls = false - external_certificates_offer_url = "admin/${var.ca_model}.certificates" - external_ca_cert_offer_url = "admin/${var.ca_model}.send-ca-cert" -} diff --git a/tests/integration/cos_dev/tls_full/test_cos_dev_tls_full.py b/tests/integration/cos_dev/tls_full/test_cos_dev_tls_full.py deleted file mode 100644 index af58a5df..00000000 --- a/tests/integration/cos_dev/tls_full/test_cos_dev_tls_full.py +++ /dev/null @@ -1,31 +0,0 @@ -"""There are 2 sections of the COS Dev deployment (internal and external) which can implement TLS -communication. This python test file deploys COS Dev with external and internal TLS. - -For more further TLS configuration details, refer to our documentation: -https://documentation.ubuntu.com/observability/latest/how-to/configure-tls-encryption/""" - -from pathlib import Path - -import jubilant -from helpers import ( - catalogue_apps_are_reachable, - get_tls_context, - no_errors_in_otelcol_logs, - wait_for_active_idle_without_error, - xfail_otelcol_logs, -) - -TRACK_DEV_TF_FILE = Path(__file__).parent.resolve() / "track-dev.tf" - - -def test_deploy(tmp_path, tf_manager, ca_model: jubilant.Juju, cos_model: jubilant.Juju): - tf_manager.init(TRACK_DEV_TF_FILE) - tf_manager.apply(ca_model=ca_model.model, cos_model=cos_model.model) - wait_for_active_idle_without_error([ca_model, cos_model]) - tls_ctx = get_tls_context(tmp_path, ca_model, "self-signed-certificates") - catalogue_apps_are_reachable(cos_model, tls_ctx) - - -@xfail_otelcol_logs -def test_no_errors_in_otelcol_logs_dev(cos_model: jubilant.Juju): - no_errors_in_otelcol_logs(cos_model) diff --git a/tests/integration/cos_dev/tls_full/track-dev.tf b/tests/integration/cos_dev/tls_full/track-dev.tf deleted file mode 100644 index 7b09b326..00000000 --- a/tests/integration/cos_dev/tls_full/track-dev.tf +++ /dev/null @@ -1,41 +0,0 @@ -terraform { - required_version = ">= 1.5" - required_providers { - juju = { - source = "juju/juju" - version = ">= 1.0" - } - } -} - -variable "ca_model" { - type = string -} - -variable "cos_model" { - type = string -} - -data "juju_model" "ca-model" { - name = var.ca_model - owner = "admin" -} - -data "juju_model" "cos-model" { - name = var.cos_model - owner = "admin" -} - -module "ssc" { - source = "git::https://github.com/canonical/self-signed-certificates-operator//terraform" - model_uuid = data.juju_model.ca-model.uuid -} - -module "cos-dev" { - source = "git::https://github.com/canonical/observability-stack//terraform/cos-dev" - model_uuid = data.juju_model.cos-model.uuid - risk = "edge" - internal_tls = true - external_certificates_offer_url = "admin/${var.ca_model}.certificates" - external_ca_cert_offer_url = "admin/${var.ca_model}.send-ca-cert" -} diff --git a/tests/integration/cos_dev/tls_internal/test_cos_dev_tls_internal.py b/tests/integration/cos_dev/tls_internal/test_cos_dev_tls_internal.py deleted file mode 100644 index 0b0b1f91..00000000 --- a/tests/integration/cos_dev/tls_internal/test_cos_dev_tls_internal.py +++ /dev/null @@ -1,28 +0,0 @@ -"""Integration test for COS Dev deployed with internal TLS. - -For more further TLS configuration details, refer to our documentation: -https://documentation.ubuntu.com/observability/latest/how-to/configure-tls-encryption/""" - -from pathlib import Path - -import jubilant -from helpers import ( - catalogue_apps_are_reachable, - no_errors_in_otelcol_logs, - wait_for_active_idle_without_error, - xfail_otelcol_logs, -) - -TRACK_DEV_TF_FILE = Path(__file__).parent.resolve() / "track-dev.tf" - - -def test_deploy(tf_manager, cos_model: jubilant.Juju): - tf_manager.init(TRACK_DEV_TF_FILE) - tf_manager.apply(model=cos_model.model) - wait_for_active_idle_without_error([cos_model]) - catalogue_apps_are_reachable(cos_model) - - -@xfail_otelcol_logs -def test_no_errors_in_otelcol_logs_dev(cos_model: jubilant.Juju): - no_errors_in_otelcol_logs(cos_model) diff --git a/tests/integration/cos_dev/tls_internal/track-dev.tf b/tests/integration/cos_dev/tls_internal/track-dev.tf deleted file mode 100644 index c9d72bdc..00000000 --- a/tests/integration/cos_dev/tls_internal/track-dev.tf +++ /dev/null @@ -1,25 +0,0 @@ -terraform { - required_version = ">= 1.5" - required_providers { - juju = { - source = "juju/juju" - version = ">= 1.0" - } - } -} - -variable "model" { - type = string -} - -data "juju_model" "model" { - name = var.model - owner = "admin" -} - -module "cos-dev" { - source = "git::https://github.com/canonical/observability-stack//terraform/cos-dev" - model_uuid = data.juju_model.model.uuid - risk = "edge" - internal_tls = true -} diff --git a/tests/integration/cos_dev/tls_none/test_cos_dev_tls_none.py b/tests/integration/cos_dev/tls_none/test_cos_dev_tls_none.py deleted file mode 100644 index ad2057ca..00000000 --- a/tests/integration/cos_dev/tls_none/test_cos_dev_tls_none.py +++ /dev/null @@ -1,28 +0,0 @@ -"""Integration test for COS Dev deployed without TLS. - -For more further TLS configuration details, refer to our documentation: -https://documentation.ubuntu.com/observability/latest/how-to/configure-tls-encryption/""" - -from pathlib import Path - -import jubilant -from helpers import ( - catalogue_apps_are_reachable, - no_errors_in_otelcol_logs, - wait_for_active_idle_without_error, - xfail_otelcol_logs, -) - -TRACK_DEV_TF_FILE = Path(__file__).parent.resolve() / "track-dev.tf" - - -def test_deploy(tf_manager, cos_model: jubilant.Juju): - tf_manager.init(TRACK_DEV_TF_FILE) - tf_manager.apply(model=cos_model.model) - wait_for_active_idle_without_error([cos_model]) - catalogue_apps_are_reachable(cos_model) - - -@xfail_otelcol_logs -def test_no_errors_in_otelcol_logs_dev(cos_model: jubilant.Juju): - no_errors_in_otelcol_logs(cos_model) diff --git a/tests/integration/cos_dev/tls_none/track-dev.tf b/tests/integration/cos_dev/tls_none/track-dev.tf deleted file mode 100644 index 87cc2cce..00000000 --- a/tests/integration/cos_dev/tls_none/track-dev.tf +++ /dev/null @@ -1,25 +0,0 @@ -terraform { - required_version = ">= 1.5" - required_providers { - juju = { - source = "juju/juju" - version = ">= 1.0" - } - } -} - -variable "model" { - type = string -} - -data "juju_model" "model" { - name = var.model - owner = "admin" -} - -module "cos-dev" { - source = "git::https://github.com/canonical/observability-stack//terraform/cos-dev" - model_uuid = data.juju_model.model.uuid - risk = "edge" - internal_tls = false -} From 73f371f6ee08f2f376ebbe763a8116c2054d4f24 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Mon, 6 Jul 2026 10:57:58 -0400 Subject: [PATCH 26/41] chore --- terraform/cos-lite/README.md | 2 +- terraform/cos-lite/applications.tf | 7 +++---- terraform/cos/README.md | 2 +- terraform/cos/applications.tf | 7 +++---- 4 files changed, 8 insertions(+), 10 deletions(-) diff --git a/terraform/cos-lite/README.md b/terraform/cos-lite/README.md index fed20180..b4982c35 100644 --- a/terraform/cos-lite/README.md +++ b/terraform/cos-lite/README.md @@ -20,7 +20,7 @@ This is a Terraform module facilitating the deployment of the COS Lite solution, | [loki](#module\_loki) | git::https://github.com/canonical/loki-k8s-operator//terraform | tf-3.7.2 | | [prometheus](#module\_prometheus) | git::https://github.com/canonical/prometheus-k8s-operator//terraform | tf-3.11.2 | | [ssc](#module\_ssc) | git::https://github.com/canonical/self-signed-certificates-operator//terraform | rev653 | -| [traefik](#module\_traefik) | git::https://github.com/canonical/traefik-k8s-operator//terraform | traefik-k8s-rev345 | +| [traefik](#module\_traefik) | git::https://github.com/canonical/traefik-k8s-operator//terraform | traefik-k8s-rev360 | ## Inputs diff --git a/terraform/cos-lite/applications.tf b/terraform/cos-lite/applications.tf index 1859970b..4681d739 100644 --- a/terraform/cos-lite/applications.tf +++ b/terraform/cos-lite/applications.tf @@ -89,12 +89,11 @@ module "ssc" { } module "traefik" { - source = "git::https://github.com/canonical/traefik-k8s-operator//terraform?ref=traefik-k8s-rev345" + source = "git::https://github.com/canonical/traefik-k8s-operator//terraform?ref=traefik-k8s-rev360" count = local.traefik_enabled ? 1 : 0 - app_name = var.traefik.app_name - # FIXME: Once Traefik TF module supports a base var, add it here - # base = local.bases.traefik + app_name = var.traefik.app_name + base = local.bases.traefik channel = local.channels.traefik config = var.traefik.config constraints = var.traefik.constraints diff --git a/terraform/cos/README.md b/terraform/cos/README.md index 3191db41..07bb9590 100644 --- a/terraform/cos/README.md +++ b/terraform/cos/README.md @@ -25,7 +25,7 @@ This is a Terraform module facilitating the deployment of the COS solution, usin | [opentelemetry\_collector](#module\_opentelemetry\_collector) | git::https://github.com/canonical/opentelemetry-collector-k8s-operator//terraform | tf-0.130.2 | | [ssc](#module\_ssc) | git::https://github.com/canonical/self-signed-certificates-operator//terraform | rev653 | | [tempo](#module\_tempo) | git::https://github.com/canonical/tempo-operators//terraform | tf-2.10.1 | -| [traefik](#module\_traefik) | git::https://github.com/canonical/traefik-k8s-operator//terraform | traefik-k8s-rev345 | +| [traefik](#module\_traefik) | git::https://github.com/canonical/traefik-k8s-operator//terraform | traefik-k8s-rev360 | ## Inputs diff --git a/terraform/cos/applications.tf b/terraform/cos/applications.tf index b2464b66..638ddedd 100644 --- a/terraform/cos/applications.tf +++ b/terraform/cos/applications.tf @@ -197,12 +197,11 @@ module "tempo" { } module "traefik" { - source = "git::https://github.com/canonical/traefik-k8s-operator//terraform?ref=traefik-k8s-rev345" + source = "git::https://github.com/canonical/traefik-k8s-operator//terraform?ref=traefik-k8s-rev360" count = local.traefik_enabled ? 1 : 0 - app_name = var.traefik.app_name - # FIXME: Once Traefik TF module supports a base var, add it here - # base = local.bases.traefik + app_name = var.traefik.app_name + base = local.bases.traefik 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 From a533028e2998a0e0fa39ba0ec5ac615b36325cee Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Mon, 6 Jul 2026 11:07:38 -0400 Subject: [PATCH 27/41] chore --- justfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/justfile b/justfile index 7e4f9d70..8047cc7b 100644 --- a/justfile +++ b/justfile @@ -22,7 +22,7 @@ fmt: format-terraform format-terraform-docs # Run unit tests [group("Unit")] -unit: (unit-test "cos") (unit-test "cos-lite") (unit-test "cos-dev") +unit: (unit-test "cos") (unit-test "cos-lite") # Lint the Github workflows [group("Lint")] From a3401f3e038023246fc4e83344f8e1a3d8f350b1 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Mon, 6 Jul 2026 12:02:38 -0400 Subject: [PATCH 28/41] chore --- terraform/cos/applications.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/terraform/cos/applications.tf b/terraform/cos/applications.tf index 638ddedd..60ad8ee4 100644 --- a/terraform/cos/applications.tf +++ b/terraform/cos/applications.tf @@ -100,7 +100,7 @@ module "mimir" { 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_config = merge(var.mimir_coordinator.config, { "max_global_exemplars_per_user" = "100000" }) coordinator_constraints = var.mimir_coordinator.constraints coordinator_resources = var.mimir_coordinator.resources coordinator_revision = local.revisions.mimir_coordinator From e69072f74dcf9090a997d8ee930dfcbd5523988a Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Mon, 6 Jul 2026 12:09:36 -0400 Subject: [PATCH 29/41] chore --- .github/actions/deploy-cos/action.yml | 249 -------------------------- .github/workflows/_integration.yml | 1 - .github/workflows/terraform.yml | 7 - 3 files changed, 257 deletions(-) delete mode 100644 .github/actions/deploy-cos/action.yml diff --git a/.github/actions/deploy-cos/action.yml b/.github/actions/deploy-cos/action.yml deleted file mode 100644 index 0b1ee0b8..00000000 --- a/.github/actions/deploy-cos/action.yml +++ /dev/null @@ -1,249 +0,0 @@ -name: Deploy COS -description: > - Deploy Canonical Observability Stack into a Juju model using Terraform. - Uses concierge to set up microk8s and Juju on any runner type. - -inputs: - scale: - description: "COS scale mode: monolithic (single role-all worker) or distributed (separate backend/read/write workers)" - required: true - storage: - description: "S3 storage backend: seaweedfs or ceph" - required: true - cos-model: - description: "Name of the Juju model to deploy COS into" - required: false - default: cos - juju-channel: - description: "Juju snap channel" - required: false - default: "3.6/stable" - -outputs: - cos-model: - description: "Name of the Juju model where COS was deployed" - value: ${{ steps.set-output.outputs.cos-model }} - -runs: - using: composite - steps: - - name: Validate inputs - shell: bash - run: | - case "${{ inputs.scale }}" in - monolithic|distributed) ;; - *) echo "Unknown scale: ${{ inputs.scale }}. Must be 'monolithic' or 'distributed'."; exit 1 ;; - esac - case "${{ inputs.storage }}" in - seaweedfs|ceph) ;; - *) echo "Unknown storage: ${{ inputs.storage }}. Must be 'seaweedfs' or 'ceph'."; exit 1 ;; - esac - - # --- Infrastructure setup --- - - name: Concierge prepare - shell: bash - run: | - IPADDR=$(ip -4 -j route get 2.2.2.2 | jq -r '.[] | .prefsrc') - cat > /tmp/concierge.yaml << EOF - juju: - model-defaults: - logging-config: '=INFO; unit=DEBUG' - providers: - microk8s: - enable: true - bootstrap: true - addons: - - hostpath-storage - - dns - - rbac - - "metallb:${IPADDR}-${IPADDR}" - EOF - if [ -n "${DOCKERHUB_MIRROR:-}" ]; then - printf ' image-registry:\n url: "%s"\n' "${DOCKERHUB_MIRROR}" >> /tmp/concierge.yaml - fi - - sudo snap install concierge --classic - sudo concierge prepare \ - --config /tmp/concierge.yaml \ - --juju-channel "${{ inputs.juju-channel }}" \ - --extra-snaps terraform - - # --- S3 storage backend --- - - name: Install and configure MicroCeph - if: ${{ inputs.storage == 'ceph' }} - shell: bash - run: | - function check_ceph_ok_or_exit () { - i=0 - for i in {1..5}; do - if sudo microceph.ceph status | grep HEALTH_OK; then - break - else - sudo microceph.ceph status - sleep 30 - sudo microceph.ceph health detail - fi - done - if [ "$i" -eq 5 ]; then - exit 1 - fi - } - - sudo snap install microceph - sudo microceph cluster bootstrap - sleep 30s - sudo microceph.ceph config set "mon.$(hostname)" mon_data_avail_warn 6 - sudo microceph disk add loop,2G,3 - check_ceph_ok_or_exit - - sudo microceph enable rgw --port 8080 --ssl-port 8443 - sudo microceph.radosgw-admin user create --uid=user --display-name=User - sudo microceph.radosgw-admin key create --uid=user --key-type=s3 --access-key=access-key --secret-key=secret-key - - { - echo "S3_ENDPOINT=http://$(ip -4 -j route get 2.2.2.2 | jq -r '.[] | .prefsrc'):8080" - echo "S3_ACCESS_KEY=access-key" - echo "S3_SECRET_KEY=secret-key" - } >> "$GITHUB_ENV" - - # --- Create model and deploy COS --- - - name: Create Juju model - shell: bash - run: | - juju add-model ${{ inputs.cos-model }} - juju model-config --model ${{ inputs.cos-model }} update-status-hook-interval=2m - - - name: Deploy COS - shell: bash - run: | - MODEL_UUID=$(juju show-model ${{ inputs.cos-model }} --format json | jq -r '.["${{ inputs.cos-model }}"]["model-uuid"]') - - if [[ "${{ inputs.storage }}" == "ceph" ]]; then - export TF_VAR_storage_backend=s3 - export TF_VAR_s3_endpoint="${S3_ENDPOINT}" - export TF_VAR_s3_access_key="${S3_ACCESS_KEY}" - export TF_VAR_s3_secret_key="${S3_SECRET_KEY}" - else - export TF_VAR_storage_backend=seaweedfs - fi - - # The terraform module lives at terraform/cos-dev/ relative to the repo root. - # github.action_path resolves to .github/actions/deploy-cos/ so we go up three levels. - cd "${{ github.action_path }}/../../../terraform/cos-dev" - terraform init - terraform apply -auto-approve \ - -var="model_uuid=${MODEL_UUID}" \ - -var="topology=${{ inputs.scale }}" - - - name: Wait for deployment - shell: bash - run: | - model="${{ inputs.cos-model }}" - deadline=$(( $(date +%s) + 3600 )) - - while [ "$(date +%s)" -lt "$deadline" ]; do - status_json=$(juju status --model "$model" --format json) - - # Collect all unit workload/agent statuses - unit_statuses=$(echo "$status_json" | jq -r ' - [.applications | to_entries[] | .value.units // {} | to_entries[] | .value["workload-status"].current] | @json - ') - - # Exit successfully when every unit reports "active" - all_active=$(echo "$unit_statuses" | jq 'length > 0 and all(. == "active")') - if [ "$all_active" = "true" ]; then - echo "All applications are active!" - exit 0 - fi - - # Log which units are not yet active so we can track convergence - echo "--- $(date -u '+%H:%M:%S') not yet settled ---" - echo "$status_json" | jq -r ' - .applications | to_entries[] | - .value.units // {} | to_entries[] | - select(.value["workload-status"].current != "active") | - " \(.key) workload=\(.value["workload-status"].current) msg=\(.value["workload-status"].message // "")" - ' - - # Auto-resolve any errored units so Juju retries the failed hook. - # This handles transient race conditions (e.g. ingress-relation-created firing - # before Traefik is ready to accept the relation). - errored=$(echo "$status_json" | jq -r ' - .applications | to_entries[] | .value.units // {} | to_entries[] | - select(.value["workload-status"].current == "error") | .key - ') - if [ -n "$errored" ]; then - # Workaround for traefik-k8s charm bug (issue #684 / PR #685): the - # pebble-ready hook calls `find /opt/traefik/juju -name '*.yaml' -delete` - # before _setup_dynamic_config_folder() has created the directory on a - # freshly provisioned PVC, so find exits 1. Pre-create the directory - # *before* resolving so that the hook retry can proceed. - if echo "$errored" | grep -q "^traefik/"; then - echo "Applying workaround: mkdir /opt/traefik/juju in traefik container" - kubectl exec -n "$model" traefik-0 -c traefik -- mkdir -p /opt/traefik/juju 2>/dev/null || true - fi - - echo "Auto-resolving errored units (hook retry):" - while IFS= read -r unit; do - echo " - $unit" - juju resolve "$unit" --model "$model" || true - done <<< "$errored" - fi - - sleep 30 - done - - echo "Timeout: not all applications became active within 1 hour" - exit 1 - - - name: Dump model status on failure - if: failure() - shell: bash - run: | - echo "===== juju status =====" - juju status --model ${{ inputs.cos-model }} --color=false - - echo "" - echo "===== juju debug-log (last 200 lines) =====" - juju debug-log --model ${{ inputs.cos-model }} --limit 200 --no-tail - - echo "" - echo "===== kubectl pods =====" - kubectl get pods --all-namespaces - - echo "" - echo "===== kubectl describe non-ready pods =====" - kubectl get pods -n ${{ inputs.cos-model }} --no-headers \ - | awk '{ split($2, a, "/"); if (a[1] != a[2]) print $1 }' \ - | while read -r pod; do - echo "--- $pod ---" - kubectl describe pod "$pod" -n ${{ inputs.cos-model }} - echo "" - done - - echo "" - echo "===== kubectl logs for non-ready containers =====" - kubectl get pods -n ${{ inputs.cos-model }} -o json \ - | jq -r '.items[] | .metadata.name as $pod | .status.containerStatuses[]? | select(.ready == false) | [$pod, .name] | @tsv' \ - | while IFS=$'\t' read -r pod container; do - echo "--- $pod / $container ---" - kubectl logs "$pod" -c "$container" -n ${{ inputs.cos-model }} --tail=50 2>&1 || true - echo "" - done - - echo "" - echo "===== kubectl logs for Juju-blocked/error units =====" - juju status --model ${{ inputs.cos-model }} --format json \ - | jq -r '.applications | to_entries[] | .value.units // {} | to_entries[] | - select(.value["workload-status"].current == "blocked" or .value["workload-status"].current == "error") | - .key | gsub("/"; "-")' \ - | while read -r pod; do - echo "--- $pod (all containers) ---" - kubectl logs "$pod" -n ${{ inputs.cos-model }} --all-containers --tail=50 2>&1 || true - echo "" - done - - - name: Set output - id: set-output - shell: bash - run: echo "cos-model=${{ inputs.cos-model }}" >> "$GITHUB_OUTPUT" diff --git a/.github/workflows/_integration.yml b/.github/workflows/_integration.yml index 26d82961..968ddc86 100644 --- a/.github/workflows/_integration.yml +++ b/.github/workflows/_integration.yml @@ -12,7 +12,6 @@ on: options: - cos - cos_lite - - cos_dev runner: description: 'The runner label to use for the job.' type: choice diff --git a/.github/workflows/terraform.yml b/.github/workflows/terraform.yml index 84d8ffc1..3796ecf8 100644 --- a/.github/workflows/terraform.yml +++ b/.github/workflows/terraform.yml @@ -71,10 +71,3 @@ jobs: with: product: cos runner: self-hosted-linux-amd64-noble-xlarge - test-integration-cos-dev: - name: COS Dev Terraform integration - needs: [test-unit] - uses: canonical/observability-stack/.github/workflows/_integration.yml@main - with: - product: cos_dev - runner: self-hosted-linux-amd64-noble-large From e03698caf1b3d854924c8c0a5baf9df13c781c02 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Mon, 6 Jul 2026 12:19:50 -0400 Subject: [PATCH 30/41] chore --- .../test_track_3_cos_lite_upgrade_risk.py} | 2 +- .../risk_upgrades/track-3.0.tf} | 6 +-- .../test_track_3_cos_lite_upgrade_risk.py | 27 +++++++++++ .../cos_lite/risk_upgrades/track-3.0.tf | 45 +++++++++++++++++++ 4 files changed, 76 insertions(+), 4 deletions(-) rename tests/integration/{cos_lite/risk_upgrades/test_track_dev_cos_lite_upgrade_risk.py => cos/risk_upgrades/test_track_3_cos_lite_upgrade_risk.py} (93%) rename tests/integration/{cos_lite/risk_upgrades/track-2.tf => cos/risk_upgrades/track-3.0.tf} (82%) create mode 100644 tests/integration/cos_lite/risk_upgrades/test_track_3_cos_lite_upgrade_risk.py create mode 100644 tests/integration/cos_lite/risk_upgrades/track-3.0.tf diff --git a/tests/integration/cos_lite/risk_upgrades/test_track_dev_cos_lite_upgrade_risk.py b/tests/integration/cos/risk_upgrades/test_track_3_cos_lite_upgrade_risk.py similarity index 93% rename from tests/integration/cos_lite/risk_upgrades/test_track_dev_cos_lite_upgrade_risk.py rename to tests/integration/cos/risk_upgrades/test_track_3_cos_lite_upgrade_risk.py index dc05bf5c..6ffcf027 100644 --- a/tests/integration/cos_lite/risk_upgrades/test_track_dev_cos_lite_upgrade_risk.py +++ b/tests/integration/cos/risk_upgrades/test_track_3_cos_lite_upgrade_risk.py @@ -3,7 +3,7 @@ import jubilant from helpers import generic_assertions -TF_FILE = Path(__file__).parent.resolve() / "track-2.tf" +TF_FILE = Path(__file__).parent.resolve() / "track-3.0.tf" def test_deploy_from_stable( diff --git a/tests/integration/cos_lite/risk_upgrades/track-2.tf b/tests/integration/cos/risk_upgrades/track-3.0.tf similarity index 82% rename from tests/integration/cos_lite/risk_upgrades/track-2.tf rename to tests/integration/cos/risk_upgrades/track-3.0.tf index 1dd1afdb..6d3e1124 100644 --- a/tests/integration/cos_lite/risk_upgrades/track-2.tf +++ b/tests/integration/cos/risk_upgrades/track-3.0.tf @@ -36,9 +36,9 @@ module "ssc" { } module "cos-lite" { - source = "git::https://github.com/canonical/observability-stack//terraform/cos-lite?ref=track/2" - model_uuid = data.juju_model.cos-model.uuid - channel = "2/${var.risk}" + source = "git::https://github.com/canonical/observability-stack//terraform/cos-lite?ref=track/3.0" + model = { uuid = data.juju_model.cos-model.uuid } + risk = var.risk internal_tls = true external_certificates_offer_url = "admin/${var.ca_model}.certificates" external_ca_cert_offer_url = "admin/${var.ca_model}.send-ca-cert" diff --git a/tests/integration/cos_lite/risk_upgrades/test_track_3_cos_lite_upgrade_risk.py b/tests/integration/cos_lite/risk_upgrades/test_track_3_cos_lite_upgrade_risk.py new file mode 100644 index 00000000..6ffcf027 --- /dev/null +++ b/tests/integration/cos_lite/risk_upgrades/test_track_3_cos_lite_upgrade_risk.py @@ -0,0 +1,27 @@ +from pathlib import Path + +import jubilant +from helpers import generic_assertions + +TF_FILE = Path(__file__).parent.resolve() / "track-3.0.tf" + + +def test_deploy_from_stable( + tf_manager, ca_model: jubilant.Juju, cos_model: jubilant.Juju, tmp_path +): + # GIVEN a module deployed with a "stable" risk + tf_manager.init(TF_FILE) + tf_manager.apply(ca_model=ca_model.model, cos_model=cos_model.model, risk="stable") + generic_assertions(cos_model, ca_model, tmp_path) + + +def test_upgrade_path( + tf_manager, ca_model: jubilant.Juju, cos_model: jubilant.Juju, tmp_path +): + # WHEN upgraded to higher risk + for risk in ["candidate", "beta", "edge"]: + tf_manager.init(TF_FILE) + tf_manager.apply(ca_model=ca_model.model, cos_model=cos_model.model, risk=risk) + + # THEN the model is upgraded and is healthy + generic_assertions(cos_model, ca_model, tmp_path) diff --git a/tests/integration/cos_lite/risk_upgrades/track-3.0.tf b/tests/integration/cos_lite/risk_upgrades/track-3.0.tf new file mode 100644 index 00000000..6d3e1124 --- /dev/null +++ b/tests/integration/cos_lite/risk_upgrades/track-3.0.tf @@ -0,0 +1,45 @@ +terraform { + required_version = ">= 1.5" + required_providers { + juju = { + source = "juju/juju" + version = ">= 1.0" + } + } +} + +variable "risk" { + type = string +} + +variable "ca_model" { + type = string +} + +variable "cos_model" { + type = string +} + +data "juju_model" "ca-model" { + name = var.ca_model + owner = "admin" +} + +data "juju_model" "cos-model" { + name = var.cos_model + owner = "admin" +} + +module "ssc" { + source = "git::https://github.com/canonical/self-signed-certificates-operator//terraform" + model_uuid = data.juju_model.ca-model.uuid +} + +module "cos-lite" { + source = "git::https://github.com/canonical/observability-stack//terraform/cos-lite?ref=track/3.0" + model = { uuid = data.juju_model.cos-model.uuid } + risk = var.risk + internal_tls = true + external_certificates_offer_url = "admin/${var.ca_model}.certificates" + external_ca_cert_offer_url = "admin/${var.ca_model}.send-ca-cert" +} From 5998e1bd19fd415583f734c3d2f51e280615ed0e Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Mon, 6 Jul 2026 12:37:30 -0400 Subject: [PATCH 31/41] chore --- .github/workflows/terraform.yml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/.github/workflows/terraform.yml b/.github/workflows/terraform.yml index fcda6709..c5d03754 100644 --- a/.github/workflows/terraform.yml +++ b/.github/workflows/terraform.yml @@ -71,10 +71,3 @@ jobs: # with: # product: cos # runner: self-hosted-linux-amd64-noble-xlarge - # test-integration-cos-dev: - # name: COS Dev Terraform integration - # needs: [test-unit] - # uses: canonical/observability-stack/.github/workflows/_integration.yml@main - # with: - # product: cos_dev - # runner: self-hosted-linux-amd64-noble-large From fc3ba31b897c8e3a316ecc45d62b14335e5aa6fb Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Mon, 6 Jul 2026 13:05:57 -0400 Subject: [PATCH 32/41] chore --- .github/workflows/terraform.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/terraform.yml b/.github/workflows/terraform.yml index c5d03754..3590b8e5 100644 --- a/.github/workflows/terraform.yml +++ b/.github/workflows/terraform.yml @@ -64,10 +64,10 @@ jobs: with: product: cos_lite runner: self-hosted-linux-amd64-noble-large - # test-integration-cos: - # name: COS Terraform integration - # needs: [test-unit] - # uses: canonical/observability-stack/.github/workflows/_integration.yml@main - # with: - # product: cos - # runner: self-hosted-linux-amd64-noble-xlarge + test-integration-cos: + name: COS Terraform integration + needs: [test-unit] + uses: canonical/observability-stack/.github/workflows/_integration.yml@main + with: + product: cos + runner: self-hosted-linux-amd64-noble-xlarge From 77131583f5fc334253ef3d99695b8ee7fe76fa90 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Mon, 6 Jul 2026 13:06:05 -0400 Subject: [PATCH 33/41] chore --- .github/workflows/terraform.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/terraform.yml b/.github/workflows/terraform.yml index 3590b8e5..fcde73df 100644 --- a/.github/workflows/terraform.yml +++ b/.github/workflows/terraform.yml @@ -67,7 +67,7 @@ jobs: test-integration-cos: name: COS Terraform integration needs: [test-unit] - uses: canonical/observability-stack/.github/workflows/_integration.yml@main + uses: canonical/observability-stack/.github/workflows/_integration.yml@feat/risk-upgrades with: product: cos runner: self-hosted-linux-amd64-noble-xlarge From 80b9adaab1218c8661a6577a50495796fc8f88a3 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Mon, 6 Jul 2026 14:22:59 -0400 Subject: [PATCH 34/41] chore --- .github/workflows/_integration.yml | 3 +-- .github/workflows/terraform.yml | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/_integration.yml b/.github/workflows/_integration.yml index f4f24f50..73a6f324 100644 --- a/.github/workflows/_integration.yml +++ b/.github/workflows/_integration.yml @@ -38,8 +38,7 @@ jobs: fail-fast: false matrix: juju-channel: ["3.6/stable"] - # scenario: ["risk_upgrades", "tls_full", "tls_external", "tls_internal", "tls_none"] - scenario: ["risk_upgrades"] + scenario: ["risk_upgrades", "tls_full", "tls_external", "tls_internal", "tls_none"] steps: - name: Checkout uses: actions/checkout@v4 diff --git a/.github/workflows/terraform.yml b/.github/workflows/terraform.yml index fcde73df..3796ecf8 100644 --- a/.github/workflows/terraform.yml +++ b/.github/workflows/terraform.yml @@ -60,14 +60,14 @@ jobs: test-integration-cos-lite: name: COS Lite Terraform integration needs: [test-unit] - uses: canonical/observability-stack/.github/workflows/_integration.yml@feat/risk-upgrades + uses: canonical/observability-stack/.github/workflows/_integration.yml@main with: product: cos_lite runner: self-hosted-linux-amd64-noble-large test-integration-cos: name: COS Terraform integration needs: [test-unit] - uses: canonical/observability-stack/.github/workflows/_integration.yml@feat/risk-upgrades + uses: canonical/observability-stack/.github/workflows/_integration.yml@main with: product: cos runner: self-hosted-linux-amd64-noble-xlarge From 978a00e93503944f1fdd79b1a4b40c169b3357e6 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Mon, 6 Jul 2026 16:11:23 -0400 Subject: [PATCH 35/41] chore --- .github/workflows/_integration.yml | 3 +- .github/workflows/terraform.yml | 4 +- .../test_track_3_cos_lite_upgrade_risk.py | 2 +- .../cos/risk_upgrades/track-3.0.tf | 45 ------------------- .../cos_lite/risk_upgrades/track-3.0.tf | 45 ------------------- 5 files changed, 5 insertions(+), 94 deletions(-) delete mode 100644 tests/integration/cos/risk_upgrades/track-3.0.tf delete mode 100644 tests/integration/cos_lite/risk_upgrades/track-3.0.tf diff --git a/.github/workflows/_integration.yml b/.github/workflows/_integration.yml index 73a6f324..f7c8e26d 100644 --- a/.github/workflows/_integration.yml +++ b/.github/workflows/_integration.yml @@ -38,7 +38,8 @@ jobs: fail-fast: false matrix: juju-channel: ["3.6/stable"] - scenario: ["risk_upgrades", "tls_full", "tls_external", "tls_internal", "tls_none"] + scenario: ["risk_upgrades"] + # scenario: ["risk_upgrades", "tls_full", "tls_external", "tls_internal", "tls_none"] steps: - name: Checkout uses: actions/checkout@v4 diff --git a/.github/workflows/terraform.yml b/.github/workflows/terraform.yml index 3796ecf8..fcde73df 100644 --- a/.github/workflows/terraform.yml +++ b/.github/workflows/terraform.yml @@ -60,14 +60,14 @@ jobs: test-integration-cos-lite: name: COS Lite Terraform integration needs: [test-unit] - uses: canonical/observability-stack/.github/workflows/_integration.yml@main + uses: canonical/observability-stack/.github/workflows/_integration.yml@feat/risk-upgrades with: product: cos_lite runner: self-hosted-linux-amd64-noble-large test-integration-cos: name: COS Terraform integration needs: [test-unit] - uses: canonical/observability-stack/.github/workflows/_integration.yml@main + uses: canonical/observability-stack/.github/workflows/_integration.yml@feat/risk-upgrades with: product: cos runner: self-hosted-linux-amd64-noble-xlarge diff --git a/tests/integration/cos/risk_upgrades/test_track_3_cos_lite_upgrade_risk.py b/tests/integration/cos/risk_upgrades/test_track_3_cos_lite_upgrade_risk.py index 6ffcf027..34664c7d 100644 --- a/tests/integration/cos/risk_upgrades/test_track_3_cos_lite_upgrade_risk.py +++ b/tests/integration/cos/risk_upgrades/test_track_3_cos_lite_upgrade_risk.py @@ -3,7 +3,7 @@ import jubilant from helpers import generic_assertions -TF_FILE = Path(__file__).parent.resolve() / "track-3.0.tf" +TF_FILE = Path(__file__).parent.parent.resolve() / "tls_full/track-3.0.tf" def test_deploy_from_stable( diff --git a/tests/integration/cos/risk_upgrades/track-3.0.tf b/tests/integration/cos/risk_upgrades/track-3.0.tf deleted file mode 100644 index 6d3e1124..00000000 --- a/tests/integration/cos/risk_upgrades/track-3.0.tf +++ /dev/null @@ -1,45 +0,0 @@ -terraform { - required_version = ">= 1.5" - required_providers { - juju = { - source = "juju/juju" - version = ">= 1.0" - } - } -} - -variable "risk" { - type = string -} - -variable "ca_model" { - type = string -} - -variable "cos_model" { - type = string -} - -data "juju_model" "ca-model" { - name = var.ca_model - owner = "admin" -} - -data "juju_model" "cos-model" { - name = var.cos_model - owner = "admin" -} - -module "ssc" { - source = "git::https://github.com/canonical/self-signed-certificates-operator//terraform" - model_uuid = data.juju_model.ca-model.uuid -} - -module "cos-lite" { - source = "git::https://github.com/canonical/observability-stack//terraform/cos-lite?ref=track/3.0" - model = { uuid = data.juju_model.cos-model.uuid } - risk = var.risk - internal_tls = true - external_certificates_offer_url = "admin/${var.ca_model}.certificates" - external_ca_cert_offer_url = "admin/${var.ca_model}.send-ca-cert" -} diff --git a/tests/integration/cos_lite/risk_upgrades/track-3.0.tf b/tests/integration/cos_lite/risk_upgrades/track-3.0.tf deleted file mode 100644 index 6d3e1124..00000000 --- a/tests/integration/cos_lite/risk_upgrades/track-3.0.tf +++ /dev/null @@ -1,45 +0,0 @@ -terraform { - required_version = ">= 1.5" - required_providers { - juju = { - source = "juju/juju" - version = ">= 1.0" - } - } -} - -variable "risk" { - type = string -} - -variable "ca_model" { - type = string -} - -variable "cos_model" { - type = string -} - -data "juju_model" "ca-model" { - name = var.ca_model - owner = "admin" -} - -data "juju_model" "cos-model" { - name = var.cos_model - owner = "admin" -} - -module "ssc" { - source = "git::https://github.com/canonical/self-signed-certificates-operator//terraform" - model_uuid = data.juju_model.ca-model.uuid -} - -module "cos-lite" { - source = "git::https://github.com/canonical/observability-stack//terraform/cos-lite?ref=track/3.0" - model = { uuid = data.juju_model.cos-model.uuid } - risk = var.risk - internal_tls = true - external_certificates_offer_url = "admin/${var.ca_model}.certificates" - external_ca_cert_offer_url = "admin/${var.ca_model}.send-ca-cert" -} From 81122ed6383fbf070c3e25521ac2b9cc4945f871 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Mon, 6 Jul 2026 16:13:27 -0400 Subject: [PATCH 36/41] chore --- .../risk_upgrades/test_track_3_cos_lite_upgrade_risk.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/integration/cos_lite/risk_upgrades/test_track_3_cos_lite_upgrade_risk.py b/tests/integration/cos_lite/risk_upgrades/test_track_3_cos_lite_upgrade_risk.py index 6ffcf027..34664c7d 100644 --- a/tests/integration/cos_lite/risk_upgrades/test_track_3_cos_lite_upgrade_risk.py +++ b/tests/integration/cos_lite/risk_upgrades/test_track_3_cos_lite_upgrade_risk.py @@ -3,7 +3,7 @@ import jubilant from helpers import generic_assertions -TF_FILE = Path(__file__).parent.resolve() / "track-3.0.tf" +TF_FILE = Path(__file__).parent.parent.resolve() / "tls_full/track-3.0.tf" def test_deploy_from_stable( From f96941bb6a240bb7cfe5ea88c6d0ff81da0027ad Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Mon, 6 Jul 2026 16:30:48 -0400 Subject: [PATCH 37/41] Update test_track_3_cos_lite_upgrade_risk.py Signed-off-by: Michael Thamm --- .../cos_lite/risk_upgrades/test_track_3_cos_lite_upgrade_risk.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/integration/cos_lite/risk_upgrades/test_track_3_cos_lite_upgrade_risk.py b/tests/integration/cos_lite/risk_upgrades/test_track_3_cos_lite_upgrade_risk.py index 34664c7d..1f03c4c1 100644 --- a/tests/integration/cos_lite/risk_upgrades/test_track_3_cos_lite_upgrade_risk.py +++ b/tests/integration/cos_lite/risk_upgrades/test_track_3_cos_lite_upgrade_risk.py @@ -1,3 +1,4 @@ +# TODO: Remove this comment once done testing from pathlib import Path import jubilant From be382ef5be006f5f45a13bf4a5d5453fc7b9830e Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Mon, 6 Jul 2026 16:32:24 -0400 Subject: [PATCH 38/41] Update track-3.0.tf Signed-off-by: Michael Thamm --- tests/integration/cos_lite/tls_none/track-3.0.tf | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/integration/cos_lite/tls_none/track-3.0.tf b/tests/integration/cos_lite/tls_none/track-3.0.tf index 9d28053b..ddb2283c 100644 --- a/tests/integration/cos_lite/tls_none/track-3.0.tf +++ b/tests/integration/cos_lite/tls_none/track-3.0.tf @@ -1,3 +1,4 @@ +# TODO: Remove once done testing terraform { required_version = ">= 1.5" required_providers { From 07c9e4c823c545c86eb8ef33fd11e3cfec442ad1 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Mon, 6 Jul 2026 17:03:14 -0400 Subject: [PATCH 39/41] chore --- tests/integration/cos/tls_full/track-3.0.tf | 8 +++++++- tests/integration/cos_lite/tls_full/track-3.0.tf | 8 +++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/tests/integration/cos/tls_full/track-3.0.tf b/tests/integration/cos/tls_full/track-3.0.tf index 53dd53e6..55f3642f 100644 --- a/tests/integration/cos/tls_full/track-3.0.tf +++ b/tests/integration/cos/tls_full/track-3.0.tf @@ -46,7 +46,7 @@ module "ssc" { module "cos" { source = "git::https://github.com/canonical/observability-stack//terraform/cos?ref=track/3.0" model = { uuid = data.juju_model.cos-model.uuid } - risk = "edge" + risk = var.risk internal_tls = true external_certificates_offer_url = "admin/${var.ca_model}.certificates" external_ca_cert_offer_url = "admin/${var.ca_model}.send-ca-cert" @@ -64,3 +64,9 @@ module "cos" { tempo_coordinator = { units = 1 } tempo_worker = { compactor_units = 1, distributor_units = 1, ingester_units = 1, metrics_generator_units = 1, querier_units = 1, query_frontend_units = 1 } } + +# This is used by ../risk_upgrades +variable "risk" { + type = string + default = "edge" +} diff --git a/tests/integration/cos_lite/tls_full/track-3.0.tf b/tests/integration/cos_lite/tls_full/track-3.0.tf index 13f2e83f..c53d0b5b 100644 --- a/tests/integration/cos_lite/tls_full/track-3.0.tf +++ b/tests/integration/cos_lite/tls_full/track-3.0.tf @@ -34,8 +34,14 @@ module "ssc" { module "cos-lite" { source = "git::https://github.com/canonical/observability-stack//terraform/cos-lite?ref=track/3.0" model = { uuid = data.juju_model.cos-model.uuid } - risk = "edge" + risk = var.risk internal_tls = true external_certificates_offer_url = "admin/${var.ca_model}.certificates" external_ca_cert_offer_url = "admin/${var.ca_model}.send-ca-cert" } + +# This is used by ../risk_upgrades +variable "risk" { + type = string + default = "edge" +} From 45cb089b80bc4a0af245aa545a72f2a6adcfa8ce Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Mon, 6 Jul 2026 21:29:50 -0400 Subject: [PATCH 40/41] Update tests/integration/cos_lite/risk_upgrades/test_track_3_cos_lite_upgrade_risk.py Signed-off-by: Michael Thamm --- .../cos_lite/risk_upgrades/test_track_3_cos_lite_upgrade_risk.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/integration/cos_lite/risk_upgrades/test_track_3_cos_lite_upgrade_risk.py b/tests/integration/cos_lite/risk_upgrades/test_track_3_cos_lite_upgrade_risk.py index 1f03c4c1..34664c7d 100644 --- a/tests/integration/cos_lite/risk_upgrades/test_track_3_cos_lite_upgrade_risk.py +++ b/tests/integration/cos_lite/risk_upgrades/test_track_3_cos_lite_upgrade_risk.py @@ -1,4 +1,3 @@ -# TODO: Remove this comment once done testing from pathlib import Path import jubilant From 35caa1f11fe22e7084f6cbdcdb51278f32432b91 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Mon, 6 Jul 2026 21:34:35 -0400 Subject: [PATCH 41/41] chore --- .github/workflows/_integration.yml | 3 +-- .github/workflows/terraform.yml | 4 ++-- .../test_track_3_cos_lite_upgrade_risk.py | 20 +++++++++++++++++-- .../cos_lite/tls_internal/track-3.0.tf | 2 +- .../cos_lite/tls_none/track-3.0.tf | 1 - 5 files changed, 22 insertions(+), 8 deletions(-) diff --git a/.github/workflows/_integration.yml b/.github/workflows/_integration.yml index f7c8e26d..73a6f324 100644 --- a/.github/workflows/_integration.yml +++ b/.github/workflows/_integration.yml @@ -38,8 +38,7 @@ jobs: fail-fast: false matrix: juju-channel: ["3.6/stable"] - scenario: ["risk_upgrades"] - # scenario: ["risk_upgrades", "tls_full", "tls_external", "tls_internal", "tls_none"] + scenario: ["risk_upgrades", "tls_full", "tls_external", "tls_internal", "tls_none"] steps: - name: Checkout uses: actions/checkout@v4 diff --git a/.github/workflows/terraform.yml b/.github/workflows/terraform.yml index fcde73df..3796ecf8 100644 --- a/.github/workflows/terraform.yml +++ b/.github/workflows/terraform.yml @@ -60,14 +60,14 @@ jobs: test-integration-cos-lite: name: COS Lite Terraform integration needs: [test-unit] - uses: canonical/observability-stack/.github/workflows/_integration.yml@feat/risk-upgrades + uses: canonical/observability-stack/.github/workflows/_integration.yml@main with: product: cos_lite runner: self-hosted-linux-amd64-noble-large test-integration-cos: name: COS Terraform integration needs: [test-unit] - uses: canonical/observability-stack/.github/workflows/_integration.yml@feat/risk-upgrades + uses: canonical/observability-stack/.github/workflows/_integration.yml@main with: product: cos runner: self-hosted-linux-amd64-noble-xlarge diff --git a/tests/integration/cos/risk_upgrades/test_track_3_cos_lite_upgrade_risk.py b/tests/integration/cos/risk_upgrades/test_track_3_cos_lite_upgrade_risk.py index 34664c7d..54f6b9ae 100644 --- a/tests/integration/cos/risk_upgrades/test_track_3_cos_lite_upgrade_risk.py +++ b/tests/integration/cos/risk_upgrades/test_track_3_cos_lite_upgrade_risk.py @@ -1,9 +1,21 @@ +import os from pathlib import Path import jubilant from helpers import generic_assertions TF_FILE = Path(__file__).parent.parent.resolve() / "tls_full/track-3.0.tf" +S3_ENDPOINT = { + "s3_endpoint": os.getenv("S3_ENDPOINT"), + "s3_secret_key": os.getenv("S3_SECRET_KEY"), + "s3_access_key": os.getenv("S3_ACCESS_KEY"), +} + + +def test_envvars(): + assert all(S3_ENDPOINT.values()), ( + f"export the following env vars (upper case) before running this test: {S3_ENDPOINT.keys()}" + ) def test_deploy_from_stable( @@ -11,7 +23,9 @@ def test_deploy_from_stable( ): # GIVEN a module deployed with a "stable" risk tf_manager.init(TF_FILE) - tf_manager.apply(ca_model=ca_model.model, cos_model=cos_model.model, risk="stable") + tf_manager.apply( + ca_model=ca_model.model, cos_model=cos_model.model, risk="stable", **S3_ENDPOINT + ) generic_assertions(cos_model, ca_model, tmp_path) @@ -21,7 +35,9 @@ def test_upgrade_path( # WHEN upgraded to higher risk for risk in ["candidate", "beta", "edge"]: tf_manager.init(TF_FILE) - tf_manager.apply(ca_model=ca_model.model, cos_model=cos_model.model, risk=risk) + tf_manager.apply( + ca_model=ca_model.model, cos_model=cos_model.model, risk=risk, **S3_ENDPOINT + ) # THEN the model is upgraded and is healthy generic_assertions(cos_model, ca_model, tmp_path) diff --git a/tests/integration/cos_lite/tls_internal/track-3.0.tf b/tests/integration/cos_lite/tls_internal/track-3.0.tf index 3c12880c..0ee23478 100644 --- a/tests/integration/cos_lite/tls_internal/track-3.0.tf +++ b/tests/integration/cos_lite/tls_internal/track-3.0.tf @@ -20,6 +20,6 @@ data "juju_model" "model" { module "cos-lite" { source = "git::https://github.com/canonical/observability-stack//terraform/cos-lite?ref=track/3.0" model = { uuid = data.juju_model.model.uuid } - risk = "edge" + risk = "stable" internal_tls = true } diff --git a/tests/integration/cos_lite/tls_none/track-3.0.tf b/tests/integration/cos_lite/tls_none/track-3.0.tf index ddb2283c..9d28053b 100644 --- a/tests/integration/cos_lite/tls_none/track-3.0.tf +++ b/tests/integration/cos_lite/tls_none/track-3.0.tf @@ -1,4 +1,3 @@ -# TODO: Remove once done testing terraform { required_version = ">= 1.5" required_providers {