KeithMayer.com

Be an Early Expert in Hybrid Cloud - Microsoft Azure, Windows Server 2012 R2, Hyper-V and System Center 2012 R2

KeithMayer.com

  • Step-by-Step: Revoking and Reinstating Client VPN Certificates for Azure Point-to-Site VPNs

    Microsoft Azure provides Point-to-Site VPN (aka. Client VPN) connectivity for secure remote access by development and operations teams to cloud-based workloads that are provisioned on an Azure Virtual Network.  Azure Point-to-Site VPN connectivity uses SSTP as a firewall-friendly tunneling protocol and certificates for mutual authentication of each client connection.

    Azure Site-to-Site and Point-to-Site VPN

    You can find more details on configuring Azure Point-to-Site VPNs at the following link location:

    When discussing Azure Point-to-Site VPN connectivity, one of the questions I frequently hear is ...

    Great! But ... how do I disable a Point-to-Site VPN user when they're leaving my organization?

    Azure Point-to-Site VPNs use certificates for user authentication and authorization, so we can simply revoke a user's certificate to disable their Point-to-Site VPN access.  In this article, we'll step through the process of revoking and reinstating user certificates for Azure Point-to-Site VPNs by using the Azure PowerShell module and the Azure Service Management REST API.

    Authenticate to Azure

    Before we can manage Azure resources via the Azure PowerShell module, we'll first need to authenticate.  Authentication to Azure can be accomplished via management certificates, or via Azure Active Directory.  In this article, we'll use management certificates to authenticate to Azure via both Azure PowerShell and the Azure Service Management REST API. 

    # Download Azure Management Certificate

    Get-AzurePublishSettingsFile

    # Import Azure Management Certificate

    Import-AzurePublishSettingsFile "${env:USERPROFILE}\Documents\Azure.publishsettings"

    In a future article, we'll explore using Azure AD to authenticate to Azure via Azure PowerShell and the Azure Service Management REST API.

    Select Azure Subscription

    Once we've authenticated to Azure, we'll next select the Azure subscription in which our Azure Virtual Network is provisioned.  Many organizations have more than one Azure subscription for different release stages (dev, test, production), applications or business units.

    # Select Azure Subscription

    $subscriptionName = (Get-AzureSubscription).SubscriptionName | Out-GridView -Title "Select Azure Subscription" -PassThru

    Select-AzureSubscription -SubscriptionName $subscriptionName

    Get Subscription ID and Management Certificate Thumbprint

    After selecting the appropriate Azure subscription, we'll need to grab the subscription ID and the management certificate thumbprint we used when authenticating to Azure.  We'll need these values to authenticate to Azure via the Azure Service Management REST API later in this article.

    # Get Azure subscription information

    $subscription = Get-AzureSubscription $subscriptionName -ExtendedDetails

    $certificate = $subscription.Certificate

    $subscriptionId = $subscription.SubscriptionId

    Select Azure Virtual Network

    Some organizations may have more than one Azure Virtual Network provisioned within their Azure subscription. In this step, we'll select the Azure Virtual Network that has the Point-to-Site VPN Gateway provisioned within it.

    # Select Azure VNet for which to manage VPN certificates

    $azureVNet = (Get-AzureVNetSite).Name | Out-GridView -Title "Select Azure VNet" -PassThru

    Select VPN Client Certificate to Revoke

    Now, we can choose the VPN client certificate that's associated with the user that we wish to disable.  When initially provisioning VPN client certificates for your users, be sure to use a certificate naming convention that makes it easy to identify each certificate based on username.  Also, be sure to save a copy of each certificate in a safe location so that you can easily access them later, if needed.

    # Import saved copy of user's VPN client certificate

    $certPassword = Read-Host "Enter VPN client certificate password" -AsSecureString

    Import-PfxCertificate -FilePath "${env:USERPROFILE}\Documents\Azure\P2S VPN\VPN01Client.pfx" -CertStoreLocation Cert:CurrentUser\My -Exportable -Password $certPassword

    # Select VPN client certificate to Revoke

    $vpnCertThumbprint = (Get-ChildItem Cert:\CurrentUser\My | Out-GridView -Title "Select VPN certificate to revoke" -PassThru).Thumbprint

    Revoke VPN Client Certificate

    We've selected all the relevant values we'll need when revoking a Point-to-Site VPN client certificate, so now we can call the Azure Service Management REST API to perform the actual revoke process.  When we call this API, we'll pass along the relevant values that we've collected above.

    # Build web request header

    $requestHeader = @{"x-ms-version" = "2012-03-01"}

    # Revoke a VPN Client Certificate

    $revokeVPNCertUri = "https://management.core.windows.net/$subscriptionId/services/networking/$azureVNet/gateway/clientcertificates/$vpnCertThumbprint"

    $response = Invoke-RestMethod -Uri $revokeVPNCertUri -Certificate $certificate -Method Post -Headers $requestHeader

    # Confirm Revoked VPN Client Certificates

    $listRevokedVPNCertUri = "https://management.core.windows.net/$subscriptionId/services/networking/$azureVNet/gateway/clientcertificates"

    $response = Invoke-RestMethod -Uri $listRevokedVPNCertUri -Certificate $certificate -Method Get -Headers $requestHeader

    $response.ClientCertificates.Thumbprint

    After a user's VPN client certificate is revoked, if they should attempt to connect to the Point-to-Site VPN Gateway, their connection will not be successfully authenticated and they will receive the below error message.

    Azure VPN Client

    Reinstate a Revoked VPN Client Certificate

    In some cases, you may find that you need to later reinstate a revoked VPN client certificate.  Luckily, we can use the same Azure API to reinstate certificates that were previously revoked by using the code snippet below.

    # Reinstate a VPN Client Certificate

    $reinstateVPNCertUri = https://management.core.windows.net/$subscriptionId/services/networking/$azureVNet/gateway/clientcertificates/$vpnCertThumbprint

    $response = Invoke-RestMethod -Uri $reinstateVPNCertUri -Certificate $certificate -Method Delete -Headers $requestHeader

  • Quick Tip: List Current Client Connections on Azure Point-to-Site VPN with PowerShell and REST API

    Microsoft Azure provides secure access to cloud-based VMs for developers and IT operations teams via Point-to-Site VPN (aka. Client VPN) connectivity.  This solution uses SSTP (Secure Socket Tunneling Protocol) to provide a secure, firewall-friendly solution that uses the native VPN client built-in with Windows 7 and later.  In a future article, we'll also look at a cross-platform Client VPN connectivity option to Azure for Linux and Mac OS X clients.

    After configuring Point-to-Site VPN connectivity in Azure, it's pretty easy to see the overall connection status on the Virtual Networks Dashboard page of the Azure Management Portal, as shown below.

    Click to zoom in ...

    Azure Management Portal: Virtual Network Dashboard page

    BUT ... what if we want to see the details of each individual client IP address that is currently connected to the VPN? Luckily, with a bit a PowerShell and the Azure Service Management REST API, we can fetch those details as well!

    The PowerShell snippet below prompts to select an Azure subscription and Virtual Network, and then calls the List Connections operation via the REST API to display a list of currently connected client IP addresses. Hope you find it helpful!

    # Download Azure Publish Settings file
    Get-AzurePublishSettingsFile

    # Import Azure Publish Settings file
    Import-AzurePublishSettingsFile "$env:USERPROFILE\Documents\Azure.publishsettings"

    # Select Azure subscription
    $subscriptionName = (Get-AzureSubscription).SubscriptionName | Out-GridView -Title "Select Azure Subscription" -PassThru

    # Get Azure subscription ID and certificate
    $subscription = Get-AzureSubscription $subscriptionName -ExtendedDetails
    $certificate = $subscription.Certificate
    $subscriptionId = $subscription.SubscriptionId

    # Select Azure Virtual Network
    $azureVNet = (Get-AzureVNetSite).Name | Out-GridView -Title "Select Azure VNet" -PassThru

    # Build request header and body
    $requestHeader = @{"x-ms-version" = "2012-03-01"}

    # Call the Azure REST API
    $listVPNConnectionsUri = "https://management.core.windows.net/$subscriptionId/services/networking/$azureVNet/gateway/connections"
    $VPNConnections = Invoke-RestMethod -Uri $listVPNConnectionsUri -Certificate $certificate -Method Get -Headers $requestHeader

    # List active VPN client connections
    $VPNConnections.Connections.Connection.AllocatedIPAddresses.String

  • Step-by-Step: Automated Provisioning for Linux in the Cloud with Microsoft Azure, XPlat CLI, JSON and Node.js ( Part 2 )

    There's lots of tools that can be leveraged for automating Linux workloads on Microsoft Azure, including Azure Automation, PowerShell DSC for Linux, VM Agent Custom Scripts, Cloud-Init, XPlat CLI for Azure, Vagrant, Docker and third-party tools such as Chef and Puppet.  Azure provides a wide variety of automation options so that you can choose the tools with which you're most familiar and, in some cases, may already have an existing investment.

    image

    In Part 1 of this two-part article series, we stepped through the process for getting our Linux admin workstation setup for Azure cloud automation using the XPlat-CLI and Cloud-Init.

    This article is Part 2 of this series. In this article, we'll leverage these tools for automatically provisioning an end-to-end highly available Linux server farm environment, including storage, networking, load-balancing, virtual machines and application workloads.  As we proceed through this article, we'll be build a Linux shell script that implements this provisioning logic.

    Have you completed Part 1 of this series?

    Before stepping through this article, be sure to complete Part 1 of this two-part series to setup your Linux admin workstation for Azure cloud automation.

    You may also be interested in these additional Linux / Open Source cloud resources:

    Parameters for reusability

    When provisioning new Linux workloads in the cloud, there's several values that need to be specified, such as Azure subscription, datacenter region, number of VMs, and resource names, that need to be specified for the process to be successful.  To promote reusability, I'm a big fan of using input parameters in shell scripts, so we'll start our script with defining the input parameters for provisioning our environment.

    #!/bin/sh

    # Set variable values based on parameters passed
    azureloginuname="$1" # Azure AD login ID
    azureloginpass="$2" # Azure AD password
    azuresubname="$3" # Azure subscription name
    azureregion="$4" # Azure datacenter region
    azureprefix="$5" # Unique prefix for Azure resource names
    azurevmuname="$6" # Admin username for new VMs
    azurevmpass="$7" # Admin password for new VMs
    azurevmtotal="$8" # Number of VMs to provision
    azurecloudinit="$9" # Cloud-Init config file

    newlinuxonazure.sh script - Input parameters

    With these input parameters defined, we'll be able to use this script to provision different environments in the Azure cloud just by varying the input parameter values when calling the finished script.

    Sign-in to Azure account

    Before our script can perform any provisioning steps, we'll first need to sign-in to our Azure account.  When signing in, we'll need to specify an Azure Active Directory login ID that has been delegated service administrator or co-administrator access to the Azure subscription with which we'll be working.  In our script, we can sign-in with the provided Azure AD login ID and password using the azure login command from the XPlat-CLI.

    # Sign-in to Azure account with Azure AD credentials
     
    azure login --user "$azureloginuname" --password "$azureloginpass"
     
    # Confirm that Azure account sign-in was successful
     
    if [ "$?" != "0" ]; then
        echo "Error: login to Azure account failed"
        exit 1
    fi

    newlinuxonazure.sh script - Sign-in to Azure account

    Select Azure subscription

    In Azure, an account may be associated with multiple subscriptions, so we'll next need to use the azure account set command to select the specific Azure subscription in which we'll be provisioning new workloads.

    # Select Azure subscription
     
    azure account set "$azuresubname"
     
    # Confirm that subscription is now default
     
    azuresubdefault=$(azure account show --json "$azuresubname" | jsawk 'return this.isDefault')
    if [ "$azuresubdefault" != "true" ]; then
        echo "Error: Azure subscription ${azuresubdefault} not found as default subscription"
        exit 1
    fi

    newlinuxonazure.sh script - Select Azure subscription

    In the snippet above, we're confirming that the correct Azure subscription has been selected by returning output from the azure account show command in JSON format, and then piping that output to jsawk to return the isDefault value. We'll be using JSON formatted output and jsawk throughout our script to provide additional intelligence and error handling.

    Define Affinity Group

    In Azure, Affinity Groups help to reduce latency and improve performance between provisioned resources within an Azure datacenter region by keeping them located reasonably "close together". We can define Affinity Groups using the azure account affinity-group create command. 

    # Define Azure affinity group
     
    azureagname="${azureprefix}ag"
    azure account affinity-group create --location "$azureregion" --label "$azureagname" "$azureagname"
     
    # Confirm that Azure affinity group exists
     
    azureagexist=$(azure account affinity-group list --json | jsawk 'return true' -q "[?name=\"$azureagname\"]")
    if [ $azureagexist != [true] ]; then
        echo "Error: Azure affinity group ${azureagname} not found"
        exit 1
    fi

    newlinuxonazure.sh script - Define an Affinity Group

    In the snippet above, we've provided a unique name for the new Affinity Group by leveraging the $azureprefix value that was supplied as an input parameter earlier in the script.  In addition, we've tied the Affinity Group to a particular Azure datacenter region by referencing the $azureregion value that was also provided as a script parameter.

    Create Azure Storage Account

    Azure Storage Accounts are used to provide blob storage for storing persistent virtual disks for Azure virtual machines. Our script can create a new storage account for storing the VM disks we'll be provisioning by calling the azure storage account create command.

    # Create Azure storage account
     
    azurestoragename="${azureprefix}stor"
    azure storage account create --affinity-group "$azureagname" --label "$azurestoragename" --geoReplication "$azurestoragename"
     
    # Confirm that Azure storage account exists
     
    azurestorageexist=$(azure storage account list --json | jsawk 'return true' -q "[?name=\"$azurestoragename\"]")
    if [ $azurestorageexist != [true] ]; then
        echo "Error: Azure storage account ${azurestoragename} not found"
        exit 1
    fi

    newlinuxonazure.sh script - Create an Azure Storage Account

    In the snippet above, we're also specifying the --geoReplication option to create our Azure Storage Account with built-in asynchronous Storage Geo-Replication between Azure datacenter regions for additional disaster recovery protection.

    Create Azure Virtual Network

    Azure Virtual Networks provide an isolated IP address namespace in the cloud that can optionally also connect to on-premises servers and workstations via site-to-site and point-to-site VPN tunnels.  Multiple Azure virtual machines can be co-located on a common Azure virtual network to provide an internally routable IP address range that VMs can use to communicate directly with one another - just as if those VMs were running on an internal physical network.  Our script can provision a new Azure Virtual Network by using the azure network vnet create command.

    # Create Azure virtual network
     
    azurevnetname="${azureprefix}net"
    azure network vnet create --affinity-group "$azureagname" "$azurevnetname"
     
    # Confirm that Azure virtual network exists
     
    azurevnetexist=$(azure network vnet list --json | jsawk 'return true' -q "[?name=\"$azurevnetname\"]")
    if [ $azurevnetexist != [true] ]; then
        echo "Error: Azure virtual network ${azurevnetname} not found"
        exit 1
    fi

    newlinuxonazure.sh script - Create Azure Virtual Network

    Note: In the snippet above, we're specifying the --affinity-group option when creating the Azure Virtual Network.  While this is currently a valid approach, Azure Virtual Networks are moving to a new Regional Virtual Network model that offers improved networking capabilities.  After the Azure XPlat-CLI is updated to support Regional Virtual Networks, you'll be able to supply the --location option as an alternative to specifying an Azure affinity group when creating a new Azure Virtual Network so that you'll be able to take advantage of these new networking capabilities.  In the meantime, if you wish to create a new Regional Virtual Network, you can certainly do so via the Azure Management Portal.

    Select Linux VM Image

    When provisioning our new Azure Virtual Machines, we'll need to specify the base VM image from which our new VMs will be built. This VM image can be one of the standard Linux platform images provided in the Microsoft Azure Marketplace, or it could be a custom Linux VM Image that you've created and uploaded to your Azure subscription.  Our script can select the appropriate Linux VM image by calling the azure vm image list command.

    # Select Linux VM image
     
    azurevmimage=$(azure vm image list --json | jsawk -n 'out(this.name)' -q "[?name=\"*Ubuntu-14_04_1-LTS-amd64-server*\"]" | sort | tail -n 1)
     
    # Confirm that valid Linux VM Image is selected
     
    if [ "$azurevmimage" = "" ]; then
        echo "Error: Azure VM image not found"
        exit 1
    fi

    newlinuxonazure.sh script - Select Linux VM Image

    In the snippet above, we're using jsawk to query the list of available images based on Ubuntu 14.04 LTS, and then we select the most recent image in the returned results for use within our script.

    Provision Linux VMs

    We're now ready to provision our Linux virtual machines. First, we'll define a few variables that we'll use during the VM provisioning process ...

    # Set variables for provisioning Linux VMs
     
    azurednsname="${azureprefix}app" # DNS hostname for Cloud Service
    azurevmsize='Small' # Azure VM instance size
    azureavailabilityset="${azureprefix}as" # Availability Set name
    azureendpointport='80' # Port to Load-balance
    azureendpointprot='tcp' # Protocol to Load-balance
    azureendpointdsr='false' # Direct Server Return, usually false
    azureloadbalanceset="${azureprefix}lb" # Load-balanced Set name

    newlinuxonazure.sh script - Set variables for provisioning Linux VMs

    ... then, in the snippet below, we'll use the azure vm create command to create each new VM.  We'll also use the azure vm endpoint command to configure load-balanced firewall endpoints that permit inbound web traffic.

    # Provision Linux VMs
     
    # Initialize Azure VM counter 
    azurevmcount=1
     
    # Loop through provisioning each VM
    while [ $azurevmcount -le $azurevmtotal ]
    do
     
       # Set Linux VM hostname
        azurevmname="${azureprefix}app${azurevmcount}"
     
        # Create Linux VM - if first VM, also create Azure Cloud Service
        if [ $azurevmcount -eq 1 ]; then
            azure vm create --vm-name "$azurevmname" --affinity-group "$azureagname" --virtual-network-name "$azurevnetname" --availability-set "$azureavailabilityset" --ssh 22 --custom-data "$azurecloudinit" --vm-size "$azurevmsize" "$azurednsname" "$azurevmimage" "$azurevmuname" "$azurevmpass"
        else
            azure vm create --vm-name "$azurevmname" --affinity-group "$azureagname" --virtual-network-name "$azurevnetname" --availability-set "$azureavailabilityset" --ssh $((22+($azurevmcount-1))) --custom-data "$azurecloudinit" --vm-size "$azurevmsize" --connect "$azurednsname" "$azurevmimage" "$azurevmuname" "$azurevmpass"
        fi
     
        # Confirm that VM creation was successfully submitted
        if [ "$?" != "0" ]; then
            echo "Error: provisioning VM ${azurevmname} failed"
            exit 1
        fi
     
        # Define load-balancing for incoming web traffic on each VM
        azure vm endpoint create-multiple "$azurevmname" $azureendpointport:$azureendpointport:$azureendpointprot:$azureendpointdsr:$azureloadbalanceset:$azureendpointprot:$azureendpointport
     
        # Confirm that load-balancing config was successfully submitted
        if [ "$?" != "0" ]; then
            echo "Error: provisioning endpoints for VM ${azurevmname} failed"
            exit 1
        fi
     
        # Wait until new VM is in a Running state
        azurevmstatus='None'
        while [ "$azurevmstatus" != "ReadyRole" ]
        do
            sleep 30s
            azurevmstatus=$(azure vm show --json --dns-name "$azurednsname" "$azurevmname" | jsawk 'return this.InstanceStatus')
            echo "Provisioning: ${azurevmname} status is ${azurevmstatus}"
        done
     
        # Increment VM counter for next VM
        azurevmcount=$((azurevmcount+1))
     
    done

    newlinuxonazure.sh script - Provision Linux VMs

    There's quite a bit occurring in this last script snippet, so let's step back and take a closer look ...

    • First, we initialize an $azurevmcount variable and define a while loop that will provision each VM in turn. 
       
    • Within this loop, we're setting a unique Linux hostname for each VM and calling the azure vm create command to submit a request for building a new VM with the supplied values. 
       
    • When the first VM is built, the snippet will also build a new Azure Cloud Service that holds the public DNS hostname for the load-balanced VMs.
       
    • For each VM that is created, they are configured in a common Azure Availability Set for placement in separate update domains and fault domains.  This configuration provides a financially-backed 99.95% Service Level Agreement (SLA) for the availability of these VMs.
       
    • We call the azure vm endpoint command to configure load-balancing of incoming web traffic for each VM.
       
    • After submitting provisioning requests for each VM, we check the VM status to make sure the VM has booted before continuing with provisioning the next VM.

    Provision Application Workloads

    As part of the VM provisioning process, our script also configures the application workloads running inside each VM. When configuring application workloads, there's several options that we can use, including Cloud-Init, Custom Scripts, Docker and PowerShell DSC for Linux, as well as third-party tools such as Chef and Puppet. In our script snippet above, we're supplying a Cloud-Init config file using the --custom-data option on the azure vm create command.

    #cloud-config

    # Install additional packages on first boot
    #
    # Default: none
    #
    # if packages are specified, this apt_update will be set to true
    #
    # packages may be supplied as a single package name or as a list
    # with the format [<package>, <version>] wherein the specifc
    # package version will be installed.

    packages:
    - apache2

    cloudinit-apache.txt - Install Apache2 package inside Linux VMs

    Cloud-Init provides lots of flexible options in configuring application workloads inside VMs (see the Cloud-Init documentation for more details), but in our example above we're using just a simple configuration file that ensures that the necessary package is installed for supporting web workloads in each of our Linux VMs.

    Sign-out from Azure

    At the end of our script, we can clean-up our admin environment and automatically sign-out of our Azure account using the azure logout command.

    # End of script
     
    echo "Success: Azure provisioning for ${azurednsname} completed"
    azure logout "$azureloginuname"

    newlinuxonazure.sh script - Sign-out of Azure account

    Running our script

    After we've saved on script file on our Linux admin workstation, we can flag the script as executable with the standard Linux chmod command ...

    chmod 755 ./newlinuxonazure.sh

    ... and, then run our new script with our desired parameter values to test provisioning a new highly available Linux web server farm on the Azure cloud platform!

    ./newlinuxonazure.sh "[email protected]" "password" "your-azure-subscription-name" "azure-region" "unique-azure-prefix" "vm-admin-name" "vm-admin-password" total-number-of-vms "path-to-cloud-init-config-file"

    After a few minutes, our script completes and our new highly available Linux web server farm is now up and running on the Azure cloud, ready for us to begin using ...

    Click to zoom in ...
    Microsoft Azure Management Portal - https://manage.windowsazure.com

    .... and we can browse to our new load-balanced web service using the provisioned DNS hostname to confirm that it's available ...

    Click to zoom in ...

  • Step-by-Step: Automated Provisioning for Linux in the Cloud with Microsoft Azure, XPlat CLI, JSON and Node.js ( Part 1 )

    Since previously publishing the Quick Start Guide for Building Highly Available Linux Servers in the Cloud on Microsoft Azure, several people have asked me about ways in which Linux workload provisioning can be automated with Azure.

    Automated Provisioning for Linux in the Cloud with Microsoft Azure, XPlat CLI, JSON and Node.js

    There's lots of tools that can be leveraged for automating Linux workloads on Microsoft Azure, including Azure Automation, PowerShell DSC for Linux, VM Agent Custom Scripts, Cloud-Init, XPlat CLI for Azure, Vagrant, Docker and third-party tools such as Chef and Puppet.  The Azure team provides a wide variety of automation options so that you can choose the tools with which you're most familiar and, in some cases, may already have an existing investment.

    This article is part 1 of a two-part series.  In this article, we'll step through the process for getting our Linux admin workstation setup for Azure cloud automation using the XPlat-CLI for Azure and Cloud-Init

    In part 2 of this series, we'll leverage these tools for automatically provisioning a highly available Linux server farm environment using the scenario outlined in the Quick Start Guide referenced above.

    What is the XPlat CLI for Azure?

    The XPlat CLI is a cross-platform Azure command-line interface for Linux, Mac and Windows administrators. If you're familiar with writing shell scripts, the XPlat CLI for Azure provides an easy way to get started with end-to-end automation of Linux environments on Azure.  Using the XPlat CLI, you can easily provision Azure fabric resources, such as storage, networking and VMs, along with OS and application configurations inside each VM.

    The XPlat CLI is written in JavaScript and is implemented using the Azure SDK for Node.js. It's been released under an Apache 2.0 license and the project repository is located at https://github.com/Azure/azure-xplat-cli.

    Let's Get Started ...

    To prepare for following along with this article, be sure to complete the following steps:

    1. Activate your Azure subscription. If you don't yet have an active Microsoft Azure subscription, sign-up for a free trial subscription.
       
    2. Download the Quick Start Guide. This will be a helpful resource with which you can follow along if you're not familiar with how Linux VMs work with Azure.
       
    3. Setup a Linux admin workstation. In this article, I'll be using Ubuntu 14.04 LTS for my admin workstation. If you don't currently have an admin machine setup, use the steps in the Quick Start Guide to get yours setup in the Cloud on Azure. 
       
      Note: If you're using a different Linux distro for your admin workstation than Ubuntu 14.04, the installation steps below will be a bit different.  However, the XPlat CLI commands for provisioning Azure resources will be exactly the same after you've gotten everything installed.

    Installing the XPlat CLI for Azure

    The XPlat CLI for Azure requires node.js and npm, so we'll need to install those first. On Ubuntu 14.04, we'll also need to install the nodejs-legacy package.

    sudo apt-get update
    sudo apt-get install -y nodejs nodejs-legacy npm

    After installation, you can confirm the versions of node and npm that is installed by using the following commands:

    node --version
    npm --version

    My admin machine is running node v0.10.25 and npm v1.3.10.  If you're running a very old version of node and/or npm, be sure to update to the latest versions of each before continuing.

    After the nodejs and npm packages are installed, we can install the XPlat CLI for Azure using npm.

    sudo npm install azure-cli --global

    After the azure-cli package is installed, you can check the version of the XPlat CLI using the following command:

    azure --version

    The XPlat CLI is updated on a regular basis.  Check the ChangeLog to make sure that you're using the latest version.  If you find that you need to update the azure-cli package, you can easily do so with the following command:

    sudo npm update azure-cli --global

    After installing the azure-cli package, you may wish to enable auto-completion of command lines to make it easier to work with this CLI tool.  You can enable auto-complete each time you login by using these commands:

    azure --completion >> ~/azure.completion.sh
    echo 'source ~/azure.completion.sh' >> .bash_profile

    To enable command line auto-completion for your current session without needing to logout/login, run this command:

    source ~/azure.completion.sh

    What can I do with the XPlat CLI for Azure?

    The XPlat CLI includes some pretty extensive built-in help for the various CLI commands and options.  To get help on the list of available commands, you can run:

    azure --help

    To get help on the various actions and options available for each command, simply run the command with the --help option specified at the end of the command line. For example, to see help on creating VM's via the CLI, you could run:

    azure vm --help

    or

    azure vm create --help

    You may have noticed in the help ouput that the XPlat CLI includes a --json option to output information in JSON format. This brings us to the next step ...

    Installing JSON command line tools

    After installing the XPlat CLI, you may also wish to install a JSON command line tool, such as jsawk or jq.  The XPlat CLI can return information in JSON format when using the --json option, and it's helpful to have command line tools that can easily parse JSON ouput when building shell scripts.  In this article series, we'll be using jsawk.

    Before installing jsawk, we'll first need to install the spidermonkey-bin package, which jsawk depends upon.  Use these commands to download, build and install the spidermonkey-bin package.

    sudo apt-get install mercurial autoconf2.13 -y
    hg clone
    http://hg.mozilla.org/mozilla-central/
    cd mozilla-central/js/src
    autoconf2.13
    ./configure
    make
    sudo make install

    After you've completed these steps, you can confirm that the spidermonkey-bin js interpreter is correctly installed by running this command:

    js --help

    Now, we can install jsawk with the following commands:

    curl -L http://github.com/micha/jsawk/raw/master/jsawk > jsawk
    chmod 755 jsawk
    sudo mv jsawk /usr/bin/

    We can confirm that the jsawk command line tool is properly installed by running this command:

    echo | jsawk 'return "jsawk is installed"'

    Next steps ...

    Our Linux workstation is now prepared with the tools necessary to automate Linux workload provisioning on Azure.  In part 2 of this article series, we will continue with creating a script that will authenticate to our Azure subscription and build the highly available Linux server farm environment depicted in our Quick Start Guide.

    Stay tuned for more in the Clouds!

    Keith

  • TechNet Radio: (Part 15) Building Your Hybrid Cloud - Getting Started with Automating the Hybrid Cloud using PowerShell

    In part 15 of our “ Building a Hybrid Cloud ” series, Keith Mayer and Andy Syrewicze show us to get started automating our hybrid cloud environment using PowerShell. Tune in for this great overview session on why IT Pros should think about automating their processes and how they can get started with the Microsoft Azure VM Agent Custom Script extensions, Azure PowerShell Module and the Azure Pack. [ 1:45 ] Why Automate? [ 7:23 ] DEMO: Microsoft Azure VM Agent Custom Script Extensions Azure PowerShell ...read more
  • Quick Tip: List all Static IPs on an Azure Virtual Network using PowerShell

    We can assign static internal IP addresses for Azure Virtual Machines on a Virtual Network using either PowerShell or the new Azure Preview Portal. This is a useful capability for provisioning VM workloads that may require fixed IP address assignments, such as DNS servers.

    image
    Provisioning a VM with a Static internal IP address using Azure Preview Portal

    Question: After provisioning a set of VM's with static internal IP addresses, how can I display a list of all VMs with static addresses in my subscription?

    Answer: You can list all Azure VM's configured with static internal IP addresses in your Azure subscription with the following one-line PowerShell code snippet that leverages the Azure PowerShell Module.

    Get-AzureVM | Select-Object -Property Name, @{Name='StaticIP';Expression={(Get-AzureStaticVNetIP -VM $_ ).IPAddress}}

  • Deck and Resources: SQL Server Options in the Cloud with Microsoft Azure

    Thanks for attending my presentation today at the Columbus SQLPASS User Group chapter on SQL Server Options in the Cloud with Microsoft Azure.

    We discussed various hybrid cloud options for leveraging Microsoft Azure as part of a SQL Server deployment, including the following scenarios:

    • Off-site cloud backups for databases and logs
    • Disaster recovery of on-premises databases
    • Production quality cloud-based Dev & Test environments
    • Extending on-premises applications to the cloud
    • Migration of existing applications to the cloud
    • Cloud-designed business and SaaS applications

    In this article, I've included a downloadable copy of our session deck along with a list of additional resources to help you continue your evaluation of these key scenarios.

    SQL Server Options in the Cloud with Microsoft Azure



    Download a copy of this deck for offline review.

    Additional resources

    To help you with next steps in evaluating SQL Server scenarios with the Microsoft Azure cloud platform, I've included several technical resources below ...

  • TechNet Radio: (Part 14) Building Your Hybrid Cloud - Disaster Recovery to the Cloud with Azure Site Recovery

    In part 14 of our “ Building a Hybrid Cloud ” series, Keith Mayer and Andy Syrewicze walk us through a discussion around the importance of disaster recovery as well as demo how you can implement this in Azure Site Recovery. the steps of the importance of disaster recovery. [ 3:15 ] What is Azure Site Recovery? [ 5:00 ] DEMO: Implementing Azure Site Recovery __________________________ Experience Microsoft's latest products with these FREE downloads! Build Your Lab! Download Windows Server 2012 ...read more
  • Quick Tip: Listing all IaaS VMs or PaaS Roles on an Azure Virtual Network via PowerShell

    When managing Microsoft Azure Virtual Networks via the Azure Management Portal, we can easily see a list of IaaS Virtual Machines and/or PaaS web/worker roles that are connected to a particular virtual network, as shown below.

    image
    List of resources connected to Azure Virtual Network via Management Portal

    Question: How can I determine this same type of list when using PowerShell to manage my Azure subscription?

    Answer: Virtual networks are bound to Azure cloud service deployments for IaaS Virtual Machines and PaaS web/worker roles. Use the following PowerShell code snippet to display the list of cloud services, roles and instances that are connected to a particular Azure Virtual Network.

    (Get-AzureService |
        Get-AzureDeployment |
        Where-Object `
             -Property VNetName `
             -EQ "enter-vnet-name") |
        %{
             Get-AzureRole `
                 -ServiceName $_.ServiceName `
                 -InstanceDetails |
             Select-Object `
                  -Property ServiceName,
                            InstanceName,
                            RoleName,
                            IPAddress
         }

  • Scripts-to-Tools: Automate Health Monitoring Alert Rules in the Cloud with PowerShell and the Azure Service Management REST API

    After successfully provisioning new IaaS virtual machines or PaaS cloud services in Microsoft Azure, the focus often turns to workload monitoring for ensuring the continued health of the solutions we've deployed. Microsoft Azure includes native monitoring and email alerting capabilities for deployed workloads, and you can certainly extend monitoring to more granular levels with additional tools, such as Azure Automation, Application Insights, System Center 2012 R2 Operations Manager, or other 3rd party tools like New Relic.

    image

    However, manually configuring monitoring alert rules for a large number of workloads can take a lot of time. Unfortunately, the Azure PowerShell module doesn't currently provide direct scripting support to automate alert rule definition, BUT ... the Azure Service Management REST API does provide this capability, and we can easily leverage that API via PowerShell with a bit of creativity!

    In this article, we'll step through the process of creating our own PowerShell function, named New-AzureAlert, to help us automate the provisioning of new Azure monitoring alert rules using the Azure Service Management REST API.

    Getting Started

    Before getting started in this article, you'll first need a few items:

    • An active Microsoft Azure subscription. You can sign-up for a FREE Azure subscription trial if you don't currently have one.
       
    • Microsoft Azure PowerShell module. Be sure to download and install the latest version to get all the most recent updates.
       
    • At least one IaaS virtual machine or PaaS cloud service deployed to your Azure subscription.  You can learn more about the steps involved in deploying workloads on Azure via our Early Experts program, and via our Step-by-Step Cloud Lab guides.
       
    • Familiarity with the basics of building Powershell functions. If you need a quick primer, check out my prior Scripts-to-Tools article where I stepped through the process of building re-usable tools via PowerShell functions.

    After you've collected everything you'll need to get started, let's proceed to the next step ...

    Where's my Certificate?

    To authenticate to the Azure Service Management REST API endpoints, we'll be passing the subscription ID and management certificate for your Azure subscription.  To obtain your subscription ID and management certificate, you can use the following snippet of code:

    # Download Azure Publish Settings File

    Get-AzurePublishSettingsFile

    # Import Azure Publish Settings File

    Import-AzurePublishSettingsFile 'path-to-publish-settings-file'

    # Get your Azure subscription ID and certificate

    $subscriptionName = 'your-subscription-name'

    $subscription = Get-AzureSubscription `
        -SubscriptionName $subscriptionName `
        -ExtendedDetails 

    $certificate = $subscription.Certificate

    $subscriptionId = $subscription.SubscriptionId

    Tip! If you've previously authenticated to your Azure subscription via Azure AD credentials using the Add-AzureAccount cmdlet, you may first need to remove the Azure subscription information cached in your local subscription data file by using the Remove-AzureSubscription cmdlet. If you do not perform this step, the management certificate may not be properly returned when calling the Get-AzureSubscription cmdlet above.

    Now that you've run through the lines above, you should have your Azure subscription ID stored in the $subscriptionId variable, and your management certificate should be stored in the $certificate variable.

    How do we Function?

    To make it super-easy to add new monitoring alerts via the Azure Service Management REST API, let's define a new function in PowerShell named New-AzureAlert. When defining this function, we'll include input parameters for each of the key values needed to define a new monitoring alert in an Azure subscription.  We'll also include comment-based help, so that others who are calling this function can easily learn how to use it via the Get-Help cmdlet.

    Tip! See my prior Scripts-to-Tools article for a complete walk-through on each of the components of a PowerShell function.

    Here's the code that we'll use to define the New-AzureAlert function:

    function New-AzureAlert {

       <#
        .SYNOPSIS
        New-AzureAlert defines a new monitoring alert to an existing Cloud
        Service deployment.
        .DESCRIPTION
        New-AzureAlert defines a new monitoring alert to an existing Cloud
        Service deployment
        for IaaS Virtual Machines or PaaS Web/Worker roles.
        For demonstration purposes only.
        No support or warranty is supplied or inferred.
        Use at your own risk.
        .PARAMETER subscriptionId
        The Id of the Azure Subscription in which the Cloud Service is
        deployed
        .PARAMETER certificate
        Certificate used for authenticating to Azure subscription Id
        .PARAMETER cloudServiceName
        The name of an existing Cloud Service, as reported
        by Get-AzureService
        .PARAMETER deploymentName
        The name of an existing deployment within a Cloud Service, as
        reported by Get-AzureDeployment
        .PARAMETER roleName
        The name of an existing role within a Cloud Service deployment, as
        reported by Get-AzureDeployment
        .PARAMETER alertName
        The name for the new Alert to be added.
        The name can contain only letters, numbers, commas, and periods.
        The name can be up to 32 characters long.
        .PARAMETER alertDescription
        Optional description for the new Alert to be added.
        The description can contain only letters, numbers, commas, and
        periods.
        The description can be up to 128 characters long.
        .PARAMETER metricName
        Name of the metric on which to associate an alert rule.
        Valid metricName values include:
        "Percentage CPU"
        "Disk Read Bytes/Sec"
        "Disk Write Bytes/Sec"
        "Network In"
        "Network Out"
        .PARAMETER metricWindowSize
        Rolling timeframe across which metric should be evaluated against
        threshold.
        Valid metricWindowSize values include:
        "PT5M" (5 min)
        "PT15M" (15 min)
        "PT30M" (30 min)
        "PT45M" (45 min)
        "PT60M" (60 min)
        .PARAMETER metricOperator
        Operator used to compare metricName against metricThreshold.
        Value metricOperator values include:
        "GreaterThan"
        "GreaterThanOrEqual"
        "LessThan"
        "LessThanOrEqual"
        .PARAMETER metricThreshold
        Numeric value to which metricName is compared to determine if alert
        should be issued.
        .PARAMETER alertAdmins
        Indicates whether subscription administrators and co-administrators
        should be alerted via email.
        Valid alertAdmins values include: True, False
        .PARAMETER alertOther
        Email address for additional application administrator that should
        be alerted via email.
        .INPUTS
        Parameters above.
        .OUTPUTS
        json output for alert rule configuration that was successfully
        provisioned.
        .NOTES
        Version:        1.0
        Creation Date:  Nov 8, 2014
        Author:         Keith Mayer (
    http://KeithMayer.com )
        Change:         Initial function development
        #>

        [CmdletBinding()]
        param
        (
            [string]$subscriptionId,
            [object]$certificate,
            [string]$cloudServiceName,
            [string]$deploymentName,
            [string]$roleName,
            [string]$alertName,
            [string]$alertDescription,
            [string]$metricName,
            [string]$metricWindowSize,
            [string]$metricOperator,
            [decimal]$metricThreshold,
            [boolean]$alertAdmins,
            [string]$alertOther
        )

        begin {

            $requestHeader = @{
                "x-ms-version" = "2013-10-01";
                "Accept" = "application/json"
            }
            $contentType = "application/json;charset=utf-8"
           
            $alertEnabled = "true"

            if ($alertAdmins) {
                $alertAdminsValue = "true"
            } else {
                $alertAdminsValue = "false"
            }
               
        }

        process {

            $alertId = ([GUID]::NewGuid()).Guid

            $alertManagementUri =
                "
    https://management.core.windows.net/$subscriptionId
                    /services/monitoring/alertrules/$alertID"

            $alertRequest = @"
            {
                "Id":  "$alertID",
                "Name":  "$alertName",
                "IsEnabled":  $alertEnabled,
                "Condition":  {
                                  "odata.type":  "Microsoft.WindowsAzure.Management.Monitoring.Alerts.Models.ThresholdRuleCondition",
                                  "DataSource":  {
                                                     "odata.type":  "Microsoft.WindowsAzure.Management.Monitoring.Alerts.Models.RuleMetricDataSource",
                                                     "ResourceId":  "/hostedservices/$cloudServiceName/deployments/$deploymentName/roles/$roleName",
                                                     "MetricNamespace":  "",
                                                     "MetricName":  "$metricName"
                                                 },
                                  "Operator": "$metricOperator",
                                  "Threshold":  $metricThreshold,
                                  "WindowSize":  "$metricWindowSize"
                              },
                "Actions":  [
                                {
                                    "odata.type":  "Microsoft.WindowsAzure.Management.Monitoring.Alerts.Models.RuleEmailAction",
                                    "SendToServiceOwners":  $alertAdminsValue,
                                    "CustomEmails": [
                                        "$alertOther"
                                    ]
                                }
                            ]
            }
    "@

            [byte[]]$requestBody =
                [System.Text.Encoding]::UTF8.GetBytes($alertRequest)

            $alertResponse = Invoke-RestMethod `
                -Uri $alertManagementUri `
                -Certificate $certificate `
                -Method Put `
                -Headers $requestHeader `
                -Body $requestBody `
                -ContentType $contentType

        }

        end {

            $alertListUri =
                "
    https://management.core.windows.net/$subscriptionID
                    /services/monitoring/alertrules"

            $alerts = Invoke-RestMethod `
                -Uri $alertListUri `
                -Certificate $certificate `
                -Method Get `
                -Headers $requestHeader `
                -ContentType $contentType

            $alerts.Value | ConvertTo-Json

        }
          
    }

    Note that in this function definition, the requests for defining and confirming a new monitoring alert are submitted to the Azure Service Management REST API by calling the Invoke-RestMethod cmdlet in the highlighted code blocks above. This cmdlet was introduced as a new feature in PowerShell 4.0.

    Alert! Alert!

    Our New-AzureAlert function is defined and ready to be used! We can easily call this function to define each monitoring alert as part of a larger provisioning script. 

    $alertRule = New-AzureAlert `
        -alertName "High CPU" `
        -alertDescription "Higher than 80% CPU utilization" `
        -subscriptionId $subscriptionId `
        -certificate $certificate `
        -cloudServiceName "insert-cloud-service-name" `
        -deploymentName "insert-deployment-name" `
        -roleName "insert-VM-role-name" `
        -metricName "Percentage CPU" `
        -metricWindowSize "PT15M" `
        -metricOperator "GreaterThan" `
        -metricThreshold 80.0 `
        -alertAdmins $true `
        -alertOther "[email protected]"

  • End-to-End IaaS Workload Provisioning in the Cloud with Azure Automation and PowerShell DSC ( Part 2 )

    This article is Part 2 of a two-part series on automating the end-to-end provisioning process for IaaS workloads running on the Microsoft Azure cloud platform.  This process includes orchestration of all tasks, provisioning cloud fabric resources, and configuring operating system and application workloads running inside Azure VMs. The end goal of this effort is to provide accelerated "push-button" delivery of highly available, load-balanced cloud applications.

    End-to-End IaaS Provisioning in the Cloud

    In Part 1 of this series, I provided an example of leveraging Azure Automation runbooks and PowerShell Workflows in a concerted approach to fully automate all aspects of deploying new load-balanced VM's on the Microsoft Azure cloud platform. If you haven't yet completed Part 1 of this series, be sure to go do that now, and then come back here when finished to continue on to the Part 2 steps below.

    In this article, I'll provide an example of a working PowerShell DSC Configuration that can be used with Azure Automation runbooks to customize the configuration of operating system and web application components running inside each VM as part of the provisioning process. When we're all done, we'll be able to invoke one runbook to deploy everything needed to bring our web application online: VMs, load-balancing, OS configuration, and Web application content.

    What is PowerShell DSC?

    In prior articles, we've discussed PowerShell Desired State Configuration (DSC) as a declarative approach to specify the end-state of a server and application instance.  This is in contrast to the imperative approach that is commonly used in traditional scripting.  By using a declarative approach, we're able to focus on the end-state to which a set of server and application instances should conform, rather than lots of if-then-else, try-catch conditional logic. In this manner, configuration management is streamlined and we're able to accelerate solution delivery and updates.

    PowerShell DSC was introduced with PowerShell 4.0 for Windows Server 2012 R2, and has since been extended to support Linux as well. In PowerShell 5.0, DSC continues to be enhanced with support for object classes, centralized error reporting, easier resource authoring, cross-computer dependencies and MORE!

    Let's Get Started!

    To complete the scenario presented in this article, you'll want to be sure to download the following components:

    • Download and Install: PowerShell DSC Resource Kit
       
      The PowerShell DSC Resource Kit provides an additional set of over 40 DSC resource modules. In this article, we'll be using the xWebAdministration module for provisioning IIS web application resources.
       
    • Download and Install: Microsoft Azure PowerShell Module
       
      The Azure PowerShell Module provides PowerShell scripting support for Azure subscriptions and cloud resources. In this article, we'll be using the Azure PowerShell Module to publish our DSC Configuration to an Azure Storage Account, where it will be accessible to the Azure VMs that are being provisioned from within the Azure Automation runbook that was defined in Part 1 of this article series.
       
      Tip! If you've previously downloaded the Azure PowerShell Module, be sure that you have the latest version installed on your PC - you can run Get-Module Azure to confirm the installed version of this module. The Azure PowerShell Module is regularly updated to include support for new Azure features, and to support the Azure VM Agent DSC Extension, you should be running version 0.8.6 or later.

    Configure OS and Application payloads inside Azure VMs with PowerShell DSC

    In the DSC Configuration below, we'll define all of the components required for deploying our web application on the base platform image for Windows Server 2012 R2.  This configuration includes the Windows Server features, IIS Web Site configurations, web application content, and SSL certificate that our web application will use. In addition to standard DSC resources, the example below also shows how a DSC Script resource can be leveraged, in this case for deploying the needed SSL certificate.

    Configuration WebSiteConfig
    {

        # Import DSC WebAdmin Module from DSC Resource Kit
        Import-DscResource -ModuleName xWebAdministration

        Node ("localhost")
        {

            # Install the Web Server role
            WindowsFeature IIS
            {
                Ensure = "Present"
                Name = "Web-Server"
            }

           # Install the ASP.NET 4.5 role
            WindowsFeature AspNet
            {
                Ensure = "Present"
                Name = "Web-Asp-Net45"
            }
     
           # Stop the default website 
            xWebsite DefaultSite  
            { 
                Ensure          = "Present" 
                Name            = "Default Web Site" 
                State           = "Stopped" 
                PhysicalPath    = "C:\inetpub\wwwroot" 
                DependsOn       = "[WindowsFeature]IIS" 
            } 
           
            # Copy web application content
            File MyWebAppContent
            {
                Ensure = "Present"  # You can also set Ensure to "Absent"
                Type = "Directory" # Default is "File".
                Recurse = $true # Ensure presence of subdirectories, too
                SourcePath = "\\XXXdemoad01\source\MyWebApp"
                DestinationPath = "C:\inetpub\MyWebApp"
                DependsOn = "[WindowsFeature]AspNet"   
            }

            # Install SSL Certificate
            Script MyWebAppCert
            {
                SetScript =  "Import-PfxCertificate
                  -FilePath \\XXXdemoad01\source\certs\MyWebAppCert.pfx
                  -CertStoreLocation Cert:\LocalMachine\WebHosting"
                TestScript = "try { (Get-Item
                  Cert:\LocalMachine\WebHosting\
                  C534DFBFE8DB597F22320682F7BBFBA2611DC45A
                  -ErrorAction Stop).HasPrivateKey} catch { `$False }"
                GetScript = "@{Ensure = if ((Get-Item
                  Cert:\LocalMachine\WebHosting\
                  C534DFBFE8DB597F22320682F7BBFBA2611DC45A
                  -ErrorAction SilentlyContinue).HasPrivateKey)
                  {'Present'}
                  else {'Absent'}}"
                DependsOn = "[WindowsFeature]IIS"
            }

            # Create the web site for MyWebApp 
            xWebsite MyWebAppSite  
            { 
                Ensure       = "Present" 
                Name         = "MyWebApp" 
                State        = "Started" 
                PhysicalPath = "C:\inetpub\MyWebApp"
                BindingInfo  = MSFT_xWebBindingInformation
                               {
                               Protocol              = "HTTPS"
                               Port                  = 443
                               CertificateThumbprint =
                              "C534DFBFE8DB597F22320682F7BBFBA2611DC45A"
                               CertificateStoreName  = "WebHosting"
                               }
                DependsOn    = @("[WindowsFeature]IIS",
                                 "[File]MyWebAppContent",
                                 "[Script]MyWebAppCert") 
            } 

        }

    }

    After entering the DSC Configuration above, save it to a local PowerShell script file, such as AADSCWebConfig.ps1.

    Tip! You may have noted in the DSC Configuration above that we're not specifying a password when importing the SSL Certificate as part of the Script MyWebAppCert DSC resource. Instead of using a password, we're storing this SSL certificate in a secured shared folder to which only domain computers have read access. In addition, when exporting the SSL Certificate to this folder as a PFX file, instead of protecting it with a password, we used the option to restrict access to only specific Active Directory computer accounts - a new security feature that was introduced in Windows Server 2012.

    Publish PowerShell DSC Configuration to Azure Storage Account

    After saving the DSC Configuration as a local PowerShell script file, we'll need to publish this configuration to an Azure Storage Account container so that the Azure VMs we are provisioning will be able to access it. To perform this publishing process, we'll use the Azure PowerShell Module and the script snippet below from within a new Windows PowerShell ISE session window.

    # Authenticate to Azure
    Add-AzureAccount

    # Select Azure Subscription and Storage Account
    $subscriptionName = (Get-AzureSubscription).SubscriptionName |
        Out-GridView `
            -Title "Select Your Azure Subcription" `
            -PassThru
     
    Select-AzureSubscription `
        -SubscriptionName $subscriptionName
     
    $storageName = (Get-AzureStorageAccount).StorageAccountName |
        Out-GridView `
            -Title "Select Your Azure Storage Account" `
            -PassThru
     
    Set-AzureSubscription `
        -SubscriptionName $subscriptionName `
        -CurrentStorageAccountName $storageName

    # Publish DSC Configuration to Azure Storage Account
    Publish-AzureVMDscConfiguration `
        -ConfigurationPath .\AADSCWebConfig.ps1 `
        -Force

    Tip! When selecting the Azure Subscription and Storage Account in the code snippet above, be sure to select the same Subscription and Storage Account used in Part 1 of this article series within your Azure Automation Runbook.

    During the publishing process above, the DSC Configuration will be packaged in a .ZIP file along with any modules imported using Import-Module in the Configuration block.  By default, this resulting .ZIP file package will be uploaded to a storage container named windows-powershell-dsc in the selected Azure Storage Account.

    Use Azure VM Agent extensions to apply PowerShell DSC Configuration

    We've got our PowerShell DSC Configuration defined and published to our Azure Storage Account.  Now, we'll need to add a bit of extra code to the original Azure Automation Runbook that we built in Part 1 of this series. This additional code will apply our published DSC Configuration inside each VM using the Azure VM Agent DSC extension.

    Open the Azure Automation Runbook that you defined in Part 1 of this series and edit it in Draft mode. Insert the highlighted code between the Set-AzureSubnet and New-AzureVM code blocks as shown below.

    ...

    # Specify HA Availability Set for VM
    $vm = Set-AzureAvailabilitySet `
        -VM $vm `
        -AvailabilitySetName $Using:availabilitySetName
     
    # Specify DSC Configuration to Apply within VM
    $vm = Set-AzureVMDSCExtension `
        -VM $vm `
        -ConfigurationArchive $Using:dscArchive `
        -ConfigurationName $Using:dscConfigName

     
    # Provision new VM with specified configuration
    New-AzureVM `
       -VMs $vm `
       -ServiceName $Using:vmServiceName `
       -VnetName $Using:vNetName `
       -AffinityGroup $Using:affinityGroupName `
       -WaitForBoot

    ...

    That's it! Save and test your revised Runbook.  Upon Runbook completion, you should have your finished cloud application fully deployed - cloud fabric resources, OS configuration, web application content and application settings - all from a single "push-button".

    What's next?

    In future articles, I'll be expanding on additional scenarios around automation with Microsoft Azure. In the meantime, be sure to check out these additional resources to continue your learning:

  • End-to-End IaaS Workload Provisioning in the Cloud with Azure Automation and PowerShell DSC ( Part 1 )

    In prior articles, we've discussed Azure Automation, Azure VM Agent extensions and PowerShell Desired State Configuration (DSC) as individual tools and approaches for automated workload provisioning.  I'm frequently asked about how these tools can be used together to orchestrate end-to-end provisioning of cloud workloads, including fabric, OS and application components.

    image

    This article is Part 1 of a two-part series. 

    In this article, I'll provide an example of leveraging Azure Automation runbooks and PowerShell Workflows in a concerted approach to fully automate all aspects of provisioning new IaaS workloads on the Microsoft Azure cloud platform.

    In Part 2 of this series, I'll provide an example of a working PowerShell DSC Configuration that can be used with Azure Automation runbooks to customize the configuration of operating system and application components running inside each  VM as part of the provisioning process.

    What, when and where?

    We certainly don't have a lack of automation technologies these days! In fact, one could argue that we have so many different tools for automation, that sometimes it can be confusing to know which tools to leverage for a particular scenario. As I've been helping customers with automated provisioning sequences, here's an approach that I've found works well:

    1. Orchestrate overall provisioning process with Azure Automation
       
    2. Provision cloud fabric resources with PowerShell Workflow activities using Azure Automation Runbooks
       
    3. Configure OS and Application payloads inside Azure VMs with PowerShell DSC
       
    4. Publish PowerShell DSC Configuration to Azure Storage Account
       
    5. Use Azure VM Agent extensions to apply PowerShell DSC Configuration

    In the near future, Azure Resource Manager (ARM) will also be worthwhile including in your automation toolkit to manage cloud resources as a related group of dependencies. However, currently automation of ARM is limited to a subset of Azure PaaS resources.  Azure IaaS support is coming soon, so be sure to watch this space for updates!

    In the next few sections of this article, I'll step through the details around steps #1 and #2 above.  In part 2 of this two-part series, I'll finish-up with coverage of steps #3, #4 and #5.

    Prepare your Azure subscription

    The example in this article assumes that you already have a few basic IaaS components provisioned in your Azure subscription with a consistent naming convention, including:

    • Affinity group: xxxlabag01
    • Storage account: xxxlabstor01
    • Virtual network: xxxlabnet01
    • Windows Server Active Directory VM: xxxlabad01

    When provisioning these components, replace xxx with your unique initials to arrive at a consistent naming convention that provides globally unique names for the storage account and cloud service for the Windows Server Active Directory domain controller VM. If you need help provisioning these IaaS components, check out the following resources to help you get started:

    Orchestrate overall provisioning process with Azure Automation

    Azure Automation provides a reliable, scalable platform service for orchestrating long-running processes that potentially touch several services and resources. Automation sequences are built as runbooks that include PowerShell Workflow activities. By leveraging PowerShell Workflows, Azure Automation runbooks can be suspended, resumed and recover from unexpected occurences while preserving current state of completed activities within the runbook.

    If you haven't yet setup Azure Automation in your Microsoft Azure subscription or need some help with the basics of creating runbooks, check out this step-by-step article to walk through the process for getting started ...

    Once your Azure Automation account is setup and ready to go, let's create a new Azure Automation runbook for provisioning our new cloud application, which we'll call MyWebApp in this article.

    workflow New-MyWebAppDeployment
    {

    }

    As mentioned above, Azure Automation runbooks leverage PowerShell Workflows, which is why we're defining our new runbook with the workflow keyword above.

    • Tip! For step-by-step guidance on the basics of creating new runbooks, be sure to reference the Getting Started article linked above for a quick primer.

    In an effort to make this runbook reusable for a variety of provisioning scenarios, I'll define a set of parameter inputs at the top of the workflow. Azure Automation will prompt for user input for each defined parameter when manually starting this runbook, or you can supply these parameter values when programmatically invoking this runbook from another runbook or PowerShell script.

    workflow New-MyWebAppDeployment
    {
       
        param(
           
            [parameter(Mandatory=$true)]
            [String]
            $subscriptionName,
           
            [parameter(Mandatory=$true)]
            [String]
            $deploymentPrefix,
           
            [parameter(Mandatory=$true)]
            [Int]
            $numberOfVMs,
           
            [parameter(Mandatory=$true)]
            [String]
            $vmInstanceSize,
           
            [parameter(Mandatory=$true)]
            [String]
            $vmDomain,
       
            [parameter(Mandatory=$true)]
            [String]
            $vmDomainNetBIOS
       
        )

    }

    Let's also declare a set of variables near the top of our workflow for common values that will be used when provisioning virtual machines,

    workflow New-MyWebAppDeployment
    {

           ... continued from above ...

           # Get Azure credential for authenticating to Azure subscriptions
       $cred = Get-AutomationPSCredential -Name 'AzureAutomationAccount'

       # Get vmAdmin credential for admin access inside each VM
       $vmAdmin = Get-AutomationPSCredential -Name 'AzureAdmin'
      
       # Set common variable values for provisioning each VM
       $storageName = $deploymentPrefix + 'stor01'
       $vmServiceName = $deploymentPrefix +'app'
       $affinityGroupName = $deploymentPrefix + 'ag01'
       $availabilitySetName = $deploymentPrefix + 'app'
       $vNetName = $deploymentPrefix + 'net01'
       $subnetName ='Subnet-1'
       $dscArchive = 'AADSCWebConfig.ps1.zip'
       $dscConfigName = 'WebSiteConfig'

    }

    Now that we've got the initial portion of our runbook created, let's save it as a draft and continue with adding the code that will provision our VM and application.

    Provision cloud fabric resources with PowerShell Workflow activities

    In the param section of our runbook workflow above, you'll note that we defined a $numberOfVMs parameter to accept, as input, the number of load-balanced VMs that we'd like to provision for our application.  To provide flexibility in provisioning a variable number of VMs, we'll add a for loop in our workflow that will handle the provisioning for each VM.

    workflow New-MyWebAppDeployment
    {

          ... continued from above ...

       for ($i=1; $i -le $numberOfVMs; $i++)
       {

       }

    }

    As each iteration of the for loop above begins, we'll add code to checkpoint current workflow state and connect to the desired Azure subscription.

    workflow New-MyWebAppDeployment
    {

           ... continued from above ...

       for ($i=1; $i -le $numberOfVMs; $i++)
       {

            # Save current state of workflow
            Checkpoint-Workflow
          
            # Connect to Azure subscription
            Add-AzureAccount -Credential $cred

            Select-AzureSubscription `
              -SubscriptionName $subscriptionName
          
            # Set current Azure Storage Account
            Set-AzureSubscription `
              -SubscriptionName $subscriptionName `
              -CurrentStorageAccountName $storageName

       }

    }

    Cloud workload provisioning tasks could involve many different cloud resources and be relatively long-running sequences.  Taking the above approach of checkpointing workflow state and reconnecting to the desired Azure subscription with each iteration of our for loop will provide the ability for this runbook to gracefully resume in the event that the workflow was suspended or unexpectedly interrupted.

    Next, let's add our code for provisioning each VM inside the for loop we've defined above. Since provisioning a new Azure VM can involve several individual activities to build the desired VM configuration, we'll group all of these related steps into a single InlineScript workflow activity.

    workflow New-MyWebAppDeployment
    {

           ... continued from above ...

       for ($i=1; $i -le $numberOfVMs; $i++)
       {

            Checkpoint-Workflow
          
            # Connect to Azure subscription
            Add-AzureAccount -Credential $cred

            Select-AzureSubscription `
              -SubscriptionName $subscriptionName
          
            # Set current Azure Storage Account
           
    Set-AzureSubscription `
              -SubscriptionName $subscriptionName `
              -CurrentStorageAccountName $storageName

            # Provision VM
            InlineScript {
        
                 $currentVM = "{0:D2}" -f $Using:i
                 $vmName = $Using:deploymentPrefix + 'app' + $currentVM
                 $vmImage = @((Get-AzureVMImage |
                   Where-Object Label -like `
                   "Windows Server 2012 R2 Datacenter*").ImageName)[-1]
                 $vmAdmin = $Using:vmAdmin
         
                 # Specify VM name, image and size
                 $vm = New-AzureVMConfig `
                   -Name $vmName `
                   -ImageName $vmImage `
                   -InstanceSize $Using:vmInstanceSize
        
                 # Specify VM local admin and domain join creds
                 $vm = Add-AzureProvisioningConfig `
                   -VM $vm `
                   -WindowsDomain `
                   -AdminUserName $vmAdmin.Username `
                   -Password $vmAdmin.GetNetworkCredential().Password `
                   -JoinDomain $Using:vmDomain `
                   -Domain $Using:vmDomainNetBIOS `
                   -DomainUserName $vmAdmin.Username `
                   -DomainPassword `
                     $vmAdmin.GetNetworkCredential().Password
            
                 # Specify load-balanced firewall endpoint for HTTPS
                 $vm = Add-AzureEndpoint `
                   -VM $vm `
                   -Name 'WebHTTPS' `
                   -LBSetName 'LBWebHTTPS' `
                   -DefaultProbe `
                   -Protocol tcp `
                   -LocalPort 443 `
                   -PublicPort 443
        
                 # Specify VNet Subnet for VM
                 $vm = Set-AzureSubnet `
                   -VM $vm `
                   -SubnetNames $Using:subnetName
            
                 # Specify HA Availability Set for VM
                 $vm = Set-AzureAvailabilitySet `
                   -VM $vm `
                   -AvailabilitySetName $Using:availabilitySetName
     
                 # Provision new VM with specified configuration
                 New-AzureVM `
                   -VMs $vm `
                   -ServiceName $Using:vmServiceName `
                   -VnetName $Using:vNetName `
                   -AffinityGroup $Using:affinityGroupName `
                   -WaitForBoot
     
             }

        }

    }

    At this point, you can save and test your new runbook.  When testing the runbook, you'll be prompted to input values for each parameter we defined. When prompted for a DeploymentPrefix, enter xxxlab, where xxx is your unique initials used at the top of this article. This prefix will be prepended to the Azure resource names used within the runbook to reference your unique naming convention.

    After the runbook completes, you will have multiple VMs in the specified Azure subscription, storage account, affinity group and virtual network.  Assuming you have a Windows Server Active Directory domain controller VM running on that same virtual network, each new VM will also be joined as a member server to the specified Active Directory domain.

    What's next?

    In Part 2 of this series, we'll walk through wiring in PowerShell DSC to configure the operating system and applications inside the VM as part of the provisioning process ...

  • Deck and resources: Disaster Recovery to the Cloud with Azure Site Recovery

    Thank you to those who attended my talk at CloudDevelop 2014 on Disaster Recovery to the Cloud with Azure Site Recovery today. We had some great discussions on disaster recovery planning scenarios!  I'm providing a copy of the deck we used for our session, as well as a set of additional resources that may be helpful when planning your disaster recovery approach with Azure Site Recovery.

    Deck: Disaster Recovery to the Cloud with Microsoft Azure

    Download a copy of this deck for offline review.

    Additional resources

    Continue your learning with these additional study materials ...

    - Keith

  • Deck and resources: Open Source + Microsoft Azure

    Thank you to those who attended my webcast event on Open Source + Microsoft Azure last week. It was a great opportunity to discuss and demonstrate the broad support that's available on the Azure cloud platform for Open Source software solutions! In this article, I'm providing a copy of the deck we used for our session, as well as a set of additional resources that may be helpful in your continued learning and preparation around Open Source scenarios with Azure.

    Deck: Open Source + Microsoft Azure

    Download a copy of this deck for offline review.

    Additional resources

    Continue your learning with these additional hands-on study materials ...

    - Keith

  • IT Camp deck and resources: Modernizing Your Infrastructure with Hybrid Cloud

    Thank you to those who attended my IT Camp event on Modernizing Your Infrastructure with Hybrid Cloud today in Chicago IL. I certainly enjoyed discussing cloud migration scenarios with everyone! In this article, I'm providing a copy of the deck we used for our sessions today, as well as a set of additional resources that may be helpful in your continued learning and preparation around Hybrid Cloud scenarios.

    Deck: Modernizing Your Infrastructure with Hybrid Cloud

    Download a copy of this deck for offline review.

    Additional resources

    Continue your learning on Hybrid Cloud with these additional hands-on study materials ...

    See you in the clouds!

    - Keith

  • Cloud-to-Cloud: Migrating Ubuntu Linux Virtual Machines to Microsoft Azure from Amazon AWS

    A short time ago, I assisted an organization with defining a process for migrating web applications and data running on Ubuntu Linux virtual machines to the Microsoft Azure cloud platform from Amazon AWS.  In this article, I’m documenting the general steps we used in an attempt to help other organizations that may be planning a similar migration approach.

    image

    NOTE: These steps were performed to migrate virtual machines running applications on Ubuntu Linux 14.04 and Apache2 to Microsoft Azure. The specific steps presented in this article may vary based on Linux operating system version as well as installed applications and packages. Use at your own discretion.

    Task 1: Before you begin … BACKUP!

    The migration process presented in this article makes minimal changes to the source virtual machines to prepare them for a successful migration. However, as with all migrations, performing and verifying a complete system backup is recommended to ensure that you can easily revert back to the original application environment, if necessary.

    Task 2: Confirm source OS distro and version

    For the migration to be successful, the same Linux operating system distribution and version should be used for both source and target virtual machines. Others have successfully migrated between particular distros or versions, but the migration process for such a migration often requires an intimate knowledge of the source and target operating system configurations and can involve several additional tasks that are unique to each operating system version in use.

    On each source VM, you can confirm the operating system distro and version with the following commands:

    cat /etc/issue

    uname --all

    Task 3: Provision target virtual machines on Microsoft Azure

    Based on the information collected above in Task 2, provision new target virtual machines on the Microsoft Azure cloud platform using the same operating system distribution and version as the source virtual machines. I've recently published a Quick Start Guide which can be used to step through this process.

    Task 4: Update source and target virtual machines to latest package versions

    To help ensure that platform images between cloud providers are running the same version of key operating system packages, update these packages to the latest versions on both source and target virtual machines.

    sudo apt-get update

    sudo apt-get upgrade

    Task 5: Install rsync and screen packages on source and target virtual machines

    The migration of application packages and files in this process will use rsync over ssh between source and target virtual machines. The actual transfer of files between virtual machines can take some time, so I also recommend using screen so that you can easily re-attach to an in-progress migration session if you are inadvertently disconnected.

    Ensure that rsync and screen packages are installed on both the source and target virtual machines with these commands:

    sudo apt-get install rsync

    sudo apt-get install screen

    Task 6: Add a consistent user account to both source and target virtual machines

    To facilitate the migration process, ensure that you have a consistent user account configured on both source and target virtual machines with sudo enabled.  The newly provisioned target virtual machines from Task 3 already include a user named azureuser with sudo enabled.  To configure this same user on each source virtual machine, use the following commands:

    sudo groupadd -g 500 azureuser

    sudo useradd -u 500 -g 500 -m -s /bin/bash azureuser

    sudo passwd azureuser

    When prompted for a new password for azureuser, enter the same password used when provisioning the target virtual machines in Task 3.

    Task 7: Start a screen session for the migration

    On the source virtual machine, enter a new screen session for the migration by using the following command:

    sudo screen -S AzureMigration

    If you are disconnected from the source virtual machine during the migration process, you can reconnect to the detached screen session by using the following command after signing in again to the source virtual machine:

    sudo screen -r

    Task 8: Build an exclusion list of directories and files

    During the migration, we want to be careful to skip any files that include configuration information relating to the identity of the source virtual machines, such as IP addresses, hostnames, ssh keys, etc. For the Ubuntu-based virtual machines that we migrated, we used the following commands on each source virtual machine to build our list of directories and files to exclude from the migration process:

    EXCLUDEFILE=/tmp/exclude.file

    EXCLUDELIST='/boot /etc/fstab /etc/hostname /etc/issue /etc/hosts
    /etc/sudoers /etc/networks /etc/network/* /etc/resolv.conf
    /etc/ssh/* /etc/sysctl.conf /etc/mtab /etc/udev/rules.d/*
    /lock /net /tmp'

    EXCLUDEPATH=$(echo $EXCLUDELIST | sed 's/\ /\\n/g')

    echo -e $EXCLUDEPATH > $EXCLUDEFILE

    find / -name '*cloud-init*' >> $EXCLUDEFILE

    find / -name '*cloud-config*' >> $EXCLUDEFILE

    find / -name '*cloud-final*' >> $EXCLUDEFILE

    The actual list of directories and files that you exclude may vary from this list, based on the Linux distro version, packages and applications that you are migrating.

    Credits: Kudos to Kevin Carter who wrote a great article a couple years ago that provided a useful starting point for building a list of directories and files to consider excluding as part of a Linux-to-Linux migration process!

    Task 9: Stop applications during migration

    To minimize application data changes from occurring during the migration process, stop the related applications and daemons on the source virtual machines. The application that we migrated was a web application built using Apache2, so we simply stopped the related Apache2 daemon.

    sudo service stop apache2

    Task 10: Migrate the application files and data

    From each source virtual machine, migrate application files and data using two rsync passes over ssh.  The first pass performs the bulk of the data transfer, whereas the second pass uses checksums to confirm that all files were transferred successfully.

    TARGETVM="insert_target_vm_public_ip_address"

    rsync -e "ssh" -rlpEAXogDtSzh -P -x --exclude-from="$EXCLUDEFILE" --rsync-path="sudo rsync" --verbose --progress / azureuser@$TARGETVM:/

    rsync -e "ssh" -crlpEAXogDtSzh -P -x --exclude-from="$EXCLUDEFILE" --rsync-path="sudo rsync" --verbose --progress / azureuser@$TARGETVM:/

    Task 11: Restart each target virtual machine

    After both rsync passes have completed, restart each target virtual machine to complete the migration process.

    ssh azureuser@$TARGETVM

    shutdown -r now

    Completed! What's your migration scenario?

    Do you have a different migration scenario from what's been presented in this article? If so, feel free to leave the details for your scenario in the Comments section below for us to consider documenting in a future article.

  • Tools for Building Professional Cloud Architecture Diagrams

    I’m frequently asked about templates, stencils and shapes that are available for documenting the architecture of cloud-based solutions on Microsoft Azure, Azure Pack and Office 365. Using the tools described in this article, you can quickly build professional architecture diagrams for cloud scenarios. These tools are also useful when creating presentation decks, training materials, whitepapers and infographics.

    Click to enlarge ...
    Sample LOB App Architecture on Azure IaaS

    Several completed examples using these tools are available on the MSDN Azure Architecture Blueprints page, such as the Line of Business Applications IaaS diagram above (click on it to zoom in).

    Microsoft Azure Symbol Sets

    Azure symbol/icon/shape sets are available for download in PowerPoint, Visio and PNG formats.

    Click to download Official Microsoft Azure Symbol/Icon set
    Official Microsoft Azure Symbol Sets

    Office 365 Visio Stencil

    Visio shapes for documenting Office 365, Exchange Server 2013, SharePoint Server 2013 and Lync Server 2013 deployments are also available as a free download.  This set of stencils includes more than 300 icons and shapes.

    Download Office Visio Stencil Set
    Office Visio Stencil for Office 365, Exchange 2013, SharePoint 2013 and Lync 2013

    Additional Shapes for Azure Pack and System Center

    In addition to the “official” templates above, Microsoft MVP Kevin Greene has done an outstanding job in building an “unofficial” set of Visio stencils for System Center and Azure Pack.  These stencils are super-useful when documenting Private Cloud and Hybrid Cloud architectures.

    Have you found additional templates and tools?

    Have you found additional templates, shapes and tools that you use when documenting the architecture of cloud solutions? Feel free to share any tools that you’ve found helpful in the Comments area below!

  • Quick Start Guide: Building Highly Available Linux Servers in the Cloud on Microsoft Azure in 12 Steps

    Linux is certainly a first-class workload on the Microsoft Azure cloud platform, and it's super-easy to get started with Linux + Azure to build a highly available and scalable solution in just a few minutes.

    Download this Quick Start Guide!

    To help jump-start your skills on the steps for building Linux server solutions with Azure, I've prepared a Quick Start Guide that you can download, follow, and share with others in your community ...

    Building Linux Servers on Microsoft Azure Virtual Machines

    Download a copy of this Quick Start Guide for viewing offline.

    Looking for more Linux images?

    After you've stepped through this guide, be sure to check out our VMDepot repository containing hundreds of other pre-built Linux virtual machine images that you can quickly provision on the Microsoft Azure cloud platform.

  • TechNet Radio: (Part 13) Building Your Hybrid Cloud - Cross-Premises Virtual Networking with Site-to-Site VPN and ExpressRoute

    Continuing our “ Building a Hybrid Cloud ” series, Keith Mayer and Andy Syrewicze walk us through the steps of creating a cross-premises Virtual Network connection between Microsoft Azure and an on-premise data center. Tune in for this demo heavy session and get the 411 on how to do implement this important step in building your hybrid cloud environment. [ 1:01 ] What is Cross-Premises Virtual Networking? [ 6:05 ] What are the options for connecting Azure and Azure Pack networks together? [ 9:35 ...read more
  • NEW Windows Server Technical Preview: FASTEST Way to Spin-Up Your Test Lab Environment in the Cloud with Microsoft Azure

    With all of the buzz this week around the recently announced Windows 10 Technical Preview, you may have missed this announcement that a Technical Preview for the next version of Windows Server and System Center is also now available. 

    Click to enlarge ...
    Windows Server Technical Preview – Server Manager and Start Menu

    The Windows Server technical preview bits are now available as a virtual machine image on the Microsoft Azure cloud platform.  Using this VM image on Microsoft Azure, you can spin-up your own test lab environment in the cloud in just a couple minutes – faster than you can download the installation bits from the TechNet Evaluation Center or MSDN Subscription Downloads.

    In this article, I’ll provide the steps for provisioning your own Windows Server Technical Preview test lab environment on the Microsoft Azure cloud platform.  Keep in mind that these bits contain an early pre-release build of the next version of Windows Server; these bits are not intended for running in a production environment.

    • Editor's Note: If you'd like to automate these steps with PowerShell, be sure to also read Trevor Sullivan's great article HERE.

    Before You Begin

    To follow along with the steps in this article, you will need an active subscription for Microsoft Azure.  If you don’t yet have an active subscription, you can sign-up for your own FREE Microsoft Azure trial subscription using the link below.

    Let’s Get Started

    Now you have your own active Microsoft Azure subscription, follow these steps to build your own Windows Server Technical Preview test lab in the cloud:

    1. Sign-in at the Microsoft Azure Management Portal with the user credentials that you used when activating your Microsoft Azure subscription.
       
    2. Click Virtual Machines on the left navigation panel.
       
      Click to enlarge ...
       
    3. On the bottom black toolbar, click the +NEW button.
       
    4. On the New pop-up menu, click From Gallery.
       
    5. On the Choose an Image page, scroll down the list of featured images and select Windows Server Technical Preview.
       
      Click to enlarge ...
       
      Click the Continue button to continue.
       
    6. On the Virtual Machine Configuration page, enter a unique Virtual Machine Name and also enter a local administrator User name and Password that will be provisioned as logon credentials for your new virtual machine.
       
      Click to enlarge ...
       
      Click the Continue button to continue.
       
    7. On the next Virtual Machine Configuration page, select your closest Microsoft Azure datacenter region in the Region / Affinity Group / Virtual Network field.
       
      Click to enlarge ...
       
      Click the image button to continue.
       
    8. On the last Virtual Machine Configuration page, accept all default values.
       
      Click to enlarge ....
       
      Click the image button to begin provisioning your new virtual machine.
       
    9. After a few minutes, the provisioning of your new Windows Server Technical Preview virtual machine will be completed, and the VM will be displayed on the Virtual Machines page with a Running status.
       
      Click to enlarge ...
       
    10. To sign-in to the remote console of your new Virtual Machine, click the Connect button on the bottom black toolbar and then click the Open button to open the .rdp file.
       
      Click to enlarge ...
       
      When prompted, sign-in with the local administrator user credentials that you specified in Step 6 above when provisioning your virtual machine.

    Congratulations! You’ve completed the provisioning of a new test lab in the cloud for Windows Server Technical Preview using Microsoft Azure!

    Continue learning …

    We’ll be blogging more about Windows Server Technical Preview in the coming weeks.  In the meantime, here’s some additional resources that you may wish to check-out to continue your evaluation of Microsoft Azure and Windows Server Technical Preview …

  • Dog Food Conference 2014 - Azure Automation & Hybrid Cloud - Decks and Resources

    Thank you for attending my breakout sessions at Dog Food Conference 2014 on Azure Automation and Hybrid Cloud. It was great meeting you all and discussing your scenarios with the Microsoft Azure cloud platform! For your convenience, I've included my decks below for each session.  At the end of each deck, links to additional resources for learning more on each topic area are provided.

    Orchestrating the Cloud with Azure Automation

    Download this deck for offline viewing.

    Seven Ways You Can Use Hybrid Cloud TODAY!

    Download this deck for offline viewing.

    And ... a FREE EBOOK too!

    To assist in your continued exploration of Hybrid Cloud Management, I'm also providing a free copy of my ebook on Cloud Management with System Center 2012 R2 App Controller.

    Download this FREE EBOOK!

    See you next year at Dog Food Con!

    I hope to see you again next year at Dog Food Conference 2015!

    - Keith

  • Modernizing Your Infrastructure with Hybrid Cloud - Getting Started with Automating the Hybrid Cloud using PowerShell (Part 24)

    This article is Part 24 in the Modernizing Your Infrastructure with Hybrid Cloud series by our US IT Pro team.  After you read this article, be sure to catch the full series for more information and resources.

    When migrating to Hybrid Cloud, developing automated standards for provisioning and managing application workloads is key to accelerating the predictable deployment of new business solutions.  As you begin developing scripts and workflows, being able to do so with consistency across on-premises datacenters and cloud platforms is important to promote reusability and agility when migrating these workloads.

    image

    Get Started with Hybrid Cloud Automation

    Earlier this week in our Modernizing Your Infrastructure with Hybrid Cloud series, Yung Chou and I demonstrated the ability to leverage Windows PowerShell and the Azure PowerShell module as an easy way to get started with automation tasks for both Azure Pack private clouds and Microsoft Azure public clouds via the tenant service management API and PowerShell cmdlets.

    So that you can follow along with this step-by-step demo, I’ve included the PowerShell snippets that we walked through in the section below.

    PowerShell Snippets for Tenant API

    To use the snippets below, you’ll need the following items to be setup in your environment:

    • An active Microsoft Azure subscription.  If you don’t currently have an active Microsoft Azure subscription, sign-up for a free trial subscription account.
       
    • Azure Pack in an on-premises private cloud environment.  To get started with your Azure Pack deployment, follow these steps.
       
    • The latest version of the Azure PowerShell module.  You can download and install this module from the Azure Download Center.

    After you’ve confirmed that you’ve met these requirements, open your Windows PowerShell ISE and copy/paste the snippet below to follow along with the step-by-step demo referenced above.

    # Display version of Azure PowerShell module
    Get-Module -Name Azure

    # Display Azure environments available
    Get-AzureEnvironment

    # Authenticate to Azure
    Add-AzureAccount

    # Show available Azure subscriptions
    (Get-AzureSubscription).SubscriptionName

    # List provisioned Azure VMs
    Get-AzureVM

    # Add new Azure environment for Azure Pack
    Add-AzureEnvironment `
        -Name "AzurePackOnPrem" `
        -PublishSettingsFileUrl "https://kemlabwap01.kemlabdom01.keithmayer.com:30081/publishsettings"

    # Authenticate to Azure Pack
    Get-AzurePublishSettingsFile `
        -Environment "AzurePackOnPrem"
    Import-AzurePublishSettingsFile `
        -PublishSettingsFile "E:\INSTALL\Developer Plan.publishsettings"

    # Show available Azure subscriptions
    (Get-AzureSubscription).SubscriptionName

    # Select the Azure subscription associated with the Developer Plan
    Select-AzureSubscription `
        -SubscriptionName "Developer Plan"

    # Get Windows Azure Pack VM names
    (Get-WAPackVM).Name

    # Manage Windows Azure Pack resources
    $vm = Get-WAPackVM -Name "dev02vm"
    Stop-WAPackVM -VM $vm
    Start-WAPackVM -VM $vm

    # Provision new Azure Pack resources
    (Get-WAPackVNet).Name
    $vNet = Get-WAPackVNet `
        -Name "kemlabdom01"
    (Get-WAPackVMTemplate).Name
    $vmTemplate = Get-WAPackVMTemplate `
        -Name "DB Server"
    $creds = Get-Credential
    New-WAPackVM `
        -Name "DB01" `
        -Template $vmTemplate `
        -VMCredential $Credentials `
        -Windows `
        -VNet $vNet

    Learn more about Hybrid Cloud Automation …

    Once you’ve completed this example for getting started with Hybrid Cloud automation, learn more with these additional resources:

  • Step-by-Step: Getting Started with NEW Microsoft Azure Automation preview feature

    UPDATE: Azure Automation has been updated to support Azure Active Directory authentication to simplify the steps for getting started! As an alternative to the steps below for configuring certificate-based authentication, check out this article by Joe Levy, Program Manager on the Azure Automation team,  for getting started with Azure AD with Azure Automation..


    Earlier this week, Microsoft Azure Automation was made available on the Microsoft Azure cloud platform as a public preview.  This new feature allows you to automate the creation, monitoring, deployment and management of cloud resources in your Microsoft Azure subscription using a highly-available workflow execution engine.  Azure Automation provides an orchestration feature set for public cloud resources that is similar to what the Service Management Automation (SMA) engine provides for on-premises private cloud resources via the Windows Azure Pack and System Center 2012 R2 Orchestrator.

    Activate the Azure Automation preview feature!

    Azure Automation is super-cool, because it allows us to perform automated cloud provisioning and management without needing to manually build and manage a separate set of automation servers.  And … scalability and high availability of the Azure Automation engine is provided natively via the Microsoft Azure cloud platform without any extra configuration steps, which helps to make sure that your scheduled runbooks will always execute when needed.

    • Note: this week, we also announced support for Puppet and Chef for automated provisioning and configuration management of Microsoft Azure cloud resources. If you're currently using these tools as part of your DevOps strategy, be sure to look for upcoming articles that focus on these alternatives for cloud automation.

    In this article, I’ll step through the process of getting started with Azure Automation. Along the way, we’ll build a runbook and PowerShell workflow for performing basic automation of Microsoft Azure virtual machines.

    Activate the Preview Feature for Azure Automation

    To leverage Microsoft Azure Automation, you’ll need an active Azure subscription with the Microsoft Azure Automation preview feature activated.

    1. Activate a FREE Microsoft Azure subscription (if you don’t yet have an Azure subscription).
       
    2. Activate the Azure Automation preview on the Preview Features page.
       
      Activate the Azure Automation preview feature!
       
      Click the Try it Now button.

    Create an Azure Automation Account

    1. After the Azure Automation preview feature has been activated, sign-in at the Azure Management Portal to manage this feature.
       
      Click to enlarge ...
       
      Scroll-down the left blue navigation bar and click Automation.
       
    2. Click the Create button on the bottom black toolbar to define a new Azure Automation account for managing Runbooks.
       
      Click to enlarge ...
       
      After specifying an Account Name and Region, click the image button to create the account.

    Create and Export a Management Certificate

    Azure Automation authenticates to Microsoft Azure subscriptions using certificate-based authentication.  You can create and export a new management certificate using the Internet Information Services (IIS) Manager tool from any Windows Server installed with the IIS Web Server role and management tools.

    Use the steps below to create and export a new management certificate from a server running Windows Server 2012 or 2012 R2.  After creating a new certificate, you will export this certificate as a .CER file for uploading to your Microsoft Azure subscription and also as a .PFX file for uploading to your Azure Automation account.

    1. If not already installed, you can install the IIS Web Server role and related management tools with the Install-WindowsFeature PowerShell cmdlet:
       
      Install-WindowsFeature Web-Server –IncludeManagementTools
       
    2. From the Server Manager tool, click on the Tools menu in the top-right menu bar and select Internet Information Services (IIS) Manager.
       
    3. Click on your server name in the connections panel. If prompted to Get started with Microsoft Web Platform, click the No button.
       
    4. In the center panel of the Internet Information Services (IIS) Manager tool, double-click on Server Certificates.
       
      Click to enlarge ...
       
    5. In the Actions panel located at the right, click Create Self-Signed Certificate. When prompted, enter the following information:
       
      Friendly name for certificate: Azure Automation
       
      Certificate store: Personal
       
      Click to enlarge ...
       
      Click the OK button to generate the new self-signed certificate.
       
    6. On the Server Certificates page, right-click on the Azure Automation certificate and click on View… on the pop-up menu.
       
    7. On the Certificate dialog box, click the Details tab and then click the Copy to File… button. This will launch the Certificate Export Wizard.
       
    8. Navigate through the Certificate Export Wizard using the Next button. When prompted, enter the following information:
       
      Export Private Key: No
       
      Export File Format: default (DER encoded binary X.509 .CER)
       
      File name: c:\AzureAutomation.cer
       
      Click to enlarge ...
       
      After specifying all of the above information, click the Finish button to complete the export process. Click the OK button twice to dismiss each open dialog box.
       
    9. On the Server Certificates page, right-click on the Azure Automation certificate and click on Export… on the pop-up menu.
       
    10. In the Export Certificate dialog box, enter the following information:
       
      Export to: c:\AzureAutomation.pfx
       
      Password: Enter and confirm a password to protect the Private Key exported in this certificate file.
       
      Click to enlarge ...
       
      After specifying all of the above information, click the OK button to complete the export process.

    Upload the Management Certificate to Microsoft Azure

    Now that you have a new management certificate created and exported, you’ll need to upload the exported .CER file to your Microsoft Azure subscription.

    1. Sign in at the Microsoft Azure Management Portal with the logon credentials used when you activated your Microsoft Azure subscription.
       
    2. Select Settings located on the side navigation panel on the Microsoft Azure Management Portal page. You may need to scroll down the side navigation panel to see this selection.
       
      Click to enlarge ...
       
    3. On the Settings page, click on the Management Certificates tab.
       
    4. On the Management Certificates page, click on the Upload button located on the bottom black toolbar. When prompted, browse to c:\AzureAutomation.cer and click the clip_image001 button.
       
      Click to enlarge ...
       
      After uploading, your new certificate should now appear in the list of management certificates.
       
    5. For your newly uploaded certificate, record the values listed in the Subscription and Subscription ID columns for later use in this Step-by-Step article.

    Create a Management Certificate Asset

    For your Azure Automation account to be able to authenticate to your Microsoft Azure subscription, you’ll also need to upload the certificate .PFX file.  You’ll upload this certificate as an Asset in your Azure Automation account so that it can be consistently leveraged across multiple runbooks.

    1. On the Automation page in the Azure Management Portal, click on the name on the new Azure Automation account to drill into the account properties.
       
      Click to enlarge ...
       
    2. Click on the Assets tab.
       
      Click to enlarge ...
       
    3. Click the Add Setting button on the bottom black toolbar.  When prompted, select Add Credential.
       
      Click to enlarge ...
       
    4. On the Define Credential page, select Certificate in the Credential Type list and enter a name for this new credential.
       
      Click to enlarge ...
       
      Click the image button to continue.
       
    5. On the Upload a certificate file page, browse to C:\AzureAutomation.pfx in the File field and enter the Password used to protect the private key when previously exporting this file.
       
      image
       
      Click the clip_image001 button to upload this certificate to your Azure Automation account.

    Create an Azure Connection Asset

    You can also define the connection information for your Microsoft Azure subscription as an Asset in your Azure Automation account.  Doing so allows you to easily relate your Microsoft Azure subscription name, subscription ID and management certificate together as a centralized definition for use in all of your runbooks.

    1. On the Assets tab for your Azure Automation account, click the Add Setting button on the bottom toolbar.  When prompted, click Add Connection.
       
      Click to enlarge ...
       
    2. On the Configure connection page, select Azure as the Connection Type and enter a Name that matches your Microsoft Azure subscription name recorded earlier.
       
      Click to enlarge ...
       
      Connection Type: Azure
       
      Name: Enter the name of your Microsoft Azure subscription recorded earlier.
       
      Click the image button to continue.
       
    3. On the Configure connection properties page, enter the name of the management certificate asset that you previously uploaded and enter your Microsoft Azure subscription ID that was recorded earlier.
       
      Click to enlarge ...
       
      Automation Certificate Name: Azure Automation
       
      Subscription ID: Enter the subscription ID of your Microsoft Azure subscription recorded earlier.
       
      Click the clip_image001 button to create this connection asset in your Azure Automation account.

    Import and Publish a Connect-Azure Runbook

    There's a few lines of code that are used to connect a runbook to your Microsoft Azure subscription using the management certificate asset and connection asset that were previously defined. To promote easy maintenance of runbooks, we recommend centralizing this code into one Connect-Azure runbook that other  runbooks can reference.

    Luckily, the Azure Automation team has made this approach super-easy by providing us with a standard runbook template on the Azure Automation Script Center.

    1. Download the Connect-Azure runbook template from the Azure Automation Script Center.
       
    2. On the details page of your Azure Automation account, click the Runbooks tab.
       
      Click to enlarge ...
       
    3. On the bottom toolbar, click the Import button. When prompted, browse to the Connect-Azure.ps1 runbook template that you previously downloaded.
       
      Click to enlarge ...
       
      Click the clip_image001 button to import this runbook template.
       
    4. On the Runbooks tab, click on Connect-Azure to drill into the detailed property pages of the imported runbook.
       
      Click to enlarge ...
       
    5. On the Connect-Azure page, click on the Author tab followed by the Draft tab. 
       
      Click to enlarge ...
       
    6. Click the Publish button on the bottom toolbar to publish the imported runbook. When prompted, click the Yes button to confirm publishing this runbook.

    Create Your Runbook

    We’re ready to create a runbook for automating the provisioning and management of cloud resources in your Microsoft Azure subscription. In this article, the runbook we’ll create will be used to automate the safe shutdown of on-demand lab virtual machines at the end of each day. This runbook will stop and deallocate each specified virtual machine so that compute charges for these lab VMs do not continue to accrue when they are not being used. 

    1. On the bottom toolbar, click New | App Services | Automation | Runbook | Quick Create to create a new runbook.
       
      Click to enlarge ...
       
      Use the following field values when creating this runbook:
       
      Runbook Name: Stop-MyDemo
       
      Note that runbook automation scripts are defined using PowerShell workflows.  As such, it is a best practice to name runbooks using a PowerShell verb-noun cmdlet naming convention.
       
      Automation Account: Select your previously created Azure Automation Account.
       
      Click the clip_image001 button to create this new runbook.
       
    2. On your Azure Automation account page, click on Stop-MyDemo to drill into the detailed property pages for the new runbook.
       
      Click to enlarge ...
       
    3. Click the Author tab, and then click the Draft tab to begin editing the PowerShell code for this new runbook.
       
      Click to enlarge ...
       
    4. Inside the Workflow code block, insert the PowerShell code that leverages the Connect-Azure runbook to connect to your Microsoft Azure subscription.  Be sure to replace the values for the $subName variable with the value that you recorded earlier in this article.
       
      workflow Stop-MyDemo
      {
       
          # Specify Azure Subscription Name
          $subName = 'Enter Your Azure Subscription Name'
         
          # Connect to Azure Subscription
          Connect-Azure `
              -AzureConnectionName $subName
             
          Select-AzureSubscription `
              -SubscriptionName $subName
       
       
      }
       
      You’ll use this PowerShell code at the beginning of each Azure Automation runbook that provisions or manages cloud resources in a Microsoft Azure subscription.
       
    5. Inside the Workflow code block, add the PowerShell code that you will use to automate cloud resources in your Microsoft Azure subscription.  In our sample runbook, we’ll insert the code used to stop and deallocate several Microsoft Azure virtual machines.
       
      workflow Stop-MyDemo
      {
          # Specify Azure Subscription Name
          $subName = 'Enter Your Azure Subscription Name'
         
          # Connect to Azure Subscription
          Connect-Azure `
              -AzureConnectionName $subName
             
          Select-AzureSubscription `
              -SubscriptionName $subName
             
          # Shutdown Lab VMs
          $vmList = ('labvm01','labvm02','labvm03')
          $svcName = 'labvms'
         
          For ( $vmCount = 0; $vmCount -lt $vmList.Count; $vmCount++) {
             
              $vm = Get-AzureVM `
                  -ServiceName $svcName `
                  -Name $vmList[$vmCount]
             
              if ( $vm.InstanceStatus -eq 'ReadyRole' ) {
                 
                  Stop-AzureVM `
                      -ServiceName $vm.ServiceName `
                      -Name $vm.Name `
                      -Force   
                     
              }
             
          }
         
      }

       
    6. When finished, click the Save button on the bottom toolbar to save your draft runbook.

    Test the Runbook

    After saving the draft runbook, you can test the new runbook to confirm that it executes successfully.

    1. Click the Test button on the bottom toolbar.
       
      Caution! When “testing” a runbook, the runbook is actually executed against your Microsoft Azure subscription. Be certain that you really do want to execute this runbook against provisioned cloud resources before clicking the Test button.
       
    2. As the runbook executes, the Output Pane located at the bottom of the page will be refreshed with execution status and output. 
        
      Click to enlarge ...
       
      When the runbook has completed, the Status value in the Output Pane will display Completed.

    Publish the Runbook

    When you’ve tested the runbook and confirmed that it executes successfully, you can publish the new runbook for running on a scheduled basis.

    1. Click the Publish button on the bottom toolbar.
       
    2. After the new runbook is published, click the Published tab to confirm that it has been published successfully.
       
      Click to enlarge ...

    Link the Runbook to a Schedule

    We want this new runbook to execute at the end of every day, to make sure that our lab VM’s are automatically stopped and deallocated when not being used.  To execute a runbook on a scheduled basis, we can link the runbook to a recurring schedule.

    1. Click on the Schedule tab.
       
      image
       
    2. Click Link to a New Schedule and enter End-of-Day as the name of the new schedule.
       
      Click the image button to continue.
       
    3. On the Configure Schedule page, define a scheduled Start Time and Recur Every value.
       
      image
       
      Click the clip_image001 button to add this new schedule and link it to the runbook.

    Learn more about Azure Automation!

    In this article, we’ve created a simple Azure Automation runbook to stop and deallocate lab VMs on the Microsoft Azure cloud platform. This runbook provides a great starting point, but it’s just one example of the power of this new preview feature.  Azure Automation can leverage any of the Microsoft Azure PowerShell cmdlets for automating more sophisticated cloud tasks, and we can also extend Azure Automation by importing additional PowerShell modules.

    When you’re ready to learn more about Azure Automation, be sure to check out the additional resources available on our Microsoft Azure documentation portal:

    What are your cloud scenarios?

    Are there particular cloud scenarios in which you have interest? Feel free to leave your comments and feedback below, and we’ll try to write-up as many additional scenarios as possible in the coming weeks.

      Learn more about Microsoft Azure ...

    See you in the Clouds!

    - Keith

  • Modernizing Your Infrastructure with Hybrid Cloud - Getting Started with On-demand Private Clouds using Windows Azure Pack (Part 23)

    This article is part 23 in our continuing series on Modernizing Your Infrastructure with Hybrid Cloud by our US IT Pro team. After you've read this article, be sure to catch all of the other articles in our series!

    As I’ve been traveling and speaking to IT Pros about the great scalability, resiliency and offerings in our Microsoft Azure public cloud platform, there’s also been lots of interest around deploying our free Windows Azure Pack (WAP) to bring the power and consistency of the same self-service Azure portal user interface to on-demand Private Clouds provisioned in an on-premises datacenter.

    Click to enlarge ...
    Service Management Portal in Windows Azure Pack

    In this article, we’ll step through the process of setting up Windows Azure Pack in a lab environment for provisioning and delegating VM private clouds. Along the way, I’ll call out the specific details that I found helpful to successfully build my own lab environment.

    What is Windows Azure Pack?

    For a technical overview of the Windows Azure Pack, check out this great Microsoft TechEd session:

    In addition, Thomas Maurer, MVP for Cloud and Virtualization, has written a great article that describes the overall architecture of Windows Azure Pack:

    For more detailed training on Azure Pack, attend this free online Microsoft Virtual Academy Jump Start that was recently recorded by Symon Perriman and Andrew Zeller:

    What are we building?

    Windows Azure Pack certainly has the ability to scale to support very large Private Cloud environments consisting of multiple datacenters.  However, in this article, we’ll get started by building a basic lab environment that consists of the following four (4) VMs:

    • System Center 2012 R2 Virtual Machine Manager (VMM) management server VM
       
    • SQL Server 2012 database server VM
       
    • Service Provider Foundation (SPF) server VM
       
    • Windows Azure Pack (WAP) server VM

    To configure all four (4) VMs in your lab environment, you’ll need a virtualization host with at least 16GB RAM and 300GB available disk space.

    Virtualization Hosts and Fabric Controller

    Before installing Windows Azure Pack, it’s important to confirm that your on-premises virtualization infrastructure is in-place.  Windows Azure Pack leverages System Center 2012 R2 Virtual Machine Manager (VMM) as a private cloud fabric controller for handling on-demand provisioning and management of virtual machines “behind-the-scenes”, so you’ll want to confirm that VMM is setup in your environment and is connected to one or more supported virtualization host platforms for running virtual machines, such as Hyper-V, VMware or Citrix XenServer.

    To setup VMM in your lab environment, be sure to review the following resources:

    As part of this base configuration, you’ll also install a Microsoft SQL Server that will be used by all components in this lab environment.

    Private Clouds, VM Networks and VM Templates

    After VMM is setup and connected to your virtualization hosts, there’s a few specific configuration tasks to keep in mind when defining Private Clouds and VM Networks as part of your cloud fabric in VMM.  These steps are important if you’ll be using Windows Azure Pack, because WAP won’t recognize your fabric resources as being available for on-demand provisioning via the Service Management Portal unless they are configured properly.

    VM Network Guidelines

    You must have a VM network available to which tenant VMs can be associated. This VM network can be created using the VMM Console if you wish to provide a standard VM network that is shared across tenants. 

    If you wish tenants to be able to create their own on-demand VM Networks in the WAP Service Management Portal for Tenants, you must configure the Logical Network that is associated with your cloud in the steps above for Hyper-V Network Virtualization (HNV). To do this, be sure to select the One Connected Network option, and then select the Allow VM Networks created on this logical network to use network virtualization checkbox in the VMM console when configuring your Logical Network.

    If you plan to leverage Hyper-V Network Virtualization (HNV) for your Logical Network and VM Networks, check out these resources for more details and step-by-step guidance:

    Private Cloud Guidelines

    When configuring Private Clouds in VMM, be sure to follow these TechNet guidelines:

    • You must create a cloud from host groups. For instructions, see How to Create a Private Cloud from Host Groups.
       
    • You must have already created logical networks that can be associated with the cloud. For instructions, see How to Create a Logical Network in VMM.
       
    • You must have already created a VM library share. For instructions, see How to Add a VMM Library Server or VMM Library Share.
       
    • You must assign the right amount of capacity to the cloud. The capacity that you assign to the cloud governs the resources that will be available to the tenants while provisioning virtual machines using VM Clouds.
       
    • You must not select any of the available capability profiles (ESX Server, Hyper-V, XenServer) while creating the cloud. If you do so, tenants will not be able to deploy virtual machine roles using the VM Clouds service.

    VM Template Guidelines

    When creating virtual machine templates in VMM that you will use with WAP, follow this TechNet guidance:

    • While selecting a source, make sure the VHD you select has the option to connect to the virtual machine using remote desktop.
       
    • While configuring the hardware settings, make sure you do not select any of the cloud capability profiles (XenServer, ESX Server, Hyper-V) available.
       
    • While configuring the operating system, make sure you do not set the Guest OS Profile drop-down to None. You must specify a valid value for this drop-down.

    For instructions, see How to Create a Virtual Machine Template.

    Service Provider Foundation (SPF)

    Windows Azure Pack uses Service Provider Foundation (SPF) to communicate with VMM when provisioning and managing VM Clouds.  SPF provides an extensible OData web service that the WAP Service Management Portals communicate with to interact with VMM.  SPF is a component that is included with System Center 2012 R2 Orchestrator, so you’ll be installing SPF from the Orchestrator media in these steps.

    1. Review system requirements for the SPF server
       
      Be sure to install all prerequisite components on the SPF server that are listed in the above document.
       
    2. Create an SPF Service Account as an Active Directory Domain User account.
       
    3. Add SPF Service Account as VMM Administrator
       
    4. Install SPF for System Center 2012 R2
       
    5. Confirm Local Security Groups and IIS Application Pools.
       
      After installation, confirm the following local security groups and IIS Application Pools on the SPF server
       
      Local Security Groups IIS Application Pools
      SPF_Admin
      Member: SPF Service Account
      Admin
      Identity: SPF Service Account
      SPF_Provider
      Member: SPF Service Account
      Provider
      Identity: SPF Service Account
      SPF_VMM
      Member: SPF Service Accout
      VMM
      Identity: SPF Service Account
      SPF_Usage
      Member: SPF Service Account
      Usage
      Identity: SPF Service Account
      Administrators
      Member: SPF Service Account
       

       
    6. Confirm that the SPF Service Account can communicate with the VMM server.
       
      - Login at the console of the SPF server with the SPF Service Account credentials.
       
      - Launch the Virtual Machine Manager Command Shell from the Start screen.
       
         Tip: Hit the Windows key and just start typing “Virtual …
       
      - Use the following PowerShell cmdlet to confirm communication:
       
         Get-VMMServer VMM_Server_Name
       
      If successful, you will receive output that includes the properties of your VMM server connection.
       
      image
       
      If unsuccessful, confirm that the SPF Service Account has been properly added as a VMM Administrator in step 3 above.
       
    7. Confirm that the IIS site for SPF is configured with Basic Authentication enabled.
       
      Using IIS Manager on the SPF server, drill into the properties of the SPF web site and click Authentication to confirm this configuration.
       
    8. Create a local WAP Portal Service Account and add it as a member to all four SPF_ Local Security Groups.
       
      In some deployments, the WAP portals may be running on servers in a different untrusted Active Directory domain.  As a best practice, the WAP portal connections will be configured to connect to the SPF OData web service using local account credentials.
       
      - Create this local WAP Portal Service Account using the Computer Management tool on the SPF server.
       
      - Add the local WAP Portal Service Account as a member of the SPF_Admin, SPF_Provider, SPF_VMM and SPF_Usage groups.
       
    9. Confirm that you are able to successfully communicate with the SPF OData web service.
       
      - Browse to the following URL using IE with InPrivate browsing mode:
       
         https://SPF_Server_Name:8090/SC2012R2/VMM/Microsoft.Management.Odata.svc
       
      - If prompted with a Certificate warning dialog, click Continue.
       
      - When prompted to authenticate, sign-in with the WAP Portal Service Account credentials.
       
      If successful, you should receive an XML response page.
       
      Click to enlarge ...
      Success! We can communicate with the SPF OData web service.
       
      If unsuccessful, see this great article for additional troubleshooting tips.

    Install Windows Azure Pack

    We’re now ready to install the Windows Azure Pack (WAP) components.  In this article, we use the Express installation option, where all WAP server components are installed on a single VM that is separate from the SPF server VM. For larger installations involving lots of tenants, there are also options for distributed deployment and high availability.

    1. Review the system requirements for the WAP server
       
    2. Install software prerequisites on the WAP server
       
    3. Install an Express deployment of Windows Azure Pack
       
    4. Replace Self-Signed Certificates
       
      After completing a default installation, the SPF web site on the SPF server and the WAP web sites on the WAP server are configured to use self-signed certificates. I recommend replacing these self-signed certificates with signed certificates from a trusted Certificate Authority (CA). If you don't yet have a CA configured in your lab environment, you can set one up in a few minutes using Active Directory Certificate Services (ADCS) on Windows Server 2012 R2.  My friend and colleague, Yung Chou, has published a great article that steps through the process of doing exactly this ...
       
      READ IT! Enterprise PKI with Windows Server 2012 R2 Active Directory Certificate Services
       
      At a minimum, you may wish to do the following:
       
      1. To validate secure connections between the WAP and SPF servers, export the self-signed certificate from the SPF server and import into the following certificate store on the WAP server:
         
            - Local Computer \ Trusted Root Certification Authorities \ Certificates
         
      2. To permit external tenant users to connect to the WAP Tenant Public Sites without receiving certificate validation errors, replace the self-signed certificates configured for these sites to use a certificate that is signed by a publicly trusted CA. If performing this step, replace the certificate on the following WAP Tenant Public Sites:
         
        - WAPTenant Management Portal site
         
        - WAPTenantAuth Authentication site
         
        - WAPTenPubAPI Public Tenant API site

    Ready to deploy to VM Clouds

    Now that your lab environment is built, you’re ready to register your SPF server from the Windows Azure Pack admin portal and deploy to VM Clouds!

    To continue down this path, be sure to reference these next steps …

    What’s Next?

    So far, we’ve setup the basics of provisioning and managing on-demand Private Clouds using the Windows Azure Pack.  In future articles, we’ll work on extending our lab to include the following additional components …

  • TechNet Radio: (Part 5) Modernizing Your Infrastructure with Hybrid Cloud - Hybrid Cloud Management and Automation

    In part 5 of our " Modernizing Your Infrastructure with Hybrid Cloud " series, Yung Chou and Keith Mayer demonstrate ways in which you can manage and automate your hybrid cloud environment. Tune in for this demo heavy session as they showcase System Center, Microsoft Azure and the Windows Azure Pack as well as PowerShell for Azure, PowerShell DSC for configuration management and Azure Automation for automated runbooks. [ 1:15 ] When architecting a Hybrid Cloud infrastructure, what are some ...read more
About the Author ...

Keith Mayer is a Senior Technical Evangelist at Microsoft, focused on helping ISV partners leverage the Azure cloud platform. Keith has over 20 years of experience as a technical leader of complex IT projects, in diverse roles, such as Network Engineer, IT Manager, Technical Instructor and Consultant. He has consulted and trained thousands of customers and partners worldwide on design of enterprise technology solutions.

Keith is currently certified on several Microsoft technologies, including Private Cloud, System Center, Hyper-V, Windows, Windows Server, SharePoint and Exchange. He also holds other industry certifications from VMware, IBM, Cisco, Citrix, HP, CheckPoint, CompTIA and Interwoven.

You can contact Keith online at http://aka.ms/AskKeith.