Skip to content

Commit cf233de

Browse files
committed
Initial commit
0 parents  commit cf233de

File tree

19 files changed

+1172
-0
lines changed

19 files changed

+1172
-0
lines changed

.circleci/config.yml

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
version: 2
2+
jobs:
3+
publish-image:
4+
machine: true
5+
steps:
6+
- checkout
7+
- run: |
8+
echo $JSON_KEYFILE | docker login -u _json_key --password-stdin https://gcr.io
9+
./build.sh
10+
send_notification:
11+
machine: true
12+
steps:
13+
- checkout
14+
- run: |
15+
CONTAINER_NAME=gcr.io/$GCLOUD_PROJECT/kubernetes-deploy:$(utils/get_build_tag.sh)
16+
curl -X POST --data-urlencode \
17+
"payload={\"channel\": \"#container-builds\", \"username\": \"Bob the Builder\", \"text\": \"Built and published kubernetes-deploy: $CONTAINER_NAME\", \"icon_emoji\": \":construction_worker:\"}" \
18+
$SLACK_HOOK_URL;
19+
20+
workflows:
21+
version: 2
22+
build:
23+
jobs:
24+
- publish-image:
25+
context: org-global
26+
filters:
27+
branches:
28+
only: master
29+
- send_notification:
30+
context: org-global
31+
requires:
32+
- publish-image

.flake8

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[flake8]
2+
max-line-length = 140

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
*.pyc
2+
env
3+
venv
4+
.env
5+
.venv
6+
.vscode

Dockerfile

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
FROM python:3.7-stretch
2+
3+
WORKDIR /run/app
4+
5+
RUN echo "deb [signed-by=/usr/share/keyrings/cloud.google.gpg] http://packages.cloud.google.com/apt cloud-sdk main" | tee -a /etc/apt/sources.list.d/google-cloud-sdk.list && curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key --keyring /usr/share/keyrings/cloud.google.gpg add - && apt-get update -y && apt-get install google-cloud-sdk -y
6+
7+
COPY requirements.txt ./
8+
9+
RUN pip install -r requirements.txt
10+
11+
COPY . .
12+
COPY ./run.sh /usr/local/bin
13+
14+
ENTRYPOINT ["run.sh"]

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2020 Adgorithmics Inc
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# kubernetes-deploy
2+
3+
A script to deploy projects to kubernetes. Designed to run as a kubernetes job.
4+
5+
## Setup
6+
1. Give all of your deployements the same PROJECT label as well as a fitting TIER label. Every deployment (and cronjob) with the PROJECT label will be updated in the deployment. The TIER label will determine the order in which to scale down, update, scale up deployments in the case of a cold database migration. Deployments can use different images, but they must all use the same TAG. See `Features` and `Optional` env variables below for more details.
7+
8+
## Features
9+
- Migration Job - If you would like to trigger database migrations, setup a command with on one of your deployment images that can be used to run the database migration process. Provide this deployment name as APP_MIGRATOR_SOURCE env variable as well as pass the command and args via APP_MIGRATOR_COMMAND and APP_MIGRATOR_ARGS env variables. You will also need to define the DATABASE_* env variables to perform the necessary backup to Google Storage. If the `migration` option is set to `1` (hot migration - no scale down), or `2` (cold migration - scale down and up deployments) then the deployment script will first backup the database, scale down deployments (if cold migration), fetch the APP_MIGRATOR_SOURCE deployment and update the image tag, command and args, run the migration, update all other deployment images, scale back up deployments (if cold migration).
10+
- Trello list cleanup - If you pass the necessary trello and mailgun env variables (with TRELLO_SEND_NOTIFICATION flag is True) the deployment script will collect all cards in the trello list, send out a notification email with their details, and archive the cards.
11+
- Cronjob support - If you give cronjobs the same PROJECT label, they will also be updated in the final stage of the deployment.
12+
13+
## Environment Variables
14+
15+
### Required
16+
17+
- SLACK_TOKEN - For slack notifications
18+
- PROJECT - Matches the `project` label on the deployments
19+
20+
### Required if performing migrations (`migration` option set above 0)
21+
- DATABASE_INSTANCE_NAME - Cloud SQL instance name
22+
- DATABASE_NAME - Cloud SQL database name
23+
- DATABASE_BACKUP_BUCKET - GS URI (gs://bucket/directory/etc) database backup location (will append `/PROJECT`)
24+
- APP_MIGRATOR_SOURCE - The name of the deployment to use as the base configuration for migration jobs
25+
26+
### Required if TRELLO_SEND_NOTIFICATION flag is True
27+
28+
- TRELLO_KEY - Trello api key
29+
- TRELLO_TOKEN - Trello api token
30+
- TRELLO_LIST_ID - Target trello list for release notification generation
31+
- MAILGUN_DOMAIN - Mailgun domain
32+
- MAILGUN_KEY - Mailgun api key
33+
- MAILGUN_TO - Recipients for release notification email
34+
35+
### Optional (with defaults for development cinnamon deployment)
36+
37+
- GOOGLE_APPLICATION_CREDENTIALS - Path to gcloud authentication json key file. Not needed if you have local gcloud auth initialized
38+
- DEBUG [`False`] - Will authorize kubeApi with local gcloud when `True`
39+
- DISABLED [`False`] - Exits process without deploying when `True`
40+
- APP_ENV [`development`] - App environment (production, development) to construct slack notification
41+
- HOSTNAME [`localhost`] - Host running this process (provided by Kubernetes)
42+
- NAMESPACE [`default`] - Pod namespace
43+
- SLACK_CHANNEL [`dev-null`] - Target channel for slack notifications
44+
- TIERS [`frontend,scheduler,worker,gateway,apiserver`] - Comma separated list of deployments (in scale down order)
45+
- TRELLO_SEND_NOTIFICATION [`False`] - Cleanup trello list and send release notification via email
46+
- APP_MIGRATOR_COMMAND = [`npm`] - A comma separated list of commands to on the migration job container
47+
- APP_MIGRATOR_ARGS = [`run,--prefix,/app,migration:run`] - A comma separated list of args to set on the migration job container
48+
49+
## Required Arguments
50+
51+
- -t, --tag - The new monolith image tag to roll out (`dev-20.02.18-36b17ee`)
52+
- -m, --migration - The migration level: 0=None, 1=Hot, 2=Cold
53+
54+
## Running Locally
55+
56+
Just add all of the necessary env variables and run `deploy.py` and pass the tag and migration options.
57+
58+
- `pip install -r requirements.txt`
59+
- `SLACK_TOKEN=<token> PROJECT=<your project> DEBUG=True python deploy.py --tag=<image tag> --migration=<migration level (0, 1, 2)>`

build.sh

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#!/bin/bash
2+
set -e
3+
4+
# Takes image build tag from script argument or generates from date and short sha
5+
TAG_ARG=$1
6+
BUILD_TAG=${TAG_ARG:-$(utils/get_build_tag.sh)}
7+
BASE_IMAGE=gcr.io/$GCLOUD_PROJECT/kubernetes-deploy
8+
9+
if [ "${BOOTLEG}" = 'true' ]; then
10+
random=$(
11+
head /dev/urandom | tr -dc A-Za-z0-9 | head -c 13
12+
echo ''
13+
)
14+
prefix="bootleg-$random-"
15+
TAG=$BASE_IMAGE:$prefix$BUILD_TAG
16+
docker build . --tag=$TAG
17+
docker push "$TAG"
18+
echo "BOOTLEG IMAGE PUSHED: $TAG"
19+
else
20+
LATEST_TAG=$BASE_IMAGE:latest
21+
TAG=$BASE_IMAGE:$BUILD_TAG
22+
docker build . --tag=$TAG --tag=$LATEST_TAG
23+
docker push "$TAG"
24+
docker push $LATEST_TAG
25+
echo "IMAGE PUSHED: $TAG"
26+
fi

config.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import os
2+
3+
# -------- ENV --------
4+
# Debug will authorize kube api with local gcloud auth when True
5+
DEBUG = os.getenv("DEBUG", False) in ["true", "True"]
6+
DISABLED = os.getenv("DISABLED", False) in ["true", "True"]
7+
# Determines the slack notification info
8+
APP_ENV = os.getenv("APP_ENV", "development")
9+
10+
# -------- Project, Pod, Cluster --------
11+
PROJECT = os.getenv("PROJECT")
12+
HOST_NAME = os.getenv("HOSTNAME", "localhost")
13+
NAMESPACE = os.getenv("NAMESPACE", "default")
14+
15+
# -------- Slack --------
16+
SLACK_TOKEN = os.getenv("SLACK_TOKEN")
17+
SLACK_CHANNEL = os.getenv("SLACK_CHANNEL", "dev-null")
18+
19+
# -------- Trello --------
20+
TRELLO_KEY = os.getenv("TRELLO_KEY")
21+
TRELLO_TOKEN = os.getenv("TRELLO_TOKEN")
22+
TRELLO_LIST_ID = os.getenv("TRELLO_LIST_ID")
23+
TRELLO_SEND_NOTIFICATION = os.getenv("TRELLO_SEND_NOTIFICATION", False) in [
24+
"true",
25+
"True",
26+
]
27+
28+
# -------- Mailgun --------
29+
MAILGUN_DOMAIN = os.getenv("MAILGUN_DOMAIN")
30+
MAILGUN_KEY = os.getenv("MAILGUN_KEY")
31+
MAILGUN_TO = os.getenv("MAILGUN_TO")
32+
33+
# -------- Database backup --------
34+
DATABASE_INSTANCE_NAME = os.getenv("DATABASE_INSTANCE_NAME")
35+
DATABASE_NAME = os.getenv("DATABASE_NAME")
36+
DATABASE_BACKUP_BUCKET = f"{os.getenv('DATABASE_BACKUP_BUCKET')}/{DATABASE_NAME}"
37+
38+
# -------- Migrate job --------
39+
APP_MIGRATOR_SOURCE = os.getenv("APP_MIGRATOR_SOURCE")
40+
# comma separated list
41+
APP_MIGRATOR_COMMAND = os.getenv("APP_MIGRATOR_COMMAND", "npm").split(",")
42+
# comma separated list
43+
APP_MIGRATOR_ARGS = os.getenv(
44+
"APP_MIGRATOR_ARGS", "run,--prefix,/app,migration:run"
45+
).split(",")
46+
47+
# -------- Deployment Tiers --------
48+
# comma separated listed in scale down order
49+
TIERS = os.getenv("TIERS", "frontend,scheduler,worker,gateway,apiserver").split(",")
50+
# frontend - public facing frontend
51+
# scheduler - service scheduler
52+
# worker - service queue workers
53+
# gateway - public facing api gateway
54+
# apiserver - service apiserver / internal gateway

0 commit comments

Comments
 (0)