More Azure ASP.NET MVC…

In my previous two posts I showed how to setup your system for Azure and ASP.NET MVC Development and the basics of how to create an Azure ASP.NET MVC Project.

In this post, I will delve deeper into how to configure and deploy an Azure ASP.NET MVC Project.

From my previous post, my first project looked like this:

SimpleAzureSolution

In this solution, we have:

  • A Cloud Service project called FirstProject.
  • Two role projects:
    • An MVC Web Role project called FirstProject_MvcWebRole.
    • An Azure Worker Role project called FirstProject_WorkerRole.

Inside the Cloud Service project we have two important files:

ServiceDefinition.csdef
This file defines your service, and is deployed as part of the binaries of your service.  It cannot be changed without re-deployment.

The default Azure ServiceDefinition.csdef file looks like this:

 <?xml version="1.0" encoding="utf-8"?>
<ServiceDefinition name="FirstProject" xmlns="https://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition">
  <WorkerRole name="Worker" />
  <WebRole name="Web">
    <InputEndpoints>
      <!-- Must use port 80 for http and port 443 for https when running in the cloud -->
      <InputEndpoint name="HttpIn" protocol="http" port="80" />
    </InputEndpoints>
  </WebRole>
</ServiceDefinition>

The key elements of this file you need to understand are:

  • The name="FirstProject" attribute names the service.
  • The  <WorkerRole name="Worker" /> element defines that this service contains a worker role.
  • The <WebRole name="Web"> element defines that the service contains a web role, and defines what inputs it will respond to.


ServiceConfiguration.cscfg
This file configures your service, and is deployed outside of the binaries of your service, so it can be changed while your service runs without re-deployment.

The default ServiceConfiguration.cscfg file looks like this:

 <?xml version="1.0"?>
<ServiceConfiguration serviceName="FirstProject" xmlns="https://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration">
  <Role name="Worker">
    <Instances count="1" />
    <ConfigurationSettings />
  </Role>
  <Role name="Web">
    <Instances count="1" />
    <ConfigurationSettings />
  </Role>
</ServiceConfiguration>

At this point, we need to expand our service definition and configuration files to allow us to use Azure blob, table and queue storage services.

The first step in doing this is to add more configuration settings to our ServiceDefinition.csdef file:

 <?xml version="1.0" encoding="utf-8"?>
<ServiceDefinition name="FirstProject" xmlns="https://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition">
  <WorkerRole name="WorkerRole">
    <ConfigurationSettings>
      <Setting name="AccountName"/>
      <Setting name="AccountSharedKey"/>
      <Setting name="BlobStorageEndpoint"/>
      <Setting name="QueueStorageEndpoint"/>
      <Setting name="TableStorageEndpoint"/>
      <Setting name="allowInsecureRemoteEndpoints"/>
    </ConfigurationSettings>
  </WorkerRole>
  <WebRole name="Web">
    <InputEndpoints>
      <!-- Must use port 80 for http and port 443 for https when running in the cloud -->
      <InputEndpoint name="HttpIn" protocol="http" port="80" />
    </InputEndpoints>
    <ConfigurationSettings>
      <Setting name="DevFabric"/>
      <Setting name="AccountName"/>
      <Setting name="AccountSharedKey"/>
      <Setting name="BlobStorageEndpoint"/>
      <Setting name="QueueStorageEndpoint"/>
      <Setting name="TableStorageEndpoint"/>
      <Setting name="allowInsecureRemoteEndpoints"/>
    </ConfigurationSettings>
  </WebRole>
</ServiceDefinition>

In these definitions, we’ve added two key security configuration settings:

  • AccountName – specifies your Azure storage account name.
  • AccountSharedKey – specifies your Azure storage account shared key.

And a number of endpoint settings:

  • BlobStorageEndpoint – the address/host name of the Azure blob storage endpoint.
  • QueueStorageEndpoint – the address/host name of the Azure queue storage endpoint.
  • TableStorageEndpoint – the address/host name of the Azure table storage endpoint.
  • allowInsecureRemoteEndpoints – a value which indicates whether to allow HTTP access by security-sensitive ASP.NET providers.

And, in the WebRole, we’ve added a setting named DevFabric (more on this later).

Now that we have defined that these settings exist in our ServiceDefinition.csdef file, it’s time to configure them for our actual service in our ServiceConfiguration.cscfg file.

Here’s an example of such a configuration that will work against development storage endpoints:

 <?xml version="1.0"?>
<ServiceConfiguration serviceName="FirstProject" xmlns="https://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration">
  <Role name="WorkerRole">
    <Instances count="1" />
    <ConfigurationSettings>
      <Setting name="AccountName" value="devstoreaccount1"/>
      <Setting name="AccountSharedKey" value="Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw=="/>
      <Setting name="BlobStorageEndpoint" value="https://127.0.0.1:10000"/>
      <Setting name="QueueStorageEndpoint" value="https://127.0.0.1:10001"/>
      <Setting name="TableStorageEndpoint" value="https://127.0.0.1:10002"/>
      <Setting name="allowInsecureRemoteEndpoints" value="true"/>
    </ConfigurationSettings>
  </Role>
  <Role name="Web">
    <Instances count="1" />
    <ConfigurationSettings>
      <Setting name="DevFabric" value="true"/>
      <Setting name="AccountName" value="devstoreaccount1"/>
      <Setting name="AccountSharedKey" value="Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw=="/>
      <Setting name="BlobStorageEndpoint" value="https://127.0.0.1:10000"/>
      <Setting name="QueueStorageEndpoint" value="https://127.0.0.1:10001"/>
      <Setting name="TableStorageEndpoint" value="https://127.0.0.1:10002"/>
      <Setting name="allowInsecureRemoteEndpoints" value="true"/>
    </ConfigurationSettings>
  </Role>
</ServiceConfiguration>

You will notice that each thing defined in the ServiceDefinition.csdef is configured in the ServiceConfiguration.cscfg file.

This is where things become interesting because running an Azure service in the development fabric requires one set of configuration values, and running the same Azure service in the cloud requires a different set of configuration values.

When running an Azure service on the development fabric, we need:

 <ConfigurationSettings>
  <Setting name="AccountName" value="devstoreaccount1"/>
  <Setting name="AccountSharedKey" value="Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw=="/>
  <Setting name="BlobStorageEndpoint" value="https://127.0.0.1:10000"/>
  <Setting name="QueueStorageEndpoint" value="https://127.0.0.1:10001"/>
  <Setting name="TableStorageEndpoint" value="https://127.0.0.1:10002"/>
  <Setting name="allowInsecureRemoteEndpoints" value="true"/>
</ConfigurationSettings>

So our storage endpoints point to development storage, with a special AccountName and AcountSharedKey.

And when running the same Azure service in the cloud, we need something like:

 <ConfigurationSettings>
  <Setting name="AccountName" value="YourStorageAccountName"/>
  <Setting name="AccountSharedKey" value="YourStorageAccountSharedKey"/>
  <Setting name="BlobStorageEndpoint" value="https://blob.core.windows.net"/>
  <Setting name="QueueStorageEndpoint" value = "https://queue.core.windows.net"/>
  <Setting name="TableStorageEndpoint" value="https://table.core.windows.net"/>
  <Setting name="allowInsecureRemoteEndpoints" value="true"/>
</ConfigurationSettings>

So our storage endpoints point to cloud storage.  (*Don’t get hung up on “allowInsecureRemoteEndpoints” and not using “https” at this point, more in later posts.  Also, the values for “YourStorageAccountName” and “YourStorageAccountSharedKey” will come from the development portal.)

It’s at this point that we need to start to think about configuration management.

Deployment Scenarios

There are three deployment scenarios:

  1. Running entirely locally (development fabric and development storage).
  2. Running in what I call “hybrid” mode (development fabric and cloud storage).
  3. Running entirely in the cloud (cloud fabric and cloud storage, in other words, deployed).

And they require different configurations.

Enter configuration management…

Fortunately, there is a relatively easy solution to this problem, and it is to introduce multiple Azure Cloud Service projects into our solution to cover the different deployment scenarios.

To do this, we need to add two more Azure Cloud Service Projects to our solution, and rename/reconfigure our first Azure Cloud Service Project.

Here are the steps we need to take:

First, rename your Cloud Service Project to X_DevFabric (in this case, FirstProject_DevFabric) in preparation for making it the Cloud Service Project that is configured for deployment scenario #1 above - running entirely locally (development fabric and development storage):

RenameServiceProject

Next, add two more Azure Cloud Service Projects to your solution, and call them:

X_Cloud (in this case, FirstProject_Cloud)

AddCloudProject

X_Hybrid (in this case, FirstProject_Hybrid)

AddHybridProject

At this point, your solution will look something like:

ServiceProjectsAdded 

Once you’ve done this, edit the ServiceDefinition.csdef file in the X_Cloud, X_DevFabric and X_Hybrid projects, and paste the following settings into each, so they all look like this:

<?xmlversion="1.0" encoding="utf-8"?>

<ServiceDefinition name="FirstProject" xmlns="https://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition">

<WorkerRole name="WorkerRole">

<ConfigurationSettings>

<Settingname="AccountName"/>

<Settingname="AccountSharedKey"/>

<Settingname="BlobStorageEndpoint"/>

<Settingname="QueueStorageEndpoint"/>

<Settingname="TableStorageEndpoint"/>

      <Settingname="allowInsecureRemoteEndpoints"/>

</ConfigurationSettings>

</WorkerRole>

<WebRole name="Web">

<InputEndpoints>

      <InputEndpoint name="HttpIn" protocol="http" port="80" />

</InputEndpoints>

<ConfigurationSettings>

<Settingname="DevFabric"/>

<Settingname="AccountName"/>

<Settingname="AccountSharedKey"/>

<Settingname="BlobStorageEndpoint"/>

<Settingname="QueueStorageEndpoint"/>

<Settingname="TableStorageEndpoint"/>

      <Settingname="allowInsecureRemoteEndpoints"/>

</ConfigurationSettings>

</WebRole>

</ServiceDefinition>

This sets up the service definitions in each project so that they can be properly configured.

The next step is to add the Web and Worker roles to BOTH the X_Cloud and X_Hybrid Cloud Service Projects.  Do the following in both projects:

Add the Web Role:

AddWebRole 

AddWebRoleTo

And add the Worker Role:

AddWorkerRole

AddWorkerRoleTo 

(This is getting long, I know, but just keep on keeping on… Software development isn’t for wimps.)

OK, the next step is to edit the ServiceConfiguration.cscfg files in each of our Cloud Service Projects as follows:

For the X_Cloud project, the ServiceConfiguration.cscfg contains:

 <?xml version="1.0"?>
<ServiceConfiguration serviceName="FirstProject" xmlns="https://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration">
    <Role name="WorkerRole">
        <Instances count="1" />
        <ConfigurationSettings>
            <Setting name="AccountName" value="YourStorageAccountName"/>
            <Setting name="AccountSharedKey" value="YourStorageAccountSharedKey"/>
            <Setting name="BlobStorageEndpoint" value="https://blob.core.windows.net"/>
            <Setting name="QueueStorageEndpoint" value = "https://queue.core.windows.net"/>
            <Setting name="TableStorageEndpoint" value="https://table.core.windows.net"/>
            <Setting name="allowInsecureRemoteEndpoints" value="true"/>
        </ConfigurationSettings>
    </Role>
    <Role name="Web">
        <Instances count="1" />
        <ConfigurationSettings>
            <Setting name="DevFabric" value="false"/>
            <Setting name="AccountName" value="YourStorageAccountName"/>
            <Setting name="AccountSharedKey" value="YourStorageAccountSharedKey"/>
            <Setting name="BlobStorageEndpoint" value="https://blob.core.windows.net"/>
            <Setting name="QueueStorageEndpoint" value = "https://queue.core.windows.net"/>
            <Setting name="TableStorageEndpoint" value="https://table.core.windows.net"/>
            <Setting name="allowInsecureRemoteEndpoints" value="true"/>
        </ConfigurationSettings>
    </Role>
</ServiceConfiguration>

For the X_DevFabric project, the ServiceConfiguration.cscfg contains:

 <?xml version="1.0"?>
<ServiceConfiguration serviceName="FirstProject" xmlns="https://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration">
  <Role name="WorkerRole">
    <Instances count="1" />
      <ConfigurationSettings>
          <Setting name="AccountName" value="devstoreaccount1"/>
          <Setting name="AccountSharedKey" value="Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw=="/>
          <Setting name="BlobStorageEndpoint" value="https://127.0.0.1:10000"/>
          <Setting name="QueueStorageEndpoint" value="https://127.0.0.1:10001"/>
          <Setting name="TableStorageEndpoint" value="https://127.0.0.1:10002"/>
          <Setting name="allowInsecureRemoteEndpoints" value="true"/>
      </ConfigurationSettings>
  </Role>
  <Role name="Web">
    <Instances count="1" />
      <ConfigurationSettings>
          <Setting name="DevFabric" value="true"/>
          <Setting name="AccountName" value="devstoreaccount1"/>
          <Setting name="AccountSharedKey" value="Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw=="/>
          <Setting name="BlobStorageEndpoint" value="https://127.0.0.1:10000"/>
          <Setting name="QueueStorageEndpoint" value="https://127.0.0.1:10001"/>
          <Setting name="TableStorageEndpoint" value="https://127.0.0.1:10002"/>
          <Setting name="allowInsecureRemoteEndpoints" value="true"/>
      </ConfigurationSettings>
  </Role>
</ServiceConfiguration>

For the X_Hybrid project, the ServiceConfiguration.cscfg contains:

 <?xml version="1.0"?>
<ServiceConfiguration serviceName="FirstProject" xmlns="https://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration">
    <Role name="WorkerRole">
        <Instances count="1" />
        <ConfigurationSettings>
            <Setting name="AccountName" value="YourStorageAccountName"/>
            <Setting name="AccountSharedKey" value="YourStorageAccountSharedKey"/>
            <Setting name="BlobStorageEndpoint" value="https://blob.core.windows.net"/>
            <Setting name="QueueStorageEndpoint" value = "https://queue.core.windows.net"/>
            <Setting name="TableStorageEndpoint" value="https://table.core.windows.net"/>
            <Setting name="allowInsecureRemoteEndpoints" value="true"/>
        </ConfigurationSettings>
    </Role>
    <Role name="Web">
        <Instances count="1" />
        <ConfigurationSettings>
            <Setting name="DevFabric" value="false"/>
            <Setting name="AccountName" value="YourStorageAccountName"/>
            <Setting name="AccountSharedKey" value="YourStorageAccountSharedKey"/>
            <Setting name="BlobStorageEndpoint" value="https://blob.core.windows.net"/>
            <Setting name="QueueStorageEndpoint" value = "https://queue.core.windows.net"/>
            <Setting name="TableStorageEndpoint" value="https://table.core.windows.net"/>
            <Setting name="allowInsecureRemoteEndpoints" value="true"/>
        </ConfigurationSettings>
    </Role>
</ServiceConfiguration>

At this point, we are ready to run our service in each of the deployment scenarios outlined above.

Caveat:

I am still researching <Setting name="DevFabric" value="false"/> entry. I cannot find definitive documentation on it at this time.  I suspect true when the web role is running in the development fabric, and false when the web role is deployed.  TBD.

There is a lot more to go, but this posting has brought us a lot of the way there.  In my next posting, I will cover CRUD (Create, Read, Update and Delete) operations in Azure storage running in all three deployment scenarios.

Best,

Brian

Comments

  • Anonymous
    February 17, 2009
    PingBack from http://www.clickandsolve.com/?p=9920
  • Anonymous
    March 10, 2009
    Azure Ninja Part 2! (空色の忍者) In my last posting I showed you how to run an Azure Worker Role outside the
  • Anonymous
    August 21, 2009
    よーやくプロフ持ちになれました。私の事気になった方がいましたら気軽にメールください。恋バナとか好きなんでよろしくでぇす。zuttozuttoissyodayo@docomo.ne.jp
  • Anonymous
    August 22, 2009
    女性会員様増加につき、当サイトの出張ホストが不足中です。女性の自宅やホテルに出向き、欲望を満たすお手伝いをしてくれる男性アルバイトをただいま募集していますので、興味のある方はTOPページから無料登録をお願いいたします
  • Anonymous
    August 23, 2009
    最近様々なメディアで紹介されている家出掲示板では、全国各地のネットカフェ等を泊り歩いている家出少女のメッセージが多数書き込みされています。彼女たちはお金がないので掲示板で知り合った男性とすぐに遊びに行くようです。あなたも書き込みに返事を返してみませんか
  • Anonymous
    August 24, 2009
    あなたのモテ度数を診断できる、モテる度チェッカー!日頃モテモテでリア充のあなたもそうでないヒキニートの貴方も隠されたモテスキルを測定して今以上にモッテモテになること間違いなし
  • Anonymous
    August 25, 2009
    オ○ニーライフのお手伝い、救援部でHな見せたがり女性からエロ写メ、ムービーをゲットしよう!近所の女の子なら実際に合ってHな事ができちゃうかも!?夏で開放的になっている女の子と遊んじゃおう
  • Anonymous
    August 26, 2009
    メル友募集のあそび場「ラブフリー」はみんなの出逢いを応援する全国版の逆援助コミュニティーです!女の子と真剣にお付き合いしたい方も、複数の女性と戯れたい方も今すぐ無料登録からどうぞ
  • Anonymous
    August 27, 2009
    簡単にお小遣い稼ぎをしたい方必見、当サイト逆¥倶楽部では無料登録して女性の性の欲求に応えるだけのアルバイトです。初心者でもすぐに高収入の逆¥交際に興味をもたれた方はTOPページまでどうぞ。
  • Anonymous
    August 28, 2009
    プロフ作りました。興味ある方連絡まってま〜す。メアドを乗せておくので連絡ください。色んな人の色んな話聞きたい感じですのでヨロシクhappy-my-life-.-@docomo.ne.jp