Azure N-series VMs (with GPUs)

Azure now offers N-series VM’s with 1, 2 or 4 dedicated GPUs which can be utilised for GPU optimised tasks such as graphic rendering, video editing and parallel computing.

  • The NC VMs are targeted towards computing power, and the NVMs are targeted towards on demand graphical visualisation
  • The VMs are currently only available in some regions, like US east (Virginia)
  • The VMs are currently only available for some OSes, like Windows Server 2012 R2 and Windows Server 2016
  • The VMs are currently only available connected to an HDD
  • The drivers are not installed by default, but can be found here. Once they’re correctly installed, the card(s) will be visible in device manager and GPU-Z
  • GPU-Z currently has trouble reporting accurate utilisation, but nvidia-smi, usually found in C:\Program Files\NVIDIA Corporation\NVSMI\nvidia-smi.exe, offers a command line view of GPU utilisation:


  • The NC24 VM with 4 K80s is limited to 6 simultaneous video encoding processes

Azure GA announcement


The Valet Key cloud design pattern

A Valet Key is a special key that some cars have which has limited functionality i.e. it only opens the driver’s side door and starts the engine, and does not open the glove box.

In the cloud, an application can issue an equivalent key, limited in scope and time, in the response to a request. The client then uses this key to access some other resource directly.


  • Issuing a key directly to the client means the request can return sooner, freeing up resources to handle other requests. This is especially beneficial when the operation is heavy or long running and would tie up considerable resources e.g. media transfer. Storage and data transfer are generally cheaper than computation.
  • Keys can be issued with a convenient expiry time, allowing short bursts of communication to proceed with only the one initial server request.


  • Although the keys can have fine grained scope to follow the Principle of Least Privilege, any compromise does nonetheless give an attacker full access to the resource within the scope and time limit.
  • The potential attack surface is larger as it includes the resource itself, in addition to the issuing server and the key itself.
  • Direct oversight of the resource is often lost. For example, it might not be possible to limit the size of an uploaded file, or gather download statistics.

Azure example implementation

  • The upload file request hits the ASP.NET server, which does the lightweight setup of enabling CORS from the client browser, and retrieving a token from the blob storage.
  • The browser can then upload the file directly to the blob.

valey key

Azure Valet Key

Gatekeeper cloud design pattern

The gatekeeper cloud design pattern protects an application by placing all services behind a single facade, similar to a firewall.


  • All services and data are private and hidden behind a single public endpoint, which significantly reduces the attack surface.
  • Request validation and malicious communication rejection is implemented in a single place.
  • The backend services can be optimised and scaled to handle legitimate requests only.
  • If any breach does occur, the exposure is limited to the sensitive information on the gatekeeper itself, which should be kept to a minimum.


  • The gatekeeper is a single point of failure for the entire application, and must be appropriately managed for high availability and redundancy.
  • The gatekeeper may affect performance by increasing latency, increasing load and introducing a bottleneck.


Azure example implementation

  • Place all backend services in a private virtual network.
  • Place the web app endpoint in an App Service Environment which includes an Application Gateway, from which we can make use of the Web Application Firewall which blocks many common security vulnerabilities.


Python’s enumerate

enumerate(sequence, start=0)
  • Takes as input a sequence (string, unicode string, list, tuple, bytearray, buffer or xrange) or iterable, and an arbitrary start index
  • Returns an iterator which provides tuples containing the count and value
  • Useful to generate the index corresponding to each element:
for i, animal in enumerate(["cat", "dog", "mouse"], 1):
    print("Animal #{} is a {}".format(i, animal))
PEP 279 — The enumerate() built-in function
enumerate(sequence, start=0)

Covariance vs. Contravariance

Covariance and Contravariance are two dual concepts, which enable implicit type assignment for arrays, delegates and generic type arguments.

  • Covariance is when a type can be replaced by a less derived type
  • The out keyword on a type parameter denotes a covariant type e.g. IEnumerable<out T>
  • An IEnumerable<string> outputs a string, which can be assigned to an object reference, as a string is an object
  • Contravariance is when a type can be replaced by a more derived type
  • The in keyword on a type parameter denotes a contravariant type e.g. Action<in T>
  • An Action<object> takes an object as in input, so it will happily take a string reference, as a string is an object
Covariance and Contravariance (C# and Visual Basic)
IEnumerable<T> Interface
Action<T> Delegate

Rx ReplaySubject

  • ReplaySubject is a Subject with memory
  • It can have temporal or spacial memory:
    • Construct it with an int and it will have a buffer of that size
    • Constuct it with a TimeSpan and it will have a buffer of that duration
    • Construct it with both and it will have both
  • It’s main use is when publishes occur before subscriptions, and some history is required
  • ReplaySubject(1) can be used to pass in a dependency as IObservable<FooDependency>
    • Useful when the creation of FooDependency is potentially long running
    • And when useful work can be done without FooDependency (e.g. bring up a UI or load other modules
ReplaySubject<T> Class

Law of Demeter

  • aka The Principal of Least Knowledge
  • Give clients exactly what they asked for, not some object they can use to query what they want
  • Tenet of loose coupling
  • Classes only know about the neighbours, and don’t have to talk to strangers
  • Results in less brittle, more maintainable and adaptable code
  • But, quickly results in bloat, as each type/method in a chain needs to marshal values to/from their neighbours