Legacy Azure devops - Arthyon/microservice-poc GitHub Wiki
We are using Azure DevOps for build and release-management.
As noted in the Legacy-Overview, we have one build pipeline for each service, and one for the Kubernetes provisioning configuration. There is also one for the CI-part, which runs on each commit to master and builds all the services and runs tests.
Build
The Build configurations are specified in yml-format and checked into the repository. They are comprised of a series of pipelines, or build steps, which describes how an application should be built. In this repo the yml-files are in Infrastructure/pipelines.
There are numerous pipelines to choose from here, but we have mostly used the docker pipelines, as Docker itself is a build environment.
Our build pipeline is used to build the image using the dockerfile, logging in to our private Azure Container Registry and pushing a new version of the image.
Since we are working in a monorepo, this must be a manual trigger as we cannot know which service was updated for each commit.
The Kubernetes-config has its own build pipeline, called provisioning. We need access to the config for each deploy, so the only job for this pipeline is to make the kubernetes.yml-file available as an artifact.
Lastly, there is a build pipeline that builds all the images (using docker-compose) to check that they are buildable on each commit. This is the CI-part, and should be used to run tests as well.
Release
There is only one release pipeline. All artifacts from our build pipelines feed into that release and are used to fill the kubernetes.yml-file with the correct data. Effectively, we are only using that file in the final stage of the deploy.
We are creating a working Kubernetes-config in the task Replace tokens in Kubernetes config, which gets the built image names from environment-variables. Then we apply the file to the Kubernetes cluster defined using a Service connection defined in the Azure DevOps environment. Kubernetes will figure out what parts of the file has changed, and only deploy the relevant parts.
Defining artifacts
We must define which build artifacts that should be taken into account during the release. If a new service is introduced and updated in kubernetes.yml, the deploy will fail if the artifact is not defined. That is because the correct environment variable containing the image name is not present, and the variable substitution will fail.
Each input artifact in the release pipeline is added using the artifact type Azure Container Repository. This makes it possible to set up deployment triggers that releases a new version automatically when a service is built. Then we can trigger a build of a specific service version manually to release.
Note: It is also possible to create the Azure Container Registry connection as a Docker Hub-connection using the admin password (possible to enable in the Azure portal), but this will make the release pipeline unable to trigger builds automatically and impossible to get a list of image versions to deploy. Not recommended, but a possible gotcha when setting up.
Setup
Before creating pipelines and tasks, some setup is needed, namely various Service Connections.
Service connections
Go to Project settings -> Pipelines -> Service connections to register new connections.
We need three connections in total.
Github connection
The service connection is named GitHub and should be created using a personal access to make it easier to revoke. This is used by the build pipelines to fetch the source code and tag commits after building, and by the release pipeline to
create a github release.
Private Container Registry connection
This is realized using an Azure Resource Manager-connection. Follow the instructions to create a service principal, and scope the access to the resource group where your Azure Container Registry is located.
This is used to push new images to the container registry, and by Kubernetes to pull them.
Kubernetes connection
This is of type Kubernetes and is used to run commands against Kubernetes. Follow this guide to obtain the credentials needed for Kubeconfig-authentication.
In a nutshell:
- Server URL:
kubectl config view - Kubeconfig:
%UserProfile%\.kube\configor${HOME}/.kube/config