Skip to main content

Helper for Alembic migrations within Kubernetes.

Project description

Chartreuse: Automated Alembic SQL schema migrations within kubernetes

"How to automate management of Alembic database schema migration at scale using CI/CD and Kubernetes"

Chartreuse is a wrapper around Alembic to ease, detect and automate migrations on deployed Python applications.

Chartreuse leverages Helm Hooks, the Hooks are defined in Chartreuse Helm Chart.

Usage

Requirements

  • Python >= 3.13
  • Using Helm to deploy you application
  • This Python package requires the expecteddeploymentscales.wiremind.io Kubernetes Custom Resource Definition:
helm repo add wiremind https://wiremind.github.io/wiremind-helm-charts
helm install wiremind-crds wiremind/wiremind-crds --version 0.1.0
  • Please make sure Chartreuse Python Package version and Chartreuse Helm Chart version, you use, share major.minor otherwise Chartreuse won't start.

Configuration

Using Helm

Chartreuse comes with a Helm Chart ready to be used as a Helm Subchart in your own Helm Chart.

All you have to do is build your own container image containing:

  • Chartreuse Python package
  • Your Alembic migrations in an alembic directory
  • All required dependencies to run your alembic migrations.

Usually, it will be the same container image for your project with your code as usual, with Chartreuse added as dependency in your setup.py.

and state in the Chartreuse Helm Chart values.yaml:

  • the image repository and tag
  • URL to connect to your PostgreSQL

During install and/or upgrade of your Helm Release, Chartreuse will run as Kubernetes Job and automatically migrate PostgreSQL shchema to HEAD if needed.

If required, it will also scale down Deployments that should NOT run during a Deployment using ExpectedDeploymentScale CRD.

Please refer to the example directory for example.

Diagram

The state diagram of your application while upgrading using Helm and using Chartreuse for your migrations is as follows:

alt text

Notes

  1. PG clusters managed by postgres-operator (Patroni PG):
    • When Chartreuse starts running against a PG cluster managed by postgres-operator (Patroni PG), it may run the migrations before that the cluster is configured, and by configured we mean:
      • the Roles, especially wiremind_owner_user and wiremind_owner used by Chartreuse and Alembic, are created.
      • The default privileges are set, so the other Roles, like wiremind_writer_user used by the application, can interact with the created objects. To ensure that, Chartreuse will not start until postgres-operator has performed the above two actions. To make Chartreuse wait, the environment variable CHARTREUSE_PATRONI_POSTGRESQL should be set:
      # in the appropriate Helm values file
      chartreuse-for-a-patroni-pg:
        additionalEnvironmentVariables:
          CHARTREUSE_PATRONI_POSTGRESQL: "anything"
          CHARTREUSE_ALEMBIC_POSTGRES_WAIT_CONFIGURED_TIMEOUT: 100 # It's set to 60s by default
      
    • The default privileges above-mentioned are set for the NOLOGIN owner wiremind_owner, e.g. tables should be created by wiremind_owner so wiremind_writer[_user] can insert to them. This is why we need to SET ROLE wiremind_owner in the beginning of the transaction before running the migrations, Chartreuse does set -x patroni_postgresql=yes to alembic upgrade head when the environment variable PATRONI_POSTGRESQL is set, you can then retrieve the argument and set the role in your env.py:
      ...
      patroni_postgresql: bool = "patroni_postgresql" in context.get_x_argument(as_dictionary=True)
        ...
        with connectable.connect() as connection:
          ...
          with context.begin_transaction():
            if patroni_postgresql:
              context.execute(text("SET ROLE wiremind_owner"))
            context.run_migrations()
       ...
      
  2. Chartreuse in pre-upgrade mode:
    • When running Chartreuse in pre-upgrade mode (upgradeBeforeDeployment: true), it will not start running (The Chartreuse Pod will hang in Init state) until one PG Pod (and ES Pod if ES is used) is running, so make sure these Pods are available to Chartreuse. To fix that:
      • You will need to delete the Chartreuse Job so the upgrade can resume and fix you PG and ES pods (or create them if they don't exist), then you can redeploy so your migrations can run.
      • You can also try the upgradeBeforeDeployment: false mode (maybe temporarily).

Development

Test

There are three kind of tests:

  • Unit tests
  • Integration tests: allows to run in a real environment, but still control chartreuse from the inside
  • blackbox test: deploy a real Helm Release and test if databases are migrated.

Documentation

  • The diagram has been drawn using the free online software https://draw.io, the source code is located at doc/chartreuse_sd.xml, feel free to correct it or make it more understandable.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

chartreuse-6.2.1.tar.gz (14.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

chartreuse-6.2.1-py3-none-any.whl (13.1 kB view details)

Uploaded Python 3

File details

Details for the file chartreuse-6.2.1.tar.gz.

File metadata

  • Download URL: chartreuse-6.2.1.tar.gz
  • Upload date:
  • Size: 14.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.25

File hashes

Hashes for chartreuse-6.2.1.tar.gz
Algorithm Hash digest
SHA256 da686c5971a914a5a4913d847f26b798ecb4388c29f14dd55a9279d657270c5d
MD5 5addeff4c0b40b09aa0ca22b5ce424e6
BLAKE2b-256 43c113ca8257fcf8f75a03a71564b45ff8b1663090e882737284b43a871244c8

See more details on using hashes here.

File details

Details for the file chartreuse-6.2.1-py3-none-any.whl.

File metadata

  • Download URL: chartreuse-6.2.1-py3-none-any.whl
  • Upload date:
  • Size: 13.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.25

File hashes

Hashes for chartreuse-6.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 9a26a1ef37202465556726a5606e546537af45373042498dac26f73c300545d2
MD5 7eee8cc8d0256fd90b2d7188ee2ef1bc
BLAKE2b-256 2f76b0039bb3db6e7d68b402078854ba866777953589b065de3054771d44e2ba

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page