-
Notifications
You must be signed in to change notification settings - Fork 1
Azure devops
We are using Azure DevOps for build and release-management.
As noted in the 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.
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.
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 project. Kubernetes will figure out what parts of the file has changed, and only deploy the relevant parts.
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 artifact will be added using the Azure Container Repository-type. This makes it possible to trigger manual deploys by choosing the version of each service and set up deployment triggers that releases automatically when a service is built.
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.
Before creating pipelines and tasks, some setup is needed, namely various Service Connections.
Go to Project settings -> Pipelines -> Service connections to register new connections.
We need three connections in total.
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.
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.
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