Entry
In the previous article, I showed how to create a pipeline on GitHub. Today, I would like to show you how to create the pipeline in Azure DevOps. In the previous article, I haven't built containers and checked them. It might be helpful if you want to deploy your application to Azure. I'll not show how to deploy your application, but I show how to prepare the application, create Kubernetes configuration, and configure Azure Pipeline. Sit back, and let's start.
Preconditions
Before we start, I want to enumerate preconditions for a better understanding of this material. For this practice work, you should have:
- Should be installed IDE or text editor and Docker Desktop.
- Also you should have experience with Docker.
Project
I'll not create a new template project since it'll be too simple and uninteresting. Instead, let's clone to any convenient folder the finished project from GitHub:
git clone https://github.com/SergKorol/ManagementSystem.git
And now, let's ensure that your Docker Desktop is already run and Kubernetes is also enabled and run. Both services should be green.
If everything is OK, build the project and ensure that it's not having errors, and also build up the Docker image. You should ensure that the project is opening through Docker.
Kubernetes
Now, let's start creating the configuration for Kubernetes. I'll create it in ShopManagementSystem.Dashboard project, however, you can create into any different folder at your discretion.
cd src/ShopManagementSystem/ShopManagementSystem.Dashboard
And create a YAML file in this folder:
touch k8s.deploy.yaml
Open it in any editor and paste this code:
apiVersion: apps/v1
kind: Deployment
metadata:
name: shop-system
labels:
app: shop-system-app
spec:
replicas: 1
selector:
matchLabels:
service: shop-system
template:
metadata:
labels:
app: shop-system-app
service: shop-system
spec:
containers:
- name: shop-system
image: managementsystem-webmvc
imagePullPolicy: Never
ports:
- containerPort: 80
protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
name: shop-system
labels:
app: shop-system-app
service: shop-system
spec:
type: LoadBalancer
ports:
- port: 11000
targetPort: 80
protocol: TCP
selector:
service: shop-system
The configuration file is divided into two parts. In the first part, the configuration of Kubernetes and mounting existing built Docker image. It's a simplified configuration with one replica, but injected service that is described below. The service type of LoadBalancer.
Save this file and let's apply it. Important, your Kubernetes should work!. Paste this command to the terminal:
kubectl apply -f k8s.deploy.yaml
If everything is OK, you'll see the message like this:
deployment.apps/shop-system configured
service/shop-system created
Let's check out and see our pods, put this command:
kubectl get pod
You should see this table:
NAME READY STATUS RESTARTS AGE
shop-system-7f5dc5f85f-czp7q 1/1 Running 0 3h17m
With the pod is OK. Next, let's check the service. Put this command:
kubectl get service
You should see cluster and service, like this:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 15h
shop-system LoadBalancer 10.98.254.189 localhost 11000:31224/TCP 3h6m
Pay attention, your service should have external IP. If it has a "pending" status, you should wait or delete it and create it again. And let's check out the work and type localhost:11000
in the browser. It should work fine.
Pipeline
The Azure Pipeline is similar to GitHub Actions, however, I'm gonna make it more difficult and add create a cluster. Go to the root folder of this project and paste the command and open it:
touch azure-pipelines.yml
Next step, paste this code:
trigger:
branches:
include:
- main
pool:
vmImage: 'ubuntu-latest'
variables:
buildConfiguration: 'Release'
jobs:
- job: Build
displayName: 'Build Solution'
steps:
- task: UseDotNet@2
displayName: 'Install .NET SDK'
inputs:
packageType: 'sdk'
version: '7.x'
installationPath: '$(Agent.ToolsDirectory)/dotnet'
- script: dotnet restore
displayName: 'Restore NuGet packages'
workingDirectory: '$(Build.SourcesDirectory)/src/ShopManagementSystem'
- script: dotnet build --configuration $(buildConfiguration) --no-restore
displayName: 'Build Solution'
workingDirectory: '$(Build.SourcesDirectory)/src/ShopManagementSystem'
- job: Test
displayName: 'Run Tests'
dependsOn: Build
steps:
- script: dotnet restore
displayName: 'Restore NuGet packages'
workingDirectory: '$(Build.SourcesDirectory)/src/ShopManagementSystem'
- script: dotnet build --configuration $(buildConfiguration) --no-restore --output $(Build.ArtifactStagingDirectory)/$(buildConfiguration)
displayName: 'Build Output'
workingDirectory: '$(Build.SourcesDirectory)/src/ShopManagementSystem'
- script: dotnet test $(Build.ArtifactStagingDirectory)/$(buildConfiguration)/ShopManagementSystem.UnitTests.dll --configuration $(buildConfiguration) --no-build --collect "Code Coverage"
displayName: 'Run Unit Tests'
workingDirectory: '$(Build.SourcesDirectory)/src/ShopManagementSystem'
- job: Publish
displayName: 'Publish Artifacts'
dependsOn: Test
steps:
- script: dotnet publish --configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory)
displayName: 'Publish Solution'
workingDirectory: '$(Build.SourcesDirectory)/src/ShopManagementSystem'
- task: CmdLine@2
displayName: 'Build Docker Image'
inputs:
script: 'docker-compose -f docker-compose.yml build'
workingDirectory: '$(Build.SourcesDirectory)'
- task: CopyFiles@2
displayName: 'Copy Kubernetes Deployment Files'
inputs:
SourceFolder: '$(Build.SourcesDirectory)/src/ShopManagementSystem/ShopManagementSystem.Dashboard'
Contents: '**/k8s.deploy.yaml'
TargetFolder: '$(Build.ArtifactStagingDirectory)'
CleanTargetFolder: true
OverWrite: true
flattenFolders: true
- task: PublishBuildArtifacts@1
displayName: 'Publish Artifacts'
inputs:
PathtoPublish: '$(Build.ArtifactStagingDirectory)'
ArtifactName: 'drop'
publishLocation: 'AzureBlob'
As I already mentioned, It's similar to GitHub Actions and also has a trigger for the branch. Sure, it also has the same jobs. The first job run building the project, install of SDK, making of restore. If this job was passed, the next job will run a unit test. This job requires restoring and building, otherwise, you'll get fail. The next job is composite with several tasks, that build images, create clusters and services and publish artifacts.
Azure
For adding a pipeline to Azure DevOps, you should log in to https://dev.azure.com/ and make several actions:
- Create a project
- In the left panel add a repo. If you use the Azure repo then push your changes, otherwise inject your existing updated repo to Azure from GitHub.
- Go to pipelines in the left panel and create a new pipeline. Select your Azure repo or external repo, and add a configuration file.
- Your pipeline should finish successfully.
You'll see a pipeline report like this:
Conclusion
Azure Pipeline isn't more complicated than GitHub Actions. However more flexible. This approach consists of deploying the whole project to Azure. You'll have the base cluster and services if you decide to deploy to the Azure instance.
Happy coding!