Steve Marx's blog

programming and entrepreneurship

Join Me for “An Evening on Azure” in Bellevue, WA

Microsoft and Aditi are holding an “Evening on Azure” dinner series. Please register and join us on April 25th at 5:30pm at Purple Café and Wine Bar for dinner and conversation. In my new role as Chief Windows Azure Architect for Aditi, I’m going to be leading a discussion about best practices in the cloud (and Windows Azure specifically).

The evening’s discussion will be around the following:

  1. Windows Azure monetization strategies
  2. Best practices around cloud fit analysis and application selection
  3. Windows Azure in general, and Microsoft’s cloud roadmap

Go here to register for the event: http://pages.aditi.com/l/3172/2012-03-22/bfdvx. I hope to see you there!


Joining Aditi as Chief Windows Azure Architect

I just couldn't stay away from the Windows Azure community! I've accepted the position of Chief Windows Azure Architect for Aditi. (Yup, that's my picture on our homepage.)

If you haven't heard of Aditi yet, you probably will. Not only is Aditi a top Microsoft partner already, but the company is making a big bet on Windows Azure specifically, hitting the ground running with the acquisition of Cumulux.

My new job at Aditi has two parts:

  1. I'll continue to be a voice in the Windows Azure community, now from a more hands-on perspective reflecting the experience my colleagues and I have at Aditi.
  2. I'll be working with Aditi's other architects and directly with our customers to build great solutions on Windows Azure.

Here's a video we made about my new role at Aditi (requires Silverlight):

If you're interested in hiring Aditi to help with your cloud project, don't hesitate to contact me. (I don't have an @aditi.com email address yet, but smarx@smarx.com will work.)

Also, we're hiring! If you're a Windows Azure expert and want to work with a great team (including me), check careers.aditi.com.

For those wondering what this means for my “Career vNext” plans to build something of my own, it doesn't change them in the slightest. Paddy (Aditi’s CEO) and team have been really flexible in allowing me to continue to build my own company while contributing to Aditi. I'm grateful for that.


Career vNext

I joined Microsoft in 2002, right out of college. Since then, every few years, I've looked for a new challenge, whether that's a new role (tester, developer, evangelist, program manager, two kinds of "strategist," technical product manager) or a new technology (Windows, static code analysis, ASP.NET AJAX, Windows Azure). For the past almost-decade, I've found all those new challenges within Microsoft. In my opinion, one of the biggest advantages of working at Microsoft is that it's easy to move around the company and find the right role. There's no shortage of interesting work to do and great people to work with.

After more than four years working on Windows Azure, I'm ready to find a new challenge again. This time, however, I'd like to create something all of my own. To that end, I'm cofounding a company with a friend (and former coworker). I won't say what we're going to be working on because we honestly don't know yet!

I'm sad to leave Microsoft and Windows Azure. I think this is going to be an amazing year for Windows Azure, and it's going to be strange for me to watch it from the outside. At the same time, I'm excited for the next stage of my career as an entrepreneur.

On a practical note, this blog isn't going anywhere, though its content will broaden to other topics. I'm still happy to answer questions about blog posts or code I've written over the past few years, so don't hesitate to email me at smarx@smarx.com or ping me on Twitter (@smarx) about anything.


Tutorial: Running a Python Web Application in Windows Azure

The Windows Azure SDK includes command-line tools that make it easy to package and deploy almost anything to the cloud. In this tutorial, I’ll walk through how to use those tools to package a Python web application and deploy it to the cloud, assuming no prior Windows Azure experience.

Prerequisites

To follow this tutorial, you’ll need to install the Windows Azure SDK. Because this tutorial uses Python, you’ll also want to install Python 2.7.2. Python will automatically be installed in the cloud when you deploy this application, but to develop the app and test in the Windows Azure emulator, you’ll need Python installed locally.

To complete the last step of deploying to the cloud, you’ll need a Windows Azure account. (Sign up at http://windowsazure.com.)

Quick Walkthrough

  1. Download the code at https://github.com/smarx/pythonrole. You can either click the “zip” link at the top of the page, or you can use the git command-line tools:
    git clone git://github.com/smarx/pythonrole .
  2. Run %ProgramFiles%\Windows Azure SDK\<version>\bin\setenv to add the Windows Azure SDK tools to your path, and then change directory back to where you downloaded pythonrole.
  3. Add python.exe to your path if it isn’t already there.
  4. Type run to run the application locally. Open up the browser to the address and port you see in the output of run. You should see the text “Hello, World!”
  5. Type pack to create a Windows Azure package containing the application.
  6. Browse to the Windows Azure portal and deploy the application by clicking the “new hosted service” button and filling out the dialog. The “package location” and “configuration file” should be PackAndDeploy.cspkg and ServiceConfiguration.Cloud.cscfg in the root of your packanddeploy project.

How It Works

To understand the basics of how the project is structured, first read my “Running the Mongoose Web Server in Windows Azure” tutorial. Where this project differs is around installing and executing Python.

Because installing Python requires elevated privileges, the installation is separated into a startup task. Startup tasks in Windows Azure run before the main application is started. Because they can be set to run as an elevated user (independent of whether the main application runs elevated), they’re useful for tasks like installing prerequisite components or otherwise setting up the environment. Startup tasks are defined in ServiceDefinition.csdef. The pythonrole project defines two startup tasks:

<Startup>
  <Task commandLine="installPython.cmd" executionContext="elevated">
    <Environment>
      <Variable name="EMULATED">
        <RoleInstanceValue xpath="/RoleEnvironment/Deployment/@emulated" />
      </Variable>
      <Variable name="PYTHON_PATH">
        <RoleInstanceValue
          xpath="/RoleEnvironment/CurrentInstance/LocalResources/LocalResource[@name='python']/@path" />
      </Variable>
    </Environment>
  </Task>
  <Task commandLine="installDependencies.cmd">
    <Environment>
      <Variable name="PYTHON_PATH">
        <RoleInstanceValue
          xpath="/RoleEnvironment/CurrentInstance/LocalResources/LocalResource[@name='python']/@path" />
      </Variable>
    </Environment>
  </Task>
</Startup>

The first startup task (installPython.cmd) installs Python by downloading the Python installer and executing it (line break inserted for formatting):

powershell -c "(new-object System.Net.WebClient).DownloadFile
('http://python.org/ftp/python/2.7.2/python-2.7.2.msi', 'python.msi')"
start /w msiexec /i python.msi /qn TARGETDIR="%PYTHON_PATH%"

The second startup task (installDependencies.cmd) creates a virtual Python environment using virtualenv and installs any modules our application depends on by running pip:

python virtualenv.py --no-site-packages .
call scripts\activate
cd app
pip install -r requirements.txt

requirements.txt is a simple text file with names of modules (and optionally versions). It follows the format emitted by pip freeze.

After all the startup tasks have run, the main entry point of the application (run.cmd) is executed. This activates the Python virtual environment and launches the app with python app.py. As in the Mongoose tutorial, environment variables are used to pass the correct IP address and port to the application.

More Information

For more information about the basic techniques used in this project, read the “Running the Mongoose Web Server in Windows Azure” tutorial.

View the full source code for pythonrole on GitHub: https://github.com/smarx/pythonrole.


Tutorial: Running the Mongoose Web Server in Windows Azure

The Windows Azure SDK includes command-line tools that make it easy to deploy almost anything to the cloud. I’ve blogged about this functionality in the past, but those posts have assumed a significant amount of Windows Azure background. In this tutorial, I’ll walk through how to use those tools to package a standalone executable and run it in the cloud, assuming no prior Windows Azure experience. For our example application, we’ll run the Mongoose web server, a tiny one-file web server written in C++.

Prerequisites

To follow this tutorial, you’ll need to install the Windows Azure SDK. To complete the last step of deploying to the cloud, you’ll need a Windows Azure account. (Sign up at http://windowsazure.com.)

Quick Walkthrough

  1. Download the code at https://github.com/smarx/packanddeploy. You can either click the “zip” link at the top of the page, or you can use the git command-line tools:
    git clone git://github.com/smarx/packanddeploy .
  2. Run %ProgramFiles%\Windows Azure SDK\<version>\bin\setenv to add the Windows Azure SDK tools to your path, and then change directory back to where you downloaded packanddeploy.
  3. Type run to run the application locally. Open up the browser to the address and port you see in the output of run. You should see the text “Hello, World!”
  4. Type pack to create a Windows Azure package containing the application.
  5. Browse to the Windows Azure portal and deploy the application by clicking the “new hosted service” button and filling out the dialog. The “package location” and “configuration file” should be PackAndDeploy.cspkg and ServiceConfiguration.Cloud.cscfg in the root of your packanddeploy project.

How it Works

Windows Azure applications consist of roles (essentially, components of the app). Roles come in two types: web and worker. Web roles are designed for hosting web applications under IIS. Worker roles are for everything else, with a simple “run forever” interface. This is what we’re using to run Mongoose.

Under the WorkerRole directory, you’ll see mongoose-3.0.exe, the Mongoose executable, and run.cmd, a batch file that launches Mongoose. run.cmd uses the following command to launch Mongoose:

start /w mongoose-3.0.exe -r . -p %ADDRESS%:%PORT% -e error_log.txt

ServiceDefinition.csdef in the root of the project defines the worker role to execute this batch file with the right environment variables:

<?xml version="1.0" encoding="utf-8"?>
<ServiceDefinition name="PackAndDeploy"
  xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition">
  <WorkerRole name="WorkerRole" vmsize="ExtraSmall">
    <Runtime>
      <Environment>
        <Variable name="ADDRESS">
           <RoleInstanceValue
             xpath="/RoleEnvironment/CurrentInstance/Endpoints/Endpoint[@name='HttpIn']/@address" />
        </Variable>
        <Variable name="PORT">
           <RoleInstanceValue
             xpath="/RoleEnvironment/CurrentInstance/Endpoints/Endpoint[@name='HttpIn']/@port" />
        </Variable>
      </Environment>
      <EntryPoint>
        <ProgramEntryPoint commandLine="run.cmd" setReadyOnProcessStart="true" />
      </EntryPoint>
    </Runtime>
    <Endpoints>
      <InputEndpoint name="HttpIn" protocol="tcp" port="80" />
    </Endpoints>
  </WorkerRole>
</ServiceDefinition>

This file does three main things:

  1. It defines the entry point to our application, which is run.cmd.
  2. It defines an endpoint for our application (port 80 for HTTP traffic).
  3. It configures two environment variables (ADDRESS and PORT) that communicate to our application what address and port it should listen on. (Windows Azure determines an address and port at runtime so that the application can work properly locally in the emulator as well as in the cloud.)

The run.cmd and pack.cmd commands take advantage of built-in tools in the SDK:

  • run.cmd invokes cspack with the /copyonly option to package up the application for local testing under the Windows Azure emulator. It then invokes csrun to launch the application locally.
  • pack.cmd invokes cspack again, this time without the /copyonly option, which packages the application for deployment to the cloud.

ServiceConfiguration.Local.cscfg and ServiceConfiguration.Cloud.cscfg configure the application for local testing and cloud deployment. The cloud version differs in that it configures the worker role to run on two instances (virtual machines) for high availability.

More Information

To learn more about the Windows Azure SDK authoring tools, see the documentation for cspack and csrun. To understand the various options for defining roles, see the reference documentation for ServiceDefiniton.csdef.

View the full source code for packanddeploy on GitHub: https://github.com/smarx/packanddeploy.