First look at Azure Dev Spaces – Collaborate in shared AKS cluster

With Azure Dev Spaces, you can build and debug microservices or complicated N-tier applications in Kubernetes cluster without installing entire system in your local desktop.

In this post I introduce Azure Dev Spaces using command line, and see how it works.
(Now Azure Dev Spaces has reached public preview. Azure Dev Spaces has reached generally available !)

For the beginning

Before explaining value props for Azure Dev Spaces, first we just deploy our application using Azure Dev Spaces command line (azds).

After you’ve created your AKS cluster, you should create a current controller for dev spaces with the following command (Azure CLI command). See “Quickstart: Create a Kubernetes dev space with Azure Dev Spaces” for some notations to create AKS cluster for dev spaces. (Especially, care about supported Kubernetes version and regions.)
After you run this command, dev spaces controller with “default” namespace is generated for your AKS cluster “cluster01”.

Note : This command also installs Azure Dev Spaces CLI command tool in your desktop if it’s not installed.

Note : You can see available controllers with “azds controller list“.

az aks use-dev-spaces --resource-group group01 --name cluster01

After you’ve built your application code (node.js, .NET Core), now let’s deploy your application in AKS cluster.

First you should generate configuration files for registering your application in AKS cluster by running the following command in your application directory.
The configuration is written by Helm. As you can see generated files in “templates” folder, the default configuration consists of single deployment, service, ingress, and secret in Kubernets.
Please modify the generated files if you need additional setup.

azds prep --public

The configuration differs along with project type and the type is automatically detected. For instance, if there exists package.json in your project, node image is used for cluster. (See below.)
Today only 2 types of projects (.NET Core or node.js) are supported in Azure Dev Spaces.

Here’s one important note.
As you can see in the generated configuration files, the name of current working directory is used as logical name for your deployment by default. For instance, when your working directory is “test01”, the name of your deployment is also “test01”. As you can see later, this name is very important, because it’s used for the endpoint communication for your multiple services.
If you want to change (specify) logical name by your own, please run command with --name option as follows.

azds prep --name webapp01 --public

Now let’s deploy your application in your AKS cluster with the following command. Here public DNS (*****.aksapp.io) is generated for your application.
The following “azds up” command keeps running and it watches the file modification and automatically syncs into your running application in the container. Therefore you can quickly see your modification in web browser, if the compilation is not needed.
If the compilation is needed, build and restart (stop and start) “azds up” command.

azds up

As I mentioned earlier, this command creates ingress, service, deployment, and secret in your Kubernetes cluster along with the generated Helm chart configuration. Of course, you can access with kubectl after these objects are generated.

# Example : Get generated objects with kubectl
kubectl get ingress,service,deployment,secret

NAME                        HOSTS                                          ADDRESS   PORTS     AGE
ingress.extensions/test01   test01.ee10ad82584944daa140.eastus.aksapp.io             80        18m

NAME                 TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP       <none>        443/TCP   2h
service/test01       ClusterIP   <none>        80/TCP    18m

NAME                           DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
deployment.extensions/test01   1         1         1            1           18m

NAME                         TYPE                                  DATA      AGE
secret/azds-storage          Opaque                                2         29m
secret/default-token-nw6t6   kubernetes.io/service-account-token   3         2h

Now you can access your application using web browser with public DNS address.
Note that Azure Dev Spaces creates not only public DNS but also a temporary SSH tunnel for your remote container (see below). Therefore you can also access your remote application using “localhost” from your desktop.

Note : It takes several minutes to be able to use public DNS address and you must use tunneled “localhost” while the public DNS is not available.
You can see the status using azds list-uris command.

As I mentioned earlier, your application can access another application using logical name.
For instance, if there are 2 applications – web front end “test01” and web api “test02” – deployed in your cluster as follows, the front-end web application “test01” can connect to the HTTP-based backend web api “test02” by using http://test02 as follows

test01 (javascript)

var http = require('http');
var request = require('request');

var port = process.env.PORT || 80;
http.createServer(function (req, res) {
    uri: 'http://test02'
  }, function (error, response, body) {
    res.end('api result: ' + body);

test02 (javascript)

var http = require('http');

var port = process.env.PORT || 80;
http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'application/json'});
  res.write('{ text : \'Hello\' }');

Accelerating Team Development in Microservices

The value of Azure Dev Spaces is not just deployment, but you can easily collaborate with multiple deployments !
Now let’s create sub dev space named “scott” using the following command. We assume that Scott runs this command on his working desktop (another desktop which I used for default dev spaces).
When Scott runs this command, he selects “default” (which is existing root dev space) as parent dev space. By doing this, Scott’s dev space is generated as child (sub) dev space of “default” dev space.

# select existing dev space controller
azds controller select --resource-group group01 --name cluster01
# create and select sub space named "scott"
azds space select --name scott

Dev space named “default/scott” is generated in AKS. And this dev space is selected (activated) as current dev space on Scott’s desktop.

Now let’s change test02’s code as follows and deploy using “azds up” on Scott’s desktop.

test02 (javascript)

var http = require('http');

var port = process.env.PORT || 80;
http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'application/json'});
  res.write('{ text : \'Hello. This is Scott\' }');

As you notice as follows, you can access this modified application using the public dns name with “scott.s” prefix.

For now, we’ve just generated 2 dev spaces (“default” and “default/scott”) and deployed another modified version of test02 in scott dev space.
The magic is from here !

Now let’s change “test01” code on default (parent) dev space and deploy using “azds up” again. As you can see, here we’ve just added HTTP header (“azds-route-as” header) for remote test02 API request.

test01 (javascript)

var http = require('http');
var request = require('request');

var port = process.env.PORT || 80;
http.createServer(function (req, res) {
    uri: 'http://test02',
    headers: {
      'azds-route-as': req.headers['azds-route-as']
  }, function (error, response, body) {
    res.end('api result: ' + body);

Now let’s access parent test01 application with “scott.s” prefix. Then you can find to see the result with modified test02 api as follows !

What’s going on under the hood ?

First, when you access test01 with “scott.s” prefix, the test01’s inbound proxy automatically adds header “azds-route-as : scott” in HTTP request. As I showed in my previous code, our test01 application calls test02 with “azds-route-as : scott” header.
When the outbound proxy finds “azds-route-as : scott” header in the request, it retargets the request with “scott.s” prefix in hostname, i.e, the scott’s version of test02 application.
This transformation is repeated through HTTP request call flows.

Note : If there’s no running scott’s version, the request is automatically redirected to parent’s hostname, and the previous code is adding the scott’s header.
As a result, you can insert your modified code into any level of tiers. For instance, you can also connect with : test01 “default” -> test02 “default” -> test03 “default/scott” -> test04 “default” -> …

(From : “Microsoft Build 2018 – Iteratively Develop Microservices with Speed on Kubernetes“)

As you saw above, you can debug only your modified code working with other completed components without installing other components and even without exposing your modified code to others ! (DNS with “scott.s” prefix might be only used by Scott.)

Note : For the other purpose of environments (user test, production, etc), it’s better to run other individual cluster (non-devspace cluster) and deploy your completed code separately.

IDE Integration

Azure Dev Spaces is also having the capabilities to integrate with Visual Studio or Visual Studio Code. With this integration (Azure Dev Spaces extension), you can quickly run the following tasks within IDE and can develop more faster.
(Here I don’t describe details about this integration, but please see the official tutorial.)

  • deploying (azds up) your application into the container with IDE command (incl. redeploying after your code is changed)
  • debugger attachment into the running code in remote container with IDE command

(From “Microsoft Build 2018 : Iteratively Develop Microservices with Speed on Kubernetes“)

Today the language integration is only supported for both node.js and .NET Core, but it will be expanded to other languages in the future. (See “Microsoft Build 2018 : Iteratively Develop Microservices with Speed on Kubernetes“.)


When your team has finished development, you can soon remove all the components with a few lines of command (see below). Now you can delete your AKS cluster itself.
(When you want to remove sub space “default/scott” before clean-up, run “azds space remove --name default/scott“.)

Note : If your controller remains with “failed” state (ProvisioningState) and cannot be removed, remove the resource group containing AKS cluster. (You can see the state with “azds controller list” command.)

# delete this release (incl. associated services, deployments, and ingress) in AKS cluster
azds down
# remove dev space controller
az aks remove-dev-spaces --resource-group group01 --name cluster01



Azure Dev Spaces (Quickstarts, Tutorials, How-to)

Microsoft Build 2018 – Iteratively Develop Microservices with Speed on Kubernetes


Categories: Uncategorized

Tagged as:

1 reply »

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s