Fri, 08 Oct 2010

Building, Running, and Packaging Windows Azure Applications From the Command Line

Most developers who build Windows Azure applications do so using Visual Studio, Eclipse, or the PHP command line tools. All of these IDEs and tools are based on the same underlying Windows Azure SDK (which you usually get with the Visual Studio tools but can also get as a standalone download).

In this week’s episode of Cloud Cover, Ryan and I explore packaging up a Windows Azure application using only the command line tools in the SDK. In this post, I’ll share some more details by walking you through building, running, and packaging a Windows Azure application, all from the command line.

Step 1: Authoring a web site

The first thing we’ll do is create a simple web site. To go with the theme, I did that part via the command-line too. If you had, for example, an existing ASP.NET web site, you could use that instead.

c:\CmdlineWindowsAzure>md MyWebRole

c:\CmdlineWindowsAzure>copy con MyWebRole\index.html <html><body><h1>Hello, World!</h1></body></html>^Z 1 file(s) copied.

c:\CmdlineWindowsAzure>copy con MyWebRole\web.config <?xml version="1.0" encoding="utf-8"?> <configuration> <system.webServer> <defaultDocument enabled="true"> <files> <clear /> <add value="index.html" /> </files> </defaultDocument> </system.webServer> </configuration>^Z 1 file(s) copied.

Notice that I created a minimal web.config, just to make sure index.html is configured as a default document.

Step 2: Creating a service definition

For Windows Azure to run our application, we need to describe it in a service definition file. Here, we tell Windows Azure that we have a single role, and that it’s a web role. We also specify that we want IIS to listen for incoming HTTP requests on port 80.

c:\CmdlineWindowsAzure>copy con ServiceDefinition.csdef
<?xml version="1.0" encoding="utf-8"?>
<ServiceDefinition name="CmdlineWindowsAzure" xmlns="http://schemas.microsoft.com/ServiceH
osting/2008/10/ServiceDefinition">
  <WebRole name="MyWebRole" enableNativeCodeExecution="true">
    <InputEndpoints>
      <InputEndpoint name="HttpIn" protocol="http" port="80" />
    </InputEndpoints>
  </WebRole>
</ServiceDefinition>^Z
        1 file(s) copied.

Step 3: Configuring the application

Now we have a Windows Azure application, but we still need to create a configuration file for it. In a more advanced Windows Azure application, we might declare some configuration settings (such as storage connection strings), but in the case of our simple web site, the only thing we need to specify in our configuration file is how many instances of our web role we want to run.

This next command line actually combines two steps. We’re packaging the application so we can run it locally, and at the same time, we’re asking cspack to generate a basic configuration file for us via the generateConfigurationFile parameter. Once we have the basic configuration file, we edit it in Notepad and change the instance count to two.

c:\CmdlineWindowsAzure>cspack ServiceDefinition.csdef /role:MyWebRole;MyWebRole /copyOnly
/out:CmdlineWindowsAzure.csx /generateConfigurationFile:ServiceConfiguration.cscfg
Windows(R) Azure(TM) Packaging Tool version 1.2.0.0
for Microsoft(R) .NET Framework 3.5
Copyright (c) Microsoft Corporation. All rights reserved.

c:\CmdlineWindowsAzure>type ServiceConfiguration.cscfg <?xml version="1.0"?> <ServiceConfiguration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="htt p://www.w3.org/2001/XMLSchema" serviceName="CmdlineWindowsAzure" xmlns="http://schemas.mic rosoft.com/ServiceHosting/2008/10/ServiceConfiguration"> <Role name="MyWebRole"> <ConfigurationSettings /> <Instances count="1" /> </Role> </ServiceConfiguration> c:\CmdlineWindowsAzure>notepad ServiceConfiguration.cscfg

c:\CmdlineWindowsAzure>type ServiceConfiguration.cscfg <?xml version="1.0"?> <ServiceConfiguration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="htt p://www.w3.org/2001/XMLSchema" serviceName="CmdlineWindowsAzure" xmlns="http://schemas.mic rosoft.com/ServiceHosting/2008/10/ServiceConfiguration"> <Role name="MyWebRole"> <ConfigurationSettings /> <Instances count="2" /> </Role> </ServiceConfiguration>

Step 4: Running the application in the development fabric

To run a Windows Azure application in the development fabric, it needs to packaged via cspack with the copyOnly parameter. This creates a directory with our roles in it instead of an encrypted and compressed package that we upload to the cloud. In the previous step, we actually created the local package we need already, and it’s now in CmdlineWindowsAzure.csx. (The convention is to use the .csx extension for this package/directory, but you can call it anything you want.)

To run it, we use the csrun command. It takes the local package (really a directory) and the configuration file. If you add the launchBrowser option, it will automatically open the browser to the HTTP endpoint we declared.

c:\CmdlineWindowsAzure>csrun CmdlineWindowsAzure.csx ServiceConfiguration.cscfg /launchBrowser
Windows(R) Azure(TM) Desktop Execution Tool version 1.2.0.0
for Microsoft(R) .NET Framework 3.5
Copyright (c) Microsoft Corporation. All rights reserved.

Using session id 1 Created deployment(631) Started deployment(631) Deployment input endpoint HttpIn of role MyWebRole at http://127.0.0.1:82/

If you try this, you should see the browser pop up and tell you “Hello, World” at this point.

We can check what’s running in the development fabric either by opening the development fabric UI, or by using csrun. We can also use csrun to delete the local deployment when we’re finished testing.

c:\CmdlineWindowsAzure>csrun /status
Windows(R) Azure(TM) Desktop Execution Tool version 1.2.0.0
for Microsoft(R) .NET Framework 3.5
Copyright (c) Microsoft Corporation. All rights reserved.

Using session id 1 ============================================================  Deployment-Id: 631 EndPoint: http://127.0.0.1:82/ Roles: MyWebRole 0 Started (ProcessId 5844) 1 Started (ProcessId 9060) Image-Location: c:\CmdlineWindowsAzure\CmdlineWindowsAzure.csx

c:\CmdlineWindowsAzure>csrun /remove:631 Windows(R) Azure(TM) Desktop Execution Tool version 1.2.0.0 for Microsoft(R) .NET Framework 3.5 Copyright (c) Microsoft Corporation. All rights reserved.

Using session id 1 Stopping deployment 631. Removing deployment 631.

Step 5: Deploying to the cloud

We invoke cspack again to create a package ready for the cloud. This time, we don’t specify generateConfigurationFile, since we already have one, and we don’t specify copyOnly because we want a package for the cloud, not for the development fabric. The usual convention is to use the extension .cspkg for the output package file.

c:\CmdlineWindowsAzure>cspack ServiceDefinition.csdef /role:MyWebRole;MyWebRole /out:CmdlineWindowsAzure.cspkg
Windows(R) Azure(TM) Packaging Tool version 1.2.0.0
for Microsoft(R) .NET Framework 3.5
Copyright (c) Microsoft Corporation. All rights reserved.

c:\CmdlineWindowsAzure>

At this point, we have a .cspkg file and a .cscfg file, which are the two files we need to provide when we deploy via the Windows Azure Portal (or MMC snap-in, or PowerShell scripts, or csmanage tool, etc.).

More Information

For more information, visit the Windows Azure SDK Tools Reference topic on MSDN, and specifically the documentation for cspack and csrun.

You might also want to watch this week’s Cloud Cover episode, where we use the command line tools to deploy a more interesting application.