diff --git a/docs/deployment/k8s-clusters.md b/docs/deployment/k8s-clusters.md
index cc5a13a3169edd999fa7a860dcc1a344efaf1893..f318bb0d6b1a3721f965d2441bbc217f30be1556 100644
--- a/docs/deployment/k8s-clusters.md
+++ b/docs/deployment/k8s-clusters.md
@@ -2,3 +2,8 @@
 
 This page documents how we provision and manage Kubernetes clusters via the
 Google Kubernetes Engine service.
+
+!!! warning
+
+    We have relatively few services hosted via Kubernetes and as such we are
+    still fine-tuning our procedures, processes and policies surrounding it.
diff --git a/docs/workflow/terraform-modules.md b/docs/workflow/terraform-modules.md
new file mode 100644
index 0000000000000000000000000000000000000000..270fe6f84ed7620b4cbec21015e91fb50d3d232e
--- /dev/null
+++ b/docs/workflow/terraform-modules.md
@@ -0,0 +1,56 @@
+# Publishing terraform modules
+
+We publish terraform modules using the built-in terraform registry. See the
+[gcp-function
+registry](https://gitlab.developers.cam.ac.uk/uis/devops/infra/terraform/gcp-function/-/infrastructure_registry)
+for an example.
+
+A [dedicated
+template](https://gitlab.developers.cam.ac.uk/uis/devops/continuous-delivery/ci-templates/-/blob/master/terraform-module-publish.yml)
+is available in our CI templates project which can be used to automate
+publication of modules to the terraform registry.
+
+The default template's behaviour is to publish a module when a commit is `git
+tag`-ed with a name which corresponds to a [semver
+version](https://semver.org/).
+
+## Using the CI template
+
+A minimal example of making use of the template is as follows. It should be
+added to the `.gitlab-ci.yml` file in the terraform module project.
+
+```yaml
+include:
+  - project: 'uis/devops/continuous-delivery/ci-templates'
+    file: '/terraform-module-publish.yml'
+
+stages:
+  - publish
+
+publish:
+  extends: .terraform_module_publish
+  stage: publish
+  variables:
+    TERRAFORM_MODULE_SYSTEM: google  # or local, aws, etc...
+```
+
+The `TERRAFORM_MODULE_SYSTEM` variable should be set in a manner which reflects
+the main system or provider used by the module. For most of our Google Cloud
+Platform modules this should be "google".
+
+## Releasing a new module version
+
+To release a new module version, tag the latest release with a bare version
+number. E.g. to tag current master/main:
+
+```console
+$ git checkout main       # or 'master' for older projects
+$ git pull                # ensure we're up to date
+$ git tag 2.0.1           # tag release
+$ git push origin --tags  # push tags to GitLab
+```
+
+## Changelogs
+
+You should maintain a `CHANGELOG` file in the project root which records what
+changed in each release. See the existing terraform modules for examples.
diff --git a/mkdocs.yml b/mkdocs.yml
index bc71eaa89c258b58c6f6cb14fa3217794fca37e5..05ec3650c52ef672df833f9741a24c9729897eba 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -27,6 +27,7 @@ nav:
     - workflow/pipelines.md
     - workflow/onboarding.md
     - workflow/pypi.md
+    - workflow/terraform-modules.md
     - workflow/credentials-and-secrets.md
   - 'Best Practice':
     - best-practice/index.md