Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/tofu-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
test-commons-modules:
uses: nullplatform/actions-nullplatform/.github/workflows/tofu-test.yml@main
with:
modules: '["infrastructure/commons/cert_manager", "infrastructure/commons/external_dns", "infrastructure/commons/istio"]'
modules: '["infrastructure/commons/cert_manager", "infrastructure/commons/external_dns", "infrastructure/commons/istio", "infrastructure/commons/prometheus"]'

test-aws-modules:
uses: nullplatform/actions-nullplatform/.github/workflows/tofu-test.yml@main
Expand All @@ -30,7 +30,7 @@ jobs:
test-nullplatform-modules:
uses: nullplatform/actions-nullplatform/.github/workflows/tofu-test.yml@main
with:
modules: '["nullplatform/account", "nullplatform/agent", "nullplatform/api_key", "nullplatform/dimension", "nullplatform/dimension_value", "nullplatform/users", "nullplatform/metrics", "nullplatform/asset/docker_server", "nullplatform/cloud/azure/cloud", "nullplatform/cloud/gcp/cloud", "nullplatform/cloud/aws/cloud", "nullplatform/code_repository"]'
modules: '["nullplatform/account", "nullplatform/agent", "nullplatform/api_key", "nullplatform/dimension", "nullplatform/dimension_value", "nullplatform/users", "nullplatform/metrics", "nullplatform/asset/docker_server", "nullplatform/cloud/azure/cloud", "nullplatform/cloud/gcp/cloud", "nullplatform/cloud/aws/cloud", "nullplatform/code_repository", "nullplatform/base", "nullplatform/agent"]'

test-container-orchestration-modules:
uses: nullplatform/actions-nullplatform/.github/workflows/tofu-test.yml@main
Expand Down
1 change: 1 addition & 0 deletions infrastructure/commons/cert_manager/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ resource "helm_release" "cert_manager" {
repository = "https://charts.jetstack.io"
chart = "cert-manager"
namespace = var.cert_manager_namespace
version = var.cert_manager_version

create_namespace = true
disable_webhooks = false
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
mock_provider "helm" {}

variables {
cloud_provider = "aws"
hosted_zone_name = "myorg.example.com"
account_slug = "myorg"
private_domain_name = "myorg.example.com"
aws_sa_arn = "arn:aws:iam::123456789012:role/cert-manager"
aws_region = "us-east-1"
cloud_provider = "aws"
hosted_zone_name = "myorg.example.com"
account_slug = "myorg"
private_domain_name = "myorg.example.com"
aws_sa_arn = "arn:aws:iam::123456789012:role/cert-manager"
aws_region = "us-east-1"
cert_manager_version = "v1.21.1"
}

# Validates AWS provider config plans successfully
Expand Down Expand Up @@ -100,3 +101,19 @@ run "rejects_invalid_aws_identity_mode" {

expect_failures = [var.aws_identity_mode]
}

################################################################################
# Version pinning
################################################################################

# cert_manager_version was declared with a default and never referenced: grep found one
# occurrence, its own declaration. The helm_release had no version argument, so installs
# tracked whatever charts.jetstack.io served while the README showed a number.
run "cert_manager_version_reaches_the_release" {
command = plan

assert {
condition = helm_release.cert_manager.version == "v1.21.1"
error_message = "cert_manager_version must be wired to the helm_release, not merely declared"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ variables {
azure_resource_group_name = "rg-test"
azure_tenant_id = "11111111-2222-3333-4444-555555555555"
azure_hosted_zone_name = "myorg.nullimplementation.com"
cert_manager_version = "v1.21.1"
}

# Validates Azure provider config plans successfully
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
mock_provider "helm" {}

variables {
cloud_provider = "cloudflare"
hosted_zone_name = "myorg.nullimplementation.com"
account_slug = "myorg"
private_domain_name = "myorg.nullimplementation.com"
cloudflare_token = "fake-cloudflare-token-for-testing"
cloud_provider = "cloudflare"
hosted_zone_name = "myorg.nullimplementation.com"
account_slug = "myorg"
private_domain_name = "myorg.nullimplementation.com"
cloudflare_token = "fake-cloudflare-token-for-testing"
cert_manager_version = "v1.21.1"
}

# Validates Cloudflare provider config plans successfully
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
mock_provider "helm" {}

variables {
cert_manager_version = "v1.21.1"
}

# Validates invalid cloud_provider is rejected
run "rejects_invalid_provider" {
command = plan
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ variables {
oci_compartment_ocid = "ocid1.compartment.oc1..aaaaaaaatest"
oci_sa_ocid = "ocid1.principal.oc1..aaaaaaaatest"
oci_region = "us-ashburn-1"
cert_manager_version = "v1.21.1"
}

# Validates OCI provider config plans successfully
Expand Down
9 changes: 7 additions & 2 deletions infrastructure/commons/cert_manager/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,14 @@ variable "private_domain_name" {
###############################################################################

variable "cert_manager_version" {
description = "The version of cert-manager Helm chart to deploy"
# example: v1.21.1
description = "No default: every install pins this deliberately — see VERSIONS.md. The version of cert-manager Helm chart to deploy. Was declared but never wired to the helm_release, so installs tracked whatever the chart repository served; the default is the version that resolved to as of 2026-08-27, which keeps behaviour unchanged while removing the drift."
type = string
default = "1.18.2"

validation {
condition = var.cert_manager_version != "" && !contains(["latest", "main", "master"], lower(var.cert_manager_version))
error_message = "cert_manager_version must be a non-empty fixed version, not empty and not a moving reference."
}
}

variable "cert_manager_namespace" {
Expand Down
25 changes: 25 additions & 0 deletions infrastructure/commons/prometheus/.terraform.lock.hcl

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions infrastructure/commons/prometheus/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ resource "helm_release" "prometheus" {
repository = "https://prometheus-community.github.io/helm-charts"
chart = "prometheus"
namespace = var.prometheus_namespace
version = var.prometheus_version

create_namespace = true
disable_webhooks = false
Expand Down
34 changes: 34 additions & 0 deletions infrastructure/commons/prometheus/tests/prometheus.tftest.hcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
mock_provider "helm" {}

variables {
prometheus_version = "29.27.0"
}

################################################################################
# Version pinning
################################################################################

# The helm_release carried no version argument and the module exposed no variable for one,
# so every apply resolved to whatever prometheus-community served latest, with no diff to
# review and no way to pin without editing the module.
run "prometheus_version_reaches_the_release" {
command = plan

assert {
condition = helm_release.prometheus.version == "29.27.0"
error_message = "prometheus_version must be wired to the helm_release so the deployed chart is a decision"
}
}

run "prometheus_version_is_overridable" {
command = plan

variables {
prometheus_version = "29.26.0"
}

assert {
condition = helm_release.prometheus.version == "29.26.0"
error_message = "prometheus_version must be settable by the caller"
}
}
11 changes: 11 additions & 0 deletions infrastructure/commons/prometheus/variables.tf
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
variable "prometheus_version" {
# example: 29.27.0
description = "No default: every install pins this deliberately — see VERSIONS.md. Helm chart version for the prometheus-community/prometheus chart. The helm_release carried no version at all, so every apply resolved to whatever the repository served latest; the default is the version that resolved to as of 2026-08-27, which keeps behaviour unchanged while removing the drift."
type = string

validation {
condition = var.prometheus_version != "" && !contains(["latest", "main", "master"], lower(var.prometheus_version))
error_message = "prometheus_version must be a non-empty fixed version, not empty and not a moving reference."
}
}

variable "nullplatform_port" {
description = "Port number for nullplatform service communication"
type = number
Expand Down
9 changes: 8 additions & 1 deletion nullplatform/agent/locals.tf
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,13 @@

locals {

scope_list = compact([trimspace(coalesce(var.agent_repos_scope, ""))])
# The repository lives here and only the tag is exposed, so a version bump is a variable

# change instead of a hand-assembled URL.

scope_repo = trimspace(coalesce(var.agent_repos_scope, ""))

scope_list = compact([local.scope_repo != "" ? "${local.scope_repo}#${trimspace(var.agent_repos_scope_tag)}" : ""])
# Parse comma-separated extra repositories and clean whitespace
repos_extra = compact([for s in var.agent_repos_extra : trimspace(s)])

Expand Down Expand Up @@ -42,6 +48,7 @@ locals {
CLUSTER_NAME = var.cluster_name
NAMESPACE = var.namespace
IMAGE_TAG = var.image_tag
TRAFFIC_CONTAINER_IMAGE = "${var.agent_traffic_manager_repository}:${var.agent_traffic_manager_tag}"
DOMAIN = var.domain
DNS_TYPE = var.dns_type
USE_ACCOUNT_SLUG = var.use_account_slug
Expand Down
13 changes: 8 additions & 5 deletions nullplatform/agent/tests/agent.tftest.hcl
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@ mock_provider "nullplatform" {}
mock_provider "helm" {}

variables {
api_key = "test-api-key"
cluster_name = "test-cluster"
tags_selectors = { environment = "test" }
image_tag = "latest"
cloud_provider = "gcp"
api_key = "test-api-key"
cluster_name = "test-cluster"
tags_selectors = { environment = "test" }
image_tag = "latest"
cloud_provider = "gcp"
nullplatform_agent_helm_version = "2.37.0"
agent_traffic_manager_tag = "1.8.0"
agent_repos_scope_tag = "v1.15.1"
}

run "no_extra_envs_does_not_require_ingress_templates" {
Expand Down
102 changes: 102 additions & 0 deletions nullplatform/agent/tests/agent_values.tftest.hcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
mock_provider "helm" {}
mock_provider "nullplatform" {}

variables {
api_key = "test-api-key"
cluster_name = "my-cluster"
tags_selectors = { dimension = "prod" }
cloud_provider = "aws"
aws_iam_role_arn = "arn:aws:iam::123456789012:role/agent"
image_tag = "0.9.2"
nullplatform_agent_helm_version = "2.37.0"
agent_traffic_manager_tag = "1.8.0"
agent_repos_scope_tag = "v1.15.1"
}

################################################################################
# Traffic manager image
################################################################################

# Pinning the traffic manager used to mean passing the whole image string through
# extra_envs. The registry now lives in the module and only the tag is exposed.
run "traffic_manager_image_is_assembled_from_the_tag" {
command = plan

assert {
condition = strcontains(helm_release.agent.values[0], "TRAFFIC_CONTAINER_IMAGE: \"public.ecr.aws/nullplatform/k8s-traffic-manager:1.8.0\"")
error_message = "TRAFFIC_CONTAINER_IMAGE should be built from the repository default and the pinned tag"
}
}

run "traffic_manager_repository_is_overridable" {
command = plan

variables {
agent_traffic_manager_repository = "my-mirror.example.com/nullplatform/k8s-traffic-manager"
}

assert {
condition = strcontains(helm_release.agent.values[0], "TRAFFIC_CONTAINER_IMAGE: \"my-mirror.example.com/nullplatform/k8s-traffic-manager:1.8.0\"")
error_message = "the registry must be overridable for a mirrored path"
}
}

run "extra_envs_still_overrides_the_traffic_manager_image" {
command = plan

variables {
extra_envs = {
TRAFFIC_CONTAINER_IMAGE = "public.ecr.aws/nullplatform/k8s-traffic-manager@sha256:abc123"
}
}

# extra_envs is merged last, so the previous way of doing this keeps working. That is what
# makes exposing the tag an addition rather than a breaking change.
assert {
condition = strcontains(helm_release.agent.values[0], "TRAFFIC_CONTAINER_IMAGE: \"public.ecr.aws/nullplatform/k8s-traffic-manager@sha256:abc123\"")
error_message = "extra_envs must keep precedence over the assembled image"
}
}

################################################################################
# Scope repository
################################################################################

run "scope_repo_is_pinned_to_a_tag" {
command = plan

assert {
condition = !strcontains(helm_release.agent.values[0], "#main")
error_message = "the scope repo default must not point at a moving branch"
}

assert {
condition = strcontains(helm_release.agent.values[0], "scopes.git#v1.15.1")
error_message = "the scope repo default should be pinned to the released tag"
}
}

run "scope_repo_is_overridable" {
command = plan

variables {
agent_repos_scope_tag = "v1.14.0"
}

assert {
condition = strcontains(helm_release.agent.values[0], "scopes.git#v1.14.0")
error_message = "callers must still be able to choose their own ref"
}
}

run "agent_repos_scope_rejects_an_inline_fragment" {
command = plan

variables {
agent_repos_scope = "https://github.com/nullplatform/scopes.git#v1.15.1"
}

# Catches the most likely migration mistake: pasting the old value verbatim, which would
# otherwise render repo.git#v1.15.1#v1.15.1.
expect_failures = [var.agent_repos_scope]
}
Loading
Loading