Wednesday, July 25, 2012

Create a Persistent VM using Windows Azure Service Management REST APIs

Here I’m posting on how we can create a Persistent VM using REST APIs using the basic HTTPRequest POST methods.
First we need to know where we need to POST our request. The URL will be:
You have to replace your Azure subscription id and the service on which this VM will be hosted.
Next step is what we need to post in our request. So we’ll create our request body. It is an XML file which will have some of the properties related to the service which we want to host.
So I’ll call my xml file as CreateVM.xml and it will be like:
<Deployment xmlns="http://schemas.microsoft.com/windowsazure" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
   <Name>deployment-name</Name>
   <Label>deployment-label</Label>  
   <RoleList>
      <Role>
         <RoleName>name-of-the-vm</RoleName>
         <RoleType>PersistentVMRole</RoleType>     
         <ConfigurationSets>
            <ConfigurationSet>
                <!—Include either a WindowsProvisioningConfigurationSet or a LinuxProvisioningConfigurationSet, but not both -->                <ConfigurationSetType>WindowsProvisioningConfiguration<ConfigurationSetType>                <ComputerName>computer-name</ComputerName>                <AdminPassword>administrator-password-for-the-vm</AdminPassword>                 <ResetPasswordOnFirstLogon>true|false</ResetPasswordOnFirstLogon>                <EnableAutomaticUpdate>true|false</EnableAutomationUpdate>                  <TimeZone>Pacific Standard Time</TimeZone>
                <DomainJoin>
                   <Credentials>
                        <Domain>domain-to-join</Domain>
                        <Username>user-name-in-the-domain</Username>
                        <Password>password-for-the-user-name</Password>
                   </Credentials>
                   <JoinDomain>domain-to-join</JoinDomain>
                   <MachineObjectOU>distinguished-name-of-the-ou<MachineObjectOU>
                </DomainJoin>
                <StoredCertificateSettings>
                   <CertificateSetting>
                        <StoreLocation>LocalMachine</StoreLocation>
                        <StoreName>name-of-store-on-the-machine</StoreName>
                        <Thumbprint>certificate-thumbprint</Thumbprint>
                   </CertificateSetting>
                </StoredCertificateSettings>
            </ConfigurationSet>
            <!—Include either a WindowsProvisioningConfigurationSet or a LinuxProvisioningConfigurationSet, but not both -->
            <ConfigurationSet>                <ConfigurationSetType>LinuxProvisioningConfiguration<ConfigurationSetType>
                <HostName>host-name-for-the-vm</HostName>
                <UserName>new-user-name</UserName>
                <UserPassword>password-for-the-new-user</UserPassword>
                <DisableSshPasswordAuthentication>true|false</DisableSshPasswordAuthentication>      
                <SSH>
                    <PublicKeys>
                       <PublicKey>
                           <FingerPrint>certificate-fingerprint</FingerPrint>
                           <Path>SSH-public-key-storage-location</Path>  
                       </PublicKey>
                    </PublicKeys>
                    <KeyPairs>
                       <KeyPair>
                           <FingerPrint>certificate-fingerprint</FinguerPrint>
                           <Path>SSH-public-key-storage-location</Path>
                       </KeyPair>
                    </KeyPairs>
                </SSH>
            </ConfigurationSet>    
            <ConfigurationSet>
                <ConfigurationSetType>NetworkConfiguration<ConfigurationSetType>
                <InputEndpoints>
                    <InputEndpoint>
                        <EnableDirectServerReturn>true|false</EnableDirectServerReturn>             
                        <LoadBalancedEndpointSetName></LoadBalancedEndpointSetName>
                        <LocalPort>local-port-number</LocalPort>
                        <Name>endpoint-name</Name>
                        <Port>external-port-number</Port>
                        <LoadBalancerProbe>
                            <Path>relative-path-that-contains-status</Path>
                            <Port>port-to-use-for-status</Port>
                            <Protocol>TCP|UDP</Protocol>
                        </LoadBalancerProbe>
                        <Protocol>TCP|UDP</Protocol>                 
                    </InputEndpoint>
                </InputEndpoints>
                <SubnetNames>
                 <string>FrontEndSubnet1</string>
                 <string>BackEndSubnet1</string>
                </SubnetNames>       
            </ConfigurationSet>
         </ConfigurationSets>
         <AvailabilitySetName>availability-set-for-the-vm</AvailabilitySetName>
         <DataVirtualHardDisks>
            <DataVirtualHardDisk>
               <HostCaching>ReadOnly|ReadWrite</HostCaching>
               <DiskLabel>data-disk-label</DiskLabel>         
               <DiskName>new-or-existing-disk-name</DiskName>
               <Lun>logical-unit-number</Lun>
               <LogicalDiskSizeInGB>size-in-gb-of-the-data-data-disk</LogicalDiskSizeInGB>           
               <MediaLink>url-of-the-blob-containing-the-data-disk</MediaLink>
            </DataVirtualHardDisk>
         </DataVirtualHardDisks>
         <OSVirtualHardDisk>
            <HostCaching>ReadOnly|ReadWrite</HostCaching>  
            <DiskLabel>os-disk-label</DiskLabel>
            <DiskName>new-or-existing-disk-name</DiskName>               
            <MediaLink>url-of-the-blob-containing-the-os-disk</MediaLink>
            <SourceImageName>name-of-the-image-to-use-for-disk-creation</SourceImageName>
         </OSVirtualHardDisk>     
         <RoleSize>ExtraSmall|Small|Medium|Large|ExtraLarge</RoleSize>     
      </Role>
    </RoleList>
    <VirtualNetworkName>MyProdictionNetwork</VirtualNetworkName>
    <Dns>
        <DnsServers>
            <DnsServer>
                <Name>dns-name</Name>
                <Address>dns-ip-address</Address>
            </DnsServer>
            <DnsServer>
                <Name>dns-name</Name>
                <Address>dns-ip-address</Address>
            </DnsServer>
        </DnsServers>
    </Dns>
</Deployment>
Now we will have to use this XML in our C# code to POST the request to the URL specified above.
I’ll write a function called CreatedVM which will accept parameters like URL, SubscriptionId, HostedServiceName and the location of XML file which needs to be posted.
private void CreateVM(string url, string subscriptionId, string xmlLocationPath, string hostedServiceName)
{
                Uri uri = new Uri(String.Format(url, hostedServiceName, subscriptionId));
                XDocument document = null;
                HttpWebRequest request =

HttpWebRequest)HttpWebRequest.Create(uri.ToString());
request.Timeout = 50000;
request.Headers.Add("x-ms-version", “2012-03-01”);
request.ClientCertificates.Add(certificate);
request.ContentType = "application/xml";
                If(xmlLocationPath != null || !string.IsNullorEmpty(xmlLocationPath)
                {
                                document =       XDocument.Load(xmlLocationPath);
              request.Method = "POST";
              StreamWriter writer = newStreamWriter(request.GetRequestStream());
              writer.Write(document);
writer.Close();
       }
                HttpStatusCode statusCode;
HttpWebResponse response;
try
{
       response = (HttpWebResponse)request.GetResponse();
}
catch (WebExceptionex)
{
// GetResponse throws a WebException for 400 and 500 status codes
response = (HttpWebResponse)ex.Response;
}
statusCode = response.StatusCode;
       response.Close();     
}
We can customize this method. I’ve written a very basic example to explain this.
Please note that you should have a valid X509 certificate in your cert store as well a matching certificate uploaded on Azure portal for your subscription ID. You can retrieve the certificate using the thumbprint of the certificate.
The XML mentioned above is for MS Version “2012-03-01”.
For more detailed explanation of the properties specified in XML, please refer to:
Cheers
Ankit

Tuesday, July 24, 2012

Creating a Hosted Service in Windows Azure IaaS Portal using REST APIs


I was working with the latest Windows Azure SDK 1.7 REST APIs for various operations related to services, roles and virtual machines.
Here I’m posting on how we can create a hosted service using REST APIs using the basic HTTPRequest POST methods.
First we need to know where we need to POST our request. The URL will be:
You have to replace your Azure subscription id.
Next step is what we need to post in our request. So we’ll create our request body. It is an XML file which will have some of the properties related to the service which we want to host.
So I’ll call my xml file as CreateHostedService.xml and it will be like:
<?xml version="1.0" encoding="utf-8"?>
<CreateHostedService xmlns="http://schemas.microsoft.com/windowsazure">
  <ServiceName>service-name</ServiceName>
  <Label>base64-encoded-service-label</Label>
  <Description>description</Description>
  <Location>location</Location>
  <AffinityGroup>affinity-group</AffinityGroup>
  <ExtendedProperties>
    <ExtendedProperty>
      <Name>property-name</Name>
      <Value>property-value</Value>
    </ExtendedProperty>
  </ExtendedProperties>
</CreateHostedService> 

The mandatory properties here are Service Name, Label, Location or Affinity Group (either one of them).
Now we will have to use this XML in our C# code to POST the request to the URL specified above.
I’ll write a function called CreatedHostedService which will accept parameters like URL, SubscriptionId, and the location of XML file which needs to be posted.
private void CreateHostedService(string url, string subscriptionId, string xmlLocationPath)
{
                Uri uri = new Uri(String.Format(url, subscriptionId));
                XDocument document  = null;
                HttpWebRequest request =     

HttpWebRequest)HttpWebRequest.Create(txtRestCommand.Text);       

       request.Timeout = 50000;
       request.Headers.Add("x-ms-version", “2012-03-01”);
       request.ClientCertificates.Add(certificate);
       request.ContentType = "application/xml"; 

                If(xmlLocationPath != null || !string.IsNullorEmpty(xmlLocationPath)
                {
                                document =       XDocument.Load(xmlLocationPath);
              request.Method = "POST";
              StreamWriter writer = new StreamWriter(request.GetRequestStream());
              writer.Write(document);
              writer.Close();
       }

                HttpStatusCode statusCode;
       HttpWebResponse response;

       try
       {
              response = (HttpWebResponse)request.GetResponse();
       }

catch (WebException ex)
       {
                // GetResponse throws a WebException for 400 and 500 status codes
              response = (HttpWebResponse)ex.Response;
       }
       statusCode = response.StatusCode;  
       response.Close();     
}
We can customize this method. I’ve written a very basic example to explain this.
Please note that you should have a valid X509 certificate in your cert store as well a matching certificate uploaded on Azure portal for your subscription ID. You can retrieve the certificate using the thumbprint of the certificate.
The XML mentioned above is for MS Version “2012-03-01”.
For more detailed explanation of the properties specified in XML, please refer to:
Cheers
Ankit

Tuesday, May 22, 2012

Managing Sessions in Azure using Table Storage

Hi Again,

After a long break I'm posting something new on my blog. This time something related to Windows Azure development. 

This post is about how we can manage a session in Windows Azure. As we know that there are different ways of session management in ASP.NET like:

In Proc
Out Proc (SQL Server and State Server)
Custom

So here I've used a Custom mode to store the session in Windows Azure which is called Table Storage. Below are the steps which allow us to store our session on Azure storage account using Table Storage method:

1) We have to download the code for Table Storage provider developed by Windows Azure team from the below URL:
2) Compile the project downloaded from the above URL and add the dll as a reference in your project.

3) In the web.config of the project, add the following setting in the< sessionState> section:
<sessionState mode="Custom" customProvider="TableStorageSessionStateProvider">
<providers>
<clear/>
<add name="TableStorageSessionStateProvider" type="Microsoft.Samples.ServiceHosting.AspProviders.TableStorageSessionStateProvider" />
</providers>
</sessionState>

4) Go to the web role properties and add the following setting in the ServiceConfiguration.csfg file:

<ConfigurationSettings>
<Setting name="DataConnectionString" value="DefaultEndpointsProtocol=https;AccountName=<Azure Storage Account Name>;AccountKey=<Azure Storage Account Key> " />
</ConfigurationSettings>
You can add this setting in the web.config or app.config file of your application also:
<appSettings>
<add key="DataConnectionString"value="DefaultEndpointsProtocol=https;AccountName=<Azure Storage Account Name>;AccountKey=<Azure Storage Account Key> " />
</appSettings>

5) In the Global.asax file of the project, get the CloudStorageAccount details before accessing the table storage. Write the following code to achieve this:
usingMicrosoft.WindowsAzure;
usingMicrosoft.WindowsAzure.ServiceRuntime;
usingSystem.Configuration;
protected void Application_Start()
{
CloudStorageAccount.SetConfigurationSettingPublisher((configName, configSettingPublisher) => { varconnectionString = RoleEnvironment.IsAvailable ? RoleEnvironment.GetConfigurationSettingValue(configName) : ConfigurationManager.AppSettings[configName]; configSettingPublisher(connectionString); });
}

In the above code, if you have not specified the “DataConnectionString” in the Role configuration, it will try to look up in the web.config or app.config of your application. So make sure, the “DataConnectionString” must be present in either of these two places.

6) Connect to Server Explorer and in the Windows Azure Storage section, add the new storage account with the Account Name and Key provided in the step 4. You will be able to see the Session table in the Azure.
Cheers
Ankit