Exercise 3: Deploying the WCF Service to Windows Azure

The Windows Azure Compute Emulator provides a faithful simulation of how its cloud environment works. In the previous exercises, all the code needed to provide the functionalities we wanted has been written, and it will not change regardless of the Windows Azure environment you will deploy your service to. However deploying a service to the cloud does entail knowledge of some specific aspects: resources provisioning, port number handling, alternative configuration settings are all things you need to be aware of in order to successfully roll your service in the cloud. In this last exercise you will learn how to create a hosted service, associate storage to it and take the necessary steps to make your service work in the cloud.

Note:
In order to perform this task you need to have an account and an active subscription with Windows Azure.

Note:
You require an STS project and appropriate certificates to complete this exercise. If you have not already done so, complete the Getting Started section.

Task 1 – Creating the Hosted Service using the Windows Azure Management Portal

  1. Open Microsoft Visual Studio 2010 with administrator privileges. From Start | All Programs | Microsoft Visual Studio 2010, right-click Microsoft Visual Studio 2010 and select Run as administrator.

    Note:
    If you performed all the steps from Exercise 2: Adding Diagnostics and Load Balancing, you can continue using the solution you obtained after completing that exercise and skip to step 4.

  2. Open the WIFWCFonWindowsAzure.sln solution file from the \Source\Ex3-DeployingInAzure\Begin folder of this lab.
  3. Replace the following placeholders in all solution files. To do this, you can use Visual Studio’s Quick Replace dialog (Edit | Find and Replace | Quick Replace).
    • Replace the {yourProjectName} placeholder with the name you use for the certificate and the azure project (e.g.: foo)
    • Replace the {yourCertificateThumbprint} placeholder with the thumbprint of the {yourprojectname}.cloudapp.net certificate you created during the Getting Started: Setting up the Certificates and Local STS section (e.g.: 939026E4657552526FXXXX868DEA80F788991A73)
    • Replace the {yourMachineName} placeholder with the name of your machine.

      Note:
       You can get more information on how to retrieve the thumbprint of your certificate from the How to: Retrieve the Thumbprint of a Certificate MSDN article.

      Figure 1

      Replacing begin solution placeholders

  4. Navigate to https://windows.azure.com using a Web browser and sign in using the Windows Live ID associated with your Windows Azure account.

    Figure 2

    Signing in to the Windows Azure portal

  5. Click on the New Hosted Service button on the ribbon.

    Figure 3

    Creating a new Hosted Service

  6. In the Create a new Hosted Service dialog, select the subscription where you wish to create the service from the drop down list labeled Choose a subscription.

    Figure 4

    Choosing your subscription

  7. Enter a service name in the textbox labeled Enter a name for your service and choose its URL by entering a prefix in the textbox labeled Enter a URL prefix for your service. This should be {yourprojectname} that you used to create the certificate on the Getting Started: Setting up the Certificates and Local STS section. Windows Azure uses this value to generate the endpoint URLs for the hosted service.

    Figure 5

    Choosing a service name and URL

    Note:
    Note: This is the usual {yourprojectname} that you used for the entire lab. It is the same name you picked as the subject of the X.509 certificate, and the name that will determine the URI of your service in production. If the name you picked is not available, you have to pick a new one: do your best to make it unique, remember that others are going through this lab as well (hence all the obvious names will be already taken). You will have to go back to the former tasks and repeat some steps, using the new name.

    Note:
    The portal ensures that the name is valid by verifying that the name complies with the naming rules and is currently available. A validation error will be shown if you enter name that does not satisfy the rules.

  8. Select the option labeled Create or choose an affinity group and then pick Create a new affinity group from the drop down list.

    Figure 6

    Creating a new affinity group

  9. In the Create a New Affinity Group dialog, enter wifwazwcf in the Affinity Group Name field, select its Location in the drop down list, and then click OK.

    Figure 7

    Creating a new affinity group

  10. Select the Do not Deploy option.

    Note:
    While you can create and deploy your service to Windows Azure in a single operation by completing the Deployment Options section, for this hands-on lab, you will defer the deployment step until the next steps.

  11. Click OK to create the hosted service and then wait until the provisioning process completes.

    Figure 8

    Hosted service successfully created

Task 2 – Creating the Storage Account using the Windows Azure Management Portal

In this task you will create a Windows Azure Storage Account to store the diagnostics trace logs, which were configured in the previous exercise.

  1. Click Storage Accounts on the left pane. In the Windows Azure ribbon, click New Storage Account.

    Figure 9

    Creating a new storage account

  2. In the Create a New Storage Account dialog, pick your subscription in the drop down list labeled Choose a subscription.

    Figure 10

    Choosing a subscription to host the storage account

  3. In the textbox labeled Enter a URL, enter the name for your storage account, for example, <yourname>wifwazwcf, where <yourname> is a unique name. Windows Azure uses this value to generate the endpoint URLs for the storage account services.

    Figure 11

    Choosing the URL of the new storage account

    Note:
    The portal ensures that the name is valid by verifying that the name complies with the naming rules and is currently available. A validation error will be shown if you enter a name that does not satisfy the rules.

  4. Select the option labeled Create or choose an affinity group and then pick the wifwazwcf affinity group from the drop down list—this is the same affinity group that you defined earlier, when you created the hosted service.

    Figure 12

    Choosing an affinity group

    Note:
    By choosing wifwazwcf affinity group, you ensure that the hosted service is deployed to the same location as the hosted service that you provisioned earlier.

  5. Click Create to register your new storage account. Wait until the account provisioning process completes and updates the Storage Accounts tree view. Notice that the Properties pane shows the URL assigned to each service in the storage account. Record the public storage account name—this is the first segment of the URL assigned to your endpoints.

    Figure 13

    Storage account successfully created

Task 3 – Configuring the Web Role for Azure Deployment

In this task you will update the Relying Party Web Role with the necessary configuration to run on Windows Azure.

  1. In the Storage Accounts view of the Windows Azure Management Portal where you created the storage account in the previous task, click the View button next to Primary access key in the Properties pane.
  2. In the View Storage Access Keys dialog, click Copy to Clipboard next to the Primary Access Key. You will use this value later on to configure the application.

    Figure 14

    Retrieving the storage access keys

    Note:
    The Primary Access Key and Secondary Access Key both provide a shared secret that you can use to access storage. The secondary key gives the same access as the primary key and is used for backup purposes. You can regenerate each key independently in case either one is compromised.

  3. Back to Visual Studio, set the CopyLocal property to True on the Microsoft.IdentityModel assembly reference. To do this, expand the References node of the RelyingParty project, select Microsoft.IdentityModel and press F4 to show its properties. Find the CopyLocal property and set it to true.

    Figure 15

    Setting the CopyLocal property on the reference to the Microsoft.IdentityModel assembly

    Note:
    A Windows Azure application can take advantage of any of the assemblies available in .NET 3.5. Windows Identity Foundation is distributed as a standalone update, hence it is not directly available in Windows Azure. As such, you need to make sure that a copy of the assembly Microsoft.IdentityModel is packaged together with your application bits.

  4. In Solution Explorer, double-click the RelyingParty node inside the Roles folder of the CloudConfiguration project.
  5. In the Settings tab, update the Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString setting to use the storage account that you created on the previous task. To do this, click the ellipsis (...) button, provide the account name and access key and then press OK.

    Figure 16

    Using Storage account on Windows Azure

  6. Update the value of the Deployment setting to Cloud.

    Figure 17

    Settings updated on RelyingParty Role

  7. Configure the Web Role to run in LegacyMode. To do this, open the ServiceDefinition.csdef file and delete the <Sites> section.

    XML

    <ServiceDefinition name="CloudConfiguration" xmlns="https://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition"> <WebRole name="RelyingParty"> <Sites> <Site name="Web"> <Bindings> <Binding name="Endpoint1" endpointName="HttpIn" /> <Binding name="Endpoint1" endpointName="HttpsIn" /> </Bindings> </Site> </Sites> <Endpoints> … </Endpoints> </ServiceDefinition>

  8. Open the Web.config file of the RelyingParty project. Add the following service configuration named Cloud below the Development service inside the microsoft.identityModel section. Remember to update {yourprojectname} label with your Windows Azure Hosted Service name. After that, press Ctrl + S to save the changes and close it.

    (Code Snippet – WebServicesAndIdentityInTheCloud Lab - Ex03 Cloud service section)

    XML

    <microsoft.identityModel>
    FakePre-cc37b00e5fdd4e1a854434b591e5cb52-fdda24fd202b4bed8ace9907cdf17613FakePre-f8225339343b49aca56fdd6cbd070442-548d3b92062743bc9c5655e58ba1e734FakePre-3ceffd033ec8437b9604852ad216ff7c-c366ba342dfc4bceab7409dd790aa361 <service name="Cloud"> <certificateValidation certificateValidationMode="None" /> <audienceUris> <add value="https://{yourprojectname}.cloudapp.net/" /> </audienceUris> <issuerNameRegistry type="Microsoft.IdentityModel.Tokens.ConfigurationBasedIssuerNameRegistry, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"> <trustedIssuers> <add thumbprint="40A1D2622BFBDAC80A38858AD8001E094547369B" name="https://localhost/LocalSTS/Service.svc" /> </trustedIssuers> </issuerNameRegistry> </service>FakePre-123314d07e2d4ad89b66fefa41f09324-125b6c9823f646f9ad98c94ea9879ba9

    Note:
    As you may recall from earlier steps, the Deployment string is used for switching between alternative WIF configurations from the service’s web.config. The main difference between the Development and Cloud setting sets is that the latter turns off the certificate validation, which would require the bits of the STS signing certificate to be installed in the role certificate store. That is not necessary as we expect the certificate bits to be included in the call itself: storing the certificate thumbprint in the trustedIssuer section is enough for identifying the incoming certificate as belonging to a trusted STS.

  9. Go back to the RelyingParty role configuration page. In the Endpoints tab, update the HTTP and HTTPS ports to 80 and 443 respectively.

    Figure 18

    HTTP and HTTPS ports restored to their default values

    Note:
    We don’t need to worry about port collisions any longer: in the cloud we are going to use the regular port 80 for HTTP and 443 for HTTPS, hence we need to adjust the configuration accordingly.

  10. Press Ctrl + S to save the changes and close the RelyingParty role configuration page.

Task 4 – Uploading the Certificate and Staging Deployment to Windows Azure

Web roles running on Windows Azure will need access the certificate you configured in previous tasks. In this task you will upload the certificate to Windows Azure and create a new Staging Deployment to run the weather service in Windows Azure.

  1. In Visual Studio, create a new package for the CloudConfiguration project. To do this, right-click the CloudConfiguration project and select Publish to generate the package that you will deploy to the cloud in the following steps.
  2. In the Deploy Windows Azure project dialog, make sure to choose Create Services Package Only. This will create the package and open a new window where they are located. You will use these files in the following steps.

    Figure 19

    Creating the service package for deployment

    Note:
    Although the procedure is not shown here, the Publish Cloud Service feature in the Windows Azure Tools enables deployment of your service package directly from Visual Studio. To use this feature, you need to configure a set of credentials that you use to authenticate access to the management service using a self-issued certificate that you upload to the Management Portal.

  3. Go back to the browser and the Windows Azure Management Portal.
  4. Upload the generated certificate so the WCF service can take advantage of it in the cloud. To do this, click Hosted Services on the left pane and select the Certificates folder inside the hosted service you previously created. Then, click Add Certificate in the ribbon.

    Figure 20

    Adding a new certificate

  5. Click the Browse button and select the {yourprojectname}.cloudapp.net.pfx file inside Assets\AzureCertificates folder of this Lab. Type the password you provided when creating the certificates in the passwords fields (if you didn’t provide one, remember that the default password used was “123456”), and press the Create button. Your certificate will be uploaded and you will be able to see it in the Certificates list in the portal page.

    Figure 21

    Choosing a new certificate

    Figure 22

    Certificate in the tree view

    Note:
    The instructions above assume that you used the self-signed certificate generated by the lab script. If you used your own certificate, you must provide a complete .pfx file for it. You can obtain that file by exporting the certificate via Certificates snap-in of the Windows MMC, if the certificate is installed in a local store: don’t forget to export the private key in it, too.

  6. In the left menu select Hosted Services, then select the hosted service that you created in the previous steps and then click New Staging Deployment on the ribbon.

    Note:
    A hosted service is a service that runs your code in the Windows Azure environment. It has two separate deployment slots: staging and production. The staging deployment slot allows you to test your service in the Windows Azure environment before you deploy it to production.

    Figure 23

    Hosted service summary page

  7. In the Create a new Deployment dialog, to choose a Package location, click Browse Locally, navigate to the folder where Visual Studio generated the package in Steps 1 and 2 and then select the CloudConfiguration.cspkg file.
  8. Now, to choose the Configuration File, click Browse Locally and select ServiceConfiguration.cscfg in the same folder that you used in the previous step.

    Note:
    The .cscfg file contains configuration settings for the application, including the instance count that you will update later in the exercise.

  9. Finally, for the Deployment name, enter a label to identify the deployment; for example, use v1.0.

    Note:
    The portal displays the label in its user interface for staging and production, allowing you to identify the version currently deployed in each environment.

    Figure 24

    Configuring the service package deployment

  10. Click OK to start the deployment. Notice that the package begins to upload and that the portal shows the status of the deployment to indicate its progress.

    Figure 25

    Uploading a service package to the Windows Azure Platform Management Portal

  11. Wait until the deployment process finishes, which may take several minutes. At this point, you have already uploaded the package and it is in a Ready state. Notice that the portal assigned a DNS name to the deployment that includes a unique identifier. Shortly, you will access this URL to test the application and determine whether it operates correctly in the Windows Azure environment, but first you need to configure it. Take note of the ID, you will use it to configure the Client in future steps.

    Note:
    During deployment, Windows Azure analyzes the configuration file and copies the service to the correct number of machines, and starts all the instances. Load balancers, network devices and monitoring are also configured during this time.

    Figure 26

    Package successfully deployed and ready

Verification

In order to verify that you have performed every step in the exercise correctly, proceed as follows:

  1. While you wait for the roles to start, get back to Visual Studio.
  2. Inside the app.config file of the Client project, update the endpoint address to point to the staging Web Site URL as it is shown below. {stagingDeploymentID} is a unique GUID that Windows Azure generates every time you deploy a package to Staging:

    XML

    <system.serviceModel>
    FakePre-abb9b140b36b455086a6a5cc1d30c7d5-4a41dc4ffd72412fa3e23d70f43dd129FakePre-d568fb5acff84758a16e0c0c67f82144-cb44ea3dc7ab401db825bc5d5e76eca2FakePre-f707ac14a183417d9296e4a4fc4d4a27-7ef5edc9482a4e3daa42f84dcd9f022fFakePre-c2c50246e8094f6f90b34e7c3584a3c7-0249fb571e2a4e0fae9a13d105cefc6c <endpoint address="https://{stagingDeploymentID}.cloudapp.net/WeatherService.svc" binding="customBinding" bindingConfiguration="CustomBinding_IWeatherService" contract="ServiceReference1.IWeatherService" name="CustomBinding_IWeatherService" />FakePre-984a68730a5440ac9fa4ca95fd420972-2d85ee5d8a46430b923dcdced2f8dea5FakePre-2413d5c35e664986a833bd22fff5d5c2-653588a796fa47b3ac033a436f4d741aFakePre-a052866f69974e0b9efe4e469a61ff03-91627d763402494f90983c47267568feFakePre-afabc3181e954faab456146f3abae0c0-25542e94a22f4aa1984806363600163cFakePre-0b75c6bc68284a36b0756f0262048ec6-fb7ad45c98af4a0992549eed2417c03b

  3. Since you are going to execute the client against the staging area of your Hosted Service, the certificate that you uploaded will be not valid (its CN does not match the staging Web Site URL). In order to avoid getting an error, you need to disable the client’s CN check inside the ForecastForm.cs file of the Client project. The necessary code is already in place, just uncomment the callback assignation for ServicePointManager.ServerCertificateValidationCallback.

    C#

    public partial class ForecastForm : Form
    FakePre-687c70bba85e446e8a0eb6e4a605945e-f628a0afcd3446c5b4639edca99ce588FakePre-4ea3b6217d654a2db448e8ccbc56eb0d-25c80f1229814a5e98a69a23aecc9da4FakePre-47ed81fe59d64825889fb2b78bd3556d-7fb392540d1644f68f7e7b25323465e6FakePre-b725b39f85f84481a18e8f4e38301d22-e5b66dbbb71e4c5d9955d230963b5a21 ServicePointManager.ServerCertificateValidationCallback = ValidateCert;FakePre-336227c0a3884ad4bcdb84566e7a4113-c5c46edce9d3407b9337504e2cf01901FakePre-0295c267a776445abc3efb39755a8859-25452ae7a4ce4194babc866f6eab13b0FakePre-b1712728eaa6442f9099acc9c17cbcab-bd526a7a13794674b94abbb692ad4840FakePre-8a30501b4b5a4f95bad51c4336ffafbb-9cac24b011ad4866a917f6f6dc8cd8eeFakePre-e9de908c45fc4cc0a0d8da77d766652f-57ab9c4928294798946b6e58bc1426cbFakePre-d51f322b82ae4d6a9c01c122388d6194-52b6f55412704f268508ca211091184fFakePre-904a5e92b03a4f1396ed5c8bc762d6b1-755ff4f548d04928b877d2e505ceaf76FakePre-84802dec68c64f9db3b7d7116b2e8018-d13a5d2dc62b4a61978653033069bc37FakePre-7d3e527018dc475c8b669d54c1fa2587-6f3876d57a784e67a16deb1761acfc6e
    Note:
    By always returning true, the ValidateCert callback disables any form of certificate check. This is done for keeping things simple here, but you should take steps for making sure that such code never goes in production (or for example that, despite of the fact that there is a mismatch with the actual endpoint URI, you check that the certificate is one that you recognize).

  4. Go back to the Windows Azure portal, and check if both role instances are running;

    Figure 27

    Role instances running

  5. Run two instances of the Client project. To do this, on Visual Studio, right-click the Client project and select Debug | Start New instance (repeat this to create the second instance).
  6. In the Weather Station client, enter any Zip Code (for example: 1000) and press the Get 3 Days button in both Client instances. Make sure that you press the “Get 3 days” button in the second client instance before receive the answer in the first one. You should get the forecast for the following 3 days in the different client instances from different roles running on the staging area of your Windows Azure Hosted Service; you can verify this checking their status bar.

    Figure 28

    Getting the forecast for the following 3 days from the Cloud

  7. Get the forecast for the following three and ten days several times providing different Zip codes, in this way, you can check how the different role instances handle the requests.