This is an ongoing series on Window’s Azure.  The series starts here, and all code is located on GitHub:https://github.com/mmooney/MMDB.AzureSample.

Introduction

In the last post, we covered how to easily deploy a Azure Cloud Service using the new Sriracha 2.0 command line tools, specifically the Deploy Cloud Service Task.

In that post, we just covered the minimum amount of configuration to get a basic Cloud Service site up and running.  In this post, we’ll cover the handful of more advanced configuration options that will hopefully make you’re live easier.

In the last post, we had a pretty basic configuration file:

{
    "AzureSubscriptionIdentifier": "ThisIsYourAzureSubscriptionIdentifier",
    "AzureManagementCertificate" : "ThisIsYourAzureManagementCertificate",
    "ServiceName" : "AzureViaSriracha",
    "StorageAccountName" : "srirachademo",
    "AzurePackagePath": ".\\MMDB.AzureSample.Web.Azure\\bin\\Release\\app.publish\\MMDB.AzureSample.Web.Azure.cspkg",
    "AzureConfigPath": ".\\MMDB.AzureSample.Web.Azure\\bin\\Release\\app.publish\\ServiceConfiguration.Cloud.cscfg"
}

 

For this post, we’re doing to add a bit more configuration to our project:

{
    "AzureSubscriptionIdentifier": "ThisIsYourAzureSubscriptionIdentifier",
    "AzureManagementCertificate" : "ThisIsYourAzureManagementCertificate",
    "ServiceName" : "AzureViaSriracha",
    "StorageAccountName" : "srirachademo",
    "AzurePackagePath": ".\\MMDB.AzureSample.Web.Azure\\bin\\Release\\app.publish\\MMDB.AzureSample.Web.Azure.cspkg",
    "AzureConfigPath": ".\\MMDB.AzureSample.Web.Azure\\bin\\Release\\app.publish\\ServiceConfiguration.Cloud.cscfg"
    "RoleList": {
        "MMDB.AzureSample.Web": {
            "InstanceCount": 2,
            "ConfigurationSettingValues": {
                "TestSettingValue1": "Vote Quimby",
                "TestSettingValue2": "He'd vote for you"
            },
            "CertificateThumbprints": {
                "MySSLCert": "ThisIsYourSSLThumbprint"
            }            
        }
    }
}

In this case, we’re not just setting the core configuration for the Azure Cloud Service package itself, but also some configuration for the Web Roles and/or Worker Roles contained in that package, along with the SSL certificate information.

AppSettings vs. Azure ConfigurationSettings

In most non-Azure ASP.NET web applications, you would specify most of your configuration in the appSettings or connectionStrings elements.  For example, you might have something like this in your web.config:

<appSettings>
  <add key="TestSettingValue1" value="This is the first test value"/>
  <add key="TestSettingValue2" value="This is the second test value"/>
</appSettings>

 

And then this in your ASP.NET MVC controller (using the handy AppSettingsHelper from the MMDB.Shared library, available on NuGet):

public ActionResult Index()
{
    var model = new SettingsViewModel
    {
        TestSettingValue1 = AppSettingsHelper.GetSetting("TestSettingValue1"),
        TestSettingValue2 = AppSettingsHelper.GetSetting("TestSettingValue2")
    };
    return View(model);
}

 

And this in your Razor view:

<p>TestSettingValue1: @Model.TestSettingValue1</p>
<p>TestSettingValue2: @Model.TestSettingValue2</p>

 

Which ends up looking like this:

image

While this sort of works in Azure, your web.config gets bundled up inside the Azure package file, so it can’t easily be changed when you promote it from one environment to another.  Instead, when you deploy your Azure package to a given environment, you also include a configuration file specific to that environment.

So forgetting the web.config for now, but your Azure configuration file might look like this:

<ServiceConfiguration serviceName="MMDB.AzureSample.Web.Azure" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration" osFamily="2" osVersion="*" schemaVersion="2014-01.2.3">
  <Role name="MMDB.AzureSample.Web">
    <Instances count="1" />
    <ConfigurationSettings>
      <Setting name="TestSettingValue1" value="Vote Quimby" />
      <Setting name="TestSettingValue2" value="He'd vote for you" />
    </ConfigurationSettings>
    <Certificates>
      <Certificate name="MySSLCert" thumbprint="61475037B69532AA6EE96936DF9CBC463A5F5FE8" thumbprintAlgorithm="sha1" />
    </Certificates>
  </Role>
</ServiceConfiguration>

Now you’re ASP.NET MVC controller might look like this:

var settingsAdapter = new MMDB.Azure.Settings.AppSettingsAdapter();
var model = new SettingsViewModel
{
    TestSettingValue1 = settingsAdapter.GetSetting("TestSettingValue1"),
    TestSettingValue2 = settingsAdapter.GetSetting("TestSettingValue2")
};
return View(model);

 

And that pulls the settings from the Azure configuration file instead:

image

Note: This code using our MMDB Azure Settings library, also available on NuGet.  This library will check to see if you’re actually running in an Azure environment (or even the local Azure emulator), and if so will try to pull the values from the Azure configuration file, and then will fall back and check the web.config appSettings if it’s not found there.  Alternatively, it will detect if you’re not running in Azure (either in IIS or just debugging with IIS Express in Visual Studio), in which case it will skip the Azure components and just check the web.config.  This has been invaluable for us to be able to get our whole application working fast locally as a normal ASP.NET website, but then giving us the flexibility to include an Azure configuration file when we deploy to production without having to change any code.

Configuring Azure

Now, this all seems simple enough right?  You may already have some build or deploy scripts that are doing some sort of XML poke to inject values into your web.config at a given XPath, so why can’t you just do the same thing for the Azure file?

Or, to ask another question with the same answer, what is a major reason people hate XML and have been fleeing to JSON?

The answer is XML namespaces.  If you try to write a simple XPath to inject a ConfigurationSetting value, you might try the following:

/ServiceConfiguration/Role[@name="MMDB.AzureSample.Web"]/ConfigurationSettings/Setting[@name="TestSettingValue1"]/@value

And then you would probably be confused why it didn’t find any nodes.

The reason is this xmlns attribute at the top of the configuration file:

<ServiceConfiguration serviceName="MMDB.AzureSample.Web.Azure" 
    xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration" 
    osFamily="2" osVersion="*" schemaVersion="2014-01.2.3">

That defines the default namespace to be http://schemas.microsoft.com/blah/blah/blah, and therefore that namespace must be provided at each element when you’re executing an XPath.  Sure, there are ways to simplify this in .NET code, like defining a prefix upfront for the namespace and putting that in a NamespaceManager and passing the NamespaceManager through to the SelectNodes call and …zzzzz…

I’m sorry, you seem to have dozed off.  What I was getting at is that this is annoying and wasteful and let’s not do it that way.

Sriracha’s Deploy Azure Cloud Service Task to the rescue

As we mentioned in the last post and above, you can use the Sriracha command line deployment tools to easily push an Azure package to up to the cloud.

And since the poking configuration values into Azure configuration files can be painful, we made sure to simplify this process as well.

So if we use the following configuration file to call the Sriracha Azure Deploy Cloud Service Task, it will automatically inject the values into the our Azure configuration file during the deployment:

{
    "AzureSubscriptionIdentifier": "ThisIsYourAzureSubscriptionIdentifier",
    "AzureManagementCertificate" : "ThisIsYourAzureManagementCertificate",
    "ServiceName" : "AzureViaSriracha",
    "StorageAccountName" : "srirachademo",
    "AzurePackagePath": ".\\MMDB.AzureSample.Web.Azure\\bin\\Release\\app.publish\\MMDB.AzureSample.Web.Azure.cspkg",
    "AzureConfigPath": ".\\MMDB.AzureSample.Web.Azure\\bin\\Release\\app.publish\\ServiceConfiguration.Cloud.cscfg"
    "RoleList": {
        "MMDB.AzureSample.Web": {
            "InstanceCount": 2,
            "ConfigurationSettingValues": {
                "TestSettingValue1": "Vote Quimby",
                "TestSettingValue2": "He'd vote for you"
            },
            "CertificateThumbprints": {
                "MySSLCert": "ThisIsYourSSLThumbprint"
            }            
        }
    }
}

 

The RoleList should match the list of roles in your package, although everything in it is optional so you only have to include the values for the roles you’d like to configure.

Them, you can control the number of instances, the the ConfigurationSettings, and even add the SSL certificate thumbprint if you’re Azure site is configured for using SSL. 

Also, until normal XPath poke approaches, it won’t just replace the configuration elements in your Azure configuration file if they are found, it will add any missing elements as well.

One thing you CAN’T control is the VM size.  For some reason, that is buried in the Azure service definition file, which then buried inside your Azure package.  So if you want to run ExtraSmall instances in your test site but Large instances in production site, you’d have to edit that service definition file before you build the Azure package.  We are also considering a nice-to-have feature during the deployment to crack open the Azure package and update the the VM size value, but is much more involved and some consider it a little scary to be modifying the internals of your packages between environments; but anyone who wants to jump in and submit a pull request for that, it would be greatly appreciated.

Anyhow, that gives you an overview of the how and why, but there is a lot more info on the Sriracha2 wiki: https://github.com/mmooney/Sriracha2/wiki/Azure—Deploy-Cloud-Service-Task

This is an ongoing series on Window’s Azure.  The series starts here, and all code is located on GitHub: https://github.com/mmooney/MMDB.AzureSample.

So in some previous posts we covered how to deploy Azure Cloud Services via Powershell and also via C# code using the MMDB.Azure.Management library.

Now, we’ll cover a quick and easy way to configure and push Azure Cloud Service projects with a single command and configuration file.

Sriracha v2.0

First, to give you some context, we been rebuilding large parts of our Sriracha Deployment System to make it more modular, so you can more easily leverage individual pieces without having to install the whole system.  It’s still very much a work in progress, but our goal is to steady release chunks of useful functionality as they become available.

One things I’ve needed for a while is a quick command line interface to deploy whatever I want whenever I want.  Sure, the traditional Sriracha/Octopus/BuildMaster model is great for scenarios when I can set up a server to catalog out releases, but sometimes you just need a script to push something somewhere and you want it to be as simple as possible.

There is a major design change in the new Sriracha system.  Previously, you couldn’t use anything in Sriracha unless you installed the whole system, but there was a lot of great functionality trapped in there.  This time around, we are building each type of deployment task as standalone libraries that can be executed through a simple command line tool first, and then the broader Sriracha system will then leverage these standalone libraries.

Deploying To Azure In 3 Steps

First, you’ll need an Management Certificate for your Azure account to be able to connect through their REST APIs.  If you don’t have that yet, check out the Authentication section of the last Azure post for steps to get your Subscription Identifier and Management Certificate values from the Azure publish settings.

The idea is pretty simple:

  • We’ll download a command line tool into our solution from Nuget
  • We’ll update a configuration file with the info specific to our project
  • We’ll run the command line tool to execute the deployment.

For this demonstration, we’ll be using the MMDB.AzureSample project we’ve used in earlier Azure posts.   Feel free to pull down the code if you’d like to follow along.

Now we have our solution open, the first thing we’ll do is pull down the Sriracha.DeployTask.Azure package from NuGet. 

PM> Install-Package Sriracha.DeployTask.Azure

 

This will create a SrirachaTools\Runners\Azure directory under your solution.  In there will be sriracha.runner.exe, along with a bunch of DLLs.

image

You’ll notice of those files is “Sample.DeployCloudService.json”.  Let’s put a copy of that named “MyDeployCloudService.json” and put it in the root of our solution and open it up:

image

image

You’ll see a whole bunch of settings in here.  Some of them are required, but most of them are optional.  We’ll add the bare minimum for now:

{
    "AzureSubscriptionIdentifier": "ThisIsYourAzureSubscriptionIdentifier",
    "AzureManagementCertificate" : "ThisIsYourAzureManagementCertificate",
    "ServiceName" : "AzureViaSriracha",
    "StorageAccountName" : "srirachademo",
    "AzurePackagePath": ".\\MMDB.AzureSample.Web.Azure\\bin\\Release\\app.publish\\MMDB.AzureSample.Web.Azure.cspkg",
    "AzureConfigPath": ".\\MMDB.AzureSample.Web.Azure\\bin\\Release\\app.publish\\ServiceConfiguration.Cloud.cscfg"
}

These values are:

  • AzureSubscriptionIdentifier and AzureManagementCertificate are the credentials you got from the Azure publish settings above.
  • ServiceName is the name of your service in Azure.  If this service does not yet exist, it will be created.  When we’re done, the cloud service will have the url http://[servicename].cloudapp.net/.  Note: as you would guess with the URL, this service name must be unique, not just within your account, but also throughout all of Azure cloud services, so be creative.
  • StorageAccountName is an Azure storage account that we need to to hold the Azure package binary during the deployment.  If this account doesn’t exist, it will be created.  Note: the storage account name must be between 3 and 24 characters, and can only contain lower case letters and numbers.
  • AzurePackagePath is the location of your Azure Cloud Service package (*.cspkg).  This can be created by right-clicking your Cloud Service in Visual Studio and selecting Publish
  • AzureConfigPath is the location of the Azure configuration file (*.cscfg) to deploy with your project, also created when you package your Azure Cloud Service.  By default it will use the values from this file, but those values can be overridden during deployment using the configFile paramater below.  We’ll cover the values in the configFile in the next post.

(Make sure you enter your own Azure Subscription Identifier and Management Certificate)

Then from a command line (or a batch file or NAnt script or whatever floats your boat), run the following:

.\SrirachaTools\Runners\Azure\sriracha.run.exe --taskBinary=Sriracha.DeployTask.Azure.dll --taskName=DeployCloudServiceTask --configFile=.\MyDeployCloudService.json --outputFormat text

 

The breakdown here is:

  • Run the Sriracha command line tool (sriracha.run.exe)
  • Use the taskBinary parameter to tell it which assembly has the deployment task implementation (Sriracha.DeployTask.Azure.dll)
  • Use the taskName parameter to tell it what actual task to use (DeployCloudServiceTask)
  • Use the configFile parameter to tell it where our config file lives (MyDeployCloudService.json)
  • Optionally use the outputFormat parameter tell it what type of output format we want back. Normally you’d want text, but you can use json if are piping it somewhere you want a parseable response.
  • You can find the full documentation of calling the Sriracha deployment runner here: https://github.com/mmooney/Sriracha2/wiki/Deployment-Runner 

 

That’s it.  Just run that command, and then sit back and watch the bits fly:

image

 

Now let’s go check out out the site, which again will be at http://[servicename].cloudapp.net, and there we go:

image

Now there are also some other cool things you can do with configuring your cloud service settings, instance counts, and certificates, which we will cover in the next post.

This is an ongoing series on Windows Azure.  The series starts here, and all code is located on GitHub: https://github.com/mmooney/MMDB.AzureSample.  GitHub commit checkpoints are referenced throughout the posts.

(Yes, I know that Microsoft has recently renamed Windows Azure to Microsoft Azure, but hey, I’m in the middle of a series here, and consistency is important.  In my humble opinion, nobody cares whether it’s called Windows Azure or Microsoft Azure or Metro Azure or Clippy Azure.  I’ll try to stick to just “Azure” though.)

So I’m getting back to this series after a little while (ok, a year).  I’ve spent a lot of the last year building out the Sriracha Deployment System, and open source package management and deployment system.  It’s coming along very nicely with a lot of cool features, and the beta users so far love it.  Anyhow, as a part of that I wanted to have a nice clean way to deploy a Cloud Service to Azure (mostly for selfish reasons to simplify deployments of SportsCommander).

In the last post in this series, we covered a way to automated deployments via PowerShell.  That definitely works pretty well, but it requires installing the Azure Cmdlets, and muddling around with PowerShell, which lots of folks (including me) would rather not deal with.

So what are our other options?

Azure Management REST APIs

So it turns out Azure has a bunch of really nice, logical, easy to use, well documented REST APIs.  You GET/POST to a URL, sometimes with an XML file, and get an XML file back.

But that is still a lot of work, and seems like it should be a solved problem.  You have to deal with a lot of endpoints for a simple deployment.  You need to deal with UTF encoding, URL encoding, XML schemas, error handling, and a whole bunch of blah blah blah that just seems unnecessary.

What I really wanted was a nice clean library that let me call a few functions to carry out the common steps that I and a hundred other developers want to do every day.

Wait, aren’t their already libraries for this?

Sure, there are some.  The main one is the official Windows Azure Management Libraries.  These are an add-on library that the Azure team made to work the Azure REST APIs from C#, which certainly sounds exactly like what I was looking for.  Any it very well may be, but I couldn’t get it to work. When I would call into it, it would hang indefinitely even though I know that the underlying HTTP call had completed, and I think has something to do with how it’s using the fancy new async/await stuff, and there is a deadlock somewhere.  I tried pulling the source code and building it, but it’s using a whole bunch of multitargeting stuff; I needed .NET 4.0 versions, and they were building as 4.5 by default.  Anyhow, I pouring WAAAY too much time into something that was supposed to make my life easier. 

And there are certainly other libraries as well, but they seemed to take a Swiss Army knife approach, trying to solve everyone’s probably in every situation, which means that they a little to complicated to use for my task.

Frankly, all I really to do is call some URLs and work with some XML.  My tolerance for complexity for something like that is VERY low.

Let’s reinvent that wheel as a better mousetrap

When in doubt, assume anything not invented here is junk and write it from scratch, right?  So I created a library for this which was exactly what I was looking for, and hopefully you’ll find it useful as well.

 

The code is located on GitHub at https://github.com/mmooney/MMDB.Azure, and on NuGet at https://www.nuget.org/packages/MMDB.Azure.Management.  The GitHub readme has a good intro and some sample code, but I’ll get into some more detail here.

Authentication

Before you get started you’ll need an Azure account.  If you don’t have one, some charming fellow wrote up a walkthrough on how to do it.

Once you have an account, you’ll need some authentication information to connect to the REST APIs.  Azure uses the idea of Management Certificates authorize the management calls, which gives you a lot of flexibility to issue access to different individual individuals and applications.  It also comes in handy when you accidentally check your management certificate into GitHub and need to revoke it.

Now if you Google around for how to create a mangement certificate, you’ll see a whole bunch of stuff about makecert.exe and local certificate stores and thumbprints and X.509 certificates and plenty of detailed information that will scare off a lot of developers that just wanted deploy some code and are wondering why this is so hard in the first place.

So here’s the easy way (which was covered in the last post as well):

  • Install the Azure PowerShell Cmdlets on any machine, and it doesn’t need to be your deployment machine.  This is just to get the management certificate.
  • If you have not yet, open PowerShell in Administrator mode and run the following command, also know as “Make-PowerShell-Useful”:
    Set-ExecutionPolicy RemoteSigned
  • And then run this command in PowerShell (doesn’t need to be Admin mode), which will launch up a browser, prompt you to log into Azure, and then download a Azure Publish Settings file:
Set-ExecutionPolicy RemoteSigned

And you’ll get something that looks like this:

<?xml version="1.0" encoding="utf-8"?>
<PublishData>
  <PublishProfile
    PublishMethod="AzureServiceManagementAPI"
    Url="https://management.core.windows.net/"
    ManagementCertificate="[Redacted]">
    <Subscription
      Id="[Redacted]"
      Name="3-Month Free Trial" />
  </PublishProfile>
</PublishData>

 

And that my friends, is your Azure Subscription Identifier and Management Certificate.  Grab those values, you’ll need them in a second.

Enter MMDB.Azure.Management

So I put together a simple library that does a bulk of what you may need to do for deploying an Azure Cloud Service.  The goal was abstract away all of the unnecessary noise around XML and schema namespaces and versions Base-64 encoding, and provide a nice and easy for creating, get, updating, and deleting Cloud Services, Storage Accounts, Deployments, and blob files.

First, install the NuGet Package:

PM> Install-Package MMDB.Azure.Management

 

Then, create an AzureClient object, passing in your subscription identifier and management certificate:

string subscriptionIdentifier = "FromYourPublishSettingsFile";
string managementCertificate = "AlsoFromYourPublishSettingsFile";
var client = new AzureClient(subscriptionIdentifier, managementCertificate);

 

Then you can do lots of fun stuff like creating a Cloud Service (and checking that the name is actually available first, of course):

string serviceName = "MyNewServiceName";
string message;
bool nameIsAvailable = client.CheckCloudServiceNameAvailability(serviceName, out message);
if(!nameIsAvailable)
{
    throw new Exception("Cannot create " + serviceName + ", service name is not available!  Details" + message);
}

var service = client.CreateCloudService(serviceName);

Console.WriteLine("Successfully created service " + serviceName  + "!  URL = " + service.Url);

 

Or creating a Storage Account (again, making sure that the name is available first):

string storageAccountName = "MyNewStorageAccount";

string message;
bool nameIsAvailable = client.CheckStorageAccountNameAvailability(storageAccountName, out message)
if(!nameIsAvailable)
{
    throw new Exception("Cannot create " + storageAccountName + ", service name is not available!  Details" + message);
}

var storageAccount = client.CreateCloudService(storageAccountName);

//Initial setup is complete, but it is still resolving DNS, etc
Console.WriteLine("Initial creation for storage account " + storageAccountName + " complete!  URL = " + storageAccount.Url);

//Wait for the entire setup to be complete
client.WaitForStorageAccountStatus(storageAccountName, StorageServiceProperties.EnumStorageServiceStatus.Created, timeout:TimeSpan.FromMinutes(2));
Console.WriteLine("Final setup " + storageAccountName + ", your storage account is ready to go");

 

Now, actually deploying something can take a few steps, like creating a Cloud Service, creating a Storage Account, waiting for everything to get initialized, getting the storage keys for the newly created Storage Account, uploading the Azure package file as a blob to the Storage Account, and then telling Azure to use that blob to create the Cloud Service.  Oh, and then wait for everything to actually initialize (yes, this can take a while on Azure, especially if you have a lot of instances).

string serviceName = "MyNewServiceName";
var service = client.CreateCloudService(serviceName);

string storageAccountName = "MyNewStorageAccount";
var storageAccount = client.CreateStorageAccount(storageAccountName);
client.WaitForStorageAccountStatus(storageAccountName, StorageServiceProperties.EnumStorageServiceStatus.Created);

string azureContainerName = "MyDeploymentContainer";
string azurePackageFile = "C:\\Build\\MyAzurePackage.cspkg";
string azureConfigFile = "C:\\Build\\MyAzureConfig.cscfg";
string azureConfigData = File.ReadAllText(azureConfigFile);
string deploymentSlot = "staging";

var storageKeys = client.GetStorageAccountKeys(storageAccountName);
var blobUrl = client.UploadBlobFile(storageAccountName, storageKeys.Primary, azurePackageFile, azureContainerName);

var deployment = client.CreateCloudServiceDeployment(serviceName, blobUrl, azureConfigData, deploymentSlot);
client.WaitForCloudServiceDeploymentStatus(serviceName, deploymentSlot, DeploymentItem.EnumDeploymentItemStatus.Running, TimeSpan.FromMinutes(5));
client.WaitForAllCloudServiceInstanceStatus(serviceName, deploymentSlot, RoleInstance.EnumInstanceStatus.ReadyRole, TimeSpan.FromMinutes(10));
 

 

See it in action

Again there are a basic usage examples over at the readme, and there are some more exhaustive examples in the test project

You can also see it in real-live action over in the DeployCloudService task in Sriracha.Deploy source.  There you can see how it handles a lot of the day-to-day stuff like checking whether the Cloud Service and Storage Accounts already exist, creating vs. upgrading deployments, etc.

Running the tests

The first time you try to run the test project, you will get some errors that “Azure.publishsettings.private” does not exist.  Get a copy of a publish settings file (see the Authentication section above), and drop it in the root of the MMDB.Azure.Management.Tests folder, and rename it to “Azure.publishsettings.private”, and you should be good to go.  You shouldn’t have to worry about accidentally committing this file, because .private files are excluded in the .gitignore, but make sure to keep an eye on it just to be safe.

The end

So hopefully you find this usual.  If so, let me know on Twitter (@mooneydev).  Obviously this doesn’t cover every single thing you’d want to do with Azure, and I’m sure we’ll be building more features as they are needed.  If you need something you don’t see here, create an issue over on GitHub, or better yet, take a crack at implementing and send over a pull request.  I tried to make the code really approachable and easy to work with, so it shouldn’t be too hard to get started with it and add some value.

This is an ongoing series on Window’s Azure.  The series starts here, and all code is located on GitHub: https://github.com/mmooney/MMDB.AzureSample.  GitHub commit checkpoints are referenced throughout the posts.

In the previous post we covered deploying an app to Azure through the Azure web portal and from Visual Studio.  In this post, we’ll show you how to deploy to Azure from PowerShell.  This comes in really handy if you want to be able to deploy to right from your build server, and who doesn’t want to do that?

Why now?

So we have not really gotten into much detail about Azure, and our app is stupidly simple, why are we getting into mundane operational gold-plating like automating deployments from a build server?

Because it’s really important to automate your whole build/deploy pipeline as soon as possible.  The later you automated it, the more time you are flushing down the toilet.  Even if you don’t want to deploy automatically from your build server, if you don’t at least boil your whole deployment down to single one-click script file, you’re stealing from yourself.

When I started out with SportsCommander, I was building all the code locally in Visual Studio and then deploying through the Azure web portal (I know, caveman stuff right?).  Anyhow, pretty soon I got everything built and versioned through a TeamCity build server, and even had the site being FTPed to our shared hosting test server (hello, LFC Hosting), but for production deployments to Azure I would still remote into the build server and upload the latest package from the hard drive to the Azure website.  Part of this was that I wanted to be able to test everything in the test server before deploying to production, and part of this was that I wanted to make sure it didn’t get screwed up, but part of it was also the logical fallacy that I didn’t have time to sit down and spend the time to figure out how to get the Azure deployment working.

And I was wrong.  Way wrong.  Deploying to Azure manually doesn’t take too long, but it adds up.  If it took me 15 minutes to remote into the server, browse to the Azure site, select the package, select the config, and yadda yadda yadda, it only takes a handful of times before you are bleeding whole hours.  If you are deploying several times per week, this can get really expensive.  Not only are you getting fewer fixes and features done, you aren’t even deploying the ones that you do have done, because you don’t have time to deploy and it’s a pain anyway.  Plus, really the only reason we wanted to deploy to the test server first was to smoke test, because deploying again was such a pain that I didn’t want to have to do a whole second deployment to fix a line of code; but if I could fix that line of code and redeploy with one click, I don’t even need to waste time with the test server.

So I didn’t want to spend the time figuring out who to deploy to Azure automatically.  Well I did, but it took me more than 5 minutes to Google it, find the right answer among the plethora of other answers, so it took a while to get done.

Hopefully you found this post in under 5 minutes of Googling so you don’t have any excuses.

Prerequisites

If you’ve been Googling around, you may have seen some posts about installing certificates.  Don’t bother.  This approach doesn’t require it, which is good, because that’s no fun.

First, go install the Windows Azure Cmdlets (http://www.windowsazure.com/en-us/manage/downloads/).  Go go go.

Second, make sure you can run remote signed scripts in PowerShell.  You only need to do this once, and if you have played around with PowerShell you’ve probably already done this.  Open up PowerShell in Administator mode (Start Button->type powershell->CTRL+Shift+Enter).  Then type:

Set-ExecutionPolicy RemoteSigned

and hit Enter.  You will get a message along the lines of “OMG Scary Scary Bad Bad Are you Sure!?!?! This is Scary!”.  Hit “Y” to continue.

Now comes the tricky part.  There is a whole bunch of PowerShell commands and certificate stuff that can get confusing.  Thankfully Scott Kirkland wrote a great blog post and even put a sample script up on GitHub.  I had to make a few tweaks to it to get it working for me, so here goes.

Fire up PowerShell again (doesn’t need to be Administrator mode any more), browse to your solution directory, and run:

Get-AzurePublishSettingsFile

This will launch a browser window, prompt you to log into your Azure account, and then prompt you to download a file named something fun like “3-Month Free Trial-1-23-2013-credentials.publishsettings”.  Take that file, move it to your solution directory, and name it something less fun like “Azure.publishsettings”.  If you open that fella up, you’ll see something like:

<?xml version="1.0" encoding="utf-8"?>
<PublishData>
  <PublishProfile
    PublishMethod="AzureServiceManagementAPI"
    Url="https://management.core.windows.net/"
    ManagementCertificate="[Redacted]">
    <Subscription
      Id="[Redacted]"
      Name="3-Month Free Trial" />
  </PublishProfile>
</PublishData>

So on to the script.  In the root of your project, create a PowerShell script (just a text file named something like DeployAzure.ps1):

#Modified and simplified version of https://www.windowsazure.com/en-us/develop/net/common-tasks/continuous-delivery/
#From: #https://gist.github.com/3694398
$subscription = "3-Month Free Trial" #this the name from your .publishsettings file
$service = "mmdbazuresample" #this is the name of the cloud service you created
$storageAccount = "mmdbazuresamplestorage" #this is the name of the storage service you created
$slot = "production" #staging or production
$package = "C:\Projects\MMDB.AzureSample\MMDB.AzureSample.Web.Azure\bin\Release\app.publish

\MMDB.AzureSample.Web.Azure.cspkg"
$configuration = "C:\Projects\MMDB.AzureSample\MMDB.AzureSample.Web.Azure\bin\Release\app.publish

\ServiceConfiguration.Cloud.cscfg"
$publishSettingsFile = "Azure.publishsettings"
$timeStampFormat = "g"
$deploymentLabel = "PowerShell Deploy to $service"
 
Write-Output "Slot: $slot"
Write-Output "Subscription: $subscription"
Write-Output "Service: $service"
Write-Output "Storage Account: $storageAccount"
Write-Output "Slot: $slot"
Write-Output "Package: $package"
Write-Output "Configuration: $configuration"

Write-Output "Running Azure Imports"
Import-Module "C:\Program Files (x86)\Microsoft SDKs\Windows Azure\PowerShell\Azure\*.psd1"
Import-AzurePublishSettingsFile $publishSettingsFile
Set-AzureSubscription -CurrentStorageAccount $storageAccount -SubscriptionName $subscription
Set-AzureService -ServiceName $service -Label $deploymentLabel
 
function Publish(){
 $deployment = Get-AzureDeployment -ServiceName $service -Slot $slot -ErrorVariable a -ErrorAction silentlycontinue 
 
 if ($a[0] -ne $null) {
    Write-Output "$(Get-Date -f $timeStampFormat) - No deployment is detected. Creating a new deployment. "
 }
 
 if ($deployment.Name -ne $null) {
    #Update deployment inplace (usually faster, cheaper, won't destroy VIP)
    Write-Output "$(Get-Date -f $timeStampFormat) - Deployment exists in $servicename.  Upgrading deployment."
    UpgradeDeployment
 } else {
    CreateNewDeployment
 }
}
 
function CreateNewDeployment()
{
    write-progress -id 3 -activity "Creating New Deployment" -Status "In progress"
    Write-Output "$(Get-Date -f $timeStampFormat) - Creating New Deployment: In progress"
 
    $opstat = New-AzureDeployment -Slot $slot -Package $package -Configuration $configuration -label $deploymentLabel -

ServiceName $service
 
    $completeDeployment = Get-AzureDeployment -ServiceName $service -Slot $slot
    $completeDeploymentID = $completeDeployment.deploymentid
 
    write-progress -id 3 -activity "Creating New Deployment" -completed -Status "Complete"
    Write-Output "$(Get-Date -f $timeStampFormat) - Creating New Deployment: Complete, Deployment ID: 

$completeDeploymentID"
}
 
function UpgradeDeployment()
{
    write-progress -id 3 -activity "Upgrading Deployment" -Status "In progress"
    Write-Output "$(Get-Date -f $timeStampFormat) - Upgrading Deployment: In progress"
 
    # perform Update-Deployment
    $setdeployment = Set-AzureDeployment -Upgrade -Slot $slot -Package $package -Configuration $configuration -label 

$deploymentLabel -ServiceName $service -Force
 
    $completeDeployment = Get-AzureDeployment -ServiceName $service -Slot $slot
    $completeDeploymentID = $completeDeployment.deploymentid
 
    write-progress -id 3 -activity "Upgrading Deployment" -completed -Status "Complete"
    Write-Output "$(Get-Date -f $timeStampFormat) - Upgrading Deployment: Complete, Deployment ID: $completeDeploymentID"
}
 
Write-Output "Create Azure Deployment"
Publish

https://github.com/mmooney/MMDB.AzureSample/tree/6177c18320f3ed35d41dc20d4f7247e1b3af05ef

Run that guy from the PowerShell command line, and you’re watch the bits fly.  Yes, it will take several minutes to run.

A generic version of this can be found here: https://gist.github.com/4539567.  Again, I borrowed from Scott Kirkland’s version, but his script assumed that your storage and cloud service were the same name, so I added a separate field for storage account name.  Also to alleviate my insanity, I added a little more diagnostic logging.

Next

This was the post that I started out to write, before I decided to backfill with the more beginner stuff.  From here, it’s going to be a little more ad-hoc.

Anyhow, the next post will probably be setting up your own DNS and SSL for your Azure site.

This is an ongoing series on Window’s Azure.  The series starts here, and all code is located on GitHub: https://github.com/mmooney/MMDB.AzureSample.  GitHub commit checkpoints are referenced throughout the posts.

In the previous posts we covered setting up a basic Azure-enabled web site and setting up your Azure account.  In this post, we’ll show you how to deploy that website to Azure.  First we will deploy through the Azure web UI, and then directly from Visual Studio.

Azure Deployment Package

In order to deploy your website to Azure, you’ll need two things, a deployment package and a configuration file:

  • Deployment Package (.cspkg): This is a ZIP file that contains all of your compiled code, plus a bunch of metadata about your application
  • Configuration File (.cscfg): This is an environment-specific configuration file.  We’ll get into this more later, but this lets you pull all of the environment-specific configuration away from your code which is definitely a good idea.

So go back into your solution that we build in an earlier post (or grab it from GitHub here).  To deploy this project, you will need a MMDB.AzureSample.Azure.cspkg file.  But if you search your hard drive, you won’t find one yet.  To create this package, you’ll need to right click on your Azure project and select “Package”

image

image

This will create the package, and will even launch a Windows Explorer window with the location (which is helpful, because it can be a little tricky to find:

image

And there are our two files we need to deploy.

Deploying Through Azure Website

So now that we have our deployment package and config file, let’s go back into the Azure website (https://manage.windowsazure.com/) and log in.

image

We want to create a new Cloud Services project, so let’s click Create An Item and drill down to Compute->Cloud Service –>Quick Create:

image

image

We’ll enter our URL, which will end with .cloudapp.net, but does not have to the the final name of your website.

We’ll also select a Region/Affinity Group, which is where your servers will be hosted.  Select somewhere closest to where your biggest user base will be.  The different areas in the US don’t make a huge difference, but US vs. Europe vs. Asia can have a big impact.

image 

So then we click Create Cloud Service, and we have ourselves a cloud service:

image

Now we’ll go ahead and set it up.  Click the little arrow next to the service name, then Upload A New Production Deployment, and start filling in the details:

image

image

Enter a name for your deployment.  This is specific to this deployment, and the idea is that it could/should change on subsequent deployments.  I usually try to put the release version number in there.

Also browse for your package and config file, and select Deploy even if one or more roles contain single instance (which is in fact the case with our simple little test app), and select Start Deployment:

image

Click the checkmark button, and then go get yourself a cup of coffee. This is going to take a few minutes.

image

image

image

Oh you’re back already?  Go sneak out for a smoke, we have a few more minutes to go:

image

This is one of the downsides to Azure, these deployments can take a while, especially for new deployments.  Down the line we’ll show you how to automate this so you can click a button and walk away for a while, but for now just keep watching.

Ok, so after about 5 minutes, it looks like everything is running.  We can click the Instances tab to see more detail:

image

image

Back on the Dashboard screen, if you scroll down, you’ll see a whole bunch of useful stuff:

2013-01-20_1438

Including the Site URL.  Try clicking that and let’s see what we get:

image

Hey, there’s our website!  Nice.

Deploying Through Visual Studio

Now that you’re familiar with the Azure website, we can also deploy right from Visual Studio.

Let’s go back into Visual Studio, right click our project, and select Publish:

image

Now we’ll set up our subscription details.  Under “Choose your subscription”, select “<Manage…>”, and then click the New button, and that will take you to the New Subscription screen:

image

image

image

We’ll need to create a management certificate, so under the dropdown select “<Create…>”, enter a name for the certificate, and click OK.

2013-01-20_1457

image

How that we have that, upload that certificate to the Azure portal web site. Click the link to copy the path and then the link to go to the Azure portal:

image

One you’re there, go all the way to the bottom, select Settings->Upload Management Certificate. 
image

image 

Select the certification (using the path in your clipboard) and click OK.

image

2013-01-20_1515

OK, now that we’ve uploaded our certificate, let’s go back to the New Subscription screen.  Next it’s asking for our subscription ID, which is back in the Azure portal.  Paste that in, give a name for your subscription, and click OK:

image

2013-01-20_1438_001

And now we’re all the way back to the publish screen.  Now we’ll use that subscription click next, and …

image

image

…and now it’s asking to create an Azure storage account?  Why? 

The reason is that when you deploy right from the Azure portal website, it does everything all at once on the server.  However, when you deploy from the Visual Studio (or from Powershell, which we’ll get into later), it first uploads the package to the storage account and then tells Azure to deploy the package from there.

Let’s enter the name of our new storage account and location (yes, it’s a good idea to use the same location as the Region/Affinity Group you entered above) and click OK

Now we have some nice default settings to deploy with, and so let’s click Publish:

image

It may ask you to replace the existing deployment, and that is OK:

image

Now this will run for a while, and will take about as long as the deployment from the website.

2013-01-20_1534

Once that’s done, click the Website URL, and check out your fancy new website:

2013-01-20_1541

image

What to be careful of

  • When deploying through the website, make sure you build and package each time before you deploy.  If you are deploying from Visual Studio, it will automatically package everything for you.  However, if you build your project but forget to package it, and then upload the package to the Azure website, you’ll be uploading and older version package.  This is the type of thing that can cause a lot of time wasted trying to figure out why your new changes are not appearing.
  • Also, as a general rule, deploying right from your development environment is bad bad bad.  All of the awful reasons are long enough for another blog post, but in short you really want to have an independent build server which is responsible for pulling the latest code from source control, building it, running any tests it can, and publishing it out to Azure.

Next

Next, we’ll cover another key part of Azure deployments, which is deploying via command line.  While deploying from Visual Studio and the Azure portal is easy when you’re getting started, eventually you’re going to want to automate this from a build server.

This is an ongoing series on Window’s Azure.  The series starts here, and all code is located on GitHub: https://github.com/mmooney/MMDB.AzureSample.  GitHub commit checkpoints are referenced throughout the posts.

In the last post we covered setting up a basic Azure-enabled web site.  In this post, we’ll show you how to setup your Azure account.  Next, we’ll cover deploying the project to Azure.

So head on over to http://www.windowsazure.com/ and click the Free Trial link:

image

Singe in with your Microsoft/Live/Password/Metro/Whatever user ID. If you don’t have on, create one:

image

Why yes, I would like the 90-Day Free Trial:

image

Once you do a little validation of your phone and credit card, they will go ahead and setup your account.

image

After a minute or two, click the Portal link:

image

This takes you to https://manage.windowsazure.com/, the main place you want to be for managing your Azure application.

image

And there we are.  Poke around a little bit, there is a lot of interesting stuff in here.  In the next post, we’ll create a Cloud Service and deploy our sample application there.

This is an ongoing series on Window’s Azure.  The series starts here, and all code is located on GitHub: https://github.com/mmooney/MMDB.AzureSample.  GitHub commit checkpoints are referenced throughout the posts.

Prerequisites

I’m assuming that you have Visual Studio 2012.  Now go install the latest Windows Azure SDK.  Go go go.

Getting Started

So the first thing we are going to do is build a simple Windows Azure web application.  To do this, we’ll create a new VS2012 solution:

image

 https://github.com/mmooney/MMDB.AzureSample/tree/76b9bbcd11146bca026b815314df907406b99048

And we’ll create a plan old MVC web application:

image

image

image 

Now we have a empty project, and add in a Home controller a view, we have ourselves an simple but working MVC web application.

image

image

 

Now Let’s Azurify This Fella

Now if we want to deploy this to Azure, we need to create an Azure project for it. Right-click on your project and select “Add Windows Azure Cloud Service Project”

image

That will add a bunch of Azure references to your MVC app, and will create a new wrapper project:

image

Now if you can still run the original web application the same as before, but you if you run the new Azure project, you’ll get this annoying, albeit informative error message:

image

Ok so let’s shut it all down and restart VS2012 in Administrator mode.

(Tip: if you have a VS2012 icon on your Windows toolbar, SHIFT-click it to start in Admin mode)

When we come back in Admin mode and run the Azure project, it’s going to kick up an Azure emulator:

image
image

And we get our Azure app, which looks much the same as a our existing app, but running on another port:

image

 

The idea here is to simulate what will actually happen when the application runs in Azure, which a little different than running in a regular IIS web application.  There are different configuration approaches, and the Web/Worker Roles get fired up.  This is very cool, especially when you are getting started or migrating an existing site, because it gives you a nice test environment without having to upload to Azure all the time. 

However, the simulator does have it’s downsides. First, requiring Administrator mode is annoying.  I forget to do this EVERY TIME, and so right when I’m about to debug the first time, I have to shut everything down and restart Visual Studio and reopen my solution in Admin mode.  Not the end of the world, but an annoying bit of friction.  Second, it is SLOW to start up the site in simulator; not unusably slow, but noticeably and annoyingly slow, so I guess it’s almost unusably slow. 

To combat this, I try to make sure that my web application runs fine all the time as a regular .NET web application, and then I just test from there.  Then before I release a new feature, I test it out in  simulator mode to sanity check, but being able to run as a vanilla web application makes everything a lot faster.

Also, and this is important, it forces you to keep your web application functioning independent of Azure.  Besides the obvious benefit of faster debuggability, it also ensures that your application has enough seams that if we had to move away from Azure, you can.  I’ve gone on and on about how great Azure is, but it might not be the right thing for everyone, or might stop being the right thing in the future, and you want to have the option to go somewhere else, so you really don’t want Azure references burned in all over the place.  Even if you stay with Azure, you might want to replace some of their features (like replacing Azure Table Storage with RavenDB, or replacing Azure Caching with Redis).  We’ve used a few tricks for this in the past that I’ll get into in some later blog posts.

https://github.com/mmooney/MMDB.AzureSample/tree/a56beb73e44b025d90570978541f83f3622e9eac

Next

Next we’ll actually deploy this thing to Azure, but first we need to setup an account, which we’ll do next.  Get your checkbook ready (just kidding).

Overview

This is the first in a series of blog posts on getting started with building .NET applications in Windows Azure.  We’ve been a big fan of Azure for a lot of years, and we’ve used it for SportsCommander.com’s event registration site since the very beginning. 

I started off writing a blog post on automatically deploying web applications to Azure from TeamCity, but I ended up with too many “this blog assumes…” statements, so I figured should take care of those assumptions first.

What the deuce is Windows Azure any why should I care?

According to Wikipedia, Windows Azure is:

Windows Azure is a Microsoft cloud computing platform used to build, deploy and manage applications through a global network of Microsoft-managed datacenters. Windows Azure allows for applications to be built using many different programming languages, tools or frameworks and makes it possible for developers to integrate their public cloud applications in their existing IT environment. Windows Azure provides both Platform as a Service (PaaS) and Infrastructure as a Service (IaaS) services and is classified as the “Public Cloud” in Microsoft’s cloud computing strategy, along with its Software as a Service (SaaS) offering, Microsoft Online Services.

 

According to me, Windows Azure is:

A hosting platform, sort of line Amazon EC2, because you can deploy to virtual machines that abstract away all of the physical configuration junk that I don’t want to care about, but even better because it also abstracts away the server configuration stuff that I also don’t want to care about, so I can just build code and ship it up there and watch run without having to care about RAID drives or network switches or load balancers or whether someone is logging into these servers and running Windows Update on them.

 

Azure has grown into a lot of things, but as far as I’m concern Azure primary product is a Platform-as-a-Service (Paas) offering called Cloud Services.  Cloud Services lets you use combination of Web Roles and Worker Roles to run web applications and background services.

Glossary

These types of terms get thrown around a lot these days, so let’s defined them.

Before the cloud came in to overshadow our whole lives, we had the these options:

  • Nothing-as-a-Service: You went to Best Buy and bought a “server.”  You’re running it under your desk.  Your site goes down when your power goes out or someone kicks the plug out of the wall.  Or when your residential internet provider changes your IP because you won’t shell out the money for a business account with static IPs.  Then the hard drive fan dies and catches fire, your mom complains about the burning smell and tells you to get a real job.
  • Co-Location: This is a step up.   You still bought the server and own it, but you brought it down the street to hosting company that takes care of it for you, but you are still responsible for the hardware and software, and when the hard drive dies you have to shlep down to the store to get a new one.
  • Dedicated Hosting: So you still have a single physical box, but you don’t own it, you rent it from the data center.  This cost hundreds up to thousands per month, depending on how fancy you wanted to get.  You are responsible for the software, but they take care of the hardware.  When a network card dies, they swap it out for a new one.
  • Shared Hosting: Instead of renting a whole server, you just rent a few folders.  This option is very popular for very small sites, and can cost as little as $5-$10/month.  You have very little control over the enviornment though, and you’re fighting everyone else on that server for resources.
  • Virtual Hosting: A cross between Dedicated and Shared hosting.  You get a whole machine, but it’s a virtual machine (VM) running on a physical machine with a bunch of other virtual machines.  This is the ground work for Infrastructure as a service.  You get a lot more control of the operating system, and supposedly you are not fighting with the other VMs for resources, but in reality there can always be some contention, especially for disk I/O.  The cost is usually significantly less than dedicated hosting.  You don’t care at all about the physical machines, because if one piece of physical hardware fails, you can be transferred to another physical machine.

 

In today’s brave new cloudy buzzword world, you have:

  • Infrastructure-as-a-service: This is basically Virtual Hosting, where you get a virtual machine and all of the physical machine info is abstracted away from you.  You say you want a Windows 2008 Standard Server, and in a few minutes you have a VM running that OS.  Amazon EC2 is the classic example of this.
  • Platform-as-a-Service: This is one level higher in the abstraction.  It means that you write some code, and package it up in a certain way, give it some general hosting information like host name and number of instances, and then the hosting company takes it from there.  Windows Azure is an example of this, along with Google App Engine.
  • Software-as-a-Service (SaaS): This means that someone is running some software that you depend on.  Either you interact with it directly, or your software interacts with it.  You don’t own or write or host any code yourself.  The classic example of this is SalesForce.com.

 

So why is Azure and PaaS more awesome than the other options?

Because it let’s me focus on the stuff that really care about, which is building software.  As long as I follow the rules for building Azure web applications, I don’t have to worry about any of the operations stuff that I’m really not an expert in, like have I applied the right Windows updates and is my application domain identity setup up correctly and how do I add machines to the load balancer and a whole lot of other stuff I don’t even know that I don’t know.

Some IT balk at this and insist that you should control your whole stack, down to the physical servers.  That is a great goal once you get big enough to hire those folks, but when you are getting started in a business, your time is your most valuable asset, and you need a zero-entry ramp and you need to defer as much as possible to experts.  If you are spending time running Windows Updates on your servers when you are the only developer and you could be coding, you are robbing your company blind.

Shared hosting platforms were close to solving this problem.  As long as your website was just a website, and it’s small, you could host it on a shared hosting service and not worry about anything, until somebody else pegs the CPU or memory.  Or if you need to go outside the box a little and run a persistent scheduled background process.  Also, scaling across mulitple servers is pretty much out of the question, you are stuck with “less than one server” of capacity, and you can never go higher. 

But after you grow out of shared hosting and move up to dedicated hosting or virtual hosting, it costs a whole lot more per month (like 5x or 10x), and the increased maintenance effort is even worse.  It’s a pretty step cliff to jump off from shared to dedicated/virtual hosting.

Azure fills that gap more cleanly nicely.  You are still just focusing on the application instead of the server, but you get a lot more power with features like Worker Roles and Azure Storage, and you can even expand out into full blown VMs if you really need it.

Ah ha, VMs!  What about them?  And Azure Websites?

By the time you’ve read this blog post, I’m sure the Azure team will have come out with 27 new features.  Ever since the Scott Gu took over Azure, the rate at which Azure’s been releasing new features has gotten a little ridiculous.  Two for of the more interesting features are Azure VMs and Azure Websites.

Azure VMs were late feature that it seems like the Azure team didn’t even really want to add.  Every Azure web instance is actually a VM, so this lets you remote into the underlying machine like it was a regular Windows server, or even create new VMs by uploading the an existing VM image.  This was introduced so that companies could have an easier migration path to Azure.  If they app still needed some refactoring to fit cleanly into an Azure web or worker role, or it had dependencies on other systems that would not fit into an Azure application, it gives them a bridge to get there, instead of having to rewrite the whole world in one day.  But to be clear, this was not introduced because it’s a good idea to run a bunch of VMs in Azure, because it misses out on the core abstraction and functionality that Azure offers.  If you really just want VMs, just go to Amazon EC2, they are the experts.

Azure Website are a more recent feature (still in Beta) which mimics shared hosting in the Azure world.  While the feature set is more involved than your run of the mill shared hosting platform, it does not nearly give you the power that Azure Cloud Services provides.  They work best with simple or canned websites, like DotNetNuke, Orchard CMS, or WordPress.  In fact, right now we’re testing out moving this blog and the MMDB Solutions website to Azure Websites to consolidate and simplify our infrastructure.

The End…?

In the coming blog posts, I’ll cover some more stuff like creating an account, setting up an Azure web application, deploying it, dealing with SQL Azure, and lots more.  Stay tuned.

So while ago I wrote about my adventures in SQL Azure backups.  At the time, there was very little offered by either Microsoft or tool vendors to provide an easy solution for scheduling SQL Azure backups.  So in the end, I cobbled together a solution involving batch files, Task Scheduler, and most importantly Red Gate Compare and Data Compare.

But much has changed the past year.  Red Gate released their new SQL Azure Backup product, whose functionality looks freakishly similar to other less polished solutions that people had written about.  The cool part is that while the SQL Compare solution I proposed originally required a purchased copy of the Red Gate SQL tools, Red Gate has been nice enough to release their Azure backup tool for free.

Also, Microsoft has released a CTP version of their SQL Import/Export Service.  This service allows you to backup and restore your database using Azure Blob storage instead having to download it to a local database server, which is actually what most of us really wanted in the first place anyway.  The latest versions of Red Gate’s Azure Backup also supports this functionality, which gives you a lot of options.

So just to close the loop on this, here’s the updated batch script file we’re using for SportsCommander now for doing regular production backups of our database.  We’re opting to use the the Import/Export functionality as our primary backup strategy:

SET SqlAzureServerName=[censored]
SET SqlAzureUserName=[censored]
SET SqlAzurePassword=[censored]
SET SqlAzureDatabaseName=[censored]

SET AzureStorageAccount=[censored]
SET AzureStorageKey=[censored]
SET AzureStorageContainer=[censored[

for /f "tokens=1-4 delims=/- " %%a in (‘date /t’) do set XDate=%%d_%%b_%%c
for /f "tokens=1-2 delims=: " %%a in (‘time /t’) do set XTime=%%a_%%b

SET BackupName=SportsCommander_Backup_%XDate%_%XTime%


C:\SQLBackups\RedGate.SQLAzureBackupCommandLine.exe /AzureServer:%SqlAzureServerName% /AzureDatabase:%SqlAzureDatabaseName% /AzureUserName:%SqlAzureUserName% /AzurePassword:%SqlAzurePassword% /CreateCopy /StorageAccount:%AzureStorageAccount% /AccessKey:%AzureStorageKey% /Container:%AzureStorageContainer% /Filename:%BackupName%.bacpac

 

A few notes:

- This runs the same Import/Export functionality you can get through the Azure portal.  If you have any problems with the parameters here, you can experiment in Azure portal

- The AzureStorageAccount parameter is the account name of your storage account.  So if your blob storage URL is http://myawesomeapp.blob.core.windows.net, your would want to use “myawesomeapp” in this parameter

- The /CreateCopy parameter will use SQL Azure’s CREATE DATABASE AS COPY OF method to create a snapshot first and then back that up, instead of just backing up the live database.  This takes a little extra time, but it is important to ensure that you are getting a transactionally consistent backup.

 

Of course, if you still want to copy down a local instance of the database like we did in the previous post, you can easily do that too:

SET SqlAzureServerName=[censored]
SET SqlAzureUserName=[censored]
SET SqlAzurePassword=[censored]
SET SqlAzureDatabaseName=[censored]

SET LocalSqlServerName=[censored]
SET LocalSqlUserName=[censored]
SET LocalSqlPassword=[censored]

for /f "tokens=1-4 delims=/- " %%a in (‘date /t’) do set XDate=%%d_%%b_%%c
for /f "tokens=1-2 delims=: " %%a in (‘time /t’) do set XTime=%%a_%%b

SET BackupName=SportsCommander_Backup_%XDate%_%XTime%

C:\SQLBackups\RedGate.SQLAzureBackupCommandLine.exe /AzureServer:%SqlAzureServerName% /AzureDatabase:%SqlAzureDatabaseName% /AzureUserName:%SqlAzureUserName% /AzurePassword:%SqlAzurePassword% /CreateCopy /LocalServer:%LocalSqlServerName% /LocalDatabase:%BackupName% /LocalUserName:%LocalSqlUserName% /LocalPassword:%LocalSqlPassword% /DropLocal

 

Good luck.

The Error

So if you are working in SQL Azure, you’ve probably learned the hard way that you can’t just script out your DDL changes in your local SQL Management Studio and run it against your Azure database.  It throws in a whole bunch of extra fancy-pants DBA-y stuff that SQL Azure just doesn’t let you use. 

For example, say I throw together a simple table in my local database.  Depending on your SQL source control approach (you have one, right?), you might script it out in SQL Management Studio and get something like this:

CREATE

TABLE MyWonderfulSampleAzureTable (

[ID] [int] IDENTITY(1,1) NOT NULL,

[GoEagles] [varchar](50) NOT NULL,

[BeatThemGiants] [varchar](50) NOT NULL,

[TheCowboysAreAwful] [bit] NOT NULL,

[AndyReidForPresident] [varchar](50) NULL,

CONSTRAINT [PK_MyWonderfulSampleAzureTable] PRIMARY KEY CLUSTERED

(

[ID] ASC)

WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]

)

ON [PRIMARY]

GO

 

Pretty enough, no?  Sure, it’s full of a lot of gibberish you don’t really care about, like PAD_INDEX=OFF, but hey if it runs, what’s the problem?

Now, let’s run that against our SQL Azure database:

Msg 40517, Level 16, State 1, Line 10
Keyword or statement option ‘pad_index’ is not supported in this version of SQL Server.

 

Ooops.  This is a pain to fix when you’re deploying a single script.  However, when you’re running a whole development cycle worth of these against your production database at 3 AM and it chokes one of these scripts, this is absolutely brutal.

Censorship Brings Peace

So why does this happen?  Why can’t SQL Azure handle these types of cool features?  Mostly because they just don’t want to.  Sure, some of the features missing from SQL Azure are because they just haven’t been implemented yet, but some of them are deliberately disabled to prevent unmitigated chaos.

While you may have a DBA managing your on-premise database who is working in your best interest (or at least your company’s interest), SQL Azure has a much bigger problem to solve.  They need to provide a shared SQL environment that does not let any one consumer hose up everyone else.  If you’ve ever hosted a SQL database in a high-traffic shared hosting environment, you’ve probably feel the pain of some joker going cookoo-bananas with the database resources.

In other words, what you do in the privacy of your own home is all well and good, but if you are going to go play bocce in the public park, you’re certainly going to have to watch your language and act live a civilized person.

And a lot of these features you don’t really have to care about anyway.  No doubt, you are really really smart and know when your indexes should be recompiled, but the reality is that much of the time whatever algorithm the folks on the SQL team came up with is going to be a little bit smarter than you, Mr. SmartyPants.

Anyhow, for your edification, here’s a wealth of information about the stuff you can’t do.

The Manual Workaround

So how do we get our script to run?  My general rule of thumb is to rip out all of the WITH stuff and all of the file group references:

CREATE TABLE MyWonderfulSampleAzureTable (

[ID] [int] IDENTITY(1,1) NOT NULL,

[GoEagles] [varchar](50) NOT NULL,

[BeatThemGiants] [varchar](50) NOT NULL,

[TheCowboysAreAwful] [bit] NOT NULL,

[AndyReidForPresident] [varchar](50) NULL,

CONSTRAINT [PK_MyWonderfulSampleAzureTable] PRIMARY KEY CLUSTERED

(

[ID] ASC)

WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]

)

ON [PRIMARY]

GO

See, I had a general rule of thumb for this, because I encountered it a lot.  On just about every DDL script I had to generate.  And missed a lot of them.  Quite the pain in the neck.

 

The Much Better, Not-So-Manual Workaround

So I was at the a Philly.NET user group meeting last night and Bill Emmert from Microsoft was walking through the options for migrating SQL Server databases, and he showed us this setting that I wish I knew about a year ago:

SQLAzureSettings

If you change this to SQL Azure Database, it will change your environment settings to always use create SQL scripts that are compatible with Azure.  No more manual script trimming!  Unless, of course, you are into that kind of thing, in which case you really wasted the last 10 minutes reading this.

Good Luck.