Skip to content

Commit d62de3e

Browse files
committed
cherry-pick: add database migration
1 parent 69eb1f9 commit d62de3e

File tree

5 files changed

+88
-0
lines changed

5 files changed

+88
-0
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ This repository is language/business-logic agnostic; mainly showcasing some univ
3131
| | |-- deployment.yml
3232
| | |-- kustomization.yml
3333
| | |-- service.yml
34+
│   ├── migration/
35+
│   │   └── job.yml
3436
| |-- overlays/
3537
| | |-- production/
3638
| | | |-- deployment.yml

templates/.circleci/config.yml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,25 @@ jobs:
249249
DEPLOYMENT=<< parameters.repo >>
250250
NAMESPACE=<< parameters.namespace >>
251251
kubectl create namespace $NAMESPACE || echo "Namespace already exists"
252+
253+
MIGRATION_NAME=<< parameters.repo >>-migration
254+
SQL_DIR="${PWD}/database/migration"
255+
pushd kubernetes/migration
256+
kubectl -n $NAMESPACE delete configmap $MIGRATION_NAME || echo "no migration configmap existing for deletion"
257+
if [ -f ${SQL_DIR}/*.sql ] ; then
258+
kubectl -n $NAMESPACE create configmap $MIGRATION_NAME --from-file ${SQL_DIR}/*.sql
259+
else
260+
kubectl -n $NAMESPACE create configmap $MIGRATION_NAME
261+
fi
262+
kubectl -n $NAMESPACE delete job $MIGRATION_NAME || echo "no migration job existing for deletion"
263+
kubectl -n $NAMESPACE create -f job.yml
264+
if ! kubectl -n $NAMESPACE wait --for=condition=complete --timeout=180s job/$MIGRATION_NAME ; then
265+
echo "$MIGRATION_NAME run failed:"
266+
kubectl -n $NAMESPACE describe job $MIGRATION_NAME
267+
exit 1
268+
fi
269+
popd
270+
252271
cd kubernetes/overlays/<< parameters.config-environment >>
253272
IMAGE=<< parameters.account-id >>.dkr.ecr.<< parameters.region >>.amazonaws.com/<< parameters.repo >>
254273
kustomize edit set image fake-image=${IMAGE}:${VERSION_TAG}

templates/README.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,37 @@ You likely want to run processes dependent on your backend codebase; so the imag
4747
As per the image attribute noted above, you will likely be running custom arguments in the context of that image.
4848
You should specify those arguments [as per the documentation](https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/).
4949

50+
## Database Migration
51+
Database migrations are handled with [Flyway](https://flywaydb.org/). Migrations run in a docker container started in the Kubernetes cluster by CircleCI or the local dev environment startup process.
52+
53+
The migration job is defined in `kubernetes/migration/job.yml` and your SQL scripts should be in `database/migration/`.
54+
Migrations will be automatically run against your dev environment when running `./start-dev-env.sh`. After merging the migration it will be run against other environments automatically as part of the pipeline.
55+
56+
The SQL scripts need to follow Flyway naming convention [here](https://flywaydb.org/documentation/concepts/migrations.html#sql-based-migrations), which allow you to create different types of migrations:
57+
* Versioned - These have a numerically incrementing version id and will be kept track of by Flyway. Only versions that have not yet been applied will be run during the migration process.
58+
* Undo - These have a matching version to a versioned migration and can be used to undo the effects of a migration if you need to roll back.
59+
* Repeatable - These will be run whenenver their content changes. This can be useful for seeding data or updating views or functions.
60+
61+
Here are some example migrations:
62+
63+
`V1__create_tables.sql`
64+
```sql
65+
CREATE TABLE address (
66+
id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
67+
person_id INT(6),
68+
street_number INT(10),
69+
street_name VARCHAR(50),
70+
reg_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
71+
);
72+
```
73+
74+
`V2__add_columns.sql`
75+
```sql
76+
ALTER TABLE address
77+
ADD COLUMN city VARCHAR(30) AFTER street_name,
78+
ADD COLUMN province VARCHAR(30) AFTER city
79+
```
80+
5081
<!-- Links -->
5182
[base-cronjob]: ./kubernetes/base/cronjob.yml
5283
[base-deployment]: ./kubernetes/base/deployment.yml

templates/database/migration/.migrations-go-here

Whitespace-only changes.
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
apiVersion: batch/v1
2+
kind: Job
3+
metadata:
4+
name: <% .Name %>-migration
5+
spec:
6+
template:
7+
spec:
8+
containers:
9+
- name: flyway
10+
image: flyway/flyway:7.4.0
11+
args:
12+
- info
13+
- repair
14+
- migrate
15+
- info
16+
env:
17+
- name: FLYWAY_URL
18+
value: jdbc:<% index .Params `database` %>://database.<% .Name %>/<% index .Params `databaseName` %>
19+
- name: FLYWAY_USER
20+
valueFrom:
21+
secretKeyRef:
22+
name: <% .Name %>
23+
key: DATABASE_USERNAME
24+
- name: FLYWAY_PASSWORD
25+
valueFrom:
26+
secretKeyRef:
27+
name: <% .Name %>
28+
key: DATABASE_PASSWORD
29+
volumeMounts:
30+
- mountPath: /flyway/sql
31+
name: sqlfiles
32+
volumes:
33+
- name: sqlfiles
34+
configMap:
35+
name: <% .Name %>-migration
36+
restartPolicy: Never

0 commit comments

Comments
 (0)