Deploying Drupal 7 on Windows Azure | Déploiement de Drupal 7 sur Windows Azure

English Français
This article shows most of the steps decribed on the Interoperability Bridges web site. The main differences are that it shows more screen shots, it is tested against Windows Azure SDK 1.6 (Nov. 2011) with latest available package (Drupal 7.9), the package is slighty customized before uploading, and explanations are also in French Winking smile. Cet article montre la plupart des étapes qui sont décrites sur le site Web Interoperability Bridges. Les différences les plus importantes sont qu’il y a plus de copies d’écrans, il a été testé avec Windows Azure SDK 1.6 (Novembre 2011) avec le dernier package du moment (Drupal 7.9), le paquet est également modifié légèrement avant chargement sur Windows Azure. De plus, les explications sont aussi en français Winking smile.
The starting point in this blog post are: - a local Windows Server 2008 R2 development environment with Windows Azure SDK 1.6 installed. - An active Windows Azure subscription. You may get one from https://windowsazure.fr for instance. - An Azure SQL Server setup in a local region (North Europe in this example) with correct firewall rules (cf instructions here)- Windows Azure SDK for PHP installed as described in this post. Le point de départ de ce billet est constitué des éléments suivants: - un serveur local Windows Server 2008 R2- un environnement de développement local avec le SDK 1.6 de Windows Azure installé - un abonnement à Windows Azure en cours de validité. Il est possible de s’en procurer un  à partir de https://windowsazure.fr par exemple.- un serveur SQL Azure créé dans une région local (Europe du Nord dans cet exemple) avec les bonnes règles de pare-feu (voir instructions ici)- Le SDK Windows Azure pour PHP installé tel que décrit dans ce billet.
The main steps are the following Les principales étapes sont schématisées ainsi

image

Then a few steps happen inside Drupal itself to configure it. D’autres étapes sont également nécessaires ensuite dans Drupal lui-même pour le configurer.

 

Let’s get started. Démarrons.
Create a SQL Azure database Créer une base SQL Azure

image

image

In order to avoid using the sysadmin login to connect to this drupal database, create a drupal login which will be the owner of the database. This can be done from the SQL Server Management Studio (from the developmenet environment) or from the management portal De façon à éviter d’utiliser un compte de connexion administrateur du serveur SQL Azure pour se connecter à la base drupal, créons un compte pour drupal qui sera propriétaire de la base. Cela peut être fait depuis SQL Server Management Studio (depuis l’environnement de développement) ou depuis le portail de gestion

image

 

image

image

image

the code of the query is le code de la requête est le suivant

CREATE LOGIN drupalLogin WITH PASSWORD = 'BVvvgdjs65'

image

Connect to the drupal database now (instead of the master database) Se connecter maintenant sur la base drupal (à la place de la base master)

image

(sames steps as before) The script is the following: (mêmes étapes qu’avant)Le script est le suivant:

CREATE USER drupalUser FOR LOGIN drupalLogin WITH DEFAULT_SCHEMA = dbo
GO
EXEC sp_addrolemember N'db_owner', N'drupalUser'
GO

image

Let’s now create a strorage account from the Windows Azure Management portal Créons maintenant un compte de stockage depuis le portail de gestion Windows Azure

image

image

NB: create the storage account in the same region as the SQL Azure Server (North Europe in this example). NB: créer le compte de stockage dans la même région que le serveur SQL Azure (Europe du Nord dans cet exemple)

image

image

At this stage, we have the following assets and credentials (NB: no need to try to use the passwords and keys, they have been changed since this post was written). A cette étape, on dispose des crédentités suivantes (NB: n’essayez pas d’utiliser ces mots de passe et clefs, ils ont été changés depuis l’écriture de ce billet)
  • SQL Azure:
    • server=j2f2uoqrmd.database.windows.net,
    • database=durpal
    • username=drupalLogin,
    • password=BVvvgdjs65
  • Windows Azure Storage:
    • drupal111205a
    • key= QQ9TTO5oCjnWZxcMW/pegWHJccKCOHW9WaeRZbNK5vGPAwbhle3AbQCynf6sVmWAuCqjWPL45d5iQWnyFvFUfg==
With a tool like Azure Storage Explorer, create a public container named drupalazurestorage Avec un outil tel que Azure Storage Explorer, créer un conteneur public appelé drupalazurestorage

image

image

the following warning can be ignored le message d’avertissement suivant peut être ignoré

image

image

image

image

Let’s now start the creation of the Windows Azure package that will contain Drupal engine. Download the following file to the local hard drive. Démarrons maintenant le création du package Windows Azure qui contiendra le moteur Drupal. Télécharger le fichier suivant vers le disque local.

https://github.com/downloads/Interop-Bridges/Windows-Azure-PHP-Scaffolders/drupal.zip

Unblock the zip file before unzipping it (File Properties, Unblock) Débloquer le fichier zip avant de le dézipper (File Properties, Unblock)

image

Unzip its content (drupal.phar) file into C:\temp Dézipper le contenu (drupal.phar) de ce fichier dans C:\temp
NB: a .phar file is a PHP archive NB: un fichier .phar est une archive PHP
In the same folder (C:\temp), create a new text file (start, run, notepad, File, Save As…) and name it Dans le même répertoire (C:\temp), créer un nouveau fichier texte (start, run, notepad, File, Save As…) et lui donner un nom

C:\Temp\scaffold-drupal.cmd

image

The content of the file should be the following (replace with your own names, keys and passwords): Le contenu du fichier doit être le suivant (remplacer avec vos propres noms, clefs et mots de passes)

set here=%~dp0%

scaffolder run -s="%here%Drupal.phar" -out="C:\Temp\Drupal01" -DiagnosticsConnectionString="DefaultEndpointsProtocol=https;AccountName=drupal111205a;AccountKey=QQ9TTO5oCjnWZxcMW/pegWHJccKCOHW9WaeRZbNK5vGPAwbhle3AbQCynf6sVmWAuCqjWPL45d5iQWnyFvFUfg==" -sql_azure_database=drupal -sql_azure_username=drupalLogin@j2f2uoqrmd -sql_azure_password=BVvvgdjs65 -sql_azure_host=j2f2uoqrmd.database.windows.net -sync_account=drupal111205a -sync_key=QQ9TTO5oCjnWZxcMW/pegWHJccKCOHW9WaeRZbNK5vGPAwbhle3AbQCynf6sVmWAuCqjWPL45d5iQWnyFvFUfg==
pause

image

Then, double click on the cmd file in order to run it: Puis, double-cliquer sur le fichier cmd de façon à le lancer

image

This created the following folder with the following content: Cela a créé le répertoire suivant avec le contenu suivant

image

download the following file and save it in the c:\temp folder, and unblock it before unzipping it Télécharger le fichier suivant et le sauvegarder dans le répertoire c:\temp, le débloquer avant de le dézipper

https://github.com/downloads/Interop-Bridges/Windows-Azure-File-System-Durability-Plugin/FileSystemDurabilityPlugin-v1.1.zip

image

Extract content to the following folder Extraire le contenu dans le dossier suivant

C:\Program Files\Windows Azure SDK\v1.6\bin\plugins

image

Let’s now change the .cscfg and .csdef files. Modifions maintenant les fichiers .cscfg et .csdef.
NB: The .csdef file corresponds to what cannot be changed after packaging, while .cscfg file may be changed at runtime from the Windows Azure Portal or other means (API, …) NB: le fichier .csdef correspond à ce qui ne peut pas être changé après avoir créer le paquet de déploiement, alors que le fichier .cscfg peut être changé au moment de l’exécution depuis le portail de gestion Windows Azure ou d’autres moyens (API, …)
In this example, this is done with notepad++, but this can also be done with any text editor, even notepad. The advantage of an editor that has XML syntax colorization is that it is less error prone, especially while dealing with XML comments. Dans cet exemple, cela est fait avec notepad++, mais cela peut aussi être fait avec n’importe quel éditeur de texte, y compris notepad. L’avantage d’un éditeur qui dispose de coloration syntaxique XML est que cela peut éviter des erreurs, en particulier quand on est en train de supprimer des commentaires XML.

image

Optionally, if you want to enable remote desktop, i.e. being able to access to any server in the web farm once installed to Windows Azure, you may add the corresponding lines in the .csdef and .cscfg files. This is documented here. For instance: Optionnellement, si on veut autoriser l’accsè au bureau à distance, c’est-à-dire être capcable de se connecter à n’importe quel serveur de la ferme une fois installée dans Windows Azure, il est possible d’ajouter les lignes correspondantes dans les fichiers .csdef et .cscfg. Cela est documenté ici. Par exemple:

image

image

Another important change is to choose the number of instances that the web farm will start with Un autre changement important est de choisir le nombre d’instances avec laquelle la ferme Web sera initialement déployée

image

You may also want to change the size of a Virtual Machine inside the web farm. This is a .csdef parameter (i.e. changing it requires re-packaging and re-deployment). Possibles values for vmsize parameter are documented on MSDN web site. On peut aussi vouloir changer la taille de chaque machine virtuelle dans la ferme Web. C’est un paramètre .csdef (et donc le modifier suppose de repackager et de redéployer). Les valeurs possibles pour le paramètre vmsize sont documentées sur le site MSDN.

image

So here is what can end up with, as an example, for the 2 files Donc voici ce à quoi on peut aboutir, par exemple, pour les 2 fichiers

image

 <?xml version="1.0" encoding="utf-8"?>
<ServiceConfiguration serviceName="PhpOnAzure" xmlns="https://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration" osFamily="2" osVersion="*">
  <Role name="WebRole">
    <Instances count="2" />
    <ConfigurationSettings>
      <Setting name="Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString" value="UseDevelopmentStorage=true" />

      <Setting name="sql_azure_database" value="drupal" />
      <Setting name="sql_azure_username" value="drupalLogin@j2f2uoqrmd" />
      <Setting name="sql_azure_password" value="BVvvgdjs65" />
      <Setting name="sql_azure_host" value="j2f2uoqrmd.database.windows.net" />
      <Setting name="db_prefix" value="" />
      <Setting name="update_free_access" value="FALSE" />
      <Setting name="drupal_hash_salt" value="Some unique value" />
      <Setting name="base_url" value="" />
      
      <!-- For RDP access. Commented by default -->
      <Setting name="Microsoft.WindowsAzure.Plugins.RemoteAccess.Enabled" value="true" />
      <Setting name="Microsoft.WindowsAzure.Plugins.RemoteAccess.AccountUsername" value="RDAdmin" />
      <Setting name="Microsoft.WindowsAzure.Plugins.RemoteAccess.AccountEncryptedPassword" value="MIIBnQYJKoZIhvcNAQcDoIIBjjCCAYoCAQAxggFOMIIBSgIBADAyMB4xHDAaBgNVBAMME1dpbmRvd3MgQXp1cmUgVG9vbHMCEDaxSocNGM2iRQtC8o1w9HwwDQYJKoZIhvcNAQEBBQAEggEAPQmdrnOVCRj6fgK8mHHep9AuuA7rCiFPPNPvai4YGX8FtML7SK0x5Op0SoqKhZhMgEFOFstpcHFxLkN/fnKwL2ojz8sFVDNjuLUddt2AzbuPwC5ELmF2uhKqu1kPxFZKb3m8sqvtMyM1buUd8g545bNhCeOLzlL1YTW/CiDmpwYwl+SzHovSPx+8ApX6TSmizgq6h4ScpiLFk5LWCcLP50jvaPNQPgf7Wbl+k8zs6t0popnEaZpefKjZc364B95Ko8PvQGZbrDTtYxYabSHIG/SOn+bUzYOmVd23y1cGkc4BJB2XM4+6q3jIfenbKgj1Hjcs2ocrRzAuW5Py6v5wfzAzBgkqhkiG9w0BBwEwFAYIKoZIhvcNAwcECPjMHCD1PGNRgBB6G4T5FNd86FGG/UCBqKKE" />
      <Setting name="Microsoft.WindowsAzure.Plugins.RemoteAccess.AccountExpiration" value="2012-12-07T23:59:59.0000000+01:00" />
      <Setting name="Microsoft.WindowsAzure.Plugins.RemoteForwarder.Enabled" value="true" />
      </ConfigurationSettings>
    <!-- Certificate for RDP access. Commented by default --> 
    <Certificates>
      <Certificate name="Microsoft.WindowsAzure.Plugins.RemoteAccess.PasswordEncryption" thumbprint="C9D6F3C6FFB37EE967244FC7BAC7E9C362DF70BE" thumbprintAlgorithm="sha1" />
    </Certificates>
  </Role>
</ServiceConfiguration>
 <?xml version="1.0" encoding="utf-8"?>
<ServiceDefinition name="PhpOnAzure" xmlns="https://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition">
  <WebRole name="WebRole" enableNativeCodeExecution="true" vmsize="ExtraSmall">
    <Sites>
      <Site name="WebRole" physicalDirectory="./WebRole">
        <Bindings>
          <Binding name="Endpoint1" endpointName="HttpEndpoint" />
        </Bindings>
      </Site>
    </Sites>
    <Startup>
      <Task commandLine="install-php.cmd >> .\startup-tasks-log.txt 2>>.\startup-tasks-error-log.txt" executionContext="elevated" taskType="simple" /> 
    </Startup>
    <Endpoints>
      <InputEndpoint name="HttpEndpoint" protocol="http" port="80" />
    </Endpoints>
    <Imports>
      <Import moduleName="Diagnostics"/>

      <!-- For RDP access. Commented by default -->
      <Import moduleName="RemoteAccess"/>
      <Import moduleName="RemoteForwarder"/>
    </Imports>
    <ConfigurationSettings>
      <Setting name="sql_azure_database" />
      <Setting name="sql_azure_username" />
      <Setting name="sql_azure_password" />
      <Setting name="sql_azure_host" />
      <Setting name="db_prefix" />
      <Setting name="update_free_access" />
      <Setting name="drupal_hash_salt" />
      <Setting name="base_url" />
    </ConfigurationSettings>
  </WebRole>
</ServiceDefinition>
This is now a good time to also download a translation. In this example, we’ll donwload the French translation. Go to C’est maintenant également le bon moment pour télécharger une traduction. Dans cet exemple, nous allons prendre le français. Aller à

https://localize.drupal.org/translate/languages/fr

image

(https://ftp.drupal.org/files/translations/7.x/drupal/drupal-7.10.fr.po)

image

image

image

We also need to change a file in the package source. In the following file On doit également changer un fichier dans les sources du paquet de déploiement. Dans le fichier suivant

C:\Temp\Drupal01\WebRole\includes\database\sqlsrv\database.inc

replace the following function remplacer la fonction suivante
   /**
   * Internal function: prepare a query by calling PDO directly.
   *
   * This function has to be public because it is called by other parts of the
   * database layer, but do not call it directly, as you risk locking down the
   * PHP process.
   */
  public function PDOPrepare($query, array $options = array()) {
    if (!$this->bypassQueryPreprocess) {
      $query = $this->preprocessQuery($query);
    }
    // THIS FIX IS TEMPORARY UNTIL MICROSOFT MOVE THE IMPLEMENTATION
    // OF THIS ATTRIBUTE IN THE PDO DRIVER OPTIONS.
    // Let's emulate the attributes preparation because it costs a little
    // bit more to have it disabled than enabled and because we are not
    // leveraging the benefits of it.
    $options[PDO::ATTR_EMULATE_PREPARES] = TRUE;
    return parent::prepare($query, $options);
  }
 
by this one (the fix does not work with SQL Azure) par celle-ci (la correction ne fonctionne pas pour SQL Azure)
   /**
   * Internal function: prepare a query by calling PDO directly.
   *
   * This function has to be public because it is called by other parts of the
   * database layer, but do not call it directly, as you risk locking down the
   * PHP process.
   */
  public function PDOPrepare($query, array $options = array()) {
      $query = $this->preprocessQuery($query);
    return parent::prepare($query, $options);
  }
 
You may also want to add an SMTP Server. Windows Azure does not provide one, but it is possible to connect to an external one.Like for other parameters, this can be done by updating the following file: On peut aussi vouloir ajouter un serveur SMTP. Windows Azure n’en fournit pas, mais il est possible de se connecter à un serveur externe. Comme pour d’autres paramètres, cela peut se faire en modifiant le fichier suivant:

C:\Temp\Drupal01\WebRole\php\php.ini

 

Let’s now create the package from the package sources. Go to C:\Temp and create a text file named package-drupal.cmd containing the following code: Créons maintenant le paquet de déploiement à partir des sources du paquet de déploiement. Aller à C:\Temp et créer un fichier texte appelé package-drupal.cmd contenant le code suivant:

set here=%~dp0%

package create -in="%here%Drupal01" -out="%here%." -dev=false
pause

image

Execute the script Exécuter le script

image

this created the Windows Azure Package (.cspkg), that goes with the .cscfg file. They will both be uploaded to Windows Azure. Cela a crée le paquet de déploiement pour Windows Azure (.cspkg), qui va avec le fichier .cscfg. Les deux devront être déployés vers Windows Azure.

image

In order to deploy, go to the Windows Azure portal, Pour déployer, aller dans le portail Windows Azure

image

If you haven’t done so yet, create a hosted service. Si ce n’est déjà fait, créer un service hébergé

image

Note that the choosen hosted service must be in the same region as SQL Azure and Windows Azure storage (North Europe) and it must be the same as the one used when optionally setting remote desktop. A noter: le service hébergé choisi doit être dans la même région que SQL Azure et le stockage (Europe du Nord) et être le même que celui utilisé lors de l’éventuel ajout de l’accès au bureau à distance.
Select the hosted service and choose to deploy Choisir le service hébergé et déployer

image

The two files to deploy are the ones in C:\Temp. The deployment name is whatever you choose. Les deux fichiers à déployer sont ceux dans C:\temp. Le nom de déploiement peut être choisi librement

image

image

After a few minutes, the application is available and can be reached at the URL shown in the portal Après quelques minutes, l’application est disponible et peut être atteinte par l’URL montrée dans le portail

image

If you click on the URL you will get this error Si on clique sur l’URL, on a l’erreur suivante

image

PDOException: SQLSTATE[IMSSP]: An invalid statement option was specified.: SELECT SCHEMA_NAME(); Array ( ) in lock_may_be_available() (line 167 of E:\approot\includes\lock.inc).

This is because you firt need to initialize the database by running install.php. Add install.php to the URL. In our example, as the hosted service is named appazure, the URL is C’est parce qu’il faut d’abord initialiser la base en exécutant install.php. Ajouter install.php à l’URL. Dans notre exemple, comme le service hébergé s’appelle appazure, l’URL est

https://appazure.cloudapp.net/install.php

which starts the installation wizard ce qui démarre l’assistant d’installation

image

image

In the next page enter the drupalLogin password (BVvvgdjs65) Dans la page suivante, entrer le mot de passe du compte drupalLogin (BVvvgdjs65)

image

image

In next screen, a Drupal Admin password is created (LNdevikw03 in this example, do no try it, it is not the real one!) Dans l’écran suivant, un mot de passe d’administrateur Drupal est créé (LNdevikw03 dans cet exemple, mais là encore ce mot de passe n’est pas le vrai, ne pas l’essayer!)

image

image

image

The warning would not have happened if we had set an SMTP server in php.ini which was not done in this example. Windows Azure does not provide an SMTP server so you need to bring one from your network provider for instance.In this example, we ignore the warning, and we’ll receive no e-mail. Le message d’avertissement ne serait pas apparu si on avant renseigné plus haut le serveur SMTP dans le fichier php.ini, ce qui n’a pas été fait dans cet exemple.Windows Azure ne fournit pas de serveur SMTP donc il faut utiliser celui qu’on fournit depuis sont fournisseur d’accès à Internet par exemple. Dans cet exemple, on ignore le message d’avertissement, et l’on ne recevra pas de message.

image

image

image

image

image

image

image

image

image

Here is now where we give the credentials of the Windows Azure storage (drupal111205a) we created above. Voici maintenant où l’on entre les crédentités du compte de stockage Windows Azure (drupal111205a) que l’on avait créé plus haut.

image

image

image

image

image

image

image

image

image

image

 

After publishing an article with an image, you can see that the image is stored in Windows Azure blob storage Après avoir publié un article avec une image, on peut voir que cette image a été stockée dans un blob Windows Azure

image

image

 

Smile

Benjamin