Originally published at: How to Set Up Liquibase in Spinnaker | Liquibase.com
We’ve been having a lot of fun with CICD integrations at Liquibase. We’ve recently released our official GitHub Action and an example for Travis CI. It’s past time to do the same for Spinnaker!
For the uninitiated, Spinnaker is an open source, multi-cloud continuous delivery platform built by Netflix for releasing software changes with high velocity and confidence. Fun fact: Spinnaker uses Liquibase to manage the internal database that holds configuration information. A lot of amazing companies use Spinnaker: Netflix, Google, Microsoft, Veritas, Target, Kenzan, Schibsted, and many others.
If Liquibase is good enough for Spinnaker, imagine what it can do for your CI/CD workflow.
Using Liquibase in Spinnaker
You can execute Liquibase within Spinnaker using the Run Job (Manifest) stage. This stage uses the Liquibase Docker image to execute Liquibase commands. This is the same underlying workflow that we have used for GitHub Action and Travis CI.
High-Level Architecture
![](upload://k9XxuNVvJf9AHX32t2bHsdCCidy.png)Spinnaker Setup
In Spinnaker, configure a Run Job (Manifest) stage and use the following manifest source text (YML):
apiVersion: batch/v1 kind: Job metadata: name: liquibase-runner spec: backoffLimit: 0 template: spec: containers: - args: - '--classpath=/workspace/example/changelogs' - '--changeLogFile=samplechangelog.h2.sql' - '--username=liqubase' - '--password=password' - '--url=jdbc:sqlserver://<IP OR HOSTNAME>:1433;database=<database name>' - update image: 'index.docker.io/liquibase/liquibase:4.1' name: liquibase volumeMounts: - mountPath: /workspace name: workspace initContainers: - command: - git - clone - '--single-branch' - '--branch' - $(BRANCH) - $(REPO) - /workspace env: - name: BRANCH value: main - name: REPO value: 'https://github.com/liquibase/liquibase-github-action-example' image: alpine/git name: git volumeMounts: - mountPath: /workspace name: workspace restartPolicy: Never volumes: - emptyDir: {} name: workspace
Notice that in the code above, the following parameters are hard-coded for reference:
- BRANCH: main
- REPO: https://github.com/liquibase/liquibase-github-action-example
Once you have create the job, you should see the following in Spinnaker:
![](upload://e4rpmXR2QtGZxGxZnBtF4gkmNZs.png)And when executed, you will see a happy Liquibase update
.
Author’s note: I wanted to give a big thanks to our good friends at Armory. If you are interested in using Spinnaker in an Enterprise setting, we can think of no better partner than Armory. They are super helpful and just great people to work with!
Author’s second note: Of course, all Spinnaker jobs are JSON under the hood. So, here’s the underlying JSON for the job listed above if you prefer to manage your Spinnaker pipeline as code:
{ "keepWaitingPipelines": false, "lastModifiedBy": "admin", "limitConcurrent": true, "spelEvaluator": "v4", "stages": [ { "account": "spinnaker", "alias": "runJob", "application": "liquibasejenkins", "cloudProvider": "kubernetes", "credentials": "spinnaker", "manifest": { "apiVersion": "batch/v1", "kind": "Job", "metadata": { "name": "liquibase-runner" }, "spec": { "backoffLimit": 0, "template": { "spec": { "containers": [ { "args": [ "--classpath=/workspace/example/changelogs", "--changeLogFile=samplechangelog.h2.sql", "--username=liqubase", "--password=password", "--url=jdbc:h2:file:./H2_project/h2tutorial", "update" ], "image": "index.docker.io/liquibase/liquibase:4.1", "name": "liquibase", "volumeMounts": [ { "mountPath": "/workspace", "name": "workspace" } ] } ], "initContainers": [ { "command": [ "git", "clone", "--single-branch", "--branch", "$(BRANCH)", "$(REPO)", "/workspace" ], "env": [ { "name": "BRANCH", "value": "main" }, { "name": "REPO", "value": "https://github.com/liquibase/liquibase-github-action-example" } ], "image": "alpine/git", "name": "git", "volumeMounts": [ { "mountPath": "/workspace", "name": "workspace" } ] } ], "restartPolicy": "Never", "volumes": [ { "emptyDir": {}, "name": "workspace" } ] } } } }, "name": "Run Job (Manifest)", "refId": "1", "requisiteStageRefIds": [], "source": "text", "type": "runJobManifest" } ], "triggers": [], "updateTs": "1603738482000" }
Reference: Extending Spinnaker with Kubernetes and Containers