Skip to content
Closed
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
70 changes: 70 additions & 0 deletions decision-records/2026-04-02--terraform-module-tagging.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
**Date:** 2026-04-02<br/>
**Author:** Michael Thamm (@crucible)

## Context and Problem Statement

Prior discussion was conducted in this GitHub issue:
- https://github.com/canonical/observability/issues/427

with 2 Observability team Cafes to come to an agreement. This document will summarize the agreed direction for tagging Terraform charm and product modules.

## Decision: use separate full-SemVer tag dedicated to Terraform

Design goals:
- Clear Terraform mapping to solution track / charm workload version
- Strict pinning (precise reproducibility)
- Tagging must be compatible with Terrareg

In the context of __Terraform-first Juju operations__,
facing __the friction between track-first and SemVer-first tagging__,
we decided for __Separate full-SemVer tag dedicated to Terraform__,
and rejected __Major.minor, metadata__,
to achieve __strict reproducibility__,
accepting __version opaqueness__.

## User experience
Note: The *channel* input is validated by Terraform for the track and by the Juju client for the risk; guiding the user. No validation can be done on the *revision* (currently not feasible with the Terraform Juju provider), so we say "incorrect config is user error".

1. First deployment
- *terraform apply*
2. In-track refresh
- No change to source e.g., ?ref=1.0.0
- Update the risk and/or revision input
- *terraform apply*
3. Cross-track refresh
- Update the source e.g., ?ref=2.0.0
- Update the channel or revision input
- Read the module’s docs for extra guidance
- *terraform apply*
4. Revert failed deployment
- Revert to the most recently used (working) version
- *terraform apply*

## Implementation
1. OBC-1544 “26.04 LTS prep and dogfooding” will address:
- Implementing the tagging rework of our TF modules (charms and products)
- Implement tagging CI on version bump
Comment thread
MichaelThamm marked this conversation as resolved.
2. OBC-1760 “Terraform-first end-to-end charm lifecycle” will address:
- Ensuring users can upgrade/downgrade in-track/cross-track our products with tagging

## Appendix - extra context

We need to conform to the [CC008](https://docs.google.com/document/d/1k1psLCfcf0Nr5KeVtWGFi9wmzhcg5AP9GVZTsRyVQSQ/edit?tab=t.0) spec and our solution must:
- have friendly UX for our users
- be extendible to product modules
- be automatable: tagging the repo and releasing to the TF registry

### Maintenance scenarios
| Upstream | Track | Cycle | Event | Tag |
|---|---|---|---|---|
| `3.6.7` | `3.6` | `26.04` | | `1.0.0` |
| | | | A TF endpoint added to track `3.6` | `1.1.0` |
| | | | A TF endpoint added to previous track e.g., `2.9` | `n-1.n+1.0` or `n.n+1.0` |
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why the ambiguity in the tag? Can we swap this with a concrete number like the other examples?

Copy link
Copy Markdown
Contributor Author

@MichaelThamm MichaelThamm Apr 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❗️Some issues with our approach

A tag is based on a commit on track/0 and we are now on track/1, but we never had to make any TF changes until track/2 is released. Now we bump the major to e.g. 1.0.0 and this tag is based on a commit on track/2. However, now we want to go back and add an endpoint to the 0.x.x TF module, but I don't know which track to tag a commit from.

Solution idea: we can use branches named after major TF tag versions to avoid outdated TF in older branches.


If we have charms in a product that do not have breaking changes, then they have minor bumps per cycle. What do we do with the product version to stay up-to-date with docs? The concern Luca brought up is that we will not be able to version our stack docs separately from the i.e., we have a core mapping conflict between TF modules vs. RTD.

We might have a workaround if we name tracks after major.minor of the product tf module
Then you'd have separate docs every time we change the charm channels (likely every 6 months); the downside is of course that if most documentation stays the same, we need to backport docs changes, but that's probably fine

| `3.6.7` | `3.6` | `26.10` | We consciously decide not to track bump (to `3.7.0`) across cycles | `1.1.0` |
| `4.1.0` | `4.1` | `27.04` | We time a breaking change with `27.04` | `2.0.0` |
| | | | We decide to make a breaking change mid-cycle | `3.0.0` |

### Shortcomings of our decision
- ❗️Tags are opaque to charm-tracks e.g., `1.0.0` is specific to track `2`.
- A user needs to search release notes / module docs to understand what tracks are allowed.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that the validation on tracks also implies users can't deploy chosen version of the workloads besides the few combinations that we explicitly allow.

If we have:

  • 1.0.0 with Loki 2.9 and Grafana 10
  • 2.0.0 with Loki 3.6 and Grafana 12

If a user wants to deploy Loki 3.6 with Grafana 10, they'll have to fork our Terraform module and write their own; I would add that here.

Copy link
Copy Markdown
Contributor Author

@MichaelThamm MichaelThamm Apr 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not necessarily true. The bumping of applications/components within COS (likely every cycle) may not require a major change in the product module. E.g., this is also possible if we did not break the product API:

  • 1.0.0 with Loki 2.9 and Grafana 10
  • 1.1.0 with Loki 3.6 and Grafana 12

Regardless, the user can still override the channel for a specific application if they choose to. E.g.,

module "cos" {
  source = 1.1.0
  grafana = {channel = 10.1/stable}
}

- We have to manage a `VERSION` file for tagging CI.
Loading