Kubernetes, GitHub, and DevOps: Putting it all together to increase confidence in PR reviews.

Nick Greenfield
Microsoft Azure
Published in
8 min readMay 29, 2019

Development teams often collaborate in feature branches and pull requests. When finishing feature branches, developers submit pull requests for review before merging into the application’s main branch. This process works well for static code diffs where newly committed code is reviewed to meet the team’s standards for consistency and maintainability.

Unfortunately, this process is commonly limited to team members who directly work on that specific part of the application and have context to provide reliable feedback. Additionally, when working with microservice applications, there is minimal visibility of the end to end impact on the application behavior when modifying an individual service.

With Azure Dev Spaces and Azure Pipelines, you can easily test your PR code in the context of the broader application running in Azure Kubernetes Service (AKS). As a bonus, team members such as, product managers and designers can become part of the review process during early stages of development.

In this guide you will learn how to:

  • Set up Azure Dev Spaces on a managed Azure Kubernetes Service (AKS) cluster in Azure.
  • Deploy a large application with multiple microservices to a dev space..
  • Configure an Azure Pipeline that dynamically creates review apps whenever a pull request is created or updated.

If you need help troubleshooting any of the steps in this article visit our issues page on our Github repository.

Prerequisites

Set up your AKS cluster

You must create an AKS cluster in a supported region. The below commands create a resource group called MyResourceGroup and an AKS cluster called MyAKS.

$ az group create --name MyResourceGroup --location eastus$ az aks create -g MyResourceGroup -n MyAKS --location eastus --node-vm-size Standard_DS2_v2 --node-count 1 --disable-rbac --generate-ssh-keys

Enable Azure Dev Spaces on your AKS cluster

Use the use-dev-spaces command to enable Dev Spaces on your AKS cluster and follow the prompts. The below command enables Dev Spaces on the MyAKS cluster in the MyResourceGroup group and creates a dev space called dev.

$ az aks use-dev-spaces -g MyResourceGroup -n MyAKS --space dev --yes

Get the sample application

Fork the Azure Dev Spaces sample github repository. Clone your fork and navigate to the dev-spaces/samples/BikeSharingApp/ directory.

$ git clone https://github.com/USERNAME/dev-spaces
$ cd dev-spaces/samples/BikeSharingApp/

Retrieve the HostSuffix for dev

Use the azds show-context command to show your AKS cluster’s HostSuffix for dev.

$ azds show-context

Name ResourceGroup DevSpace HostSuffix
---------- ------------- -------- -----------
MyAKS MyResourceGroup dev fedcab0987.eus.azds.io

Update the Helm chart with your HostSuffix

Open charts/values.yaml and replace all instances of <REPLACE_ME_WITH_HOST_SUFFIX> with the HostSuffix value you retrieved earlier. Save your changes and close the file.

Run the sample application in Kubernetes

The commands for running the sample application on Kubernetes are part of an existing process and have no dependency on Azure Dev Spaces tooling. In this case, Helm is the tooling used to run this sample application but other tooling could be used to run your entire application in a namespace within a cluster. The Helm commands are targeting the dev space named dev you created earlier, but this dev space is also a Kubernetes namespace. As a result, dev spaces can be targeted by other tooling the same as other namespaces.

You can use Azure Dev Spaces for team development after an application is running in a cluster regardless of the tooling used to deploy it.

Use the helm init and helm install commands to set up and install the sample application on your cluster.

$ cd charts/
$ helm init --wait
$ helm install -n bikesharing . --dep-up --namespace dev --atomic

The helm install command may take several minutes to complete. The output of the command shows the status of all the services it deployed to the cluster when completed:

$ cd charts/
$ helm init --wait
...
Happy Helming!
$ helm install -n bikesharing . --dep-up --namespace dev --atomic Hang tight while we grab the latest from your chart repositories...NAME READY UP-TO-DATE AVAILABLE AGE
bikes 1/1 1 1 4m32s
bikesharingweb 1/1 1 1 4m32s
billing 1/1 1 1 4m32s
gateway 1/1 1 1 4m32s
reservation 1/1 1 1 4m32s
reservationengine 1/1 1 1 4m32s
users 1/1 1 1 4m32s

Navigate to the bikesharingweb service by opening the public URL from the azds list-uris command. In the below example, the public URL for the bikesharingweb service is http://dev.bikesharingweb.<random suffix>.eus.azds.io/

$ azds list-urisUri                                                       Status
-------------------------------------- -------
http://dev.bikesharingweb.<random suffix>.eus.azds.io/ Available
http://dev.gateway.<random suffix>.eus.azds.io/ Available

Navigate to the bikesharingweb service by opening the public URL from the azds list-uris command. In the above example, the public URL for the bikesharingweb service is http://dev.bikesharingweb.<random suffix>.eus.azds.io/. Select Aurelia Briggs (customer) as the user. Then select a bike to rent.

Notice the image for the bike is using a placeholder. You are going modify it to use an actual image of the bike.

Configure your CI/CD pipeline

Create an Azure Pipelines account by browsing here.

Install the Azure Pipelines app in your GitHub account.

Install the following extension into your Azure Pipelines organization.

In Azure DevOps under Preview features, enable Multi-stage pipelines. The new YAML pipeline feature was announced at the //Build 2019 conference.

Next create an Azure Container Registry. You can follow the steps here. After you create the Container Registry, follow the steps provided here to grant your AKS cluster access to your ACR.

Now we will create Service Connections. You can follow the steps provided here. Below is the list of service connections you need to create.

  • Docker Registry (Azure Container Registry)
  • Kubernetes (Azure Subscription)
  • Azure Resource Manager (Service Principal Authentication)
  • GitHub

After you have created your Service Connections, navigate to Pipelines and create a new Pipeline.

In the next step you will be asked to point to your code repository. Select GitHub and choose the repository you forked earlier.

Azure Pipelines will analyze your repository content and suggest CI/CD templates.

Select “Existing Azure Pipelines YAML file”.

Type the path (samples/BikeSharingApp/Bikes/azds_pipeline.yaml) to the YAML file in the Bikes directory and continue.

Now it’s time to edit the YAML. Consider opening your service connections in a separate tab since you will reference them frequently.

  1. Replace CONTAINER-REGISTRY-CONNECTION-NAME (line 20) with the Docker Registry service connection name.
  2. Replace CONTAINER-REGISTRY-URL (line 23). You can find this information in the Azure Portal under your Azure Container Registry. It should look something like this: login server: builddemo.azurecr.io.
  3. Replace KUBERNETES-CONNECTION-NAME (line 26) with the Kubernetes service connection name.
  4. Replace the KUBERNETES-CLUSTER-NAME (line 29) with your AKS cluster name.
  5. Replace the KUBERNETES-CLUSTER-RESOURCE-GROUP (line 32) with your Azure Resource Group name in which you have created the cluster.
  6. Replace the AZURE-CONNECTION-NAME (line 35) with your Azure Resource Manager service connection name.
  7. Replace GITHUB-CONNECTION-NAME (line 38) with your GitHub service connection name.

Please take note of the trigger section which ensures that this pipeline will run only when you make changes to the Bikes service.

There are two stages in the pipeline, and each has a condition which ensures they run only on changes to the master branch or when a pull request is created for master.

Now you are ready to commit the changes to the GitHub repository.

Work in a feature branch and update the code

Create a new branch named bike-images using the git checkout command.

$ git checkout -b bike-images

When creating branches only use alphanumeric characters, hyphens and periods. Verify you are on the bike-images branch using the git status command.

$ git status
On branch bike-images
nothing to commit, working tree clean

Open Bikes/server.js with a text editor and remove lines 233 and 234:

// Hard code image url *FIX ME*
theBike.imageUrl = "/static/logo.svg";

The remaining code should look like:

...
var theBike = result;
theBike.id = theBike._id;
delete theBike._id;
res.send(theBike);
...

Stage and commit your changes to the bike-images branch.

$ git add Bikes/server.js
$ git commit -m "Removing hard coded imageUrl from /bikes/:id route"

Push the bike-images branch to your fork on GitHub.

$ git push origin bike-images

Pull Request Flow

Navigate to your forked repository on GitHub and create a new pull request. The base branch will be master and the branch you are comparing is bike-images.

Navigate to your build pipeline and confirm it has started building the Bikes service.

Once the build pipeline has successfully completed, navigate back to your pull request on GitHub.

Test and interact with your pull request changes

In the most recent build check, click Show all checks.

Open the review app by clicking on Details to the right of the Dev Spaces review app label.

Navigate back to the detail page for renting a bike. Confirm the placeholder image has been replaced with an actual image of the bike.

Now that we have our changes running in a new dev space, this is a great opportunity to include team members such as product managers and designers to look over our changes and provide feedback.

Once the pull request is merged, the build pipeline will trigger and redeploy the parent branch to the parent dev space. In our scenario the master branch is deployed to the dev space named “dev”. You should try this exercise on your own.

With the Azure Dev Spaces and Azure Pipelines pull request flow, we have tested our changes before code has been merged into the application’s main branch. By creating a review app for integration testing, team members can confidently approve pull requests by ensuring the new changes will not have a negative impact on other services in the application.

--

--