Installing PHP on Windows Azure leveraging Full IIS Support: Part 2

Update: The Windows Azure PowerShell CmdLets have added the necessary bootstrap information in order to set up PHP on Windows Azure Cloud Services. Download the Windows Azure PowerShell CmdLets.

In the last post of this Series, Installing PHP on Windows Azure leveraging Full IIS Support: Part 1, we created a script to launch the Web Platform Installer Command-line tool in Windows Azure in a Command-line Script.

In this post we’ll be looking at creating the Service Definition and Service Configuration files which will describe what are deployment is to consist of to the Fabric Controller running in Windows Azure.

Creating a Windows Azure Service Definition

Unfortunately there isn’t a magical tool that will create a starter point for our Service Definition file, this is mostly due to the fact that Microsoft doesn’t know what to provide as a default. Windows Azure is all about Developer freedom, you create your application and let Microsoft worry about the infrastructure that it’s running on.

Luckily, Microsoft has documented the Service Definition (.csdef) file on MSDN, so we can use this documentation to guide us through the creation of our Service Definition. Let’s create a file called ‘ServiceDefinition.csdef’ outside of our Deployment folder. We’ll add the following content to the file, and I’ll explain a few of the key elements below.

Defining a Windows Azure Service

<?xml version="1.0" encoding="utf-8"?>
<ServiceDefinition name="PHPonAzure" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition">
	<WebRole name="Deployment" vmsize="ExtraSmall" enableNativeCodeExecution="true">
		<Startup>
			<Task commandLine="install-php.cmd" executionContext="elevated" taskType="background" />
		</Startup>
		<Endpoints>
			<InputEndpoint name="defaultHttpEndpoint" protocol="http" port="80"/>
		</Endpoints>
		<Imports>
			<Import moduleName="RemoteAccess"/>
			<Import moduleName="RemoteForwarder"/>
		</Imports>
		<Sites>
			<Site name="PHPApp" physicalDirectory=".\Deployment\Websites\MyPHPApp">
				<Bindings>
          				<Binding name="HttpEndpoint" endpointName="defaultHttpEndpoint" />
        				</Bindings>
      			</Site>
		</Sites>
	</WebRole>
</ServiceDefinition>

We will be using a Windows Azure WebRole to Host our application [remember WebRoles are IIS enabled], you’ll notice that our first element within our Service Definition is WebRole. Two Important pieces of the WebRole Element are the vmsize and enableNativeCodeExecution attributes. The VMSize Attribute hands off the VM Sizing requirements to the Fabric Controller so it can allocate our new WebRole. For those of you familiar with the .NET Stack the enabledNativeCodeExecution attribute will allow for FullTrust if set to true, or MediumTrust if set to false [For those of you that aren’t familiar, Here’s a Description of the Trust Levels in ASP.NET]. The PHP Modules for IIS need elevated privileges to run so we will need to set enableNativeCodeExecution to true.

In Part one of this series we created a command-line script that would initialize a PHP installation using WebPI. You’ll notice under the Startup Element, we’ve added our script to a list of Task Elements which defines the startup Tasks that are to be run on the Role. These scripts will run in the order stated with either limited [Standard User Access] or elevated [Administrator Access] permissions. The taskType determines how the Tasks are executed, there are three options simple, background and foreground. Our script will run in the background, this will allow us to RDP into our instance and check the Logs to ensure everything installed properly to test our deployment.

In the Service Definition above we’ve added some additional folders to our deployment, this is where we will be placing our website [in our case, we’re simply going to add an index.php file]. Within the Deployment Folder, add a new folder called Websites, within the new Websites folder, create a folder called MyPHPApp [or whatever you would like it named, be sure to modify the physicalDirectory attribute with the folder name].

Create a Websites Folder in the Deployment FolderCreate a MyPHPApp Folder within the Websites Folder

Now that our directories have been added, create a new file named index.php within the MyPHPApp folder and add the lines of code below.

<?php

phpinfo();

?>

Creating a Windows Azure Service Configuration

Now that we have a Service Definition to define the hard-requirements of our Service, we need to create a Service Configuration file to define the soft-requirements of our Service.

Microsoft has provided a way of creating a Service Configuration from our Service Definition to ensure we don’t miss any required elements.

If you intend to work with Windows Azure Tools on a regular basis, I would suggest adding the Path to the tools to your System Path, you can do this by executing the following script in a console window.

path=%path%;%ProgramFiles%\Windows Azure SDK\v1.3\bin;

We’re going to be using the CSPack tool to create our Service Configuration file. To Generate the Service Configuration we’ll need to open a console window and navigate to our project folder. Then we’ll execute the following command to create our Service Configuration (.cscfg) file.

cspack ServiceDefinition.csdef /generateConfigurationFile:ServiceConfiguration.cscfg

After you run this command take a look at your project folder, it should look relatively close to this:

Project after running CSPack to Create Configuration File

You’ll notice that executing CSPack has generated two files. First, It has generated our Service Configuration file, which is what we’re interested in. However, the tool has also gone and compiled our project into a Cloud Service Package (.cspkg) file, which is ready for deployment to Windows Azure [we’ll get back to the Cloud Service Package in the next post in this series]. Let’s take a look at the Configuration file.

<?xml version="1.0"?>
<ServiceConfiguration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" serviceName="PHPonAzure" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration">
  <Role name="Deployment">
    <ConfigurationSettings>
      <Setting name="Microsoft.WindowsAzure.Plugins.RemoteAccess.Enabled" value="" />
      <Setting name="Microsoft.WindowsAzure.Plugins.RemoteAccess.AccountUsername" value="" />
      <Setting name="Microsoft.WindowsAzure.Plugins.RemoteAccess.AccountEncryptedPassword" value="" />
      <Setting name="Microsoft.WindowsAzure.Plugins.RemoteAccess.AccountExpiration" value="" />
      <Setting name="Microsoft.WindowsAzure.Plugins.RemoteForwarder.Enabled" value="" />
    </ConfigurationSettings>
    <Instances count="1" />
    <Certificates>
      <Certificate name="Microsoft.WindowsAzure.Plugins.RemoteAccess.PasswordEncryption" thumbprint="0000000000000000000000000000000000000000" thumbprintAlgorithm="sha1" />
    </Certificates>
  </Role>
</ServiceConfiguration>

Where did all of this come from? Let’s look at a simple table, that matches up how these settings relate to our Service Definition.

Service Definition Snippet

Service Configuration Snippet

<ServiceDefinition name=”PHPonAzure”/> <ServiceConfiguration serviceName=”PHPonAzure”/>
<WebRole name=”Deployment”/> <Role name=”Deployment”/>
<Import moduleName=”RemoteForwarder”/> <Setting name=”RemoteForwarder.Enabled”/>
<Import moduleName=”RemoteAccess”/> <Setting name=”RemoteAccess.Enabled”/>

<Setting name=”RemoteAccess.AccountUsername”/>

<Setting name=”RemoteAccess.EncryptedPassword”/>

<Setting name=”RemoteAccess.AccountExpiration”/>

<Certificate name=”RemoteAccess.PasswordEncryption”/>

For more information on the RemoteAccess and RemoteForwarder check out the series that I did on RDP in a Windows Azure Instance. These posts will also take you through the instructions on how to provide proper values for the RemoteAccess and RemoteForwarder Elements that were Generated by the Import statements in the ServiceDefinition.

  1. Upload a Certification to an Azure Hosted Service
  2. Setting up RDP to a Windows Azure Instance: Part 1
  3. Setting up RDP to a Windows Azure Instance: Part 2
  4. Connecting to a Windows Azure Instance via RDP

There are two additional attributes in which I would recommend adding to the ServiceConfiguration Element, osFamily and osVersion.

osFamily="2" osVersion="*"

These attributes will change the underlying Operating System Image that Windows Azure runs to Windows Server 2008 R2 and sets your Role to automatically update to the new image when available.

You can control the number of instances of your Roles are deployed by changing the value of the count attribute in the Instances Element. For now we’ll leave this value at 1, but keep in mind that Microsoft’s SLA requires 2 instances of your role to be running in order to guarantee 99.95% uptime.

Great Resources

Conclusion

In this entry we created both a Service Definition and a Service Configuration. Service Definitions provide information to the Fabric Controller to create non-changeable configurations to a Windows Azure Role. The Service Configuration file will provide additional information to the Fabric Controller to manage aspects of the environment that may change over time. In the next post we will be reviewing the Cloud Service Package and Deploying our Cloud Service into the Windows Azure Environment.

Happy Clouding!

Golden Eggs of Windows Azure ‘Cloud’ Best Practices

Remembering back to when I was in the Audience in the Community, the one thing I always wanted to find out about was Best Practices for the Particular Technology I was listening about. I’m sure a number of people feel the same way.

Best Practices are hard to introduce in a talk as you’re typically only speaking to 10% (if that) of your audience and leaving the other 90% scratching their heads. For this reason, I am providing this blog post as a resource to find allow people interested in Best Practices to proactively seek them out with a little bit of Guidance.

Getting in the Know

Let’s face it, you may want to know the Best Practices from the beginning as you think you’re doing yourself a favour by knowing how to be a smooth operator. STOP, Let’s take a moment to step back and thing about this.

Just because something has been outlined as a best practice doesn’t guarentee that it is for your particular situation. Part of Identifying a Best Practice is knowing your options for a particular situation. Once  you know you have the right fit for your particular situation then you can extend your implementation to leverage a Best Practice to Guarentee that you’ve solidified your feature in it’s Best Possible Functioning Implementation.

My First Tip for seeking out best practices is to Know your Platform & Your Options.

There are a number of resources for getting to know Windows Azure on my blog [which I’ve recently installed Microsoft Translator to provide great content for all to read] and the Windows Azure Team Blog.

Further Research is Necessary

As good as the content is that you read online, you will want to turn to a number of printed [or electronic] books. Here are a few books that I would suggestion.

Manning Books – Azure In Action

AzureInAction

This book is not about Best Practices. However, it provides the best explanation of the Windows Azure Internals to date. The first few chapters provide insight into the Fabric Controller and the Windows Azure Fabric.

I would consider this an initial “Deep Dive” Starter read to get into Microsoft’s Cloud Computing initiative and an understanding of Windows Azure’s offerings in the Platform as a Service (PaaS) Cloud Space.

 

Microsoft Patterns & Practices

cat

My most recent read was Moving Applications to the Cloud by the Microsoft Pattern and Practices Team. This book was very insightful as to some of the Practices that Microsoft has been implementing while moving into the cloud, obviously obfuscated through a hypothetical company Adatum and their Expenses Tracking System aExpense.

This book got me thinking about a number of great architecture concepts and some great value add code that can be re-used over a number of Projects.

 

Developing-Applications-for-the-Cloud-on-Windows-Azure

I enjoyed the previous book so much that I will be picking up the other guidance book from Microsoft, Developing Applications for the Cloud.

I’m going out on a limb to say that based on the previous book, I’m betting that this book will be rather insightful, hopefully providing more guidance on Architecting Applications for Windows Azure.

 

 

The Cloud Developer Tool Belt Reference Guide

This next resource might not be something you will read end to end. I would say that this is definitely an item you should be referring to when designing your Cloud Architecture.

AzureScope: Benchmarking and Guidance for Windows Azure is an all encompassing guide for Best Practices, Benchmarks, Code Samples next to which my Essential Guide for Getting Started with Windows Azure post look like one of those rings you pick up at the cash register of your local dollar store.

XCG_Sharepoint_Header

Conclusion

Hopefully this post will help those in my audiences that I am unable to reach out to at this point with that Best Practice Deep Dive. I have no doubt that Cloud Computing is the future of Application Deployment and Hosting. I also believe that Microsoft is putting forth a very strong offering with Windows Azure. Regardless your technology, the Best Practices provided in this document will provide you with some thought provoking reading material which after all is most likely one of the main contributing factors in choosing Software Development as a Career.

Happy Clouding!

Installing PHP on Windows Azure leveraging Full IIS Support: Part 1

Update: The Windows Azure PowerShell CmdLets have added the necessary bootstrap information in order to set up PHP on Windows Azure Cloud Services. Download the Windows Azure PowerShell CmdLets.

Considering this blog post is about an open source language (PHP), I’m intentionally avoiding my trusty development tool Visual Studio. Even without using Visual Studio it will be necessary to download the Windows Azure Tools & SDK 1.3, this will provide us with some necessary command-line tools. That’s right, Windows Azure is Console Ready!

Context is Everything

Over the next three blog posts, I am going to be describing how to Install PHP on Windows Azure.

With the release of the 1.3 release of the Windows Azure SDK, Microsoft has enabled Full IIS (Internet Information Services) support in Windows Azure [this provides support for IIS Modules] and Start-up Scripts [which allow you to run command-line or powershell scripts on your deployment while the role is starting].

We will be leveraging start-up scripts to execute the [new] WebPI Command-line tool to install and configure PHP in IIS within a Windows Azure Web Role.

There has been an update to the WebPI Tools, download the WebPI v4 Command-line tool

We need a few things to Help us along the Way

  1. Web Platform Installer [WebPI] Command-line Tool [Any CPU]
  2. Windows Azure Tools & SDK 1.3
  3. Your Favourite Text Editor [I like Notepad++]

Creating your Start-up Scripts

Before we can even write our first start-up script there is one thing we need to get out of the way first and that’s where we create them. To understand what we’re doing lets do a quick break down on how deployments work in Windows Azure.

Breaking down a Windows Azure Deployment

Windows Azure requires only two files when deploying an application to the Cloud.

First, is a Cloud Service Package file which is essentially a Zip file which contains a number of encrypted files. Amongst these encrypted files are:

  • A Cloud Service Definition file which defines the fixed resources for our Windows Azure Compute Instance. The Service Definition is responsible for setting up Web Roles, Worker Roles, Virtual Machine Roles and Network Traffic Rules. These settings are then relayed to the Fabric Controller which selects the appropriate resources for your Compute Instance from the Fabric and begins provisioning your Deployment.
  • Your Application, which can consist of many Roles. Considering we’re using the Platform as a Service Model that Windows Azure offers, there are two main types of Roles: Web Roles and Worker Roles. A Web Role is like a typical Web or Application Server which runs IIS and Serves up Web Content. A Worker Role is a continuously running process which basically mimics a Windows Service.

Second, is the Cloud Service Configuration file which builds on top of what the Service Definition file provides to the Windows Azure Fabric Controller, only these values can be changed without the need to redeploy the Service Package. The Service Configuration is where you control the number of Instances your application is distributed across, as well as Windows Azure Storage Service Connection Strings and other values which may need to get changed over an Applications Lifespan.

That’s Great, but why did you tell me this?

Windows Azure is using the Convention over Configuration approach when it comes to start-up script location. You will be configuring where your application is actually located on your physical machine, but the Azure Tools are going to be looking for your scripts in ‘AppRoot/bin’. The AppRoot is determined by the name of your Role within the Service Definition file.

For now, lets stick with a very simple directory structure and we’ll talk about the Service Definition in the next post. In a directory that you’ve created for your deployment create a ‘Deployment’ directory and within that create a bin folder. We will be adding our start-up scripts to the bin folder.

Folder Structure for a Custom Windows Azure Deployment

Show me Teh Codez Already!

Fire up Notepad++ we’re going to create our start-up scripts to enable PHP within IIS in Windows Azure.

[Update: The Windows Update Script is no longer required by WebPICmdLine]

The first script that we need to create will enable Windows Update on the Windows Azure Web Role Image. The WebPI tool uses the Windows Update Process to install the Items that have been downloaded. Create a file, ‘enable-windows-update.cmd’ and paste the following script.

Script for enabling Windows Update

All Windows Azure Instances run on 64bit Processors, so you can possibly get rid of the Conditional logic.

Our next script is going to leverage the WebPI Commandline tool which you would have downloaded from the resource list above. This download is also required as part of the Cloud Service Package that we will be creating in a future post. Within the Deployment directory, create a folder called ‘Assets’ and another folder within ‘Assets’ called ‘WebPICmdLine’. Copy the WebPI binaries into the newly created WebPICmdLine folder.

Note: The WebPI tool is very powerful tool and can do much more than just install PHP. You may want to read the documentation found on the IIS Blogs and on MSDN.

Create a new file, ‘install-php.cmd’ and paste the following script.

Script for installing PHP with WebPI

PHP 5.2
PHP 5.3

The last line of that Script is a call to another script that needs to be run after PHP is actually installed. This isn’t a necessary step, however the ‘install-php-azure’ script [provided below] will place the ‘php_azure.dll’ in the php/ext folder and add the extension within the php.ini file. Adding the dll from the Open Source Project Windows Azure SDK for PHP available on CodePlex gives you the ability to leverage Blobs, Tables, Queues and other Azure API features.

You will need to add the php_azure.dll file that you download from CodePlex to the Assets directory [for consistency create a directory called ‘Windows Azure SDK for PHP’]. Create a file, ‘install-php-azure.cmd’ and paste the following code.

Script for Installing Windows Azure SDK for PHP

After you have completed creating these three files your folder structure should look like this:

image image

 

Download all Files

 

Until Next Time…

We have completed creating the scripts required to install PHP on Windows Azure. In my next blog post in this series I will explain how to create the Cloud Service Definition and Cloud Service Configuration files. We’ll start to get a better understanding as to how our Deployment fits together in the Windows Azure Platform. In the Third Part of this series we will package the Deployment using the command-line tools for Windows Azure and finally deploy our application to the cloud.

Running PowerShell Scripts in Windows Azure Start-up Tasks

With the release of the Windows Azure SDK 1.3, Microsoft introduced Startup tasks to Windows Azure Service Definition files.

Startup Tasks XML Schema

Start-up tasks are configured using XML in the Cloud Service Definition file (.csdef) using the Startup and Task Element. Here is the Startup Element for my particular Cloud Service Definition file.

<Startup>
<Task commandLine="PowerShellScriptLauncher.cmd" executionContext="elevated" taskType="simple" />
</Startup>

Anatomy of the PowerShell Script Launcher

The best implementation of Startup Tasks would be to create a library of common tasks that are reusable. You can pass arguments into a PowerShell Script to provide specific details required for an individual deployment.

Enabling PowerShell Execution in Windows Azure

PowerShell is installed by default on Windows Azure, however ExecutionPolicy does not allow unsigned scripts to be run by default. In order for our PowerShell scripts to be executed it is necessary to change the ExecutionPolicy to allow RemoteSigned Scripts.

Windows Azure has two different Versions of Windows (Server 2008 SP1 & Server 2008 R2) which can be controlled by setting the osFamily and osVersion.

Changing PowerShell ExecutionPolicy on Server 2008 SP1

Server 2008 SP1 is considered osFamily 1 on Windows Azure.

PowerShell 1.0 didn’t support the Set-ExecutionPolicy command [which was introduced in PowerShell 2.0]. In order to get around this I’ve created a registry file which makes the ExecutionPolicy change in the Registry. Create a file “ExecutionPolicy.reg” and include:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1\ShellIds Microsoft.PowerShell] "ExecutionPolicy"="RemoteSigned"

Changing PowerShell ExecutionPolicy on Server 2008 R2

Server 2008 R2 is considered osFamily 2 on Windows Azure.

Server 2008 R2 is running PowerShell 2.0, so executing a Set-ExecutionPolicy command is possible. Create a file “ExecutionPolicy.ps1” and include:

Set-ExecutionPolicy RemoteSigned -Force

Now that you have created a way of executing PowerShell on Windows Azure you need to add the appropriate method to the Startup Task Script. Add the appropriate line below to your PowerShellLauncher.cmd file:

REM This is for Server 2008 SP1
ExecutionPolicy.reg

REM This is for Server 2008 R2
powershell.exe ExecutionPolicy.ps1

Now you can execute full featured PowerShell commands to get your instances up to a Running State.

Great Resources

Essential Resources for Getting Started with Windows Azure

This following blog post was co-authored by John Bristowe and Cory Fowler.

windows-azure-logo-lg

Important! Check out the Windows Azure Introductory Special. It is the easiest way to get started with Windows Azure. To make it even easier, Barry Gervin and Cory Fowler have created some step by step videos on how to register for Windows Azure using the Introductory Special. If you’re a [Premium, Ultimate, or BizSpark] MSDN Subscriber, you are eligible to participate in a Windows Azure Benefits which includes free consumption of Windows Azure Services.

Essential Downloads

Folks in the Know

Events

Blogs and Websites

Essential Reading

Books

Screencasts/Videos/Webcasts

Essential Listening

Projects, Third Party Tools and Other Downloads

Essential Code/Scripts/Virtual Labs

This article also appears on Canadian Developer Connections.

Connecting to an Azure Instance via RPD

This post is a conclusion to a series of blog entries on how to RPD into a Windows Azure instance. If you haven’t already done so, you may want to read the previous posts:

This post will provide two pieces of information: first, now that your Windows Azure Platform Portal has been configured for RPD, I will show you how to initialize the RDP Connection to a Windows Azure Instance. Second, I’ll step back and explain how to Setup the Cloud Service Configuration manually (which is typically automated by Visual Studio).

Connecting to Windows Azure via RDP

At this point you should have already uploaded a Certificate to the Hosted Service, checked the Enable checkbox in the Remote Access section of the Portal Ribbon and configured a Username and Password for accessing the particular Hosted Service.

In the Hosted Service Configuration page, select the Instance you would like to connect to.

Select Windows Azure Role Instance for RDP

This will enable the Connect button within the Remote Access section of the Portal Ribbon. Click on the Connect button to initialize a download of the RPD (.rpd) file to connect to that particular instance.

Windows Azure Platform Portal Remove Access Settings

You can obviously choose open, however this is a good opportunity to save the RDP connection to an instance just for that odd chance you can’t access the Windows Azure Platform Portal to download it again. I would suggest saving at least one RDP file in a save location for this very reason.

Save RPD File for Future Use

You may need to accept a Security warning because the RDP file is Unsigned.

Unknown Publisher Warning

Then supply your username and password which was set up in the previous set of posts.

Entering your Credentials to the Windows Azure

Initializing Connection to Windows Azure

Once the connection has been initialized there is one last security warning to dismiss before the desktop of your Windows Azure Instance appears.

Indentify Connection to the Cloud

Welcome to your Windows Azure Instance in the Cloud!

Windows Azure Instance Desktop

Manually Configuring RDP Access to Windows Azure

In order to manually configure RDP access to a Windows Azure Instance in the csconfig file there are a few things that need to be done. There is a well written outline on MSDN in a post entitled “Setting up a Remote Desktop Connection for a Role”.

During Step 2 of the process outlined on MSDN, Encrypting the Password with Powershell, there is the need to provide a thumbprint for a Self-Signed Certificate. What isn’t mentioned within the article is that it is necessary to Capitalize the Letters and Remove the Spaces in the thumbprint in order for the Powershell script to work.

[Update – Jan 2, 2010]

A Common mistake for Manually Configuring RDP Access to Windows Azure is forgetting to add an important Configuration Setting. If you are creating your deployment outside of an IDE you will be working with the Cloud Service Definition (csdef) file. You will need to add 2 Import nodes within the Imports Node of your CSDEF file.

  1. RemoteAccess
  2. RemoteForwarder

These options will create the appropriate configuration setting xml in the Cloud Service Configuration (cscfg) file.

To Ensure that RPD Works set RemoteForwarder to True in the cscfg file.

[/Update]

Happy Clouding!