Microsoft officially announce support end dates for ADAL and the Azure AD Graph API

I still have some old projects I’ve worked on in my own personal code repository, which still utilise ADAL and the Azure AD Graph API. Without question, there most definitely software solutions on the market which still use the the same nuget packages or endpoints via REST API’s to authenticate users and pull back/update user profile information in a multitude of ways as required by the application.

Just incase you missed this, Microsoft have now provided official guidance on the end of support timelines for both the Active Directory Authentication Library and the Azure Active Directory Graph API.

I’ve been using the Microsoft Authentication Library and MS Graph for a few years now, as the guidance from Microsoft has always been to urge developers to use MSAL and MS Graph for all new development projects. So, now it’s official and time to move over and start migrating over and work with the Microsoft Identity Platform v2.0 endpoint and v2.0 tokens.

Blazor Apps: The Login Display – Part 2

This is part two of two, on Blazor Apps and the Login Display.

In my first post I discussed some basics around the LoginDisplay Razor component in Blazor server-side applications. In this post I will expand out the sample, to link the user display name value to navigate to another Razor component as a page to call MS Graph and return a basic set of user properties.

Updating your Blazor App Dependencies

You will need to update your application dependencies and introduce a new service, in this case a TokenProvider, to return the access token and refresh token, with additional scopes to call MS Graph. For simplicity of this article, this is well defined in the following article already by Microsoft.

ASP.NET Core Blazor Server additional security scenarios

MS Graph Client

Whilst you can build your own HTTP client to call the MS Graph REST APIs, Microsoft provide the Graph Client library for .Net, so in my sample I installed the nuget package in my project.

Azure AD Permissions

I already have the Azure AD permissions in place for the application to read user profiles in the tenant, but I’ve provided a sample below.

New UserProfile.cs Class

A new class is created for each profile property I was interested in displaying on the profile page. The code for the class is below. For simplicity, the types are all strings.

namespace BlazorProfile.Data
{
    public class UserProfile
    {
        public string ObjectId { get; set; }
        public string DisplayName { get; set; }
        public string Office { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string UPN  { get; set; }
        public string JobTitle { get; set; }
        public string Department { get; set; }
        public string MobilePhone { get; set; }
        public string CompanyName { get; set; }
        public string EmployeeId { get; set; }
    }
}

New LCProfile Component

I then created a new Razor page “LCProfile” to host the code required to utilise the TokenProvider service. The code for the component is below.

@page "/lcprofile"
@using BlazorProfile.Data
@inject AuthenticationStateProvider AuthenticationStateProvider
@using Microsoft.Identity.Client
@inject Microsoft.Extensions.Configuration.IConfiguration config
@using Microsoft.Graph
@using Microsoft.AspNetCore.Components.Authorization
@using System.Net.Http.Headers
@using Microsoft.AspNetCore.Http
@inject IHttpContextAccessor httpContextAccessor
@using BlazorProfile.Auth
@inject TokenProvider TokenProvider

<AuthorizeView>
    <Authorized>
        <h3>Profile</h3>
        <table class="table" width="500px">
            <tr>
                <td>First Name: @prof.FirstName</td>
            </tr>
            <tr>
                <td>Last Name: @prof.LastName</td>
            </tr>
            <tr>
                <td>ObjectId: @prof.ObjectId</td>
            </tr>
            <tr>
                <td>Display Name: @prof.DisplayName</td>
            </tr>
            <tr>
                <td>Company: @prof.CompanyName</td>
            </tr>
            <tr>
                <td>Job Title: @prof.JobTitle</td>
            </tr>
            <tr>
                <td>Department: @prof.Department</td>
            </tr>
            <tr>
                <td>Office: @prof.Office</td>
            </tr>
            <tr>
                <td>UPN: @prof.UPN</td>
            </tr>
            <tr>
                <td>Office Phone: @prof.MobilePhone</td>
            </tr>
        </table>
@ErrorMessage
</Authorized>
        <NotAuthorized>
            You have not authenticated!
        </NotAuthorized>
    </AuthorizeView>

@code {

        private string ErrorMessage;

        private UserProfile prof = new UserProfile();

        protected override async Task OnInitializedAsync()
        {
                ErrorMessage = "No exceptions on page load";
            try
            {

                var accesstoken = TokenProvider.AccessToken;

                var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
                var authenticateduser = authState.User.Claims.First(c => c.Type == "preferred_username");




                var graphClient = new GraphServiceClient(
                new DelegateAuthenticationProvider(requestMessage =>
                {
                    requestMessage.Headers.Authorization =
                        new AuthenticationHeaderValue("bearer", accesstoken);
                    return Task.FromResult(0);
                }));


                User graphuser = await graphClient.Users[authenticateduser.Value]
                   .Request()
                   .Select(u => new
                   {
                       u.GivenName,
                       u.Surname,
                       u.Id,
                       u.UserPrincipalName,
                       u.OfficeLocation,
                       u.Department,
                       u.JobTitle,
                       u.MobilePhone,
                       u.DisplayName,
                       u.EmployeeId,
                       u.CompanyName,
                       u.City
                   })
           .GetAsync();

                prof.FirstName = graphuser.GivenName;
                prof.LastName = graphuser.Surname;
                prof.ObjectId = graphuser.Id;
                prof.UPN = graphuser.UserPrincipalName;
                prof.Office = graphuser.OfficeLocation;
                prof.Department = graphuser.Department;
                prof.JobTitle = graphuser.JobTitle;
                prof.MobilePhone = graphuser.MobilePhone;
                prof.DisplayName = graphuser.DisplayName;
                prof.EmployeeId = graphuser.EmployeeId;
                prof.CompanyName = graphuser.CompanyName;

            }
            catch (Exception e)
            {
                //throw new Exception (e.Message);
                ErrorMessage = e.Message;
            }
        }
    }

The TokenProvider is injected into the component and then referenced in the GraphClient. I also use the AuthenticationStateProvider to pull back the users principal name, in order to query MS Graph for the users Azure AD profile data.

Since the default users profile data is limited, an explicit selection for the properties in the user profile are selected and returned as part of the request. The Razor component should contain an authorised view.

Note: This is sample code, so you should check for Nulls in your own implementation. In fact, you would want to ensure that you check each property and likely store the values i.e. in a container that can be then referenced by the application. Typically, you could implement the scope offline_access for the application to retrieve refresh tokens as this is explicitly required for the v2.0 token endpoint i.e. you don’t want your application to fail based on the fact it doesn’t have the necessary structure to utilise refresh tokens to request new access tokens, otherwise you will end up receiving the an error similar to the one below.

Kungfu Developer 
Profile 
First Name: 
Last Name: 
Objectld: 
Display Name: 
Company: 
Job Title: 
Department: 
Office: 
UPN: 
Office Phone: 
Log out 
About 
Code: InvalidAuthenticationToken Message: Access token has expired. Inner error: AdditionalData: date: request-id: 72849096-54fb-4199-9f17- 
d6c6a7e6bc25 ClientRequestld: 72849096-54fb-4199-9f17-d6c6a7e6bc25

Updating the LoginDisplay Razor Component

For this sample, I’ve simply updated the component to add <a href tag> around the @UserName property to access the new LCprofile Razor Component.

@inject AuthenticationStateProvider AuthNStateProvider

<AuthorizeView>
    <Authorized>
        <a href="/lcprofile" >@UserName</a>
        <a href="AzureAD/Account/SignOut">Log out</a>
    </Authorized>
    <NotAuthorized>
        <a href="AzureAD/Account/SignIn">Log in</a>
    </NotAuthorized>
</AuthorizeView>

The Result

When the user name is clicked in the header, the user navigates to the lcprofile razor component and the profile properties are displayed .

This reminds me of the days when I developed custom controls for SharePoint several years ago, for users to edit their own profiles.

This ends the sample on the update to the LoginDisplay component in Blazor server-side applications.

Blazor Apps: The Login Display

When you first start to develop Blazor sever-side web applications and for this topic, integrate identity into the application with Azure AD, one of the first things I immediately change in the template is the login display on the top header bar. You’ll notice that most .Net web applications always display the HttpContext User.Identity.Name, essentially a property of the IPrincipal object for the current signed in user. The implementation in Blazor server-side apps is found in the Shared\LoginDisplay.razor component in the project.

The LoginDisplay component is referenced in the MainLayout.razor component.

The easiest way to change the behavior and ideally display the users full name, is to display the “name” claim in the LoginDisplay.razor component from the users claims that are represented from the id_token, which effectively forms the basis for the users session in terms of the security context. This of course excludes any roles, unless you have injected any other role claims from Azure AD or as part of the OIDC flow. Alternatively, the whole user context can be derived within the application itself as required from a variety of sources e.g. roles or the applications internal storage mechanisms.

Updating the Login Display Component

One of the simplest ways to update the display name is to update the LoginDisplay.razor component directly. Information in the security context, within an authorised view, is readily accessible. I make a simple change to pull out the “name” claim from the identity by injecting the AuthenticationStateProvider in the code sample below, then reference the value in @UserName.

@inject AuthenticationStateProvider AuthNStateProvider

<AuthorizeView>
    <Authorized>
        @UserName
        <a href="AzureAD/Account/SignOut">Log out</a>
    </Authorized>
    <NotAuthorized>
        <a href="AzureAD/Account/SignIn">Log in</a>
    </NotAuthorized>
</AuthorizeView>

@code {

    public string UserName { get; set; }

    protected override async Task OnInitializedAsync()
    {
        try
        {
            var authState = await AuthNStateProvider.GetAuthenticationStateAsync();
            var user = authState.User;

            if (authState.User.Identity != null)
            {
                UserName = authState.User.Claims.First(c => c.Type == "name").Value;
            }
        }
        catch
        {
            UserName = "Exception:User display name not set!";
        }
    }
}

Then the signed in users display name is then added to the header.

In my next post I will show how this simple implementation can be expanded to include other pieces of information from the users Azure AD profile.

AADSTS53003 – BlockedByConditionalAccess

Recently I’ve been troubleshooting conditional access policy errors in relation to applications failing to allow users to login to specific applications. Conditional Access Policies (CAPs), are at the heart of identity security for Azure at present, to manage access to your applications with various conditions like where the user is logging in from, defining trusted sites and setting different access controls e.g. MFA.

One specific issue I have been troubleshooting is an error code from the Microsoft Identity Platform: AADSTS53003. A user was able to login from one specific site without any issues, but from another location the user received this application error, which was identified in the backend logs of the application.

After reviewing the Azure AD Sign-in logs in the tenant, there was nothing specific showing what this error related to, when sign-in logs were checked against the application itself. There wasn’t much available in terms of troubleshooting this error apart from backend logs, so it was time to understand the user flow to determine why one physical site the user simply could not sign in at all, but at other sites everything was fine. The trusted site was valid for the application in the CAPs, so this made the troubleshooting process a little more challenging.

Back to the drawing board

After understanding where the application was failing, I developed a ASP.Net Core Blazor web application to start troubleshooting this issue in a completely separate environment. Knowing the application was trying to call MS Graph on-behalf-of the user, which then failed, it was an easy setup to recreate in a Blazor server-side application. I used the MS Graph Client and pulled across some basic profile properties for a user in the test tenant, with an on-behalf-of flow to display the results in a basic table.

As this was a application for debugging purposes, I also added a page element, to include any errors on the page component to display any code errors. In the above screen shot, no exceptions were found. Now I had a basis to start to troubleshoot the issues.

I setup my conditional access polices in a similar manner to the production Azure AD tenant to block access from untrusted sites.

I had setup a single policy, with a single test user and tested the policy based on location. A simple setup where I had my development office location and a VM in Azure with a public IP address, which was trusted as this was an exclusion in this case.

I setup a second policy to block access to Office 365, as the production application also had API permissions to access Office 365 and also enforced MFA for the user.

Testing

Now for the test. The user accessed the application from a trusted location, but this resulted in a successful page load, with MFA as applied in the CAPs. At this point my application was only calling Microsoft Graph, just like the production application. I wasn’t concerned with Office 365 APIs at this time.

I asked the user to sign into login.microsoftonline.com, as we all know this is the Microsoft Identity Platform endpoint for all user, device and application access, which contains all the components we need to authenticate with Azure AD, and of course where we receive the AADSTS53003 error as part of the application access token request flow. At this point the user received the following error, after entering their password, even though MFA was enforced.

This was somewhat confusing as the user could sign in with MFA into the application, with MFA, but accessing login.microsoftonline.com, to sign into the users Azure AD tenant actually failed with the above error, without MFA.

The Cause

A CAP was which blocked Office 365 from untrusted locations did not have the users location trusted IP address assigned for exclusion of the policy. Well that was an easy fix, but the the application that had issues signing the user in from another location, other than their home location, failed to provide them access with the AADSTS53003 error, when it call MS Graph. What comes next?

Re-creating the behavior

I wanted to re-create the behavior in my test Blazor application, so I determined that the error was not to do with the direct relationship with MS Graph, and started to add some scopes for SharePoint Online.

I then launched the application in Visual Studio, and hey presto!! the error was re-produced.

Why did this occur?

I determined that the error was not to do with the direct relationship with MS Graph, but the fact when the application was calling MS Graph, on-behalf-of the user, requesting an access token for the MS Graph resource, it was the fact the application had scopes assigned to access Office 365 API’s in it’s manifest. So this error was then simple to re-create, the Office 365 block policy required the users site to be trusted as part of an exclusion, so the application would not be blocked from requesting an access token for the MS Graph resource.

Hopefully, this post will help someone troubleshoot a similar error.

I launched Cloud Release on Google Play

On the 8th of November, I submitted an Android app on Google Play named Cloud Release. Google published the app to the store on the 11th November and it is currently available in 10 countries.

As a Microsoft Azure Cloud Architect, it was important for me to keep up to date with all the latest previews, developments and releases into the Microsoft Azure cloud platform which is why I have created the Android app, so that I can easily be kept informed of all Microsoft Azure updates. I’ve kept the layout simple, in a listview, with a web browser view to launch directly into the published article from Microsoft. This enables me to keep up to date on a regular basis on all recent developments in Microsoft Azure in one place. I developed the app during my train journey’s and in some of my spare time in the evenings and I’m delighted to release it free to the Google Play store. I’ll be releasing new features over time, but for now this is what the app provides.

  • Synchronisation of the latest articles on the application launch
  • A local database is used for all downloaded articles
  • Quick search feature to query the local database
  • Direct Web browser view, to review the full article on the Microsoft docs web site

You can download the app free from the Google Play store here.

Enjoy!

A focus on Azure Security Options

A number of options are available for Microsoft Azure security solutions and as part of planning your azure subscriptions. There are a number of options any customer should consider.

I have put together a small whitepaper which introduces some of the key concepts and solutions which should be considered for any cloud deployment.

You can download my published whitepaper below.

MICROSOFT AZURE SECURITY A FOCUS ON CLOUD SECURITY SOLUTIONS

Azure VNet Peering

I’ve recently been reviewing VNet peering for Azure in detail and if you have VNet VPN gateways today, it’s time to switch to VNet peering if you have VNets connected together with the old method, especially now that it is in general availability. This is only a consideration for VNet’s connected in the same region as currently VNet peering is not available across Azure regions e.g. UK West and UK South.

VNet peering allows you to connect two or more Azure VNet’s together with a few simple steps vs the old method of provisioning gateway subnets and VPN Gateways. You also don’t have to provision a VPN gateway for VNet peering as the traffic travels through the Azure backbone and not through a site-to-site (S2S) IPSEC VPN tunnel. This obviously has numerous benefits, with Azure regional virtual networks that have provide the appropriate infrastructure for high bandwidth use. VNet-to-VNet connections always had limited connectivity based on the gateway type that was provisioned.

You can follow the Microsoft Azure article below if you have a need to provision VNet-to-VNet connections using VPN gateways, based on your requirements e.g. you need to connect two VNet’s together in different Azure regions.

Configure a VNet-to-VNet connection using the Azure portal

Here’s my example of how to create two Azure VNet’s and peer them using PowerShell. I’ll wrap these into my custom Azure PowerShell module in a couple of functions, with the appropriate  parameter input types, for future use.


# Login to Azure
Login-AzureRmAccount
# Use Select-AzureRmSubscription to select the subscription you want to create the VNets into

# New resource group in the location where we will hold all the resources
New-AzureRmResourceGroup -Name RG-VNETS -Location ukwest

# Create Virtual Network A with a subnet in the UK West Region
$NSGSubNetA = New-AzureRmNetworkSecurityGroup -Name NSG-SubNetA -ResourceGroupName RG-VNETS -Location ukwest
$SubNetA = New-AzureRmVirtualNetworkSubnetConfig -Name SubnetA -AddressPrefix 10.1.1.0/24 -NetworkSecurityGroup $NSGSubNetA
$VNetA = New-AzureRmVirtualNetwork -Name VNETA -ResourceGroupName RG-VNETS -Location ukwest -AddressPrefix 10.1.0.0/16 -Subnet $SubNetA

# Create Virtual Network B with a subnet in the UK West Region
$NSGSubNetB = New-AzureRmNetworkSecurityGroup -Name NSG-SubNetB -ResourceGroupName RG-VNETS -Location ukwest
$SubNetB = New-AzureRmVirtualNetworkSubnetConfig -Name SubnetB -AddressPrefix 10.2.1.0/24 -NetworkSecurityGroup $NSGSubNetB
$VNetB = New-AzureRmVirtualNetwork -Name VNETB -ResourceGroupName RG-VNETS -Location ukwest -AddressPrefix 10.2.0.0/16 -Subnet $SubNetB

# Add peering VNETA to VNETB (this initiates the peering)
Add-AzureRmVirtualNetworkPeering -Name Peering-VNETA-to-VNETB -VirtualNetwork $VNETA -RemoteVirtualNetworkId $VNETB.Id

Notice that the peering status is initiated.

vnet-peering-initiated

We now need to create the peering from VNETB to VNETA.


# Add peering VNETB to VNETA (this completes the peering)
Add-AzureRmVirtualNetworkPeering -Name Peering-VNETB-to-VNETA -VirtualNetwork $VNETB -RemoteVirtualNetworkId $VNETA.Id

The peering is now complete.

vnet-peering-connected

Be aware of the additional settings that are available to peering connections shown below.

vnet-peering-settings

You can enable or disable virtual network access from a peered VNet.

Allow forwarded traffic: Allows traffic from the peered network, not originating from the peered network, into the local VNet.

Allow gateway transit: allows the peered VNet to use the gateway in the local VNet. The peered network “use remote gateways option” must be enabled. It will only be available if the local VNet has a gateway configured.

Use Remote Gateways: The VNet will use the remote peered VNet gateway, but the remote VNet must have the “Allow gateway transit option enabled”.

Important

You cannot daisy chain VNets and expect them all to act as one address space with routing between then, regardless of the number of options you specify above. Daisy chaining isn’t really the best networking practice to follow in any case. I recommended that a hub and spoke topology is implemented with the appropriate security controls. I also recommended that you have Network Virtual Appliances (NVAs) in the hub as that will provide you with the most flexibility for controlling your network traffic between the VNet’s and subnets. Managing lots of NSG’s can be very cumbersome, but this depends on your release mechanism and experience as you could still use ARM templates to manage updates to NSGs.

The most common NVAs are CheckPoint vSEC, Barracuda NextGen and Fortinet FortiGate. For further information see the Microsoft Azure Docs article below.

Deploying high availability network virtual appliances

For further information on VNet Peering, you can review Microsoft Azure Docs overview article below.

VNet Peering

 

Shared Responsibilities: Cloud Computing

Whilst implementing security controls in Microsoft Azure, it is also important to understand the shared responsibilities between cloud service providers and what the customer can configure and control in terms of networking and security for the services customers require. Responsibilities change when you work with SaaS, PaaS and IaaS. It’s also important to understand how Microsoft handles security response and the process which is followed..

Alice Rison, Senior Director, Microsoft Azure has just published details on two recent whitepapers which were recently released to provide insight into the shared responsibilities and security response at Microsoft.

The published papers can be found linked to this announcement here: Microsoft Incident Response and shared responsibility for cloud computing

Azure NSG Rules:Beware

Recently, I had reviewed an issue with a load balancer which was not working correctly in Azure IaaS. This load balancer was specifically created in Azure Resource Manager (ARM) and it was load balancing a SQL Server AlwaysOn Availability Group (AOAG) listener. Client connections would fail to connect to the SQL Server standard TCP port 1433, through the load balancer, but would be accessible from to host with a direct reference.

After a fair amount of troubleshooting, Network Security Group (NSG) rules were preventing the load balancer from working correctly. The default rules in NSGs are set at a very high priority, which do allow load balancers to access the local virtual networks. This is currently defined in the default rule highlighted below. The source tag AzureLoadBalancer is used to allow a destination of any with any service/port on the NSG.

AzureNSGDefaultInBoundRulespng

The rule which blocked the load balancer from functioning correctly has been shown below.

AzureNSGInternetBlocktInBoundRule

Creating a rule blocking a source tag of Internet with destination any and service of any with any source/target port ranges of any, rendered the load balancer inoperable. The rule is actually not required since the default DenyAllInBound rule would block any internet traffic. Besides, you would need to either load balance requests or NAT traffic from the internet to the local subnet or host in order to have the appropriate communication pass through.

When you define your NSGs and apply these to subnets or host network interfaces, be aware that you have the capability to block Azure services from working correctly.

Manage the security architecture correctly and ensure that you design your NSGs based on your requirements, also be aware of the default NSG rules which are implicitly implied.

Azure IaaS Guidance, the basics…

The importance of planning and designing in Azure IaaS is just as important as in the days you designed your own on premises infrastructure. Azure has many capabilities which all rely on dependent resource models when you design your application infrastructure to support your projects. With any platform, private or public cloud, you need to ensure that you follow the appropriate guidance around the principles which are focused on best practices for successful implementations of cloud projects. As you would do with any infrastructure design project, there are common components which are key to how you design your applications to achieve operational excellence and performance. Some of the key basic elements have been outlined below.

Data Center Azure IaaS
Physical Machine/Virtual Machine Azure Virtual Machine
SAN Available through Storage Accounts (Tables, Queues, Blobs)
LAN Multiple Virtual Networks with Subnets
WAN/VPN enablement ExpressRoute/VPN Gateway
Network Security Polices Network Security Groups

 

Ingredient 1: VM Sizing

With all the current VM sizes in Azure it can be complicated to start with sizing your requirements up front. It’s important to review your application requirements and how you intend to deploy your overall architecture and instances to support your needs throughout the project and application lifecycle. If you don’t need load balancing and you have some simple VM requirements you can start with A series VMs. If you need something more powerful with additional features like load balancing, you’ll need to move to the standard tier VMs. For intensive compute applications like SQL Server, especially if you are expecting high transactional loads, you should move up to at least the D or DS series VMs. The G series and GS series offer most performance, more disks, larger temporary disks and RAM with the most powerful processors today. Each tiered VM has different capabilities with the number of CPU cores and speed, disk bandwidth and maximum number of attached data disks and virtual network interface adapters. You also need to be aware of the disk limits and I/O limits of each VM size, the number of data disks that you could attach and the max number of IOPS each VM can support with the appropriate storage account type.

It’s important to note that premium storage is only available for use with the DS and GS series VMs. They also use solid state drives for improved I/O, the same as premium storage.

For further information, see https://azure.microsoft.com/en-gb/documentation/articles/virtual-machines-size-specs/.

Ingredient 2: Storage

Once you’ve sized your VMs, storage is key to application performance and based upon IOPS requirements. If you have an idea of IOPS requirements for your applications, then life is much simpler in designing your storage requirements. Azure storage comes with different capabilities, tables, queues and blobs. For VMs, you will use storage accounts with blob storage. Each Virtual Hard Disk (VHD) is stored as a page blob. With Azure storage you have the choice of choosing Locally Redundant Storage (LRS), Zone Redundant Storage (ZRS), Geographically Redundant Storage (GRS) and Read Access Geographically Redundant Storage (RA-GRS). All these redundancy options need to be taken into consideration when you design your storage strategy in Azure for your VMs.

You also need to be aware of the max number of supported VHDs for your VMs in the storage accounts. Not to say that with a standard storage account you can have up to 500TB of space which could hold many VHDs, but you need to determine how many storage accounts you need as part of your design. For example, if you have multiple VMs and data disks and you use one storage account, each VM based on tier has max IOPS to each disk. If you had all your VHDs in one storage account you would end up with throttling your throughput because standard storage account can only support a number of highly utilised disks before throttling occurs. Premium storage with the DS and GS series VMs considerably improves your latency, but your storage space is currently reduced to 35TB per storage account.

With standard tier storage you pay for the data written to the VHD, regardless of the VHD size, each up to 1023GB. With premium storage, you have to create the data disks and you are charged for the whole size up front, unlike standard storage.

For further information, see https://azure.microsoft.com/en-gb/documentation/articles/storage-scalability-targets/ and https://azure.microsoft.com/en-gb/documentation/articles/storage-introduction/.

Ingredient 3: Network

How you design your Virtual Networks and Subnets is important from a number of aspects. You need to think about isolating your resources and how they will be accessed and by whom. The most common theme I have utilized is to ensure that you group your resources into Subnets which take more sense from an application perspective and tie these with security policies. For example, you wouldn’t have VMs exposed in a Subnet to a public IP address which don’t need to be part of a traditional DMZ in your data center. You would do exactly the same in Azure Virtual Networks and segment your virtual network design around your applications and accessibility requirements for your applications. Another way to think about segmentation around applications is to have front end, middle tier and backend Subnets for each set of groups of resources.

For further information, see https://azure.microsoft.com/en-gb/documentation/articles/virtual-networks-overview/.

For on premises connectivity you should consider ExpressRoute or VPN options with VPN Gateways. Each solution offers it’s own benefits.

For further information, see https://azure.microsoft.com/en-gb/documentation/articles/vpn-gateway-about-vpngateways/

Ingredient 4: Security

Security can be managed in different ways in Azure, with virtual appliances available through the VM depot, network security groups, endpoints, load balancers, firewalls, group policies etc. This is a very large area to consider and is of highest importance in any environment. As part of your blueprint and building our logical design, ensure that you take deep consideration into network security groups which can be applied to VMs, Network Interfaces and Subnets. A series of Access Control Lists (ACL’s) can be applied to the resources I mentioned earlier as part of a defence-in-depth strategy. Cloud security should be layered from the VMs, VM firewall, network isolation, access control lists and any protection that can be provided by virtual appliances. You can also force tunnel connections through your on premises environment if you are extending to Azure from your data center and mange traffic to the internet from on premise network security appliances..

For further information, see https://azure.microsoft.com/en-us/documentation/articles/virtual-networks-nsg/.

Ingredient 5: Deployment

The deployment aspects of the cloud can be achieved in different ways. You can use the Azure Portal, Azure PowerShell Cmdlets, Azure Command Line Interface (CLI) and a combination of the highly recommended deployment method with Azure Resource Manager (ARM) templates. In Azure IaaS V1, we focused on Cloud Services as a container for resources. In ARM (IaaS v2), you focus on the whole application, or pieces of the deployment which makes up your footprint for your application architecture. There are a number of ARM templates available on GitHub to get you started. I would recommend building your own ARM templates to understand how the templates glue together before using ARM templates which might be complex. ARM allows you to define your blueprint and deploy this in a repeatable consistent manner, which is perfect for testing your deployments through the application lifecycle. There are certain elements you need to be aware of when you use ARM, for example your storage account deployment will fail if you don’t use lowercase alphanumeric characters from 3-24 characters. Something which isn’t debugged by Visual Studio when you develop the template, so be aware of some of the rulesets you need to follow.

For more information, see https://azure.microsoft.com/en-gb/documentation/articles/resource-group-overview/.

For Quickstart ARM templates to get you up and running, see https://azure.microsoft.com/en-gb/documentation/templates/.

That’s the end of the IaaS basics starter post for today, I hope you found it informative.