[SDK1.3] Windows Azure で管理者権限を使ってみる

Windows Azure SDK 1.3 がリリースされ、Window Azure の持つ多くの機能が解放されてきています。管理者権限を利用できるようになるのもその機能の一つ。

管理者権限を利用するには2つの方法があります。一つはスタートアップタスクでの昇格、もう一つは管理者モード(Elevated Privilege)です。

スタートアップタスクでの昇格

スタートアップタスクとは、ロールが起動するとき実行されるタスクです。 Guest OS である Windows Server 内のコンポーネントのセットアップや、パッケージに内包させたモジュール等をロール起動時に行い、ロール上のアプリケーション実行のための前提環境の構築等に利用できます。実行権限は、既定の権限と管理者権限の2つの権限が設定可能で、以下のように サービス定義ファイル(csdef) に設定します。

    1:  <Startup>
    2:      <Task commandLine="mysetup.cmd" executionContext="elevated" taskType="simple" />
    3:  </Startup>

管理者モード(Elevated Privilege)

管理者モードとは、ロールのランタイムの権限を管理者へ昇格させる機能です。権限昇格と呼ぶこともあります。権限は、既定の権限と管理者権限の2つの権限が設定可能で、以下のように サービス定義ファイル(csdef) に設定します。

    1:  <Runtime executionContext="elevated" />

Windows Azure で管理者権限の使用例 - IIS 7.5 のアプリケーションプールの設定

.NET Framework 4 では、 Web アプリケーションのプリロード機能と呼ばれる、最初のHTTP トラフィックを受け入れる前にアプリケーションの初期プロセスをあらかじめ実行する機能があります。このプリロード機能は IIS 7.5 (Windows Server 2008 R2) と組み合わせで利用できる機能で、利用する際 applicationHost.config ファイルに以下のような設定を行います。

    1:  <applicationPools>
    2:      <add name="MyApplicationPool" startMode="AlwaysRunning" />
    3:  </applicationPools>

この設定を Full IIS 上で動作するWeb ロールのアプリケーションプールに対して行ってみます。

この設定はIIS 7.5 が対象となるため、IIS 7.5 が動作している Guest OS 2.x 系が対象となります。そこで、サービス構成ファイル(cscfg)上で osFamily =”2” に設定しGuest OS を 2.x系にします。

    1:  <?xml version="1.0" encoding="utf-8"?>
    2:      <ServiceConfiguration serviceName="W2008R2Lab" xmlns=https://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration
              osFamily="2" osVersion="*">
    3:  <Role name="WebRole1">

次に、スタートアップタスクで行うか、管理者モードで行うか判定します。

スタートアップタスク実行中は、Web ロールのアプリケーションに対するアプリケーションプールが存在せず既定の3つのアプリケーションプールのみが存在するため、スタートアップタスクは選択枝から外れます。さらに、Web ロールの OnStart() メソッド内等でアプリケーションプールの存在を確認すると、Webロールに対してアプリケーションプールが存在しています。そこで、管理者モードを利用して、Web ロールのエントリーポイントである OnStart() メソッド内で設定を行うことにします。

サービス定義ファイル(csdef)の設定により、ラインタイムの権限を管理者権限に昇格させます。

    1:  <Runtime executionContext="elevated">

OnStart() メソッド内で設定を行うため、Microsoft.Web.Administration.dll の参照を追加し、ServerManager クラス等を利用して、アプリケーションプールのコレクションの取得と、当該アプリケーションプールへの設定を行います。以下 C# のコード例です。

    1:  using Microsoft.Web.Administration;
    2:   
    3:  public override bool OnStart()
    4:  {
    5:      using (ServerManager serverManager = new ServerManager())
    6:      {
    7:          Configuration config = serverManager.GetApplicationHostConfiguration();
    8:          ConfigurationSection applicationPoolsSection = 
                          config.GetSection("system.applicationHost/applicationPools");
    9:   
   10:          foreach (var ap in applicationPoolsSection.GetCollection()){
   11:              string apname = ap.GetAttributeValue("name").ToString();
   12:              if (apname == "DefaultAppPool" ||
   13:                  apname == "Classic .NET AppPool" ||
   14:                  apname == "ASP.NET v4.0" ||
   15:                  apname == "ASP.NET v4.0 Classic")
   16:              {/* 何もしない */}else{
   17:                  ap.SetAttributeValue("startMode", "AlwaysRunning");
   18:                  serverManager.CommitChanges();
   19:              }
   20:          }
   21:      }
   22:      return base.OnStart();
   23:  }

プロジェクトをビルドし Windows Azure のホスティングサービスへ発行します。

リモートデスクトップでこの Web ロールへ接続し applicationHost.config ファイルを確認すると、OnStart() メソッドの結果が反映されていることがわかります。

    1:  <applicationPools>
    2:      <add name="….. />
    3:      <add name="(Web ロールのアプリケーションプール)" startMode="AlwaysRunning" />
    4:  </applicationPools>

Windows Azure SDK 1.3 では、興味深い機能がほかにもあります。管理者権限への昇格をうまく活用することで、自由な拡張性を手に入れつつ、管理からの解放の両立が実現できそうですね。

[参考]

Service Definition Schema : https://msdn.microsoft.com/en-us/library/ee758711.aspx

ASP.NET 4 および Visual Web Developer の新機能 : https://msdn.microsoft.com/ja-jp/library/s57a598e.aspx