Windows Azure で、対象ホスト毎にVMサイズを変更する方法

だいぶ間が空きましたが、Windows AzureでSSL接続を行うためには - しがないプログラマ の日記 のさらに続きです。

今回は、Production環境ではVMサイズが SだけどDevelopment環境ではVMサイズを XSにしたい場合の設定方法を書いて行きたいと思います。
しかし、インスタンス数はVisualStudioから各環境別に設定可能ですが、VMサイズは全体としてしか設定できません。もちろん、管理ポータルからもインスタンス数は「構成」から変更可能ですが、VMサイズはデプロイ時にしか変更できません。そのため、VMサイズの変更は「ServiceDefinition.csdef」ファイルをビルド時に書き換えるという、強引な手段で解決することにしました。
結論から言いますと、Azureプロジェクトのプロジェクトファイル(拡張子が ccproj)に、以下のTargetを追加することで構成ファイルを変更できます。

  
    
  

この例ですと、ビルドターゲットが「Release-XSmall」だった場合に、VMサイズの項目をExtraSmallに書き換えています。注意点としては、デフォルトではvmsizeが記述されていないため、うまく動きませんので明示的にVMサイズを設定する必要があります。VisualStudioのプロパティでVMサイズを何か変更してからSmallに戻せばOKです。

これで何をしているのかの解説は以下で。

Azureの構成情報は、ServiceDefinition.csdefとServiceConfiguration.*.cscfgにそれぞれ記述されます。ServiceConfigurationは、各環境別に設定できる情報が記述されていて、VisualStudioからそれぞれの環境ごとに編集が可能です。しかし、ServiceDefinitionはプロジェクトに1つしかないため、ここの記述は全環境に影響してしまいます。そのため、VMサイズの設定やホスト名でのendpointの切り替え等が環境別に設定できませんでした。
しかし、AzureのBuildプロセス中で「ServiceDefinition.csdef」を「ServiceDefinition.build.csdef」にコピーされそちらのファイルが使われるのが判明しました。それならば、ServiceDefinition.build.csdefがコピーされた直後にこのファイルを書き換えてしまえば、その設定が有効になるはず、と試した所うまく行ったわけです。
このコピーが動くタスク名が「CopyServiceModel」だったので、MSBuildのAfterTargets機能を使いタスクの終了をフックしTargetを起動させます。後は、ServiceDefinition.build.csdefを適当に書き換えれば良いだけなので、例のようにFileUpdateタスクを使うのも良し、その他の手段で書き換えるなり、ファイル自体を差し替えるなり、やりたい放題ですね。ポイントとしては、ConfigurationにAzureプロジェクトの構成名が設定されるので、デフォルトから変更しない環境に対してはそれが判断可能な構成名を付けておくと良いです。後は、MSBuildの使い方を調べて下さい。
自分は、ホスト名制限をするために Bindingの設定に「hostHeader」プロパティを追加する処理もしています。