Managing database migrations via code is good! back in DBA days i used SSDT and RedGate tools to do my SQL Server deployments. In my current shop we normally use postgres so I needed to find a new tool. Searching around i found flyway which also happens to have owned by RedGate and this lets you do migration deployments to postgres, sql server, mysql and a host of others im sure.

To run it locally is super easy, download the client create your conf file with the database you want to deploy to and write your .sql files. But when you have a more locked down production environment that you need to copy the .sql files into, get the tool on a box and be allow patching and all the rest of it, we ran into problems. My solution (though some may say not very elegant) is the create a docker image from the flyway base image load in the sql files as part of a CI/CD and push it to kubernetes Then i just needed to run it. Which is a perfect example of a job and pass it the conf (Hello configmap).

Code for the solution is below

Dockerfile

FROM flyway/flyway:7.3.2

RUN ["rm", "-fr", "/flyway/sql"]
COPY sql/ /flyway/sql/

ENTRYPOINT ["flyway", "migrate", "-url=jdbc:postgresql://localhost:5432/customerdb", "-user=postgres", "-password=postgres"]

Kubernetes Manifests

I used a configmap to create my flyway.conf file. You can do it as a secret or I believe in pass in values as environment variables

ConfigMap

apiVersion: v1
kind: ConfigMap
metadata:
  name: flyway-configmap
data:
  flyway.conf: |
    flyway.url=jdbc:postgresql://<RDS-INSTANCE>:5432/<database>
    flyway.user=<FLYWAY-ACCOUNT>
    flyway.password=<PASSWORD-FOR-ACCOUNT>    

Then you just need a job to call the image and run it

apiVersion: batch/v1
kind: Job
metadata:
  name: flyway
spec:
  template:
    metadata: 
      name: flyway
    spec:
      containers:
        - name: flyway
          image: ECR_URL:<TAG>
          command: ["flyway", "migrate"]
          volumeMounts:
            - name: flyway-config-volume
              mountPath: /flyway/conf
      volumes:
        - name: flyway-config-volume
          configMap:
              name: flyway-configmap
      restartPolicy: Never

With it now being in kubernetes you can use kustomize to allow easy deployments to different environments and image upgrades.

Hope this helps!