/deployment-python

Deployment scripts for Python, Docker, AWS, Kubernetes

Primary LanguageShell

Deployment for Python

Opinionated shell scripts for deploying Python.

A lot is based on the repository name and therefore the SLUG environment variable. In the examples, you should assume that we have a repository named foobar-service and we didn't set SLUG by hand.

Btw, use the excellent ShellCheck to lint your scripts!

Build with

Here's the explanation in order of recommended execution:

slug.sh

A lot of things are derived from the repository's name, i.e. you either set the SLUG environment variable manually or you replace <REPLACE_WITH_REPOSITORY_NAME_ENV_VAR> with something provided by your CI/CD like GITHUB_REPOSITORY_NAME, BITBUCKET_REPO_SLUG, ...

Example: BITBUCKET_REPO_SLUG=foobar-service will result in SLUG=foobar

master.sh

Sets up all the environment variables for a specific branch/environment, i.e. rename this file to production.sh or duplicate it for whatever environment you build for. It requires some replacements:

  • <REPLACE_WITH_AWS_ACCOUNT_ID>, e.g. 123456789012 or environment variable

  • <REPLACE_WIHT_AWS_REGION>, e.g. us-east-1 or environment variable

  • <REPLACE_WITH_API_URL_NAME>, e.g. api.foobar.com or environment variable

Then we have the CONTEXT for our API which I like to base on the SLUG, e.g. api.company.com/foobar but you can also set it manually.

build.sh

Triggers make, see Makefile, if you don't want to use pip-tools, change it.

lint.sh

Triggers make lint, see Makefile for an example. If you don't use ruff, change it.

docker.sh

Here we build the docker image and push it to the ECR repository. Have a look at the inlined Dockerfile, and change the CMD if you need something different from FastAPI.

It also requires some environment_variables to be set:

  • SLUG, set by slug.sh or manually, e.g. in master.sh

  • <REPLACE_WITH_BRANCH_NAME_ENV_VAR>, e.g. GITHUB_REF##*/, BITBUCKET_BRANCH, ...

  • <REPLACE_WITH_COMMIT_HASH_ENV_VAR>, e.g. GITHUB_SHA, BITBUCKET_COMMIT, ...

  • AWS_ECR_URL

  • AWS_REGION

  • AWS_ACCESS_KEY_ID

  • AWS_SECRET_ACCESS_KEY

A multi-staged build follows that can use a specific CONTEXT (set in master.sh) environment variable for the server.

The images pushed assume an existing repository with SLUG as it's name, e.g. foobar.

It will push the image with the tags latest and branch name with shortened commit hash, e.g. master-1234567.

k8s.sh

So one assumption here is that STAGE is basically also your k8s namespace, e.g. (STAGE=PRODUCTION) == (NAMESPACE=production).

Yet another assumption is that you've created a secret in the secrets-manager with name $SLUG-secrets, e.g. foobar-secrets.

I use envsubst to replace variables in the *.yml files with environment variables.

Have a look at the YAML files yourself, they provide a basic skeleton.