Annexe : Exemple d’application de correction (génération d’applications cloud Real-World avec Azure)

par Rick Anderson, Tom Dykstra

Télécharger le projet de correction

Le livre électronique Building Real World Cloud Apps avec Azure est basé sur une présentation développée par Scott Guthrie. Il explique 13 modèles et pratiques qui peuvent vous aider à développer avec succès des applications web pour le cloud. Pour plus d’informations sur le livre électronique, consultez le premier chapitre.

Cette annexe du livre électronique Building Real World Cloud Apps with Azure contient les sections suivantes qui fournissent des informations supplémentaires sur l’exemple d’application Fix It que vous pouvez télécharger :

Problèmes connus

L’application Fix It a été développée à l’origine afin d’illustrer aussi simplement que possible certains des modèles présentés dans ce livre électronique. Toutefois, étant donné que le livre électronique concerne la création d’applications réelles, nous avons soumis le code fix it à un processus de révision et de test similaire à ce que nous devrions faire pour les logiciels publiés. Nous avons détecté un certain nombre de problèmes et, comme pour toute application réelle, certains d’entre eux ont été résolus et d’autres que nous avons reportés à une version ultérieure.

La liste suivante inclut les problèmes qui doivent être résolus dans une application de production, mais pour une raison ou pour une autre, nous avons décidé de ne pas traiter dans la version initiale de l’exemple d’application Corriger.

Sécurité

  • Vérifiez que vous ne pouvez pas affecter une tâche à un propriétaire inexistant.
  • Assurez-vous que vous pouvez uniquement afficher et modifier les tâches que vous avez créées ou qui vous sont affectées.
  • Utilisez HTTPS pour les pages de connexion et les cookies d’authentification.
  • Spécifiez une limite de temps pour les cookies d’authentification.

Validation des entrées

En général, une application de production effectue plus de validation d’entrée que l’application Corriger. Par exemple, la taille d’image/taille de fichier image autorisée pour le chargement doit être limitée.

Fonctionnalité d’administrateur

Un administrateur doit être en mesure de modifier la propriété sur les tâches existantes. Par exemple, le créateur d’une tâche peut quitter l’entreprise, ne laissant personne autorisé à gérer la tâche, sauf si l’accès administratif est activé.

Traitement des messages en file d’attente

Le traitement des messages de file d’attente dans l’application Corriger a été conçu pour être simple afin d’illustrer le modèle de travail centré sur la file d’attente avec une quantité minimale de code. Ce code simple ne serait pas adapté à une application de production réelle.

  • Le code ne garantit pas que chaque message de file d’attente sera traité au maximum une fois. Lorsque vous recevez un message de la file d’attente, il existe un délai d’expiration, pendant lequel le message est invisible pour les autres écouteurs de file d’attente. Si le délai d’expiration expire avant la suppression du message, le message redevient visible. Par conséquent, si un rôle de travail instance passe beaucoup de temps à traiter un message, il est théoriquement possible que le même message soit traité deux fois, ce qui entraîne une tâche en double dans la base de données. Pour plus d’informations sur ce problème, consultez Utilisation des files d’attente de stockage Azure.
  • La logique d’interrogation de la file d’attente peut être plus économique, en effectuant la récupération des messages par lot. Chaque fois que vous appelez CloudQueue.GetMessageAsync, il y a un coût de transaction. Au lieu de cela, vous pouvez appeler CloudQueue.GetMessagesAsync (notez le pluriel 's'), qui obtient plusieurs messages dans une seule transaction. Les coûts de transaction pour les files d’attente de stockage Azure étant très faibles, l’impact sur les coûts n’est pas important dans la plupart des scénarios.
  • La boucle serrée dans le code de traitement des messages de file d’attente provoque une affinité processeur, qui n’utilise pas efficacement les machines virtuelles multicœurs. Une meilleure conception utiliserait le parallélisme des tâches pour exécuter plusieurs tâches asynchrones en parallèle.
  • Le traitement des messages en file d’attente a uniquement une gestion rudimentaire des exceptions. Par exemple, le code ne gère pas les messages incohérents. (Lorsque le traitement des messages provoque une exception, vous devez enregistrer l’erreur et supprimer le message, sinon le rôle de travail tente de le traiter à nouveau, et la boucle continue indéfiniment.)

Les requêtes SQL ne sont pas limitées

Le code correctif actuel n’impose aucune limite au nombre de lignes que les requêtes pour les pages d’index peuvent retourner. Si un grand volume de tâches est entré dans la base de données, la taille des listes obtenues peut entraîner des problèmes de performances. La solution consiste à implémenter la pagination. Pour obtenir un exemple, consultez Tri, filtrage et pagination avec Entity Framework dans une application MVC ASP.NET.

L’application Fix It utilise la classe d’entité FixItTask pour transmettre des informations entre le contrôleur et la vue. Une bonne pratique consiste à utiliser des modèles d’affichage. Le modèle de domaine (par exemple, la classe d’entité FixItTask) est conçu autour de ce qui est nécessaire pour la persistance des données, tandis qu’un modèle d’affichage peut être conçu pour la présentation des données.

L’application Corriger stocke les images chargées comme publiques, ce qui signifie que toute personne qui trouve l’URL peut accéder aux images. Les images peuvent être sécurisées au lieu d’être publiques.

Aucun script d’automatisation PowerShell pour les files d’attente

Les exemples de scripts d’automatisation PowerShell ont été écrits uniquement pour la version de base de Fix It qui s’exécute entièrement dans Azure App Service Web Apps. Nous n’avons pas fourni de scripts pour la configuration et le déploiement sur l’application web et l’environnement de service cloud requis pour le traitement de la file d’attente.

Gestion spéciale des codes HTML dans l’entrée utilisateur

ASP.NET empêche automatiquement de nombreuses façons dont les utilisateurs malveillants peuvent tenter des attaques par script intersites en entrant un script dans les zones de texte d’entrée utilisateur. Et l’assistance MVC DisplayFor utilisée pour afficher les titres et les notes des tâches encode automatiquement les valeurs HTML qu’il envoie au navigateur. Mais dans une application de production, vous pouvez prendre des mesures supplémentaires. Pour plus d’informations, consultez Validation des demandes dans ASP.NET.

Bonnes pratiques

Voici quelques problèmes qui ont été résolus après avoir été découverts dans la révision du code et le test de la version d’origine de l’application Corriger. Certains sont dus au fait que le codeur d’origine n’a pas connaissance d’une bonne pratique particulière, d’autres simplement parce que le code a été écrit rapidement et n’était pas destiné aux logiciels publiés. Nous listons les problèmes ici au cas où il y aurait quelque chose que nous avons appris de cette révision et de ce test qui pourrait être utile à d’autres personnes qui développent également des applications web.

Supprimer le référentiel de base de données

La FixItTaskRepository classe doit supprimer le instance Entity Framework DbContext . Pour ce faire, nous implémentons IDisposable dans la FixItTaskRepository classe :

public class FixItTaskRepository : IFixItTaskRepository, IDisposable
{
    private MyFixItContext db = new MyFixItContext();

    // other code not shown

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (disposing)
        {
            // Free managed resources.
            if (db != null)
            {
                db.Dispose();
                db = null;
            }
        }
    }
}

Notez qu’AutoFac supprimera automatiquement le FixItTaskRepository instance. Nous n’avons donc pas besoin de le supprimer explicitement.

Une autre option consiste à supprimer la DbContext variable membre de FixItTaskRepository, puis à créer une variable locale DbContext dans chaque méthode de dépôt, à l’intérieur d’une using instruction . Par exemple :

// Alternate way to dispose the DbContext
using (var db = new MyFixItContext())
{
    fixItTask = await db.FixItTasks.FindAsync(id);
}

Inscrire les singletons en tant que tels avec DI

Étant donné qu’une seule instance de la classe et Logger de la PhotoService classe est nécessaire, ces classes doivent être inscrites en tant qu’instances uniques pour l’injection de dépendances dans DependenciesConfig.cs :

builder.RegisterType<Logger>().As<ILogger>().SingleInstance();
builder.RegisterType<FixItTaskRepository>().As<IFixItTaskRepository>();
builder.RegisterType<PhotoService>().As<IPhotoService>().SingleInstance();

Sécurité : Ne pas afficher les détails de l’erreur aux utilisateurs

L’application Fix It d’origine n’avait pas de page d’erreur générique et laissait simplement toutes les exceptions s’afficher dans l’interface utilisateur. Par conséquent, certaines exceptions telles que les erreurs de connexion de base de données peuvent entraîner l’affichage d’une trace de pile complète dans le navigateur. Des informations détaillées sur les erreurs peuvent parfois faciliter les attaques par des utilisateurs malveillants. La solution consiste à journaliser les détails de l’exception et à afficher une page d’erreur à l’utilisateur qui n’inclut pas les détails de l’erreur. L’application Correction était déjà en cours de journalisation et, pour afficher une page d’erreur, nous avons ajouté <customErrors mode=On> dans le fichier Web.config.

<system.web>
  <customErrors mode="On"/>
  <authentication mode="None" />
  <compilation debug="true" targetFramework="4.5" />
  <httpRuntime targetFramework="4.5" />
</system.web>

Par défaut, views\Shared\Error.cshtml est affiché pour les erreurs. Vous pouvez personnaliser Error.cshtml ou créer votre propre affichage de page d’erreur et ajouter un defaultRedirect attribut. Vous pouvez également spécifier différentes pages d’erreur pour des erreurs spécifiques.

Sécurité : autoriser uniquement la modification d’une tâche par son créateur

La page Index du tableau de bord affiche uniquement les tâches créées par l’utilisateur connecté, mais un utilisateur malveillant peut créer une URL avec un ID pour la tâche d’un autre utilisateur. Nous avons ajouté du code dans DashboardController.cs pour retourner un 404 dans ce cas :

public async Task<ActionResult> Edit(int id)
{
    FixItTask fixittask = await fixItRepository.FindTaskByIdAsync(id);
    if (fixittask == null)
    {
        return HttpNotFound();
    }

    // Verify logged in user owns this FixIt task.
    if (User.Identity.Name != fixittask.Owner)
    {
       return HttpNotFound();
    }

    return View(fixittask);
}

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Edit(int id, [Bind(Include = "CreatedBy,Owner,Title,Notes,PhotoUrl,IsDone")]FormCollection form)
{
    FixItTask fixittask = await fixItRepository.FindTaskByIdAsync(id);

    // Verify logged in user owns this FixIt task.
    if (User.Identity.Name != fixittask.Owner)
    {
       return HttpNotFound();
    }

    if (TryUpdateModel(fixittask, form))
    {
        await fixItRepository.UpdateAsync(fixittask);
        return RedirectToAction("Index");
    }

    return View(fixittask);
}

Ne pas avaler les exceptions

L’application Fix It d’origine vient de renvoyer la valeur Null après la journalisation d’une exception résultant d’une requête SQL :

catch (Exception e)
{
    log.Error(e, "Error in FixItTaskRepository.FindTasksByOwnerAsync(userName={0})", userName);
    return null;
}

Cela donnerait à l’utilisateur l’impression que la requête a réussi, mais qu’elle n’a tout simplement pas retourné de lignes. La solution consiste à lever à nouveau l’exception après l’interception et la journalisation :

catch (Exception e)
{
    log.Error(e, "Error in FixItTaskRepository.FindTasksByCreatorAsync(creater={0})", creator);
    throw;
}

Intercepter toutes les exceptions dans les rôles de travail

Toutes les exceptions non gérées dans un rôle de travail entraînent le recyclage de la machine virtuelle. Vous souhaitez donc encapsuler tout ce que vous faites dans un bloc try-catch et gérer toutes les exceptions.

Spécifier la longueur des propriétés de chaîne dans les classes d’entité

Pour afficher du code simple, la version d’origine de l’application Fix It n’a pas spécifié de longueurs pour les champs de l’entité FixItTask et, par conséquent, ils ont été définis comme varchar(max) dans la base de données. Par conséquent, l’interface utilisateur accepterait presque n’importe quelle quantité d’entrée. La spécification de longueurs définit des limites qui s’appliquent à la fois à l’entrée utilisateur dans la page web et à la taille de colonne dans la base de données :

public class FixItTask
{
    public int FixItTaskId  { get; set; }
    [StringLength(80)]
    public string CreatedBy { get; set; }
    [Required]
    [StringLength(80)]
    public string Owner { get; set; }
    [Required]
    [StringLength(80)]
    public string Title { get; set; }
    [StringLength(1000)]
    public string Notes { get; set; }
    [StringLength(200)]
    public string PhotoUrl { get; set; }
    public bool IsDone      { get; set; }  
}

Marquer les membres privés comme étant en lecture seule lorsqu’ils ne sont pas censés changer

Par exemple, dans la DashboardController classe, une instance de FixItTaskRepository est créée et n’est pas censée changer. Nous l’avons donc définie comme étant en lecture seule.

public class DashboardController : Controller
    {
        private readonly IFixItTaskRepository fixItRepository = null;

Utiliser la liste. Any() au lieu de list. Count() > 0

Si tout ce qui vous importe est de savoir si un ou plusieurs éléments d’une liste correspondent aux critères spécifiés, utilisez la méthode Any , car elle retourne dès qu’un élément correspondant aux critères est trouvé, alors que la Count méthode doit toujours itérer au sein de chaque élément. Le fichier Dashboard Index.cshtml avait à l’origine ce code :

@if (Model.Count() == 0) {
    <br />
    <div>You don't have anything currently assigned to you!!!</div>
}

Nous l’avons remplacé par ceci :

@if (!Model.Any()) {
    <br />
    <div>You don't have anything currently assigned to you!!!</div>
}

Générer des URL dans les vues MVC à l’aide des helpers MVC

Pour le bouton Créer un correctif sur la page d’accueil, l’application Corriger a codé en dur un élément d’ancrage :

<a href="/Tasks/Create" class="btn btn-primary btn-large">Create a New FixIt &raquo;</a>

Pour les liens Affichage/Action comme celui-ci, il est préférable d’utiliser l’assistance HTML Url.Action , par exemple :

@Url.Action("Create","Tasks")

Utiliser Task.Delay au lieu de Thread.Sleep dans le rôle de travail

Le modèle nouveau projet place Thread.Sleep dans l’exemple de code d’un rôle de travail, mais si le thread est mis en veille, le pool de threads génère des threads inutiles supplémentaires. Vous pouvez éviter cela à l’aide de Task.Delay à la place.

while (true)
{
    try
    {
        await queueManager.ProcessMessagesAsync();
    }
    catch (Exception ex)
    {
        logger.Error(ex, "Exception in worker role Run loop.");
    }
    await Task.Delay(1000);
}

Éviter le void asynchrone

Si une méthode asynchrone n’a pas besoin de retourner une valeur, retournez un Task type au lieu de void.

Cet exemple provient de la FixItQueueManager classe :

// Correct
public async Task SendMessageAsync(FixItTask fixIt) { ... }

// Incorrect
public async void SendMessageAsync(FixItTask fixIt) { ... }

Vous devez utiliser async void uniquement pour les gestionnaires d’événements de niveau supérieur. Si vous définissez une méthode comme async void, l’appelant ne peut pas attendre la méthode ou intercepter les exceptions levées par la méthode. Pour plus d’informations, consultez Meilleures pratiques en matière de programmation asynchrone.

Utiliser un jeton d’annulation pour interrompre la boucle de rôle de travail

En règle générale, la méthode Run sur un rôle de travail contient une boucle infinie. Lorsque le rôle de travail s’arrête, la méthode RoleEntryPoint.OnStop est appelée. Vous devez utiliser cette méthode pour annuler le travail effectué à l’intérieur de la méthode Run et quitter correctement. Sinon, le processus peut être arrêté au milieu d’une opération.

Désactiver la procédure de détection MIME automatique

Dans certains cas, Internet Explorer signale un type MIME différent du type spécifié par le serveur web. Par instance, si Internet Explorer trouve du contenu HTML dans un fichier fourni avec l’en-tête de réponse HTTP Content-Type : text/plain, Internet Explorer détermine que le contenu doit être affiché au format HTML. Malheureusement, cette « détection MIME » peut également entraîner des problèmes de sécurité pour les serveurs hébergeant du contenu non approuvé. Pour résoudre ce problème, Internet Explorer 8 a apporté un certain nombre de modifications au code de détermination de type MIME et permet aux développeurs d’applications de refuser la détection MIME. Le code suivant a été ajouté au fichier Web.config .

<system.webServer>
     <httpProtocol>
        <customHeaders>
           <add name="X-Content-Type-Options" value="nosniff"/>
        </customHeaders>
     </httpProtocol>
     <modules>
      <remove name="FormsAuthenticationModule" />
    </modules>
  </system.webServer>

Activer le regroupement et la minimisation

Lorsque Visual Studio crée un projet web, le regroupement et la minimisation des fichiers JavaScript ne sont pas activés par défaut. Nous avons ajouté une ligne de code dans BundleConfig.cs :

// For more information on bundling, visit https://go.microsoft.com/fwlink/?LinkId=301862
public static void RegisterBundles(BundleCollection bundles)
{
    bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
                "~/Scripts/jquery-{version}.js"));
 
   // Code removed for brevity/
 
   BundleTable.EnableOptimizations = true;
}

Définir un délai d’expiration pour les cookies d’authentification

Par défaut, les cookies d’authentification expirent dans deux semaines. Un temps plus court est plus sécurisé. Vous pouvez modifier ce paramètre dans StartupAuth.cs :

app.UseCookieAuthentication(new CookieAuthenticationOptions
{
    AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
    LoginPath = new PathString("/Account/Login"),
    ExpireTimeSpan = System.TimeSpan.FromMinutes(20)
});

Comment exécuter l’application à partir de Visual Studio sur votre ordinateur local

Il existe deux façons d’exécuter l’application Corriger :

  • Exécutez l’application de base qui écrit de nouvelles tâches directement dans la base de données SQL.
  • Exécutez l’application à l’aide d’une file d’attente et d’un service principal pour créer des tâches. Le modèle de file d’attente est décrit dans le chapitre Modèle de travail centré sur la file d’attente.

Exécuter l’application de base

  1. Installer Visual Studio 2017.
  2. Installez le Kit de développement logiciel (SDK) Azure pour .NET pour Visual Studio.
  3. Téléchargez le fichier .zip à partir de MSDN Code Gallery.
  4. Dans Explorateur de fichiers, cliquez avec le bouton droit sur le fichier .zip, cliquez sur Propriétés, puis dans le Fenêtre Propriétés cliquez sur Débloquer.
  5. Décompressez le fichier.
  6. Double-cliquez sur le fichier .sln pour lancer Visual Studio.
  7. Dans le menu Outils , cliquez sur Gestionnaire de package NuGet, puis sur Console du Gestionnaire de package.
  8. Dans la console du Gestionnaire de package (PMC), cliquez sur Restaurer.
  9. Quittez Visual Studio.
  10. Démarrez l’émulateur de stockage Azure.
  11. Redémarrez Visual Studio en ouvrant le fichier solution que vous avez fermé à l’étape précédente.
  12. Vérifiez que le projet FixIt est défini comme projet de démarrage, puis appuyez sur Ctrl+F5 pour exécuter le projet.

Exécuter l’application avec le traitement de la file d’attente

  1. Suivez les instructions pour Exécuter l’application de base, puis fermez le navigateur et fermez Visual Studio.

  2. Démarrez Visual Studio avec des privilèges d’administrateur. (Vous allez utiliser l’émulateur de calcul Azure, ce qui nécessite des privilèges d’administrateur.)

  3. Dans le fichier deWeb.config de l’application dans le projet MyFixIt (le projet web), remplacez la valeur de appSettings/UseQueues par « true » :

    <appSettings>
        <!-- Other settings not shown -->
        <add key="UseQueues" value="true"/>
    </appSettings>
    
  4. Si l’émulateur de stockage Azure n’est pas encore en cours d’exécution, recommencez-le.

  5. Exécutez simultanément le projet web FixIt et le projet MyFixItCloudService.

    Utilisation de Visual Studio :

    1. Appuyez sur F5 pour exécuter le projet FixIt.
    2. Dans Explorateur de solutions, cliquez avec le bouton droit sur le projet MyFixItCloudService, puis cliquez sur Déboguer>Démarrer une nouvelle instance.

    Utilisation de Visual Studio 2013 Express pour le web :

    1. Dans Explorateur de solutions, cliquez avec le bouton droit sur la solution FixIt et sélectionnez Propriétés.

    2. Sélectionnez Plusieurs projets de démarrage.

    3. Dans la liste déroulante Action sous MyFixIt et MyFixItCloudService, sélectionnez Démarrer.

    4. Cliquez sur OK.

    5. Appuyez sur F5 pour exécuter les deux projets.

      Lorsque vous exécutez le projet MyFixItCloudService, Visual Studio démarre l’émulateur de calcul Azure. Selon la configuration de votre pare-feu, vous devrez peut-être autoriser l’émulateur via le pare-feu.

Comment déployer l’application de base sur Azure App Service Web Apps à l’aide des scripts Windows PowerShell

Pour illustrer le modèle Automatiser tout , l’application Corriger est fournie avec des scripts qui configurent un environnement dans Azure et déploient le projet dans le nouvel environnement. Les instructions suivantes expliquent comment utiliser les scripts.

Si vous souhaitez exécuter dans Azure sans utiliser de files d’attente et que vous avez apporté les modifications nécessaires à l’exécution locale avec des files d’attente, veillez à revenir à la valeur useQueues appSetting sur false avant de suivre les instructions suivantes.

Ces instructions supposent que vous avez déjà téléchargé et exécuté la solution Corriger en local, et que vous disposez d’un compte Azure ou d’un abonnement Azure que vous êtes autorisé à gérer.

  1. Installez la console Azure PowerShell. Pour obtenir des instructions, consultez la rubrique Installation et configuration d'Azure PowerShell.

    Cette console personnalisée est configurée pour fonctionner avec votre abonnement Azure. Le module Azure est installé dans le répertoire Program Files et est automatiquement importé à chaque utilisation de la console Azure PowerShell.

    Si vous préférez travailler dans un autre programme hôte, tel que Windows PowerShell ISE, veillez à utiliser l’applet de commande Import-Module pour importer le module Azure ou à utiliser une commande dans le module Azure pour déclencher l’importation automatique du module.

  2. Démarrez Azure PowerShell avec l’option Exécuter en tant qu’administrateur.

  3. Exécutez l’applet de commande Set-ExecutionPolicy pour définir la stratégie d’exécution Azure PowerShell sur RemoteSigned. Entrez Y (pour Oui) pour effectuer la modification de la stratégie.

    PS C:\> Set-ExecutionPolicy RemoteSigned
    

    Ce paramètre vous permet d’exécuter des scripts locaux qui ne sont pas signés numériquement. (Vous pouvez également définir la stratégie d’exécution sur Unrestricted, ce qui éliminerait la nécessité de l’étape de déblocage ultérieurement, mais cela n’est pas recommandé pour des raisons de sécurité.)

  4. Exécutez l’applet Add-AzureAccount de commande pour configurer PowerShell avec les informations d’identification de votre compte.

    PS C:\> Add-AzureAccount
    

    Ces informations d’identification expirent après un certain temps et vous devez réexécuter l’applet Add-AzureAccount de commande. À mesure que ce livre électronique est en cours d’écriture, la limite de temps avant l’expiration des informations d’identification est de 12 heures.

  5. Si vous avez plusieurs abonnements, utilisez l’applet de commande Select-AzureSubscription pour spécifier l’abonnement dans lequel vous souhaitez créer l’environnement de test.

  6. Importez un certificat de gestion pour le même abonnement Azure à l’aide des Get-AzurePublishSettingsFile applets de commande et Import-AzurePublishSettingsFile . La première de ces applets de commande télécharge un fichier de certificat et, dans la seconde, vous spécifiez l’emplacement de ce fichier pour l’importer. > [! IMPORTANT]

    Conservez le fichier téléchargé dans un emplacement sécurisé ou supprimez-le lorsque vous en avez terminé, car il contient un certificat qui peut être utilisé pour gérer vos services Azure.

    PS C:\Users\username\Documents\Visual Studio 2013\Projects\MyFixIt\Automation> Get-AzurePublishSettingsFile
    PS C:\Users\username\Documents\Visual Studio 2013\Projects\MyFixIt\Automation> Import-AzurePublishSettingsFile "C:\Users
    \username\Downloads\Azure MSDN - Visual Studio Ultimate-12-14-2013-credentials.publishsettings"
    

    Le certificat est utilisé pour un appel d’API REST qui détecte l’adresse IP de l’ordinateur de développement afin de définir une règle de pare-feu sur le serveur SQL Database.

  7. Exécutez l’applet de commande Set-Location (les alias sont cd, chdiret sl) pour accéder au répertoire qui contient les scripts. (Ils se trouvent dans le dossier Automation du dossier solution Corriger.) Placez le chemin entre guillemets si l’un des noms de répertoires contient des espaces. Par exemple, pour accéder au c:\Sample Apps\FixIt\Automation répertoire, vous pouvez entrer la commande suivante :

    PS C:\> cd "c:\Sample Apps\MyFixIt\Automation"
    
  8. Pour autoriser Windows PowerShell à exécuter ces scripts, utilisez l’applet de commande Unblock-File. (Les scripts sont bloqués, car ils ont été téléchargés à partir d’Internet.)

    Avertissement

    Sécurité : avant de s’exécuter Unblock-File sur un script ou un fichier exécutable, ouvrez le fichier dans le Bloc-notes, examinez les commandes et vérifiez qu’elles ne contiennent pas de code malveillant.

    Par exemple, la commande suivante exécute l’applet de Unblock-File commande sur tous les scripts du répertoire actif.

    PS C:\Sample Apps\FixIt\Automation> Unblock-File -Path .\*.ps1
    
  9. Pour créer l’application web pour l’application de base (sans traitement des files d’attente) Fix It, exécutez le script de création d’environnement.

    Le paramètre requis Name spécifie le nom de la base de données et est également utilisé pour le compte de stockage créé par le script. Le nom doit être globalement unique dans le domaine azurewebsites.net. Si vous spécifiez un nom qui n’est pas unique, comme Fixit ou Test (ou même comme dans l’exemple, fixitdemo), l’applet New-AzureWebsite de commande échoue avec une erreur interne qui signale un conflit. Le script convertit le nom en minuscules pour respecter les exigences de nom pour les applications web, les comptes de stockage et les bases de données.

    Le paramètre requis SqlDatabasePassword spécifie le mot de passe du compte d’administrateur qui sera créé pour SQL Database. N’incluez pas de caractères XML spéciaux dans le mot de passe (& <> ;). Il s’agit d’une limitation de la façon dont les scripts ont été écrits, et non d’une limitation d’Azure.

    Par exemple, si vous souhaitez créer une application web nommée « fixitdemo » et utiliser un mot de passe d’administrateur SQL Server « Passw0rd1 », vous pouvez entrer la commande suivante :

    PS C:\Sample Apps\FixIt\Automation> .\New-AzureWebsiteEnv.ps1 -Name 
    fixitdemo <required params here>
    

    Le nom doit être unique dans le domaine azurewebsites.net, et le mot de passe doit répondre à SQL Database exigences en matière de complexité du mot de passe. (L’exemple Passw0rd1 répond aux exigences.)

    Notez que la commande commence par « ». Pour empêcher l’exécution malveillante de scripts, Windows PowerShell nécessite que vous fournissiez le chemin d’accès complet au fichier de script lorsque vous exécutez un script. Vous pouvez utiliser un point pour indiquer le répertoire actif (« . ») ou fournir le chemin d’accès complet, par exemple :

    PS C:\Temp\FixIt\Automation> C:\Temp\FixIt\Automation\New-AzureWebsiteEnv.ps1 -Name fixitdemo -SqlDatabasePassword Pas$w0rd
    

    Pour plus d’informations sur le script, utilisez l’applet de Get-Help commande .

    PS C:\Sample Apps\FixIt\Automation> Get-Help -Full .\New-AzureWebsiteEnv.ps1
    

    Vous pouvez utiliser les Detailedparamètres , Full, Parameterset Examples de l’applet de commande Get-Help pour filtrer l’aide retournée.

    Si le script échoue ou génère des erreurs, telles que « New-AzureWebsite : Appeler Set-AzureSubscription et Select-AzureSubscription d’abord », vous n’avez peut-être pas terminé la configuration de Azure PowerShell.

    Une fois le script terminé, vous pouvez utiliser le portail de gestion Azure pour voir les ressources qui ont été créées, comme indiqué dans le chapitre Automatiser tout .

  10. Pour déployer le projet FixIt dans le nouvel environnement Azure, utilisez le script AzureWebsite.ps1 . Par exemple :

    PS C:\Sample Apps\FixIt\Automation> .\Publish-AzureWebsite.ps1 ..\MyFixIt\MyFixIt.csproj -Launch
    

    Une fois le déploiement terminé, le navigateur s’ouvre avec Correction en cours d’exécution dans Azure.

Résolution des problèmes liés aux scripts Windows PowerShell

Les erreurs les plus courantes rencontrées lors de l’exécution de ces scripts sont liées aux autorisations. Vérifiez que Add-AzureAccount et Import-AzurePublishSettingsFile ont réussi et que vous les avez utilisés pour le même abonnement Azure. Même si Add-AzureAccount a réussi, vous devrez peut-être l’exécuter à nouveau. Les autorisations ajoutées par Add-AzureAccount expirent dans 12 heures.

La référence d’objet n’a pas pour valeur une instance d’un objet.

Si le script retourne des erreurs, telles que « La référence d’objet n’est pas définie sur un instance d’un objet », ce qui signifie que Windows PowerShell ne trouve pas d’objet à traiter (il s’agit d’une exception de référence Null), exécutez l’applet Add-AzureAccount de commande et réessayez le script.

New-AzureSqlDatabaseServer : Object reference not set to an instance of an object.
At C:\ps-test\azure-powershell-samples-master\WebSite\create-azure-sql.ps1:80 char:19
+ $databaseServer = New-AzureSqlDatabaseServer -AdministratorLogin $UserName -Admi ...
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : NotSpecified: (:) [New-AzureSqlDatabaseServer], NullReferenceException
    + FullyQualifiedErrorId : 
Microsoft.WindowsAzure.Commands.SqlDatabase.Server.Cmdlet.NewAzureSqlDatabaseServer

InternalError : le serveur a rencontré une erreur interne.

L’applet New-AzureWebsite de commande retourne une erreur interne lorsque le nom n’est pas unique dans le domaine azurewebsites.net. Pour résoudre l’erreur, utilisez une valeur différente pour le nom, qui se trouve dans le paramètre Name de New-AzureWebsiteEnv.ps1.

New-AzureWebsite : InternalError: The server encountered an internal error. 
Please retry the request.
At line:1 char:1
+ New-AzureWebsite -Name fixitdemo
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          
: CloseError: (:) [New-AzureWebsite], Exception
+ FullyQualifiedErrorId : 
Microsoft.WindowsAzure.Commands.Websites.NewAzureWebsiteCommand

Redémarrage du script

Si vous devez redémarrer le script New-AzureWebsiteEnv.ps1 parce qu’il a échoué avant l’impression du message « Le script est terminé », vous pouvez supprimer les ressources que le script a créées avant son arrêt. Par exemple, si le script a déjà créé l’application web ContosoFixItDemo et que vous réexécutez le script avec le même nom, le script échoue, car le nom est en cours d’utilisation.

Pour déterminer les ressources créées par le script avant son arrêt, utilisez les applets de commande suivantes :

  • Get-AzureWebsite
  • Get-AzureSqlDatabaseServer
  • Get-AzureSqlDatabase: pour exécuter cette applet de commande, dirigez le nom du serveur de base de données vers Get-AzureSqlDatabase: Get-AzureSqlDatabaseServer | Get-AzureSqlDatabase.

Pour supprimer ces ressources, utilisez les commandes suivantes. Notez que si vous supprimez le serveur de base de données, vous supprimez automatiquement les bases de données associées au serveur.

  • Get-AzureWebsite -Name <WebsiteName> | Remove-AzureWebsite
  • Get-AzureSqlDatabase -Name <DatabaseName> -ServerName <DatabaseServerName> | Remove-SqlAzureDatabase
  • Get-AzureSqlDatabaseServer | Remove-AzureSqlDatabaseServer

Comment déployer l’application avec le traitement de file d’attente sur Azure App Service Web Apps et un service cloud Azure

Pour activer les files d’attente, apportez la modification suivante dans le fichier MyFixIt\Web.config. Sous appSettings, remplacez la valeur de UseQueues par « true » :

<appSettings>
    <!-- Other settings not shown -->
    <add key="UseQueues" value="true"/>
</appSettings>

Déployez ensuite l’application MVC sur une application web dans Azure App Service, comme décrit précédemment.

Ensuite, créez un service cloud Azure. Les scripts inclus dans l’application Corriger ne créent pas ou ne déploient pas le service cloud. Vous devez donc utiliser Portail Azure pour cela. Dans le portail, cliquez sur Nouveau -- calculCréation rapidedu service -- cloud, puis entrez une URL et un emplacement du centre de données. Utilisez le même centre de données que celui où vous avez déployé l’application web.

Diagramme montrant le portail Azure Cloud Service et les onglets multiples, avec leurs sélections disponibles, pour la création d’un projet de service cloud Azure

Avant de pouvoir déployer le service cloud, vous devez mettre à jour certains fichiers de configuration.

Dans MyFixIt.WorkerRole\app.config, sous connectionStrings, remplacez la valeur de la appdb chaîne de connexion par la chaîne de connexion réelle de l’SQL Database. Vous pouvez obtenir les chaîne de connexion à partir du portail. Dans le portail, cliquez sur Bases de données - SQLappdb - Affichage SQL Database chaînes de connexion pour ADO .Net, ODBC, PHP et JDBC. Copiez le ADO.NET chaîne de connexion et collez la valeur dans le fichier app.config. Remplacez « {your_password_here} » par le mot de passe de votre base de données. (En supposant que vous utilisiez les scripts pour déployer l’application MVC, vous avez spécifié le mot de passe de la base de données dans le SqlDatabasePassword paramètre de script.)

Le résultat doit se présenter comme suit :

<add name="appdb" connectionString="Server=tcp:####.database.windows.net,1433;Database=appdb;User ID=####;Password=####;Trusted_Connection=False;Encrypt=True;Connection Timeout=30;" providerName="System.Data.SqlClient" />

Dans le même fichier MyFixIt.WorkerRole\app.config, sous appSettings, remplacez les deux valeurs d’espace réservé pour le compte de stockage Azure.

<appSettings>
  <add key="StorageAccountName" value="{StorageAccountName}" />
  <add key="StorageAccountAccessKey" value="{StorageAccountAccessKey}" />
</appSettings>

Vous pouvez obtenir la clé d’accès à partir du portail. Consultez Guide pratique pour gérer les comptes de stockage.

Dans MyFixItCloudService\ServiceConfiguration.Cloud.cscfg, remplacez les deux mêmes valeurs d’espaces réservés pour le compte de stockage Azure.

<ConfigurationSettings>
    <Setting name="Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString" 
             value="DefaultEndpointsProtocol=https;AccountName={StorageAccountName};AccountKey={StorageAccountAccessKey}" />
  </ConfigurationSettings>

Vous êtes maintenant prêt à déployer le service cloud. Dans Explorateur de solutions, cliquez avec le bouton droit sur le projet MyFixItCloudService, puis sélectionnez Publier. Pour plus d’informations, consultez « Déployer l’application sur Azure », qui est dans la partie 2 de ce didacticiel.