How to configure deployment CI/CD
In parts 1 and 2 we have created a container and corresponding kubernetes manifests which describe the deployment of that container. This guide now focuses on how those manifests can be deployed and updated automatically. To do this we will use a mixture of GitHub Actions for Continuous Integration and ArgoCD for Continuous Deployment. We will also set up our three stages prod, stage and dev.
Goal
After following this guide, you will have automatically deployed an example application in three stages prod, stage and dev.
Prerequisites
This guide assumes that you already have a repository with a working Dockerfile as well as generic manifests that just need to be deployed.
1) Build Container automatically
First we need to set up CI for our application repository so that its docker image is built automatically.
To do this, create the file .github/workflows/container_image.yml
and fill it with the following content.
Info
For more details about the workflow file see the Github Action Syntax Reference as well as our repositoriy of reusable workflows.
What this workflow achieves is:
- run the workflow whenever a change is pushed to one of the branches main, stage or develop
- build a container image and automatically tag it based on the branch
- deploy the just-built image
2) Create -deploy repository
Step 1) just deploys the image however what this actually means is that it updates the digest1 which should be deployed in another repository. We call this other repository the -deploy repository. So, in order for GitHub Actions to update the digest the -deploy repository needs to actually exist.
Important
The -deploy repository should be named like your app repository in addition to a -deploy postfix.
2.1) Create dev stage folder
Each -deploy repository is structured to contain one folder for each deployment stage.
We start with the dev stage which means you simply need to create a folder called dev
.
Create dev folder | |
---|---|
2.2) Create additional manifests
Remember that in part 2 we created kubernetes manifests that are very general and don't include any deployment details. This means that such deployment details need to be added now since the -deploy repositories different stage folders are exactly where such details are known.
An Ingress definition is very important because it defines how our app is reachable via http from the outside network.
A simple manifest that terminates all traffic to https://example-app.dev.vivaconagua.org
(and http with automatic redirects) and then forwards it to the service called example-app
can be seen below.
Info
Relevant Kubernetes documentation is about Ingresses, backing services and available ingress manifest fields.
We also want to put all resources into their own namespace to keep things organized. To do so simply create the manifest file that can be seen below.
Info
See relevent Kubernetes namespace documentation and available namespace manifest fields.
2.4) Write dev kustomization
Now that a folder for the dev stage exists and contains all deployment relevant manifests we just need to bundle them together so that the whole stage can be deployed in unison.
dev/kustomization.yml | |
---|---|
3) Register app with ArgoCD
The app is now theoretically completely deployable, but it still needs to actually be deployed. This is done using ArgoCD2. All our applications are defined inside the repository github.com/Viva-con-Agua/argocd-apps.
Add a manifest for your application definition like the following. This manifest will instruct ArgoCD to scan for folders inside the -deploy repository and creates an appropriate application definition for every folder it finds. Since our -deploy repositories contain one folder for each deployed stage, ArgoCD creates a separate application for each stage.
Info
The relevant documentation is from ArgoCD about Applications and ApplicationSets.
Additionally don't forget to also include this app definition in the repositories kustomization.yml
kustomization.yml | |
---|---|
4) Monitor status on ArgoCD
As said above, the actual deployment is now done by ArgoCD, but you can monitor it over at https://argocd.vivaconagua.org.
-
Digests are a content-addressable identifier of an image. As long as the input used to generate the image is unchanged, the digest value is predictable. ↩
-
See our ArgoCD reference about how we have set it up and how it works. ↩