From 146c14ac36670b6cb6dcaf78052f230fbd1825d1 Mon Sep 17 00:00:00 2001 From: wesbragagt Date: Thu, 9 Oct 2025 21:50:23 -0500 Subject: [PATCH] feat(kube_pg_cluster): support custom_image --- .../infrastructure/kube_pg_cluster/README.md | 98 +++++++++++++++++++ .../infrastructure/kube_pg_cluster/main.tf | 2 +- .../infrastructure/kube_pg_cluster/vars.tf | 21 ++++ 3 files changed, 120 insertions(+), 1 deletion(-) diff --git a/packages/infrastructure/kube_pg_cluster/README.md b/packages/infrastructure/kube_pg_cluster/README.md index dcca8866e..adbd92612 100644 --- a/packages/infrastructure/kube_pg_cluster/README.md +++ b/packages/infrastructure/kube_pg_cluster/README.md @@ -16,6 +16,104 @@ The default value for `pg_version` is the one that we test in our clusters, so w automatically when `pg_version` is changed. +### Custom PostgreSQL Images with Extensions + +If you need PostgreSQL extensions (like pgvector, PostGIS, timescaledb, etc.), you can use a custom +PostgreSQL container image instead of the default CNPG image. + +#### Using Pre-built CNPG Images + +CloudNativePG provides pre-built images with popular extensions: + +```hcl +module "database" { + source = "${var.pf_module_source}kube_pg_cluster${var.pf_module_ref}" + + pg_custom_image = "ghcr.io/cloudnative-pg/postgis:17" + # pg_version is ignored when pg_custom_image is set + + ... +} +``` + +#### Building Your Own Custom Image + +For custom extension combinations, build your own image using Docker Bake: + +1. **Create a `bake.hcl` file:** + +```hcl +extensions = [ + "pgvector", + "pg-stat-kcache", +] + +target "myimage" { + dockerfile-inline = < + For detailed instructions on building custom images, see the + [CNPG blog post on Docker Bake](https://cloudnative-pg.io/blog/building-images-bake/). + + + + Custom images bypass the ECR pull through cache. Ensure: + - Your image is accessible from your Kubernetes cluster + - Proper image pull secrets are configured if using private registries + - The image is compatible with CloudNativePG (includes required PostgreSQL executables) + + +#### Available Extensions + +Common Debian package extensions you can install: +- `postgresql-NN-pgvector` - Vector similarity search +- `postgresql-NN-postgis-3` - Geographic objects support +- `postgresql-NN-cron` - Job scheduler +- `postgresql-NN-partman` - Partition management +- `postgresql-NN-pg-stat-kcache` - Kernel statistics +- And many more from [apt.postgresql.org](https://apt.postgresql.org/) + +Replace `NN` with your PostgreSQL major version (e.g., `16`, `17`). + ### Credentials For in-cluster applications, credentials can be sourced from the following Kubernetes Secrets named in the module's outputs: diff --git a/packages/infrastructure/kube_pg_cluster/main.tf b/packages/infrastructure/kube_pg_cluster/main.tf index 54601aeec..2ab420d70 100644 --- a/packages/infrastructure/kube_pg_cluster/main.tf +++ b/packages/infrastructure/kube_pg_cluster/main.tf @@ -280,7 +280,7 @@ resource "kubernetes_manifest" "postgres_cluster" { } } spec = { for k, v in { - imageName = "${module.pull_through.github_registry}/cloudnative-pg/postgresql:${var.pg_version}" + imageName = var.pg_custom_image != null ? var.pg_custom_image : "${module.pull_through.github_registry}/cloudnative-pg/postgresql:${var.pg_version}" instances = var.pg_instances minSyncReplicas = var.pg_sync_replication_enabled ? var.pg_instances - 1 : 0 primaryUpdateStrategy = "unsupervised" diff --git a/packages/infrastructure/kube_pg_cluster/vars.tf b/packages/infrastructure/kube_pg_cluster/vars.tf index c196ba872..4e356cce5 100644 --- a/packages/infrastructure/kube_pg_cluster/vars.tf +++ b/packages/infrastructure/kube_pg_cluster/vars.tf @@ -14,6 +14,27 @@ variable "pg_version" { default = "16.6-13" } +variable "pg_custom_image" { + description = <<-EOT + Custom PostgreSQL container image to use instead of the default CloudNativePG image. + + This allows you to use: + - Pre-built CNPG images with extensions (e.g., 'ghcr.io/cloudnative-pg/postgis:17') + - Custom-built images with your own extensions (e.g., 'myregistry.io/postgres:16.9-custom') + + When set, this overrides the 'pg_version' variable for image selection. + The image must be compatible with CloudNativePG requirements. + + Note: Custom images bypass the ECR pull through cache. Ensure your cluster + has appropriate image pull secrets and registry access configured. + + Example building custom image with pgvector: + See https://cloudnative-pg.io/blog/building-images-bake/ + EOT + type = string + default = null +} + variable "pg_instances" { description = "The number of instances to deploy in the postgres cluster" type = number