In Azure DevOps you can use Kubernetes resources to target Kubernetes clusters in an environment for deployment. You can configure your local Kubernetes cluster using Docker-desktop and then create an environment in Azure DevOps. You can use deployment job in pipeline to deploy your microservice in Kubernetes resource created in environment.
Steps:
Note: It requires a self hosted build agent to be running on this laptop where Docker-desktop kubernetes setup is running.
1. Install Docker-desktop and enable kubernetes. This will create local kubernetes setup on your laptop/desktop.
2. Now create service account, role and rolebinding to allow Azure DevOps to access this local Kubernetes cluster in Docker-desktop. The existing ServiceAccount can be mapped to a Kubernetes resource within your environment to a namespace.
–> Create Namespace
apiVersion: v1 kind: Namespace metadata: name: dev-cluster
–> Create Service-Account
apiVersion: v1 kind: ServiceAccount metadata: name: dev-cluster-svc namespace: dev-cluster
–> Create Role
apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: namespace: dev-cluster name: role-dev-cluster rules: - apiGroups: ["extensions", "apps",""] resources: ["*"] verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
–> Create Role-binding
apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: role-binding-dev-cluster namespace: dev-cluster roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: role-dev-cluster subjects: - kind: ServiceAccount name: dev-cluster-svc namespace: dev-cluster
Note: You can change scope of Role and name of service and namespace.
3. Now create Kubernetes Resource under Environments in Azure DevOps. Login to Azure DevOps and select Environments under Pipelines as shown-
>>> On the new screen enter Name, description and select Kubernetes as shown-
>> To fill the values on new screen, use the following commands to get the values of cluster, namespace, api server url and serviceaccount’s secret value.
#get cluster names kubectl config get-contexts #get api server url kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}{"\n"}' #get service account secret names kubectl get serviceAccounts dev-cluster-svc -n dev-cluster -o=jsonpath='{.secrets[*].name}{"\n"}' #get secret value in json format kubectl get secret dev-cluster-svc-token-7scpf -n dev-cluster -o json
>> Click on “Validate and create”. It will throw error windows as shown. The reason is Azure DevOps not able to reach your local Kubernetes Server Api URL. you can click on “continue anyway”. It will create Environment.
NOTE: The only limitation is that Azure DevOps will not be able to connect to K8s resources to show the service, pods etc in the Environment screen. Also the deployment will work only with self host build agent running on this laptop where docker-desktop kubernetes cluster is setup.
>>> It will show the environment created as shown-
4. Now we will add deployment task in build pipeline-
For my sample project which is in Golang, the pipeline is
trigger:
- main
pool:
name: Self-Hosted-Agent
variables:
- group: dev
stages:
- stage: Build
jobs:
- job:
displayName: Build the application
steps:
- task: Go@0
displayName: "Go Get"
inputs:
command: 'get'
arguments: '-d'
workingDirectory: '$(System.DefaultWorkingDirectory)'
- task: Go@0
displayName: "Go Build"
inputs:
command: 'build'
workingDirectory: '$(System.DefaultWorkingDirectory)'
- task: qetza.replacetokens.replacetokens-task.replacetokens@3
displayName: 'Replace image version in deployment.yaml'
inputs:
rootDirectory: '$(System.DefaultWorkingDirectory)'
targetFiles: 'deployment.yaml'
tokenPrefix: '#{'
tokenSuffix: '}#'
- task: CopyFiles@2
inputs:
SourceFolder: '$(System.DefaultWorkingDirectory)'
Contents: 'deployment.yaml'
TargetFolder: '$(Build.ArtifactStagingDirectory)'
- task: PublishBuildArtifacts@1
inputs:
artifactName: drop
- task: Docker@2
displayName: Build an image
inputs:
command: build
dockerfile: '$(System.DefaultWorkingDirectory)/Dockerfile'
buildContext: '$(System.DefaultWorkingDirectory)'
repository: $(AWS_ECR_MAGE_URI)
- task: ECRPushImage@1
inputs:
awsCredentials: 'AWS_Service'
regionName: $(AWS_REGION)
imageSource: 'imagename'
sourceImageName: $(AWS_ECR_MAGE_URI)
sourceImageTag: $(Build.BuildId)
pushTag: $(Build.BuildId)
repositoryName: $(AWS_ECR_REPOSITORY_NAME)
- stage: Dev
dependsOn: Build
jobs:
- deployment:
displayName: Dev deploy
environment: dev
strategy:
runOnce:
deploy:
steps:
- script: kubectl apply -f deployment.yaml
displayName: 'Dev Deploy'
Deployment.yaml is
apiVersion: apps/v1
kind: Deployment
metadata:
name: helloworld-deploy
namespace: dev-cluster
labels:
app: hello-world-deploy
spec:
replicas: 1
selector:
matchLabels:
app: hello-world-app
template:
metadata:
labels:
app: hello-world-app
spec:
containers:
- name: helloworldapp
image: 706949302588.dkr.ecr.ap-southeast-2.amazonaws.com/test-hello-world:#{Build.BuildId}#
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
resources:
limits:
cpu: 100m
memory: 512Mi
requests:
cpu: 100m
memory: 512Mi
securityContext:
runAsUser: 1000
imagePullSecrets:
- name: aws-registry
---
apiVersion: v1
kind: Service
metadata:
labels:
app: hello-world-svc
name: hello-world-svc
namespace: dev-cluster
spec:
ports:
- name: helloworld
nodePort: 30423
port: 8080
protocol: TCP
targetPort: 8080
selector:
app: hello-world-app
sessionAffinity: None
type: NodePort
When you run the pipeline, no need to provide Kubernetes connection details. Only Environment name needs to be set in Dev stage. It deploys the pods and service into the cluster based on resource set for Dev environment.
The deployment will look like below screen after successful deployment-
Also under Environments you can see the deployments
Reference:
https://docs.microsoft.com/en-us/azure/devops/pipelines/process/environments-kubernetes?view=azure-devops









