Azure Cloud Services の Web Role を使って IIS の設定を変更してみたかったので、田口社長のブログを検索して、その中の 1 つを参考にしつつ試しました。
http://blogs.gine.jp/taka/archives/2846
さすが安心と信頼の田口社長、クラウドサービスは全て田口社長で安心。と思っていたら田口社長は海外出張中なので、半泣きになりながら自分で調べました。
ちなみに題材としては前に書いた IIS 8.5 のカスタムログの設定を自動化してみます。
必要な設定は URL Rewrite の allowedServerVariables への追加と、ログにサーバー変数を書きだす設定の追加となります。簡単そうに見えますね。
Startup Task として書く方法と RoleEntryPoint の OnStart で書く方法があるみたいですが、IIS の設定を変える場合には OnStart で実行した方が良いみたいでした。
スタートアップ処理のスタートアップ タスク段階では IIS が完全に構成されていない可能性があります。そのため、ロール固有のデータが使用できない場合があります。ロール固有のデータが必要なスタートアップ タスクは Microsoft.WindowsAzure.ServiceRuntime.RoleEntryPoint.OnStart を使用してください。
https://msdn.microsoft.com/ja-jp/library/azure/hh180155.aspx
なので RoleEntryPoint を使うことにしました。
Microsoft.Web.Administration.dll を参照に追加
IIS の設定を弄るのに必要な Microsoft.Web.Administration.dll は IIS がインストールされているディレクトリと同じ場所にあります。*1
注意点としては IIS のバージョンと Microsoft.Web.Administration.dll のバージョンは対応しているみたいなので、このあたりだけ注意したいところです。
更にローカルマシンの IIS によって古いバージョンだったり、HintPath の都合で GAC を参照したりするみたいなので、プロジェクトにコピーしておくのが無難かもしれません。
RoleEntryPoint を追加する
IIS の設定を弄るためには権限を与えておかないといけないので、ServiceDefinition.csdef に以下のような設定を追加しておきます。
<Runtime executionContext="elevated"></Runtime>
これで RoleEntryPoint の OnStart で IIS の設定を弄れるようになります。
実際に書いた WebRole のコードは以下のような感じです。
public class WebRole : RoleEntryPoint { public override bool OnStart() { using (var serverManager = new ServerManager()) { // CustomLogFields var site = serverManager.Sites[RoleEnvironment.CurrentRoleInstance.Id + "_Web"]; site.LogFile.CustomLogFields.Clear(); site.LogFile.CustomLogFields.Add("SESSION_VALUE", "SESSION_VALUE", CustomLogFieldSourceType.ServerVariable); // allowedServerVariables var config = serverManager.GetApplicationHostConfiguration(); var allowedServerVariablesSection = config.GetSection("system.webServer/rewrite/allowedServerVariables"); var allowedServerVariablesCollection = allowedServerVariablesSection.GetCollection(); var addAllowedServerVariablesElement = allowedServerVariablesCollection.CreateElement("add"); addAllowedServerVariablesElement["name"] = @"SESSION_VALUE"; allowedServerVariablesCollection.Clear(); allowedServerVariablesCollection.Add(addAllowedServerVariablesElement); serverManager.CommitChanges(); } return base.OnStart(); } }
注意点としてはインプレース更新の場合、既に反映済みの applicationHost.config に対して処理を行ってしまうので、設定を削除してから追加するようにしました。本来なら該当する項目だけ削除するのが良いんでしょうが、今回はめんどくさいので全部消します。
これでデプロイすると applicationHost.config に設定が追加されていることが確認出来ます。
Azure Web Apps チームがどのように大量の VM を管理しているのか、事例を聞いてみたいです。
*1:つまり C:\Windows\System32\inetsrv とか