pico journal

café, clavier, clope

Faire tourner son appli PHP sur le cloud (azure)

clock May 4, 2011 20:22 by author pierre

J'ai réalisé il y a quelques jours une série de petites vidéos sur Azure, et l'une d'entre elles est spécifquement dédiée à PHP et Azure. Comment installer son application, comment utiliser les composants de Windows Azure, et quels sont les frameworks dèjà capables de faire tout ça :

Get Microsoft Silverlight

 

Je ferai un billet plus spécifique à Zend Framework prochainement. Si vous avez besoin de billes rapidement, un petit mail à pierre point couzy at microsoft point com et on en discute.



Azure et PHP : comment installer le runtime

clock March 30, 2011 16:57 by author pierre couzy

Depuis novembre 2010, les évolutions de Windows Azure ont ouvert les fonctionnalités de Windows Azure, mais ces évolutions ont également apporté quelques différences de fonctionnement, notamment pour l'installation de PHP sur Azure. Voici donc les méthodes que j'ai pu trouver, et une opinion sur leur intérêt.

Installation de PHP dans Hosted Web Core

Cette technique est celle qui était préconisée avant la disponibilité de Full IIS dans Azure, et elle repose sur l'installation de PHP depuis un Web Role. Cette technique est toujours utilisable, mais il faut retoucher légèrement les projets fournis en standard par Visual Studio. En effet, le mode de paramétrage change entre IIS et Hosted Web Core. Dans Hosted Web Core, les paramètres de votre site Web sont logiquement dans Web.Config, mais vous pouvez également prendre la main sur le paramétrage d'IIS en vous appuyant sur le fichier web.roleconfig. Voici par exemple la déclaration de PHP au module fastCGI et son utilisation sur le site web :

web.roleconfig :

<configuration>
  <system.webServer>
    <fastCgi>
      <application fullPath="e:\approot\php\php-cgi.exe"/>
    </fastCgi>
  </system.webServer>
</configuration> 

 

Web.config :

  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true" />
    <handlers>
      <add name="PHPFastcgi" verb="*" 
           path="*.php" scriptProcessor="e:\approot\php\php-cgi.exe" 
           modules="FastCgiModule" resourceType="Either" />
    </handlers>
     ...

Malheureusement, cette belle mécanique ne fonctionne pas dans le mode Full IIS (le fichier web.roleconfig est ignoré), et la solution pour la rétablir consiste simplement à forcer votre Web Role à revenir en mode Hosted Web Core, en modifiant le fichier csdef qui définit vos rôles, et en supprimant la sections sites :

 

<?xml version="1.0" encoding="utf-8"?>
<ServiceDefinition name="JoomlaDansAzure" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition">
  <WebRole name="JoomlaWeb" vmsize="ExtraSmall">
<!--
    <Sites>
      <Site name="Web">
        <Bindings>
          <Binding name="Endpoint1" endpointName="Endpoint1" />
        </Bindings>
      </Site>
    </Sites>
-->    
    <Endpoints>
      
      <InputEndpoint name="Endpoint1" protocol="http" port="80" />
    </Endpoints>
    <Imports>
      <Import moduleName="Diagnostics" />
      <Import moduleName="RemoteAccess" />
      <Import moduleName="RemoteForwarder" />
    </Imports>
  </WebRole>
  
</ServiceDefinition>

 

Un grand merci au passage au blog d'Avkash Chauhan qui contient un paquet de choses intéressantes sur les évolutions d'Azure.

Installation de PHP par le biais de WebPI

C'est la technique actuellement présentée dans la majorité des posts, et elle repose sur un principe assez simple : au lieu de procéder soi-même à l'installation de PHP, on délègue cette tâche à quelque chose qui le fait déjà, et qui est en plus capable de gérer les dépendances.

Cette délégation d'installation se fait dans une startup task : juste avant d'insérer votre nouvelle instance dans le load balancer, on exécute un certain nombre de tâches sous la forme suivante :

<?xml version="1.0" encoding="utf-8"?>
<ServiceDefinition name="InstallPHP" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition">
  <WebRole name="PHPWebRole">
    <Sites>
      <Site name="Web">
        <Bindings>
          <Binding name="HttpIn" endpointName="HttpIn" />
        </Bindings>
      </Site>
    </Sites>
    <ConfigurationSettings>
    </ConfigurationSettings>
    <Startup>
      <Task commandLine="InstallPHP.cmd" executionContext="elevated" taskType="simple" />
    </Startup>
    <Endpoints>
      <InputEndpoint name="HttpIn" protocol="http" port="80" />
    </Endpoints>
    <Imports>
      <Import moduleName="Diagnostics" />
      <Import moduleName="RemoteAccess" />
      <Import moduleName="RemoteForwarder" />
    </Imports>
  </WebRole>
</ServiceDefinition>

Le fichier InstallPHP.cmd fait ensuite appel à webPI pour sélectionner la version de PHP à installer (regarder dans le Windows Azure Training Kit pour en savoir plus). Le souci, c'est que si vous voulez avoir plus de contrôle sur l'installation, il faut soit créer ses propres feeds (compliqué et fragile), soit enchaîner les installations avec WebPI en priant pour ne pas avoir de dépendance incompatible avec Azure (et il y a un hotfix de Windows 2008 qui ne s'applique pas à Azure, entre autre choses qui peuvent bloquer l'installation).

De plus, impossible de définir avec précision son php.ini ou d'ajouter une extension.

Installation manuelle de PHP dans Azure en mode Full IIS

C'est la technique que je suis en train d'explorer et pour le moment j'en suis content (mais je n'ai pas encore couvert tous les cas possibles). L'idée est de revenir au modèle proposé par Hosted Web Core. Le problème de Full IIS est qu'il est impossible de paramétrer correctement les composants d'IIS qui ne sont pas sous le contrôle de Web.Config. Après avoir un peu tourné autour du problème et lu la documentation d'installation manuelle de PHP sous IIS faite par Ruslan Yakushev, j'ai utilisé le Web.Config et une startup task.

Le début du packaging est strictement identique à celui de PHP en mode HWC : on pose son runtime dans un répertoire PHP à la racine du site Web (on peut également le déporter ailleurs sur le disque si on le souhaite en utilisant d'autres startup tasks, mais je n'ai pas encore peaufiné assez pour m'occuper de ce genre de configuration).

On insère ensuite une startup task de la forme suivante dans le csdef :

    <Startup>
      <Task commandLine="PHP\InstallPHP.cmd" executionContext="elevated" taskType="simple"></Task>
    </Startup>

Et le fichier InstallPHP.cmd fait simplement ce que faisait web.roleconfig en mode Hosted Web Core :

rem Creating IIS FastCGI process pool
%windir%\system32\inetsrv\appcmd set config /section:system.webServer/fastCGI /+[fullPath='e:\approot\php\php-cgi.exe'] > PHPInstallLog.txt

rem Creating handler mapping for PHP requests
%windir%\system32\inetsrv\appcmd set config /section:system.webServer/handlers /+[name='PHP_via_FastCGI',path='*.php',verb='*',modules='FastCgiModule',scriptProcessor='e:\approot\php\php-cgi.exe',resourceType='Either'] >> PHPInstallLog.txt

rem Configuring FastCGI and PHP recycling
%windir%\system32\inetsrv\appcmd.exe set config -section:system.webServer/fastCgi /[fullPath='E:\AppRoot\PHP\php-cgi.exe'].instanceMaxRequests:10000 >> PHPInstallLog.txt
%windir%\system32\inetsrv\appcmd.exe set config -section:system.webServer/fastCgi /+"[fullPath='E:\AppRoot\PHP\php-cgi.exe'].environmentVariables.[name='PHP_FCGI_MAX_REQUESTS',value='10000']" >> PHPInstallLog.txt

rem Configuring FastCGI timeout settings
%windir%\system32\inetsrv\appcmd.exe set config -section:system.webServer/fastCgi /[fullPath='E:\AppRoot\PHP\php-cgi.exe',arguments=''].activityTimeout:"90"  /commit:apphost >> PHPInstallLog.txt
%windir%\system32\inetsrv\appcmd.exe set config -section:system.webServer/fastCgi /[fullPath='E:\AppRoot\PHP\php-cgi.exe',arguments=''].requestTimeout:"90"  /commit:apphost >> PHPInstallLog.txt

rem Changing the location of php.ini file
appcmd.exe set config  -section:system.webServer/fastCgi /+"[fullPath='e:\approt\php\php.exe',arguments=''].environmentVariables.[name='PHPRC',value='e:\approt\php\']" /commit:apphost >> PHPInstallLog.txt

A noter : en mode Full IIS, le package est déployé deux fois, une à la racine de approot et une dans un sous-répertoire qui est physiquement utilisé par IIS. La technique de déploiement ci-dessus utilise la version déployée dans AppRoot, ce qui permet de supprimer le répertoire PHP du répertoire utilisé par IIS afin de ne pas déployer le runtime PHP dans une zone du filesystem accessible en http.

Attention à un dernier détail : si vous préférez faire l'association entre votre site et FastCGI en utilisant web.config, l'exemple fourni dans les web roles CGI est incorrect : en effet, il utilise %RoleRoot% pour désigner le lecteur où est installé votre package dans la VM Azure, mais cette variable d'environnement n'est pas disponible au moment où le Web.Config est parsé, et il faut donc coder en dur E: de cette façon :

<?xml version="1.0"?>
<configuration>

  <system.web>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>

  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
    <handlers>

      <add name="PHPHandler"
           verb="*"
           path="*.php"
           scriptProcessor="E:\approot\php\php-cgi.exe"
           modules="FastCgiModule"
           resourceType="Either" />

    </handlers>
  </system.webServer>
</configuration>


Eclipse Day Paris 2010 : Azure et Eclipse (Java / PHP)

clock November 7, 2010 23:27 by author pierre couzy

Vendredi dernier, j’étais avec Yves Yang de Soyatec à l’Eclipse Day 2010. Yves a montré ce qu’il avait réalisé autour d’Azure et d’Eclipse, le résultat est très impressionnant.

Les sites pour suivre les mises à jour des outils et SDKs :

 

Pour PDT (Eclipse PHP)

http://www.windowsazure4e.org/

Pour Java

http://www.windowsazure4j.org/

 

Ah oui, les slides :



Un peu d’actualité PHP dans le monde Microsoft

clock September 27, 2010 23:47 by author pierre couzy

Quelques petites nouvelles plus ou moins surprenantes de ces derniers jours :

Windows Azure Companion

image

J’essaierai d’en faire un topo plus complet dans les semaines qui viennent, c’est un framework de déploiement d'applications PHP sur Azure, qui permet de déployer en quelques minutes des applications PHP, avec une gestion de dépendances (un genre de WebPI pour PHP et Azure). Le principe : un package azure prédéfini vous donne une console de déploiement et d’administration pour des applications (dont la liste est, un peu comme dans WebPI, exposée sous forme d’un flux XML, ce qui permet de faire évoluer les applications disponibles sans toucher au package déployé). De ce que j’en comprends pour le moment, les applications sont déployées sur un VHD hébergé dans un blob Azure, et ensuite montées en utilisant Hosted Web Core (un IIS light).

Ce qu’on gagne :

Un déploiement rapide et automatisé

Les limitations :

Comme le système repose sur un VHD, on ne peut pas créer de fermes de serveur – on ne peut jouer que sur la taille de la VM qui monte le VHD.

Ah, c’est là : http://code.msdn.microsoft.com/azurecompanion

Windows Azure Command-Line tools for PHP

Celui-là est pour les acharnés de notepad. Ce n’est pas une nouveauté mais une mise à jour. Le principe : un ensemble d’outils qui s’occupent de packager une application PHP existante pour en faire un package Azure. Rien de bien excitant sur le plan technique, mais un confort appréciable si vous voulez automatiser vos déploiements.

C’est (sans surprise) basé sur le SDK Azure, et ça permet donc de déployer au choix un package sur Azure ou dans la fabrique locale.

Pour en savoir plus : http://azurephptools.codeplex.com

image Windows Azure SDK for PHP

Instrumentation, log, accès à Azure Storage (blobs, tables, queues), gestion des exceptions, et quelques autre goodies. Là encore rien de nouveau, c’est une mise à jour. Pour y aller : http://phpazure.codeplex.com/

Windows Azure for Eclipse

Là aussi une mise à jour, j’en parle surtout parce que – même si c’est pas évident dans le titre – cet outil est un plugin pout PDT, donc spécifiquement tourné vers PHP. Un paquet de nouveautés, le plus simple c’est d’aller voir : http://www.windowsazure4e.org/

Windows Live and WordPress.com

Migration des blogs Windows Live sur Wordpress.

Oui, ça semble un peu étonnant.. Microsoft et WordPress.com ont monté un partenariat qui intègre WordPress comme plate-forme de blog pour Windows Live. 30 millions de comptes vont être migrés. Le détail de l’annonce est .

Drupal executives meetup Brussels 2010

Quand les cols blancs du monde Drupal organisent une réunion sur leurs modes de fonctionnement, la gestion de la croissance, ils se réunissent … chez Microsoft. J’espère que tout ce petit monde va vite se trouver de nouveaux ennemis, Microsoft est de moins en moins crédible dans ce rôle.



Utilisation des certificats pour les APIs de gestion Azure

clock September 15, 2010 23:38 by author pierre couzy

Windows Azure dispose d’un jeu d’APIs vous permettant d’automatiser la gestion des tâches les plus courantes, et même si certaines opérations doivent être faites par le portail, pouvoir automatiser les autres est indispensable.

 

L’API permettant tout ça est assez simple d’utilisation, d’autant plus qu’elle est déjà encapsulée dans une API .net. Voici les étapes nécessaires pour l’utiliser, à travers un petit exemple qui va automatiquement monitorer une application Azure et vous avertir de ses changements d’état.

 

Préparation de l’environnement Azureimage

La première chose à faire est de fournir la clé publique d’un certificat à l’infrastructure windows azure. Dans Visual Studio, quand vous sélectionnez Publier sur un projet Cloud, l’IHM vous permet de créer un certificat. Ensuite, vous pouvez l’exporter depuis la MMC des certificats à sous différents formats, notamment CER (clé publique uniquement) et PFX (avec clé privée et mot de passe). Le but : permettre à Azure de vérifier votre identité avant d’accepter de faire pour votre compte des opérations de reconfiguration des environnements :

 

 

C’est là que vous allez uploader le fichier CER qui représente la clé publique de votre certificat. Notez le thumbprint, il vous servira peut-être plus tard:

image 

Mise à disposition du certificat pour le code qui va manipuler les APIs Azure

Deux cas de figure se présentent à vous :

 

Vous comptez manipuler les APIs depuis votre machine

Il suffit de disposer du certificat sur votre machine, ce que vous devriez déjà avoir sinon vous n’auriez pas pu générer le CER..

 

Vous comptez manipuler les APIs depuis un environnement Azure

imagePar exemple parce que vous voulez pouvoir dynamiquement changer le nombre d’instances.. Dans ce cas, vous devez mettre le certificat complet à disposition de l’application qui l’utilisera. Vous allez donc exporter votre certificat complet (avec sa clé privée) dans un fichier .PFX et déployer ce certificat sur l’environnement Azure qui contrôlera les autres. Ca se fait depuis le portail, mais plus spécifiquement depuis un environnement d’hébergement (nommé pico dans mon exemple) :

 

A partir de maintenant, les rôles tournant dans pico auront la possibilité d’accéder au certificat que je viens d’uploader. Il faut quand même le leur indiquer, et ça se fait directement dans les fichier de config de votre projet Cloud :

 

image

 

 

Utilisation des APIs

Bon, la partie publique certificat est dans Azure, et l’autre près du code qui doit manipuler; comment continuer ? Il me manque un paramètre, qui est “mais quel environnement Azure ?”. C’est le SubscriptionID qu’on trouve dans le portail :

image

Voilà un bout de code qui va récupérer l’état de mon déploiement sur Azure :

 

// Mon certificat et mon ID Azure
string MonThumnbrint = "";
string MonSubscriptionID = "";
            
// Choper le certificat à partir de son thumbprint
X509Store certificateStore = new X509Store(StoreName.My, StoreLocation.CurrentUser);
certificateStore.Open(OpenFlags.ReadOnly);
X509Certificate2Collection certs = certificateStore.Certificates.Find(X509FindType.FindByThumbprint, MonThumnbrint, false);
if (certs.Count != 1)
{
    // Ah, pas trouvé. S'il a été installé dans IIS il est dans LocalMachine, si dans Azure il est dans CurrentUser
    throw new Exception("Impossible de trouver le certificat, essayez StoreLocation.LocalMachine ?");
}
var monCertificat = certs[0];

// Je me connecte
var serviceManagement = ServiceManagementHelper.CreateServiceManagementChannel("WindowsAzureEndPoint", monCertificat);
// Je cherche le premier service hosté
var x = serviceManagement.ListHostedServices(MonSubscriptionID);
string s = x.First().ServiceName;
// Je regarde l'état du déploiement
var details = serviceManagement.GetHostedServiceWithDetails(MonSubscriptionID, s ,true);
if (details.Deployments.Count > 0)
{
    Console.WriteLine ("etat du déploiement : " + details.Deployments.First().Status);
}
else
{
    Console.WriteLine("Rien de déployé !");
}

Bon, le code mériterait d’être un peu plus joli, mais vous voyez l’idée.

Ah, les using pour pouvoir reprendre tout ça sans trop de peine :

 

using Microsoft.Samples.WindowsAzure.ServiceManagement;
using System.Security.Cryptography.X509Certificates;
using Microsoft.WindowsAzure.ServiceRuntime;