Chartreuse: Automated Alembic migrations within kubernetes

Overview

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.7
  • Using Helm to deploy you application
  • This Python package requires the expecteddeploymentscales.wiremind.io Kubernetes Custom Resource Definition from wiremind-kubernetes repository:
kubectl apply -f https://raw.githubusercontent.com/wiremind/wiremind-kubernetes/main/CustomResourceDefinition-expecteddeploymentscales.yaml
  • 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("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.
Comments
  • chore(deps): bump oauthlib from 3.1.1 to 3.2.1

    chore(deps): bump oauthlib from 3.1.1 to 3.2.1

    Bumps oauthlib from 3.1.1 to 3.2.1.

    Release notes

    Sourced from oauthlib's releases.

    3.2.1

    In short

    OAuth2.0 Provider:

    • #803 : Metadata endpoint support of non-HTTPS
    • CVE-2022-36087

    OAuth1.0:

    • #818 : Allow IPv6 being parsed by signature

    General:

    • Improved and fixed documentation warnings.
    • Cosmetic changes based on isort

    What's Changed

    New Contributors

    Full Changelog: https://github.com/oauthlib/oauthlib/compare/v3.2.0...v3.2.1

    3.2.0

    Changelog

    OAuth2.0 Client:

    • #795: Add Device Authorization Flow for Web Application
    • #786: Add PKCE support for Client
    • #783: Fallback to none in case of wrong expires_at format.

    OAuth2.0 Provider:

    • #790: Add support for CORS to metadata endpoint.
    • #791: Add support for CORS to token endpoint.
    • #787: Remove comma after Bearer in WWW-Authenticate

    OAuth2.0 Provider - OIDC:

    • #755: Call save_token in Hybrid code flow
    • #751: OIDC add support of refreshing ID Tokens with refresh_id_token
    • #751: The RefreshTokenGrant modifiers now take the same arguments as the AuthorizationCodeGrant modifiers (token, token_handler, request).

    ... (truncated)

    Changelog

    Sourced from oauthlib's changelog.

    3.2.1 (2022-09-09)

    OAuth2.0 Provider:

    • #803: Metadata endpoint support of non-HTTPS
    • CVE-2022-36087

    OAuth1.0:

    • #818: Allow IPv6 being parsed by signature

    General:

    • Improved and fixed documentation warnings.
    • Cosmetic changes based on isort

    3.2.0 (2022-01-29)

    OAuth2.0 Client:

    • #795: Add Device Authorization Flow for Web Application
    • #786: Add PKCE support for Client
    • #783: Fallback to none in case of wrong expires_at format.

    OAuth2.0 Provider:

    • #790: Add support for CORS to metadata endpoint.
    • #791: Add support for CORS to token endpoint.
    • #787: Remove comma after Bearer in WWW-Authenticate

    OAuth2.0 Provider - OIDC:

    • #755: Call save_token in Hybrid code flow
    • #751: OIDC add support of refreshing ID Tokens with refresh_id_token
    • #751: The RefreshTokenGrant modifiers now take the same arguments as the AuthorizationCodeGrant modifiers (token, token_handler, request).

    General:

    • Added Python 3.9, 3.10, 3.11
    • Improve Travis & Coverage
    Commits
    • 88bb156 Updated date and authors
    • 1a45d97 Prepare 3.2.1 release
    • 0adbbe1 docs: fix typos
    • 6569ec3 docs: Fix a few typos
    • bdc486e Fixed isort imports
    • 7db45bd Fix typo in server.rst
    • b14ad85 chore: s/bode_code_verifier/body_code_verifier/g
    • b123283 Allow non-HTTPS issuer when OAUTHLIB_INSECURE_TRANSPORT. (#803)
    • 2f887b5 Docs: fix Sphinx warnings for better ReadTheDocs generation (#807)
    • d4bafd9 Merge pull request #797 from cclauss/patch-2
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 1
  • chore(deps): bump mako from 1.1.5 to 1.2.2

    chore(deps): bump mako from 1.1.5 to 1.2.2

    Bumps mako from 1.1.5 to 1.2.2.

    Release notes

    Sourced from mako's releases.

    1.2.2

    Released: Mon Aug 29 2022

    bug

    • [bug] [lexer] Fixed issue in lexer where the regexp used to match tags would not correctly interpret quoted sections individually. While this parsing issue still produced the same expected tag structure later on, the mis-handling of quoted sections was also subject to a regexp crash if a tag had a large number of quotes within its quoted sections.

      References: #366

    1.2.1

    Released: Thu Jun 30 2022

    bug

    • [bug] [tests] Various fixes to the test suite in the area of exception message rendering to accommodate for variability in Python versions as well as Pygments.

      References: #360

    misc

    • [performance] Optimized some codepaths within the lexer/Python code generation process, improving performance for generation of templates prior to their being cached. Pull request courtesy Takuto Ikuta.

      References: #361

    1.2.0

    Released: Thu Mar 10 2022

    changed

    • [changed] [py3k] Corrected "universal wheel" directive in setup.cfg so that building a wheel does not target Python 2.

      References: #351

    • [changed] [py3k] The bytestring_passthrough template argument is removed, as this flag only applied to Python 2.

    ... (truncated)

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 1
  • chore(deps): bump certifi from 2022.9.24 to 2022.12.7

    chore(deps): bump certifi from 2022.9.24 to 2022.12.7

    Bumps certifi from 2022.9.24 to 2022.12.7.

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
  • Resources without -ephemeral are created even when we don't need them.

    Resources without -ephemeral are created even when we don't need them.

    confimap.yaml (which is always created) is only needed to be created when "Upgrade BEFORE deployment" mode INITIAL deployment of version N but not when "Upgrade BEFORE deployment" mode UPGRADE existing deployment N-1 to version N, in this case we can rely on hooks and confimap-ephemeral.yaml is used.

    those resources will continue to live in the namespace. (the goal of ephemeral resources was to avoid keeping a Role/RoleBinding in the cluster).

    opened by desaintmartin 0
  • Possible mess when upgradeBeforeDeployment: true on an install with multiple chartreuses

    Possible mess when upgradeBeforeDeployment: true on an install with multiple chartreuses

    during the upgrade we do control the order (helm hooks order)

    2 chartreuses = 2 jobs on install (first time), the first one (may be the least important one, may finish first and start-pods while the import chartreuse is still running) => error logs

    maybe upgradeBeforeDeployment: true on install should run as upgradeBeforeDeployment: false

    opened by desaintmartin 0
Releases(v4.3.1)
  • v4.3.1(Nov 22, 2022)

    What's Changed

    • fix(setup): do not pin major versions of alembic/psycopg2 dependencies. by @desaintmartin in https://github.com/wiremind/chartreuse/pull/19

    Full Changelog: https://github.com/wiremind/chartreuse/compare/v4.3.0...v4.3.1

    Source code(tar.gz)
    Source code(zip)
  • v4.3.0(Oct 6, 2022)

    What's Changed

    • Support Kube HPAScaleToZero feature gate, see here for more details.

    Full Changelog: https://github.com/wiremind/chartreuse/compare/v4.2.0...v4.3.0

    Source code(tar.gz)
    Source code(zip)
  • v4.2.0(Aug 2, 2022)

    What's Changed

    • added an environment variable CHARTREUSE_ALEMBIC_CONFIG_FILE_PATH to set a custom alembic configuration path

    Full Changelog: https://github.com/wiremind/chartreuse/compare/v4.1.0...v4.2.0

    Source code(tar.gz)
    Source code(zip)
  • v4.1.0(Aug 1, 2022)

    What's Changed

    • correctly added mypy support for src/ and example/alembic
    • added an environment variable CHARTREUSE_ALEMBIC_DIRECTORY_PATH to set a custom alembic folder
    • setup.py: added long_description and platforms

    Full Changelog: https://github.com/wiremind/chartreuse/compare/v4.0.5...v4.1.0

    Source code(tar.gz)
    Source code(zip)
  • v4.0.5(Nov 24, 2021)

    What's Changed

    • Revert "fix(setup): setup.py: require psycopg2-binary instead of psycopg2" by @desaintmartin in https://github.com/wiremind/chartreuse/pull/10

    Full Changelog: https://github.com/wiremind/chartreuse/compare/v4.0.4...v4.0.5

    Source code(tar.gz)
    Source code(zip)
  • v4.0.4(Nov 18, 2021)

    What's Changed

    • fix(setup): setup.py: require psycopg2-binary instead of psycopg2. by @desaintmartin in https://github.com/wiremind/chartreuse/pull/9

    Full Changelog: https://github.com/wiremind/chartreuse/compare/v4.0.3...v4.0.4

    Source code(tar.gz)
    Source code(zip)
  • v4.0.3(Oct 9, 2021)

    What's Changed

    • ci: add 3.10 support by @desaintmartin in https://github.com/wiremind/chartreuse/pull/8

    Full Changelog: https://github.com/wiremind/chartreuse/compare/v4.0.2...v4.0.3

    Source code(tar.gz)
    Source code(zip)
  • v4.0.2(Oct 9, 2021)

    What's Changed

    • fix: upgrade wiremind-kubernetes to ignore failed (like Evicted) Pods when stop-pods by @desaintmartin in https://github.com/wiremind/chartreuse/pull/7

    Full Changelog: https://github.com/wiremind/chartreuse/compare/v4.0.1...v4.0.2

    Source code(tar.gz)
    Source code(zip)
  • v4.0.1(Oct 4, 2021)

  • v4.0.0(Oct 4, 2021)

    4.0.0 (2021-10-01)

    Breaking Changes

    • Drop eslembic support
    • drop wiremind.fr CRD

    Fix

    • Avoid logging the PG password when seding alembic.ini.

    Chore

    • Open source
    Source code(tar.gz)
    Source code(zip)
Owner
Wiremind
Wiremind
🎡 Build Python wheels for all the platforms on CI with minimal configuration.

cibuildwheel Documentation Python wheels are great. Building them across Mac, Linux, Windows, on multiple versions of Python, is not. cibuildwheel is

Python Packaging Authority 1.3k Jan 02, 2023
CTF infrastructure deployment automation tool.

CTF infrastructure deployment automation tool. Focus on the challenges. Mirrored from

Fake News 1 Apr 12, 2022
A basic instruction for Kubernetes setup and understanding.

A basic instruction for Kubernetes setup and understanding Module ID Module Guide - Install Kubernetes Cluster k8s-install 3 Docker Core Technology mo

648 Jan 02, 2023
Nagios status monitor for your desktop.

Nagstamon Nagstamon is a status monitor for the desktop. It connects to multiple Nagios, Icinga, Opsview, Centreon, Op5 Monitor/Ninja, Checkmk Multisi

Henri Wahl 361 Jan 05, 2023
Tools for writing awesome Fabric files

About fabtools includes useful functions to help you write your Fabric files. fabtools makes it easier to manage system users, packages, databases, et

1.3k Dec 30, 2022
Rundeck / Grafana / Prometheus / Rundeck Exporter integration demo

Rundeck / Prometheus / Grafana integration demo via Rundeck Exporter This is a demo environment that shows how to monitor a Rundeck instance using Run

Reiner 4 Oct 14, 2022
CI repo for building Skia as a shared library

Automated Skia builds This repo is dedicated to building Skia binaries for use in Skija. Prebuilt binaries Prebuilt binaries can be found in releases.

Humble UI 20 Jan 06, 2023
Python job scheduling for humans.

schedule Python job scheduling for humans. Run Python functions (or any other callable) periodically using a friendly syntax. A simple to use API for

Dan Bader 10.4k Jan 02, 2023
Copy a Kubernetes pod and run commands in its environment

copypod Utility for copying a running Kubernetes pod so you can run commands in a copy of its environment, without worrying about it the pod potential

Memrise 4 Apr 08, 2022
Glances an Eye on your system. A top/htop alternative for GNU/Linux, BSD, Mac OS and Windows operating systems.

Glances - An eye on your system Summary Glances is a cross-platform monitoring tool which aims to present a large amount of monitoring information thr

Nicolas Hennion 22k Jan 08, 2023
GitGoat enables DevOps and Engineering teams to test security products intending to integrate with GitHub

GitGoat is an open source tool that was built to enable DevOps and Engineering teams to design and implement a sustainable misconfiguration prevention strategy. It can be used to test with products w

Arnica 149 Dec 22, 2022
Project 4 Cloud DevOps Nanodegree

Project Overview In this project, you will apply the skills you have acquired in this course to operationalize a Machine Learning Microservice API. Yo

1 Nov 21, 2021
Official Python client library for kubernetes

Kubernetes Python Client Python client for the kubernetes API. Installation From source: git clone --recursive https://github.com/kubernetes-client/py

Kubernetes Clients 5.4k Jan 02, 2023
Automatically capture your Ookla Speedtest metrics and display them in a Grafana dashboard

Speedtest All-In-One Automatically capture your Ookla Speedtest metrics and display them in a Grafana dashboard. Getting Started About This Code This

Aaron Melton 2 Feb 22, 2022
Bugbane - Application security tools for CI/CD pipeline

BugBane Набор утилит для аудита безопасности приложений. Основные принципы и осо

GardaTech 20 Dec 09, 2022
A collection of beginner-friendly DevOps content

mansion Mansion is just a testing repo for learners to commit into open source project. These are the steps you need to learn: Please do not edit thes

Bryan Lim 62 Nov 30, 2022
The leading native Python SSHv2 protocol library.

Paramiko Paramiko: Python SSH module Copyright: Copyright (c) 2009 Robey Pointer 8.1k Jan 04, 2023

Tencent Yun tools with python

Tencent_Yun_tools 使用 python3.9 + 腾讯云 AccessKey 利用工具 使用之前请先填写config.ini配置文件 Usage python3 Tencent_rce.py -h Scanner python3 Tencent_rce.py -s 生成CSV

<img src="> 13 Dec 20, 2022
Run Oracle on Kubernetes with El Carro

El Carro is a new project that offers a way to run Oracle databases in Kubernetes as a portable, open source, community driven, no vendor lock-in container orchestration system. El Carro provides a p

Google Cloud Platform 205 Dec 30, 2022