Unhelpful helpers

Unhelpful helpers

In small organisations, everything is managed by a small group of people. There is no infrastructure team, nor is there a release manager. If you expect a project management office, forget it and the support team can consist of just one person. Essentially everyone can do anything and as software gets more complex these sorts of teams cannot be blamed for looking for short cuts.

When it comes to Azure it is not realistic to expect everyone to know all the details about all the services. Microsoft realise this because they are sprinkling things like helpers and advisers all over it. The one that has got my attention recently is the Azure SQL Adviser.

I have been using Azure SQL for a while now and the on the whole it just works. It looks and feels like any other SQL Server database but it just so happens that it is a running in the Cloud and some of the stuff we used to worry about such as backups and patching are now Microsoft’s problem. Even so, running and tuning a database is still complex and is a specialised skill, so a small general purpose team is thankful of any assistance they can get.

So, when customers are complaining about performance and the Azure SQL adviser is effectively flashing a big green button labelled “make the performance problems go away” that button is going to get pressed.

But wait…

Teams that are moving to DevOps are control freaks. They are creating sophisticated build and release pipelines and are trying to automate everything. In order to reduce down time things like database schema changes are closely planned and controlled using techniques like migrations. Those migrations are run as part of the release process automatically.

What is the impact of applying Azure SQL advisor recommendations immediately?

Let’s say that the adviser has applied an index on a database column used in a critical join. That change is applied immediately and all is good. Performance is improved. Customers stop complaining. Sometime later the development team are building a new feature that will be removing that column. This all works fine during development and testing but when the team try to deploy to Live, their database migrations fail. They are dropping a column that is used in an Index – an index they did not know about so there is no chance that it exists in other environments.

This can be quite a problem. Over time a team with a reliable release pipeline start to expect releases to just work and now they have a problem deploying to Live. They don’t know what to do. There is no plan for backing out or fixing forward the deployment.

The solution is quite simple. The team should look at the advisor as another source of work alongside new features and live issues. The development team should view the changes and incorporate them into their database release pipeline so it can be delivered into Live in a controlled and repeatable way. In some cases, the recommendation may relate to a critical performance problem so it becomes the highest priority. The question that the team needs to answer is how quickly this change can get into Live and is the existing process fast enough.

Advertisements

Learning from your Failures

Learning from your Failures

Despite your best endeavours problems will occur. Sometimes they will be big problems.
We work on complex systems which by their very nature are hard to predict. We are often lulled into a false sense of security that makes us think that we understand them only to be surprised when they fail spectacularly in an unexpected way.

Let me give you an example in terms of my cycling hobby.

Last week I was cycling back from work. Suddenly there was a loud bang and I immediately realised my rear wheel had a punctured. But WHY?

On examining the tyre I was expecting a simple inner tube failure, something that I was prepared for, but it was quickly obvious that the side wall of the tyre had split. But WHY?
Before continuing the investigation, I had to deal with the immediate problem. Fixing a split side wall is not something I could do by the roadside so I had to think about my immediate options. There weren’t many. There was a bike shop a couple of miles away but that would be a long walk and I would end up buying whatever they had just to get me home. Would they even be open? The other alternative was to ring my other half to be rescued. And this was what I chose.

I had accepted that the problem was real and I didn’t have many options. At this point I’m not looking for a perfect solution, I just wanted to recover the situation as quickly as possible. Being rescued looked like the best choice, there was little risk that it would make things worse and it was the scenario where I could be home and dry quickly.
Back to the investigation. I needed to know why I ended up in that situation so I could try to avoid it in the future. WHY did I split my tyre?

In my warm and dry garage, I could see that a build-up of grit on my brake block was rubbing the side wall of the tyre when the brakes were applied. But WHY did that cause a failure?

Well, the grit was only rubbing because a week or so earlier I had fitted new brake pads and on adjusting them I had them slightly too high on the wheel rim. This was not a problem when the pads were clean but when they were covered in road grime they rubbed the tyre. However, this should have not been enough for a complete failure. So WHY did the tyre fail?

When I examined the tyre and where it failed I could see other damage around the failure point that was not apparent elsewhere on the tyre. Casting my mind back I remembered having a puncture some months back where I had trapped the inner tube between the rim and tyre after hastily swapping them onto another set of wheels. When that puncture occurred, I had to ride for over a mile on the flat tyre because I wasn’t somewhere I could stop easily to fix it. Could that puncture and the damage caused by riding on the flat tyre be the root cause of a bigger problem some months later?

The point is that a number of things that are not a problem on their own, have the potential to cause bigger problems when they occur together. The only way you know that these things can cause a problem is to experience it. What I have done above is perform a simple root cause analysis on the problem to understand why it occurred. Many organisations miss this when they have an IT incident. They are relieved that the incident has been resolved and frankly don’t want to think about it again.

Unfortunately for these organisations thinking about the problem is the best way to avoid it happening again. Tracing the chain of events helps identify preventative steps and different ways to monitor and maintain your system to ensure that it is not on its way to another failure.

For me it is ensuring that I clean grime off my brake pads and examine my tyres after any punctures. For your IT systems it might be improving code review processes, doing more thorough testing or adding proactive monitoring. Mistakes and problems will happen. Obviously, you want to resolve the situation quickly and calmly but that isn’t the end. You can learn from problems as they help you understand how your systems really work and to improve them over time so problems are less likely to occur – well at least the ones you know about.

The impact of risk

The impact of risk

Oh no, a post about risk. Yes, I know this post might seem boring from the title, but bear with me. Here is a picture of cat to keep you going.

sad-cat
Right are you refreshed and invigorated, ready for a roller coaster ride of risk. Lets get started….

The normal approach to managing risk it is identify it, classify it and then provide some form of mitigation to stop it turning into an issue. Architecture is often defined as managing technical risk. When there are a lot of risks and/or their impact is high there is tendency to do work to mitigate them early. This why you might see lots of upfront design work or project planning. It is an attempt to make the uncertain, certain. It is an attempt to avoid the risk occurring because the cost of it’s impact is too high to bear.

Some examples of risk are

  1. Unreliable architecture meaning a server failure causes an outage that results in loss of revenue
  2. Changing requirements late in the day causes cost overruns or implement delays

OK, you have done well getting this far. Here is another picture of a cat to keep your energy up.

happy-cat

Still here, great!

If you could arrange things so that the impact of the risk was next to nothing, would you approach risk management in the same way?

If the impact of the risk is nothing you change from a mindset of reducing risk to accepting it. Bad things will happen but you have systems and tools in place that mean you are not affected. But how might you do this.

  • Working in small batches means that changes are smaller and the impact of that change not realising it’s intended value is low.
  • Reducing the lead time between you having an idea and testing it with real customers means you can regularly deliver. You can get feedback from your customers quickly and change course as necessary. There is less chance  of investing time and effort building something nobody wants.
  • Building a reliable and repeatable release pipeline means that the transaction cost for getting the next version of your software in front of customers is lower. Automating this also eliminated the chance of human error.
  • Regularly introducing failure into your Live environment and ensuring that your systems and processes can cope means that when something fails for real it is routine and customers don’t even notice.

Any of this sound familiar?

I have kept this short and to the point. Here is a picture of some beer as a reward. Hopefully there be some real beer nearby.

beer

AngularJS, Protractor and TeamCity

AngularJS, Protractor and TeamCity

The go to solution for creating automated end to end tests when building AngularJS applications is Protractor. In this post, I am not going to explain how to write tests using Protractor. Instead I’m going to cover some of the things I discovered when trying to integrate a suite of Protractor tests into a TeamCity based CI/CD pipeline.

Protractor Basics

The following article cover the basics of Protractor. This formed the basic understanding that I needed to work out where all the moving parts were and therefore work out how best to integrate into a CI/CD pipeline.

http://www.protractortest.org/#/

Protractor is a node module so I’ll assume that you have nodejs installed on your development machine. Once you have that you need to get protractor using

npm install protractor -g

Protractor relies on drivers for the various web browsers. It will execute your E2E test scenarios directly in the browser so this bit is important. The drivers in turn use Selenium, a common testing framework.

That is a lot of moving parts I hear you say. Luckily it is relatively simple to get this up and running. Once you have Protractor ensure you have all the latest webdriver bits

webdriver-manager update

This ensures that all the latest webdriver and selenium versions are downloaded and configured correctly. The final step is to start everything up. You can do that with

webdriver-manager start

You may hit your first hurdle at this point. Selenium is a Java based solution and as such requires Java to be installed on your development machine. So if you have a problem at this stage go off to Oracle’s site, download Java and install it. You’ll need the latest JDK.

In order to continue you’ll need an example test spec, spec.js. I used this one which is part of the Protractor tutorial.

describe('Protractor Demo App', function() {
    var firstNumber = element(by.model('first'));
    var secondNumber = element(by.model('second'));
    var goButton = element(by.id('gobutton'));
    var latestResult = element(by.binding('latest'));
    var history = element.all(by.repeater('result in memory'));

    function add(a, b) {
         firstNumber.sendKeys(a);
         secondNumber.sendKeys(b);
         goButton.click();
     }

     beforeEach(function() {
         browser.get('http://juliemr.github.io/protractor-demo/');
     });

     it('should have a history', function() {
         add(1, 2);
         add(3, 4);

         expect(history.count()).toEqual(2);

         add(5, 6);

         expect(history.count()).toEqual(3); // This is wrong!
     });
});

You also need a configuration file, conf.js. This is the one used in the tutorial.

exports.config = {
    framework: 'jasmine',
    seleniumAddress: 'http://localhost:4444/wd/hub',
    specs: ['spec.js']
}

To run this selenium must be running locally exposing an endpoint on port 4444. But if you remove the line starting seleniumAddress… guess what… an instance is started for you automatically. With the modified conf.js file you should be able to run your test with the following command.

protractor conf.js

This should work if

  1. You have installed protractor globally
  2. You have ensured that the web drivers and selenium are updated.
  3. And all the versions of protractor, your browser and its particular web driver are all aligned

When I was trying to make an old implementation of a Protractor test suite CI/CD ready. It turned out that it was using an old version of protractor so updating the web drivers downloaded old versions. The machine I was testing this on happened to have an old version of chrome so all seemed to work. This subsequently failed when other people tried because they were using the latest versions of chrome. An upgrade to protractor fixed that but then caused problems for people stuck on older versions.

You might think why are people on old versions of chrome? Blame centralised management of software in big organisations”

So the lesson I learned here was to always start with the latest versions, even when picking up older implementations. The version of the framework and the browser matter.

Making this CI/CD Friendlier

With the CI/CD pipeline I was working with I didn’t want to have an instance of the webdrivers and Selenium running constantly. Neither did I want to have to manually start up the web driver on each build. As Gulp was being used for other purposes I happened on gulp-angular-protractor which provides a wrapper for all of these things. Effectively it updates the webdrivers and starts them for you and then clears them down when you have finished. This meant that I could have a single gulp task that executed my test suite.

A good build is self-contained and minimises dependencies on what is installed on the build server. The packages I need are installed locally. In order to create a package.json file install the required packaged like this

npm install protractor -save-dev
npm install gulp-angular-protractor -save-dev
npm install gulp -save-dev

Although the final step installs gulp locally it also needs to be installed globally too. I have no idea why but it does. You can then create a Gulp file like this one

let gulp = require("gulp");
let gulpProtractorAngular = require("gulp-angular-protractor");

gulp.task("runtests", callback => {
    gulp
        .src(["myspec.js"])
        .pipe(gulpProtractorAngular({
            configFile: "protractor.conf.js",
            debug: false,
            autoStartStopServer: true
        }))
        .on("error", e => {
            console.log(e);
        })
        .on("end", callback);
});

Lets break this down.

First, I’m bringing in gulp and gulp-angular-protractor so I can use them later. Next, I’m creating a gulp task called “runtest”. The rest basically says execute conf.js with spec.js as the test spec file.

As this point you have a basic spec and conf file that can be executed from a Gulp task. This is enough to start building some real test specs and checking them out. Come back next time to see what you need to do to integrate this properly with TeamCity.

Build Once Deploy Anywhere – Configuring the Deployment Side

Build Once Deploy Anywhere – Configuring the Deployment Side

My last few posts have covered my experiences of creating a build once deploy anywhere release pipeline for Azure Cloud Services using Team City and Octopus Deploy. My first post covered some of the various deploy/release models and why you might want to try a build once deploy anywhere model. My second post went into a bit more detail about how I went about packaging my solution in order for it to be consumed by Octopus Deploy. This post covers what I found when configuring Octopus Deploy to deploy these packages.

If you are interesting in learning more about Octopus Deploy I can recommend this podcast from Scott Hanselman. Orchestrating and automating deployments with Octopus Deploy and Damian Brady.

The first thing to mention is that a lot of the hurdles I encountered and lessons I learnt were due to the use of Azure Cloud Services. Whilst the discussion that follows includes a lot of details that are specific to this type of deployment, I hope that there are commonalities that are useful in many different situations.

Deploying a Cloud Service

Deploying a Cloud Service in Octopus Deploy should be straight forwards. After all there is an out of the box deployment step designed for this very purpose. The thing you have to be aware of is how Octopus Deploy applies configuration transforms and setting changes to an already packaged Azure deployment. Essentially in unpacks it, apply transformations to the files and repackages it. So simple so far.

The first thing I tried was getting the step to swap out the packaged ServiceConfiguration.cscfg file with the environment specific one. This is something that is advertised that the deployment step will do. However ,this became the first obstacle to clear.

Whilst you can add rules to tell Octopus Deploy how to transform files in your package by enabling the configuration transforms feature this does not apply to the ServiceConfiguration.cscfg file by default. In fact, it is not really doing a transform. Instead it is swapping the *.cscfg that the build process places in the package with the one you actually want for the environment. So Octopus Deploy looks in the root of the package for a file called ServiceConfiguration.{ENV}.cscfg where ENV is the name of the environment that OD is deploying to, or one called ServiceConfiguration.Cloud.cscfg. If it does not find one, the deployment doesn’t work.

deploy1

So this is the start of the changes needed in the packaging on the build side. Originally I had

<file src="..\MyWebRole\ServiceConfiguration.*.cscfg"
target="ServiceConfiguration" />

Instead I needed

<file src="..\MyWebRole\ServiceConfiguration.*.cscfg"
target="" />

The next problem I had was that my environments in Octopus Deploy did not match the names of my Azure target profiles. So even when it was getting the files on the root of the package the deployment still failed. The only way I could see around this was to ensure these matched. There may be ways around this but I couldn’t find any in the time I had. The next stage involved the transformation of the web.config file. This proved to be the biggest challenge.

Up until now all of the files we were swapping or transforming lived outside of the Azure Cloud Service package. This time the web.config file could be found deep inside a folder structure that is defined by the Azure package itself. Within the outer NuGet package I had copied the transform files into a folder called WebConfigTransforms. Octopus Deploy could not handle this structure automatically. This was hard to find because the deployment was not failing. It is only a missing entry in a log that acts as a clue. OD allows you to define custom transformation rules. What this amount to are expressions that describe where the configuration file is relative to the transform file. In order to this I would have had to understand the file structure that results from OD unpacking the Azure package. Whilst it was possible to discover this it didn’t feel right to me to bake this folder structure into the deployment step. What if this folder structure was to change? Unlikely, but it might.

The configuration transform feature screen hints that you can do something like this

Web.BETA.config => Web.config

However this doesn’t work either. The deployment continues with only the following in the log to tell you something has gone wrong.

The transform pattern Web.BETA.config =&gt; Web.config was not performed due to a missing file or overlapping rule

It was Googling this error that finally surfaced this post from the Octopus Deploy help forum.

http://help.octopusdeploy.com/discussions/questions/5449-cloudservice-nuget-package-structure-for-config-files

This post indicated that is simplest solution was include the transforms in the Azure package by setting the Web.Config’s ‘Copy to Output Directory’ value to ‘Copy always’.

deploy2

Doing this puts the web.config and all of its transforms into the same folder. The Configure Transform step could now apply the transforms automatically. Time to remove the webconfig transform files from the *.nuspec file as there was no longer a need to add them to the NuGet package explicitly.

deploy3

The next stage was to apply the necessary transforms to the ServiceDefinition.csdef file. This can be achieved with the Configure Transforms feature but this required a tiny bit of work. The Configure Transform step doesn’t deal with this type of file automatically so you need a custom transform rule. One like this one.

ServiceDefinitionProfiles\ServiceDefinition.#{Octopus.Environment.Name}.config
=&gt; ServiceDefinition.csdef

.#{Octopus.Environment.Name} is the name of a system variable that gives you the name of the environment you are deploying to.

At this point I had a functioning deployment with all the replacements and transformations working. However, there was one other aspect of my deployment that is worth discussing. This element highlights something that you’ll commonly do as part of your release cycle that you might need to think differently about when working in a Build Once and Deploy Anywhere model. That aspect is running database migrations.

Database Migration

As discussed previously the build step is environment agnostic. Migrations on the other hand are applied to a specific environment. Therefore in a build once deploy anywhere model it does not make sense to have the build step run migrations.

In order for the deployment step to run migrations a number of things that must be in place

  • The assemblies containing the migrations must be packaged and accessible to the deployment server
  • Any scripts used to run the database migrations must be available to the deployment server
  • Any tools required to run the database migrations must be available to the deployment server

If you read the second post in this series you might realise that the answer lies in packaging. In order to make everything available to the deployment server they must be added to the NuGet package.

But first a comment about how Octopus Deploy handles deployment scripts. In the deployment process there are four stages

  • Pre Deploy
  • Deploy
  • Post Deploy
  • Deploy Failed

If the NuGet package contains powershell scripts called PreDeploy.ps1, Deploy.ps1, PostDeploy.ps1 & DeployFailed.ps1 on the root of the package, Octopus Deploy will automatically run them at the correct stage. This help article explains it in more detail. In order to have Octopus Deploy run a migration script after a success deployment of a Cloud Service, add the migration script to the root of the package and call it PostDeploy.ps1.

Now the script is not the end of the story. You’ll also need the Migration assemblies and if you are using something like FluentMigrator you’ll need that too. I ensured all of this was in the package. I don’t rely on the tool being on the deployment server in a specific location. If you to that you are coupling the script and server configuration together. You may as well hard code the script in the deployment project configuration. If you want the script to be part of the deployment package it should be stand alone. The tooling should be packaged in a known location and the script can refer to the tool in relative terms.

<!-- Package deployment script - Must be on the root -->
<file src="DeployScripts\Migrations\*.*" target="" />

<!-- Add migration DLLs in the package so they are available on the Deploy Server -->
<file src="Migrations\bin\$ConfigurationName$\Migrations.dll" target="migrationdlls" />

<!-- Bring across the Migration Tool to ensure that we can run the migration -->
<file src="packages\FluentMigrator.Tools.1.6.0\tools\AnyCPU\40\*.*" target="migrationtool" />

The powershell script itself has a line like this in it

$migrationExePath = (join-path $currentDirectory "migrationtool\Migrate.exe")

This is what it took to create a working release pipeline. I have simplified or skipped over things to keep these posts brief but they give a flavour of what the typical pain points are. I hope you find them useful.

Build Once Deploy Anywhere – Configuring the Build Side

Build Once Deploy Anywhere – Configuring the Build Side

In my last post I discussed various build and deployment models and in particular build once and deploy anywhere. Rather than leaving it there I thought I should try to make this more real by drawing on some experience of actually doing this for real.

I was using Teamcity for the build part of the model and Octopus Deploy for deployment. But this isn’t a post about how to use these technologies. Instead I hope to highlight some of the things you need to think about when implementing this model. My intention is that this is applicable to any build and deployment technology but having a concrete example is a useful reference point.

It is important to understand what you want before configuring the technology to work that way. However, you should not forget to consider how the technology wants you to work.

For example, using Octopus Deploy did end up influencing what the end result looked like. Octopus Deploy works through conventions – if you use them then the product does much of the heavy lifting without much help. If you don’t you are likely to have your work cut out. The very fact that you are using conventions that Octopus Deploy expects has impacts that ripple out to your build server and even your project or solution structure.

In this setup the Build server (Teamcity in my case) was responsible for the following

  • Getting the code from source control
  • Compiling the code
  • Running unit tests
  • Packaging the solution
  • Kicking off an automated release into a Dev/Test environment

The package is the key interface between the build and deployment server. As an interface it is the coupling point – it is the place where the build has to understand what the deployment server is expecting.

Environment configuration is the hot spot for Build Once Deploy anywhere models. Here the build cannot be relied up on to apply environment specific settings.

Once build servers would be configured to compile a build configuration in a visual studio solution. This mapped to a particular environment and the act of compiling the solution would ensure that all necessary configuration transforms were applied. The preconfigured solution was packaged and then dropped without change into an environment. The primary drawback of this was that the solution and the build server needed to know exactly how many environments you had. To some people this might not be an issue but to others this represents an unnecessary overhead.

Coming from a developer background I want all my configuration settings for all environments sitting alongside my code in my source control system. If I came from an infrastructure background maybe, I’d think differently. Maybe I’d be happy having all the configuration settings available to the deployment server in a different way, separate from the source code. However, I’m not, so the primary challenge I have when setting up a build once deploy anywhere release pipeline is how to get all the configuration settings needed from source control to the deployment stage. This is a question of how to package the solution.

Octopus Deploy wants NuGet packages, so the build process has to create and publish them. Depending on what you are deploying you may be creating a NuGet package of a package – for example if working with Azure Cloud services they need to be packaged first and then placed in a NuGet wrapper. When you look at a cloud service package there are a number of configuration points. Firstly, there is the web and worker roles themselves so there will be at least one app or web.config file lying around. Next comes the service configuration and the service definition files.

When working with a build once deploy anywhere model the first thing to remember is that it doesn’t really matter which configuration you apply to the solution at the build stage. Okay you might need to consider the configuration settings required to run your test suite but these settings are not going deployed or at least used in any target environment. Instead the deployment stage will transform or replace your configuration as necessary for the particular environment it is deploying to. Or in other words the build stage is environment agnostic – it is completely unaware of which environments you have and it is not impacted if you were to add or even remove environments.

nuget12

To create NuGet packages you need a *.nuspec files. This is an XML based manifest for the package describing all the files necessary to create it. The next thing you need is a tool to interpret the *.nuspec file and to turn it into a package. There are various tools that can do this. I chose OctoPack as I was targeting Octopus Deploy. It seemed the obvious choice. Octopack itself is a Nuget package so using it is as simple as adding it to the projects in your solution that you want to package, through the NuGet package manager, and running a command such as:

msbuild MySolution.sln /t:Build /p:RunOctoPack=true

Now we know how to create a package but how is that going to solve the problem of getting all the necessary configuration to the deployment server? The key is what we put in the *.nuspec file.

In the case of an Azure cloud service web role we need the web.config and environments specific transforms, the service definition file and its transforms and environment specific Service Configuration files. This can be achieved like this.

<file src="..\MyWebRole\bin\$ConfigurationName$\app.publish\*.*" 
       target="" />

<file src="web.*.config" target="WebConfigTransforms" /> 

<file src="..\MyWebRole\ServiceConfiguration.*.cscfg" 
        target="ServiceConfiguration" />

<file src="..\MyWebRole\bin\$ConfigurationName$\ServiceDefinition.csdef" 
        target="" />
<file src="..\MyWebRole\ServiceDefinitionProfiles\ServiceDefinition.*.config" 
        target="ServiceDefinitionTransforms" />

Here I’m doing the following

  1. Packaging the output of the Cloud Service
  2. Adding the Web.config transforms into a folder called “webconfigtransforms” in the package
  3. Adding the environment specific ServiceConfiguration.cscfg files into a folder called “ServiceConfiguration” in the package
  4. Adding the primary ServiceDefinition file to the root of the package
  5. Adding transforms for the ServiceDefinition into a folder called “ServiceDefinitionTransforms” in the package

It should be noted that the web.config file is already part of the web role and therefore it is automatically deployed in the Azure cloud package. The first line of the snippet above adds this package. The result is the *.cspkg file in the Nuget package below. This is just a zip file so you can explore its contents in your favourite zip tool.

nuget1

This represents my first attempt of packaging my solution. In the next post I’ll walkthrough what I needed to do on the deployment side to consume this package and as it turned out, what I needed to change in the packaging step to align with what Octopus Deploy wanted.

Getting lost in Azure

Getting lost in Azure

When you start working with Azure, you start with one subscription. It tends to be private for your own use. All is good.

Over time you gain experience working with Azure and perhaps you start working with a client. They give you access to their corporate subscription. Now you have to remember to switch between subscriptions and this can become a burden.

In time not only have you amassed more clients but they’ll also be putting their Azure projects into production. You might have access to these production subscriptions. Now the impact of deploying a change to the wrong place becomes larger and mistakes become inevitable.

All that power sits behind a single Windows Live account. Single Sign On is useful in many situations but maybe not in this case!

In Azure your Live account is added to a directory. Directories can relate to zero, one or more subscriptions. In both the old and new Azure portals when you select either the subscriptions option or switch between accounts what you are actually doing is switching directories. You are not switching subscriptions directly. As far as I know a subscription cannot be related to multiple directories.

azure1
Selecting a directory – Old Portal
azure2
Selecting a directory – Old Portal

When you switch directories and therefore subscriptions you want to know at a glance which one you are in. The old portal doesn’t give many options here, so as most of us have switched to the new portal the rest of this post will focus there.

The first option is to change the theme for each directory. You can do this by using the Settings option on the top right of the screen. However, you are limited to four options and they are quite similar. Changing the theme is the first step of customising the portal experience. I recommend that you configure the portal dashboard for each directory to reflect its purpose. That should give you a visual clue as to whether you have the correct directory selected.

It seems as those the Azure portal remembers the directory and subscription you were last using and that is the one it starts with when opening up the portal next time. That may or may not be useful. I have noticed though that you can pass the name of a directory as part of the query string to force the portal to start in a given directory.

For example

https://portal.azure.com/signin/index/{directoryName}

With this knowledge you can create a group of shortcuts with descriptive names to ensure you are always in the correct place.

But perhaps the simplest thing to do is add a markdown widget to the dashboard. This can contain anything but it can be used to clearly identify where you are working.

That is all well and good if you are using the portal. But what happens if you are staring into the blue abyss that is the PowerShell command prompt. How do you ensure that you are working in the right place then?

ps
The dark blue abyss…

This requires a bit more discipline and care. It is quite easy to made mistakes. The classic Azure model had the concept of a default subscription. This article explains how that works in PowerShell. However, this is not so straight forwards with the newer Resource Manager model. You’d like to think it was just a case of adding RM to the appropriate parts of the command so

 Get-AzureSubscription

Becomes

Get-AzureRmSubscription

Whilst this works for some command the results are not exactly the same.

If you are using the RM model you use the following command to login

Login-AzureRmAccount

This gives you access to all your subscriptions. You can see them all with

Get-AzureRmSubscription

This gives you the name, subscriptionId and tenant Id. Many subscriptions can exist in a single tenant. You then select a subscription with

Select-AzureRmSubscription -SubscriptionID $subscriptionId

So you can select the subscription but how do you find out what is currently selected. The following command comes to your assistance

(Get-AzureRmContext).Subscription

For a belt and braces approach you can combine these commands at the top of your scripts to ensure that you only ever work on the intended subscription.  A small price to paid for stress free Azure scripting.