Deploy Pull Requests to Kubernetes for Review with Azure DevOps

When a Pull Request got created, you might want to try out the changes in a testing environment. Here is how to optionally deploy Azure DevOps Pull Requests to a dedicated Kubernetes namespace with a single click.

linkWhat we need

To achieve automatic deployments of Pull Requests in Azure DevOps, we need a few things beside the obvious ones like a Kubernetes Cluster and your application as a Container with a Helm Chart or deployment definition.

linkCreate an Azure Pipeline for Build and Deploy

We will setup Azure DevOps, to offer running an additional Build Validation Branch Policy whenever a Pull Request to a specific branch got opened. These build validations come as Azure Pipelines.

1linkname: $(BuildID)

2linktrigger: none


4link# Replace these variables with your own values


6link - name: AzureSubscription

7link value: '<Name of Azure Resource Manager service connection>'

8link - name: KubernetesConnection

9link value: '<Name of Kubernetes service connection>'

10link - name: ContainerRegistry

11link value: '<Name of Container Registry service connection>'

12link - name: Tag

13link value: 'pr$(System.PullRequest.PullRequestId)-$(Build.BuildId)'



16link - stage: 'BuildPR'

17link jobs:

18link - job: Build

19link pool:

20link vmImage: 'Ubuntu-16.04'

21link steps:

22link # This step build the Docker image and pushes it

23link # to your container registry.

24link - task: Docker@2

25link displayName: 'Build and push container image'

26link inputs:

27link containerRegistry: $(ContainerRegistry)

28link repository: 'test'

29link command: 'buildAndPush'

30link Dockerfile: 'src/Dockerfile'

31link buildContext: '.'

32link tags: |

33link $(Tag)


35link - job: 'DeployPR'

36link displayName: 'Deploy Pull Request'

37link dependsOn: [Build]

38link variables:

39link - name: Namespace

40link value: 'myapp-pr$(System.PullRequest.PullRequestId)'

41link - name: ReleaseName

42link value: 'myapp-pr$(System.PullRequest.PullRequestId)'


44link # This step creates a new Kubernetes Namespace

45link # for the Pull Request deployment.

46link - task: Kubernetes@1

47link displayName: 'Create Namespace'

48link inputs:

49link connectionType: 'Kubernetes Service Connection'

50link kubernetesServiceEndpoint: $(KubernetesConnection)

51link command: 'apply'

52link useConfigurationFile: true

53link configurationType: 'inline'

54link inline: |

55link apiVersion: v1

56link kind: Namespace

57link metadata:

58link name: '$(Namespace)'


60link - task: HelmInstaller@1

61link displayName: 'Install Helm'

62link inputs:

63link helmVersionToInstall: 'v3.1.0'


65link # This step deploys your application to the newly

66link # created Namespace as a Helm Chart.

67link - task: HelmDeploy@0

68link displayName: 'Install Helm chart'

69link inputs:

70link connectionType: 'Kubernetes Service Connection'

71link kubernetesServiceConnection: $(KubernetesConnection)

72link namespace: $(Namespace)

73link command: 'upgrade'

74link chartType: 'FilePath'

75link chartPath: 'env/helm/MyApp'

76link releaseName: $(ReleaseName)

77link overrideValues: "\

78link tag=$(Tag)"

Once the pipeline definition is written, we can create a new Azure Pipeline from it by checking the file in to our repository and creating a new Azure Pipeline in Azure DevOps by selecting an existing YAML file.

Create a new Pipeline in Azure DevOps from an existing YAML file

Now that the pipeline is created, we can add it to the optional steps that can be kicked off from a Pull Request check.

linkAdd the pipeline as a Pull Request Check

In the Branches section of the Repos submenu in Azure DevOps, we can add Policies to each branch by clicking the menu icon next to a branch and selecting the Branch policies option.

Here we can setup requirements for Pull Request that are being made against the selected branch. Beside policies for reviewers and status checks, we can also setup Build Validations, which are Azure Pipelines that run to validate the changes. Some of them can be required and run automatically, while others can be optional and only run on a user's request. The latter is exactly what we need.

Add a Build Validation policy for the Pull Request Pipeline we created earlier and declare its trigger to manual and its requirement to optional.

Create a new optional and manual Build Validation policy for the Azure Pipeline that builds and deploys the Pull Request

Now, if someone creates a new Pull Request targeting the branch you just setup the new policy for, the reviewer can chose to deploy the changes to a dedicated Kubernetes namespace for detailed review, just by kicking off the newly created pipeline.

Running the pipeline that builds and deploys the changes is a bit hidden. In the Pull Request view, click the View all checks button to see a list of all Build Validation pipelines that can be run for this Pull Request. Here you will find the optional one, that we just created. Once you click the Queue button, your pipeline will be executed.

Deploy a Pull Request by queueing the optional pipeline hidden in the Checks

linkOptional: Post a link to the app to the Pull Request comments

Personally, I like not just silently deploying a Pull Request but also posing an internal link for reviewing automatically to the Pull Request's comments. I use the Create Pull Request Comment Task from the Azure DevOps Marketplace for that but of course you need to make sure, that your Helm Chart is built in a way, that it creates a route in your Ingress Controller for the newly deployed testing version of your app.


One thing that bothers me about that solution is the fact that I have to delete the deployment manually after merging the Pull Request. Currently, there is no Trigger in Azure DevOps to run a pipeline after merging. Fingers crossed, that Azure DevOps brings a native "Deploy Pull Requests to Kubernetes" feature one day, which includes that.

What we needCreate an Azure Pipeline for Build and DeployAdd the pipeline as a Pull Request CheckOptional: Post a link to the app to the Pull Request commentsGotchas


Deploy Pull Requests to Kubernetes for Review with Azure DevOps