Microsoft Azure
Облачный бизнес
Вам понадобится

Microsoft Azure

Попробуйте платформу Microsoft Azure совершенно бесплатно.

Visual Studio

Бесплатная версия Visual Studio, позволяющая создавать приложения для платформы Microsoft Azure.

SDKs и дополнительные
инструменты

Инструменты разработки приложений для платформы Microsoft Azure.

Microsoft Azure Management Libraries - управление облачной инфраструктурой из .NET-приложений

В этой статье дается описание библиотек Microsoft Azure Management Libraries, выпущенных недавно и предназначенных для управления из .NET-приложений облачной инфраструктурой, сервисами и элементами хранилища размещенными в Microsoft Azure. Описание возможностей библиотек дается на примерах кода WPF-приложения.

Что такое Microsoft Azure Management Libraries?

С выпуском библиотек Microsoft Azure Management Libraries широкая часть облачной инфраструктуры Microsoft Azure может быть доступна и автоматизирована из приложений на .NET. Эти библиотеки работают поверх функций открытого REST API платформы и их выпуск предназначен для облегчения работы разработчика с облачной инфраструктурой. 
Превью библиотек доступное сегодня, включает в себя поддержку облачных сервисов (Cloud Services), виртуальных машин и сетей, веб-сайтов (Web Sites), учетных записей хранилищ и таких инфраструктурных элементов как группы доступности (Affinity Groups).

Мы потратили много времени на проектирование естественного .NET Framework API, который прозрачно представляет собой лежащий ниже открытый REST API. Для нас было очень важным представить эти сервисы с помощью современных знакомых разработчикам подходов используемых на платформе .NET:

  • поддержка Portable Class Library (PCL) для .NET Framework 4.5, Windows Phone 8, Windows Store и Silverlight;
  • распространение в виде пакетов NuGet с минимумом зависимостей для облегчения версионности;
  • поддержка асинхронности и асинхронных операций на основе элементов платформы async/await (с легкой возможностью реализовать синхронные перегруженные методы);
  • наличие общей инфраструктуры для единой обработки ошибок, трассировки, конфигурации и управления пайплайном HTTP;
  • спроектировано для легкости тестирования и использования мокинга (mocking);
  • построено на базе популярных библиотек, таких как HttpClient и Json.NET.

Эти пакеты открывают перед вами богатые возможности и простоту управления, автоматизации, развертывания и тестирования облачной инфраструктуры WIndows Azure. С помощью них вы сможете управлять виртуальными машинами, облачными сервисами, виртуальными сетями, веб-сайтами и ключевыми инфраструктурными компонентами платформы.

Начало работы

Как и с любым другим SDK, для того, чтобы узнать как нам с ним работать лучше всего изучить немного кода. Ни один код не должен быть написал для решения проблемы, которой на самом деле не существует, так что давайте сначала сформулируем, какую проблему решают библиотеки Microsoft Azure Management Libraries:

У меня есть процесс, который я запускаю в Microsoft Azure в виде рабочей роли (Worker Role). Все работает замечательно, однако этот процесс, в действительности, необходимо запускать только несколько раз в неделю. Было бы замечательно иметь возможность завести новый сервис, разместить в него мой код и затем запустить его выполнение. Совсем хорошо было бы, если после выполнения сервиса, код сообщил об этом назад, так что мы могли бы удалить его автоматически. Порой, я забываю выключить этот сервис вручную, так что у меня могут быть лишние траты, когда он остается включенным после выполнения кода. Было бы замечательно иметь возможность автоматизировать создание необходимой мне инфраструктуры, ее запуск и последующее самоуничтожение.

До появления в свет библиотек Microsoft Azure Management Libraries (сокращенно, хоть и не официально, – WAML) решение описанной проблемы было непростой задачей. Правда, уже существует ряд отличных opensource-библиотек от сообщества, которые предлагают .NET-прослойку для управления сервисами Microsoft Azure, однако, ни одна из них не имеет полноты реализации функций Microsoft Azure Management REST API или полноценной реализации возможностей C#. При создании собственного слоя для управления мощностями облака Microsoft Azure вам обязательно придется написать свой собственный HTTP/XML-код для обмена запросами с REST API. Это не самое интересное, чем можно заняться в жизни. Занудная и скучная работа, особенно после того, как вы реализуете свою вторую дюжину из сотен методов API.

Установка библиотек Management Libraries

Я решил реализовать задачу в виде простого WPF-приложения, которое будет запускаться на моем рабочем столе. Так как у меня будет облачный сервис с рабочей ролью запущенные в облаке, я объединил все три проекта в единое решение, которое вы можете увидеть ниже: 

a123

Вероятно, вы обратили внимание на то, что я приготовился добавить несколько NuGet-пакетов в мое приложение. Это связано с тем, что Microsoft Azure Management Libraries распространяются в виде отдельных NuGet-пакетов. Я собираюсь выбрать пакет Microsoft.WindowsAzure.Management.Libraries и он один установит все доступные в Management Libraries библиотеки. Если мне захочется управлять только одним из аспектов Microsoft Azure, то вместо того, чтобы добавлять все библиотеки, я могу установить только один специфический пакет, например, Microsoft.WindowsAzure.Management.WebSites, который предлагает функциональность для управления только инфраструктурой Microsoft Azure Web Sites.

a124

После добавления ссылки на пакет, у меня есть все необходимое для настройки клиентской аутентификации между моим WPF-приложением и Microsoft Azure REST API.

Клиентская аутентификация

Первая реализация аутентификации пользователей, которую мы написали для WAML и Microsoft Azure, была основана на механизме X509-сертификатов. Недавно в пакете Microsoft Azure for .NET SDK 2.2, Visual Studio и для PowerShell была добавлена встроенная аутентификация на основе учетных записей. В настоящее время мы работаем над ее поддержкой в WAML. Доступный на сегодня выпуск WAML поддерживает аутентификацию только на основе сертификатов, однако, следите за новостями, мы работаем над тем, чтобы добавить в библиотеку поддержку аутентификации на базе учетных записей. 
Я не буду заострять наше внимание на обсуждении использования аутентификации на основе сертификатов. Наоборот, я намерен как можно быстрее перейти к обсуждению функциональных вещей в нашей статье. Мне потребуется информация всего о двух элементах для подключения к Microsoft Azure REST API:

  • Идентификатор подписки (Subscription ID);
  • Сертификат управления (Management Certificate).


Я получил эти значения из одного из моих файлов с настройками публикации (publish settings files). Ниже вы можете увидеть XML- содержимое такого файла:

a125

Используя ключ и идентификатор подписки далее в моем коде, я могу вызваю методGetCredentials, который возвращает экземпляр абстрактного классаSubscriptionCloudCredentials, который мы используем в коде библиотеки Management Library для представления данных о параметрах пользовательского доступа. С таким подходом, если я захочу в будущем добавить аутентификацию на основе учетных записей, то мне будет гораздо проще заменить механизм аутентификации. Код классаCertificateAuthenticationHelper из моего примера указан ниже:

using Microsoft.WindowsAzure; 
using System; 
using System.Security.Cryptography.X509Certificates; 
  namespace MyCloudServiceManager 
{ 
     internal class CertificateAuthenticationHelper 
     { 
         internal static SubscriptionCloudCredentials GetCredentials( 
            string subscrtionId, 
             string base64EncodedCert) 
         { 
             return new CertificateCloudCredentials(subscrtionId, 
                 new X509Certificate2(Convert.FromBase64String(base64EncodedCert))); 
         } 
     } 
}

Слой управления

Для того, чтобы учесть все возможные параметры, которые будут использоваться в моем сервисе, я создал класс ManagementControllerParameters. Это класс содержит все данные, которые мне понадобятся для создания сервисов и размещения в облаке моего кода.

namespace MyCloudServiceManager 
{ 
     internal class ManagementControllerParameters 
     { 
         internal string Region { get; set; } 
         internal string StorageAccountName { get; set; } 
         internal string CloudServiceName { get; set; } 
         internal string PackageFilePath { get; set; } 
         internal string ConfigurationFilePath { get; set; } 
         public string SubscriptionId { get; set; } 
         public string Base64EncodedCertificate { get; set; } 
     } 
}

Затем я создал класс, который содержит удобную функциональность по взаимодействию между пользовательским интерфейсом и слоем библиотек Management Library. Этот класс создан для более чистого кода в слое UX в дальнейшем. Обратите внимание на код конструктора. В нем создаются два клиента. Первый, StorageManagementClientпредназначен для управления учетными записями хранилища. ВторойComputeManagementClient предлагает возможность работы с вычислительными мощностями Microsoft Azure – облачными службами и виртуальными машинами, их расположениям и так далее.

В целях разделения кода между файлами на разные функциональные части я создал partial-класс ManagementController, код которого доступен вам в  публичном Gist, так что вы можете использовать его в своих собственных проектах.

using Microsoft.WindowsAzure; 
using Microsoft.WindowsAzure.Management.Compute; 
using Microsoft.WindowsAzure.Management.Storage; 
using System; 
 namespace MyCloudServiceManager 
{ 
     internal partial class ManagementController : IDisposable 
     { 
         private StorageManagementClient _storageManagementClient; 
         private ManagementControllerParameters _parameters; 
         private ComputeManagementClient _computeManagementClient; 
  
         internal ManagementController(ManagementControllerParameters parameters) 
         { 
             _parameters = parameters; 
  
             var credential = CertificateAuthenticationHelper.GetCredentials( 
                 parameters.SubscriptionId, 
                 parameters.Base64EncodedCertificate); 
  
             _storageManagementClient = CloudContext.Clients.CreateStorageManagementClient(credential); 
             _computeManagementClient = CloudContext.Clients.CreateComputeManagementClient(credential); 
         } 
 public void Dispose() 
         { 
             if (_storageManagementClient != null) 
                 _storageManagementClient.Dispose(); 
             if (_computeManagementClient != null) 
                 _computeManagementClient.Dispose(); 
         } 
     } 
}

Теперь, давайте создадим несколько клиентов для управления облаком и сделаем кое-какую работу.

Создание новой учетной записи хранилища

Первое, что нам нужно для реализации стратегии нашего сервиса – это учетная запись хранилища. Сервис будет использовать файл пакета .cspkg созданный в Visual Studio на базе проекта облачной службы. Его необходимо разместить в виде блоба в хранилище Microsoft Azure. Перед тем, как я смогу это сделать, мне необходимо создать учетную запись, в хранилище которой может быть загружен файл пакета. Код ниже предназначен для того, чтобы создать учетную запись хранилища в указанном регионе:

using Microsoft.WindowsAzure.Management.Storage; 
using Microsoft.WindowsAzure.Management.Storage.Models; 
using System.Threading.Tasks; 
 namespace MyCloudServiceManager 
{ 
     internal partial class ManagementController 
     { 
         internal async Task CreateStorageAccount() 
         { 
             await _storageManagementClient.StorageAccounts.CreateAsync( 
                 new StorageAccountCreateParameters 
                 { 
                     Location = _parameters.Region, 
                     ServiceName = _parameters.StorageAccountName 
                 }); 
         } 
     } 
}

После того, как учетная запись хранилища будет создана, я смогу ее использовать. Мне необходима строка подключения для подключения моего приложения (и моего «вскоре-будет-создан» облачного сервиса) к хранилищу. Я написал метод, который отвечает за получение ключей подключения к хранилищу Microsoft Azure через REST API. Затем, я формирую строку подключения и возвращаю ее в вызывающий код.

using Microsoft.WindowsAzure.Management.Storage; 
using System.Globalization; 
using System.Threading.Tasks; 
namespace MyCloudServiceManager 
{ 
     internal partial class ManagementController 
     { 
         private async Task<string> GetStorageAccountConnectionString() 
         { 
             var keys = await _storageManagementClient.StorageAccounts.GetKeysAsync(_parameters.StorageAccountName);
  
             string connectionString = string.Format( 
                 CultureInfo.InvariantCulture, 
                 "DefaultEndpointsProtocol=https;AccountName={0};AccountKey={1}",
                 _parameters.StorageAccountName, keys.SecondaryKey); 
return connectionString; 
         } 
     } 
}

Теперь, после создания учетной записи хранилища, я могу создать облачный сервис и опубликовать мой пакет в Microsoft Azure.

Создание и размещение нового облачного сервиса

Код необходимый для облачного сервиса удивительно прост. Все что нам нужно – это указать название сервиса и регион, в котором он должен быть создан.

using Microsoft.WindowsAzure.Management.Compute; 
using Microsoft.WindowsAzure.Management.Compute.Models; 
using System.Threading.Tasks; 
 namespace MyCloudServiceManager 
{ 
 internal partial class ManagementController 
     { 
         internal async Task CreateCloudService() 
         { 
             await _computeManagementClient.HostedServices.CreateAsync(new HostedServiceCreateParameters 
             { 
                 Location = _parameters.Region, 
                 ServiceName = _parameters.CloudServiceName 
             }); 
         } 
     } 
}

Наконец, все что мне остается для размещения облачного сервиса – это загрузить файл пакета сервиса созданного в Visual Studio в блоб, а затем вызвать REST API. Этот вызов будет состоять из адреса блоба, в котором расположен пакет и XML-данных полученных из конфигурационного файла облачного проекта. Этот код использует библиотеку Microsoft Azure Storage SDK, которая доступна в виде NuGet-пакета.

using Microsoft.WindowsAzure.Management.Compute; 
using Microsoft.WindowsAzure.Management.Compute.Models; 
using Microsoft.WindowsAzure.Storage; 
using Microsoft.WindowsAzure.Storage.Blob; 
using System.IO; 
using System.Threading.Tasks; 
namespace MyCloudServiceManager 
{ 
     internal partial class ManagementController 
     { 
         internal async Task DeployCloudService() 
         { 
             var storageConnectionString = await GetStorageAccountConnectionString(); 
  
             var account = CloudStorageAccount.Parse(storageConnectionString); 
  
             var blobs = account.CreateCloudBlobClient(); 
  
             var container = blobs.GetContainerReference("deployments"); 
  
             await container.CreateIfNotExistsAsync(); 
  
             await container.SetPermissionsAsync( 
                 new BlobContainerPermissions() 
                 { 
                     PublicAccess = BlobContainerPublicAccessType.Container 
                 }); 
 var blob = container.GetBlockBlobReference( 
                 Path.GetFileName(_parameters.PackageFilePath)); 
await blob.UploadFromFileAsync(_parameters.PackageFilePath, FileMode.Open); 
await _computeManagementClient.Deployments.CreateAsync(_parameters.CloudServiceName,
                     DeploymentSlot.Production, 
                     new DeploymentCreateParameters 
                     { 
                         Label = _parameters.CloudServiceName, 
                         Name = _parameters.CloudServiceName + "Prod", 
                         PackageUri = blob.Uri, 
                         Configuration = File.ReadAllText(_parameters.ConfigurationFilePath), 
                         StartDeployment = true 
                     }); 
         } 
     } 
}

Весь код необходимый для создания приложения в Microsoft Azure создан. Напоследок, осталось написать немного кода для уничтожения приложения в облаке.

Удаление элементов в облаке Microsoft Azure

Удалять элементы в Microsoft Azure с помощью библиотек Microsoft Azure Management Libraries так же просто, как и создавать их. Код ниже очищает созданное хранилище, затем он одновременно удаляет размещенный код и сам облачный сервис.

using Microsoft.WindowsAzure.Management.Storage; 
using Microsoft.WindowsAzure.Management.Compute; 
using Microsoft.WindowsAzure.Management.Compute.Models; 
namespace MyCloudServiceManager 
{ 
     internal partial class ManagementController 
     { 
         internal void Cleanup() 
         { 
             _computeManagementClient.Deployments.DeleteBySlot(_parameters.CloudServiceName, DeploymentSlot.Production); 
             _computeManagementClient.HostedServices.Delete(_parameters.CloudServiceName);
             _storageManagementClient.StorageAccounts.Delete(_parameters.StorageAccountName);
         } 
     } 
}

Учитывая все удобства при написании предыдущего кода, код для пользовательского интерфейса должен быть относительно простым.

Пользовательский интерфейс

Пользовательский интерфейс для нашего приложения относительно упрощен. Я всего лишь разместил пару кнопок на WPF-форму. Первая позволяет создавать необходимые элементы в Microsoft Azure и осуществлять размещение кода. Вторая удаляет элементы из облака. Ниже представлен XAML-код:

<Window x:Class="MyCloudServiceManager.MainWindow" 
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        Title="Deploy Service" Height="166" Width="308"> 
     <Grid> 
         <Grid.ColumnDefinitions> 
             <ColumnDefinition Width="112*"/> 
             <ColumnDefinition Width="125*"/> 
         </Grid.ColumnDefinitions> 
         <Button x:Name="_createButton" Content="Create" HorizontalAlignment="Left" VerticalAlignment="Top" 
          Width="75" Margin="73,80,0,0" Grid.Column="1" Click="_createButton_Click"/>
         <Button x:Name="_deleteButton" Content="Delete" HorizontalAlignment="Left" VerticalAlignment="Top" 
         Width="75" Margin="73,105,0,0" Grid.Column="1" Click="_deleteButton_Click"/>
     </Grid> 
</Window>

Управляющий код тоже очень прост. В обработчике события нажатия на кнопку Create я создаю экземпляр ManagementController, передавая ему все необходимые параметры для создания компонент приложения в Microsoft Azure. Затем я вызываю методы контролера для создания элементов в облаке.

Я так же обрабатываю событие нажатия на кнопку Delete, удаляя и очищая все созданные ранее в облаке элементы.

using Microsoft.WindowsAzure.Management.Models; 
using System.IO; 
using System.Windows; 
  
namespace MyCloudServiceManager 
{ 
     public partial class MainWindow : Window 
     { 
         private ManagementController _controller; 
         public MainWindow() 
         { 
             InitializeComponent(); 
         } 
private async void _createButton_Click(object sender, RoutedEventArgs e) 
         { 
             if (_controller == null) 
             { 
                 _controller = new ManagementController( 
                     new ManagementControllerParameters 
                     { 
                         Base64EncodedCertificate =
 "MIIKXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
                         SubscriptionId = "66c15fe5-XXXX-XXXX-XXXX-XXXXXXXXXX", 
                         CloudServiceName = "ManagementLibraryDemoSvc01", 
                         ConfigurationFilePath = "ServiceConfiguration.Cloud.cscfg", 
                         PackageFilePath = "MyCloudService.cspkg", 
                         Region = LocationNames.WestUS, 
                         StorageAccountName = Path.GetFileNameWithoutExtension(Path.GetRandomFileName()) 
                     }); 
             } 
  
             await _controller.CreateStorageAccount(); 
             await _controller.CreateCloudService(); 
             await _controller.DeployCloudService(); 
         } 
private void _deleteButton_Click(object sender, RoutedEventArgs e) 
         { 
             _controller.Cleanup(); 
         } 
     } 
}

Можно модифицировать этот код для использования возможностей Windows Storage SDK наблюдать на клиентской стороне за очередью сообщений в облачном хранилище. После того как облачный сервис завершит свою работу он отправит сообщение в очередь в облаке. Сообщение будет получено клиентом, который вызовет метод Cleanup и удалит все компоненты приложения из облака.

Бесконечные возможности автоматизации


Библиотеки Microsoft Azure Management Libraries предлагают прекрасный слой автоматизации между вашим кодом и Microsoft Azure. Вы можете использовать эти библиотеки для задач автоматизации всего спектра процессов создания и удаления компонент Microsoft Azure. В текущей версии мы предлагаем библиотеки для управления вычислительными мощностями и облачным хранилищем, а так же компонентами Microsoft Azure Web Sites. Со временем, мы добавим в библиотеки больше функций. Наша цель – предоставить вам возможность автоматизировать выполнения любой задачи в Microsoft Azure.

Мы с нетерпением ждем вашего отзыва о работе с библиотеками. Пожалуйста, пробуйте, экспериментируйте с Management Libraries и дайте нам знать для облегчений каких задач вы их используете. Мы открыты для любых ваших идей или вопросов. Код библиотек открыт, как и код многих других библиотек для Microsoft Azure, вы можете найти его в нашем  репозитории на GitHub.

Это перевод оригинальной статьи  Getting Started with the Microsoft Azure Management Libraries for .NET