Uncategorized

ARM template で Azure Web App を Setup する (PaaS の Extension)

こんにちは。

今回は、Msdeploy を理解して、ARM による Azure WebApp 配置のさまざまな応用例を理解します。

以前投稿した「Azure Resource Manager の template の How-to」では、IaaS の話を中心に、Extension を使って Azure VM (Windows と Linux 双方) の実践的な Setup を紹介しました。今回は、同じことを PaaS である Azure Web App (Azure App Services Web App) で実践します。

例えば、Azure Portal で「WordPress using MySQL replication cluster」を配置すると、Virtual Machine (IaaS) を使った MySQL のクラスター構成と、そのデータベースを使った Web App (PaaS) 上の WordPress が配置されます。(データベースのみ IaaS 環境に展開することで、PaaS の利点を享受しながら、利用者は自身の方針でよりスケーラブルなデータベース構成を選択できます。)

ここで紹介する手法を使うと、こうした IaaS と PaaS を組み合わせた template を構築して、企業で利用したり、Azure Marketplace に公開できます。

現実の展開では、アプリの配置やインストール (Setup) をおこなって、データベースとの接続など構成 (Configuration) も必要です。こうした応用的な Setup を msdeploy と Resource manager template を使って記述する方法を紹介します。

Azure WebApp の extension と siteextension

Azure Web App (PaaS) を使用したカスタム セットアップも、IaaS と同様、Extension (IaaS の Extension については「Azure Resource Manager の template の How-to」参照) を使って構成内容を記述できますが、Azure Web App には extension (Microsoft.Web/Sites/Extensions) と siteextension (Microsoft.Web/Sites/siteextensions) の 2 種類の Extension があるので注意してください。(なお、単に config を編集するだけなら、Microsoft.Web/Sites/config リソースが使用できます。)

siteextension は、Azure Portal で [Extensions] を選択して追加できる Site Replicator, phpMyAdmin, Go Lang などの公開済の extension で (Site Extension Gallery 参照)、siteextension を使った ARM template のサンプルは「azure-quickstart-templates / 101-webapp-with-golang」が参考になります。(本投稿では siteextension の解説はしません。)

一方、PHP, Node.js, Java, .NET 等で構築された一般的なカスタム アプリを展開 (構成) する場合は、ここで紹介する extension を使います。

Azure WebApp の Deployment Setup (基本)

extension を使って Custom Setup をおこなうには、Microsoft Web Deployment (以降、msdeploy と記述) を使用します。zip 化された Msdeploy Package を作成し、この Package を extension の引数に指定するだけなので、展開方法の細かな構成は、概ね、msdeploy を使ってカスタマイズすることになります。(WebPI で提供されている WordPress, Drupal 等も内部で msdeploy を使用しています。)

Msdeploy Package の実体は、配布するファイルを含むディレクトリ構造を、決まった仕様に沿って (例えば、配布方法を記述したマニフェスト ファイルを追加するなどして) zip したものです。この仕様に準じたパッケージ化をしていれば作成ツールは問いませんが、Msdeploy Package を作成する最も簡単な方法は、Visual Studio や Visual Studio Team Services (VSTS) を使用することです。(ここで紹介する内容は無償のエディションで充分可能です。)

Azure VM (IaaS) と異なり、Azure Web App 自体が IIS のエンジンで動作していることもあり、IIS に依存した配置方法になりますが、言語 (PHP, Node.js, Java 等) 環境に依存するものではないので、コードの作成は使い慣れた普段のツールでおこなって、配置用のパッケージ作成や自動ビルドの際だけ VS や VSTS と組み合わせても構いません。

まずは、超簡単なサンプルから構築してみましょう。(今回は Visual Studio 2015 を使用します。Visual Studio Community でも OK です。)

Visual Studio で Web の新規プロジェクトを作成します。(HTML/JavaScript による Single Page Application でも、MVC でも、何でも構いません。)

[ビルド] – [発行] メニュー (または、ソリューション エクスプローラーでプロジェクトを右クリックして表示される [公開] メニュー) を選択すると、発行用の Wizard が表示されるので、下図の [カスタム] を選択します。

[発行方法] で [Web Deploy Package] を選択して (下図)、Package 作成先のファイル名を入力すると、Web アプリケーションが zip 化された Msdeploy Package が完成します。

あとは、この zip をインターネット上の公開された場所に置いて、「Azure Resource Manager の template の How-to」で紹介した手順で template (json) に組み込むことで、Azure に配置できます。以下は、この template のサンプルです。(下記の http://ftp.contoso.com/test.zip が作成した Msdeploy Package です。なお、ここで指定している setParameters については、このあと解説します。)

azuredeploy.json

{  "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",  "contentVersion": "1.0.0.0",  "parameters": {  },  "variables": {  },  "resources": [{  "apiVersion": "2015-06-01",  "name": "testplan",  "type": "Microsoft.Web/serverFarms",  "location": "East US",  "properties": {"name": "testplan","sku": {  "name": "F1",  "tier": "Free",  "size": "F1",  "family": "F",  "capacity": 0},"workerSize": "0","hostingEnvironment": "","numberOfWorkers": 1  }},{  "apiVersion": "2015-06-01",  "name": "tsmatsuzsite",  "type": "Microsoft.Web/Sites",  "location": "East US",  "dependsOn": ["Microsoft.Web/serverFarms/testplan"  ],  "properties": {"name": "tsmatsuzsite","serverFarmId": "[resourceId('Microsoft.Web/serverFarms', 'testplan')]","hostingEnvironment": ""  },  "resources": [{  "apiVersion": "2015-06-01",  "name": "MSDeploy",  "type": "Extensions",  "dependsOn": ["Microsoft.Web/Sites/tsmatsuzsite"  ],  "properties": {"packageUri": "http://ftp.contoso.com/test.zip","setParameters": {  "IIS Web Application Name": "tsmatsuzsite"}  }}  ]}  ],  "outputs": {  }}

なお、上記の extension の name は、必ず「MSDeploy」にしてください。(Web Deployment を使用するためのキーワードです。)

展開が完了し、ブラウザーを使って上記で作成された Azure Web App にアクセスすると、パッケージ化した Web アプリケーションが表示されます。

Parameter 化 – msdeploy 応用編

実際の展開 (配置) ではデータベースの接続文字列などの構成 (Configuration) が必要で、こうした値は、もちろん、固定文字列として埋めておくのではなく、Parameter 化して外部から渡す必要があるでしょう。ここからは、こうした実践的な配置方法をみていきます。(以降は、msdeploy そのもののカスタマイズ方法の解説です。)

なお、残念ながら、ここから先は UI (上述の Visual Studio の Wizard) では不可能ですので、直接 Package を編集したり、msdeploy.exe コマンドを使って設定します。(このコマンドは Visual Studio と共にインストールされます。)

まず、作成された Package ファイル (zip) の中を確認してください。

parameters.xml というファイルが入っていますが、この中に Parameter 化すべき項目が既に定義されています。(下記)

parameters.xml

<parameters>  <parameter name="IIS Web Application Name" defaultValue="MyTest" tags="IisApp"><parameterEntry kind="ProviderPath" scope="IisApp" match="^C:\Demo\WebApplication1\WebApplication1\obj\Release\Package\PackageTmp$" /><parameterEntry kind="ProviderPath" scope="setAcl" match="^C:\Demo\WebApplication1\WebApplication1\obj\Release\Package\PackageTmp$" />  </parameter></parameters>

アプリケーション名 (IisApp)、配置されるファイルに対するアクセス権設定 (setAcl) など、配置で必要となる一般的な設定内容は、上記の ProviderPath という種類の Parameter で定義できます。(上記の「IIS Web Application Name」が、これに相当します。)

補足 : 使用する Provider は、通常、マニフェスト (manifest.xml) で定義されています。(ただし、今回の場合は、上図の archive.xml に記述されます。これについては後述します。) msdeploy で使用可能な Provider は「TechNet : Web Deploy Providers」を参照してください。

補足 : 上記の tags はデータの種類を表現しており、データの種類によって Web Deployment の UI による入力補助が表示されます。このため、今回は無視して結構です。(以降も、tags は空のまま記述します。)

この定義された Parameter (今回の場合、上記の「IIS Web Application Name」という名前の Parameter) に値を渡しているのが、上述の azuredeploy.json (ARM template) で記述している setParameters です。今回は「tsmatsuzsite」という固定のサイト名を設定していますが、通常、配置をおこなうユーザーに Resource manager template の parameter を使ってサイト名を入力してもらい、この入力された名前を設定するなどして構成できます。(ARM template の parameter については「Azure Resource Manager の template の How-to」を参照してください。)

テキスト ファイルの置換をおこなうには、msdeploy の TextFile Paramter を使用します。例えば、配置する下記の PHP ファイル (test.php) の定数に Azure Resource Manager (ARM) から値を設定してみましょう。

test.php

<?phpconst USERNAME = 'PARAMVALUE1';const PASSWORD = 'PARAMVALUE2';?>

この場合、zip 内の parameters.xml を下記の通り変更 (追記) します。

parameters.xml

<parameters>  <parameter name="IIS Web Application Name" defaultValue="MyTest" tags="IisApp"><parameterEntry kind="ProviderPath" scope="IisApp" match="^C:\Demo\WebApplication1\WebApplication1\obj\Release\Package\PackageTmp$" /><parameterEntry kind="ProviderPath" scope="setAcl" match="^C:\Demo\WebApplication1\WebApplication1\obj\Release\Package\PackageTmp$" />  </parameter>  <parameter name="App User Name" defaultValue="testuser" tags=""><parameterEntry type="TextFile" scope="\test.php$" match="PARAMVALUE1" />  </parameter>  <parameter name="App User Password" defaultValue="password" tags=""><parameterEntry type="TextFile" scope="\test.php$" match="PARAMVALUE2" />  </parameter></parameters>

上記の Parameter (App User Name, App User Password) に値を渡すため、azuredeploy.json には下記の通り追記します。

azuredeploy.json

{  . . .  "resources": [. . .{  "apiVersion": "2015-06-01",  "name": "tsmatsuzsite",  "type": "Microsoft.Web/Sites",  "location": "East US",  "dependsOn": ["Microsoft.Web/serverFarms/testplan"  ],  "properties": {"name": "tsmatsuzsite","serverFarmId": "[resourceId('Microsoft.Web/serverFarms', 'testplan')]","hostingEnvironment": ""  },  "resources": [{  "apiVersion": "2015-06-01",  "name": "MSDeploy",  "type": "Extensions",  "dependsOn": ["Microsoft.Web/Sites/tsmatsuzsite"  ],  "properties": {"packageUri": "http://ftp.contoso.com/test.zip","setParameters": {  "IIS Web Application Name": "tsmatsuzsite",  "App User Name": "demouser",  "App User Password": "P@ssw0rd"}  }}  ]}  ],  . . . }

上記の Resource manager template (azuredeploy.json) を展開すると、展開後の test.php は下記の通り変更されます。

展開後の test.php

<?phpconst USERNAME = 'demouser';const PASSWORD = 'P@ssw0rd';?>

なお、Web.config などの XML を変更する際は、msdeploy の XmlFile Parameter を使うことで XPath を使って特定のノードの値を変更可能です。例えば、下記のような Web.config の内容を書き換えるには、以下のような parameters.xml, azuredeploy.json を使って展開します。

Web.config

<configuration>  <appSettings><add key="appUserName" value="testuser" /><add key="appUserPassword" value="password" />  </appSettings>  . . .</configuration>

parameters.xml

<parameters>  <parameter name="IIS Web Application Name" defaultValue="MyTest" tags="IisApp"><parameterEntry kind="ProviderPath" scope="IisApp" match="^C:\Demo\WebApplication1\WebApplication1\obj\Release\Package\PackageTmp$" /><parameterEntry kind="ProviderPath" scope="setAcl" match="^C:\Demo\WebApplication1\WebApplication1\obj\Release\Package\PackageTmp$" />  </parameter>  <parameter name="App User Name" defaultValue="" tags=""><parameterEntry type="XmlFile" scope="\web.config$" match="//appSettings/add[@key='appUserName']/@value" />  </parameter>  <parameter name="App User Password" defaultValue="" tags=""><parameterEntry type="XmlFile" scope="\web.config$" match="//appSettings/add[@key='appUserPassword']/@value" />  </parameter></parameters>

azuredeploy.json

{  . . .  "resources": [. . .{  "apiVersion": "2015-06-01",  "name": "tsmatsuzsite",  "type": "Microsoft.Web/Sites",  "location": "East US",  "dependsOn": ["Microsoft.Web/serverFarms/testplan"  ],  "properties": {"name": "tsmatsuzsite","serverFarmId": "[resourceId('Microsoft.Web/serverFarms', 'testplan')]","hostingEnvironment": ""  },  "resources": [{  "apiVersion": "2015-06-01",  "name": "MSDeploy",  "type": "Extensions",  "dependsOn": ["Microsoft.Web/Sites/tsmatsuzsite"  ],  "properties": {"packageUri": "http://ftp.contoso.com/test.zip","setParameters": {  "IIS Web Application Name": "tsmatsuzsite",  "App User Name": "demouser",  "App User Password": "P@ssw0rd"}  }}  ]}  ],  . . . }

例えば、下記 (DB User, DB Password) の通り parameterEntry を使用せず Parameter の受け入れだけをおこない、この値を他の Parameter (DB Connection String) の初期値として設定することもできます。いろいろと応用的な構成が可能です。

parameters.xml

<parameters>  <parameter name="IIS Web Application Name" defaultValue="MyTest" tags="IisApp"><parameterEntry kind="ProviderPath" scope="IisApp" match="^C:\Demo\WebApplication1\WebApplication1\obj\Release\Package\PackageTmp$" /><parameterEntry kind="ProviderPath" scope="setAcl" match="^C:\Demo\WebApplication1\WebApplication1\obj\Release\Package\PackageTmp$" />  </parameter>  <parameter name="DB User" defaultValue="sa" tags="">  </parameter>  <parameter name="DB Password" defaultValue="sa" tags="">  </parameter>  <parameter name="DB Connection String"defaultValue="server=testserver;database=master;user id={DB User};password={DB Password}"tags=""><parameterEntry type="XmlFile" scope="\web.config$" match="//connectionStrings/add[@name='myDb']/@connectionString" />  </parameter></parameters>

Database の展開 – msdeploy 応用編

データベースの配置も伴う場合は、DB ユーザーの登録やテーブル追加など、通常、データベースのセットアップも必要になります。このような場合、SQL Server (または Azure SQL Database) であれば、上述した ProviderPath Parameter を使用できます。(「TechNet : Web Deploy Providers」に記載している DbFullSQL Provider を使用します。)

補足 : MySQL の場合、dbFullMySql という Custom Provider も使用できます。また、msdeploy を使用せず、ARM template の CustomScriptExtension (Windows コマンド)、CustomScriptForLinux (sh) の extension を使ってデータベースの provisioning をおこなっても構いません。(CustomScriptExtension、CustomScriptForLinux については、「Azure Resource Manager の template の How-to」を参照してください。)

配置先のファイル一覧を見ると、Msdeploy Package (下記の test.zip) 以外に SourceManifest.xml (下記の test.SourceManifest.xml) があります。

これは、msdeploy.exe (Visual Studio) が Package を作成する際に一時的に作成した msdeploy の Manifest File と呼ばれるもので、ここに、下記太字の通り、展開時に実行したい DB Script (SQL ファイル) を追加して再パッケージ化することで、SQL ファイルがパッケージに取り込まれ、配置の際に実行されます。(作成された zip ファイルを展開して、SQL ファイルが挿入されていることと、archive.xml が変更されていることを確認してください。)

SourceManifest.xml

<?xml version="1.0" encoding="utf-8"?><sitemanifest>  <IisApp path="C:\DemoWebApplication1\WebApplication1\obj\Release\Package\PackageTmp" managedRuntimeVersion="v4.0" />  <setAcl path="C:\DemoWebApplication1\WebApplication1\obj\Release\Package\PackageTmp" setAclResourceType="Directory" />  <setAcl path="C:\DemoWebApplication1\WebApplication1\obj\Release\Package\PackageTmp" setAclUser="anonymousAuthenticationUser" setAclResourceType="Directory" />  <dbfullsql path="C:\test\install.sql" transacted="false" /></sitemanifest>
msdeploy.exe -verb:sync -source:manifest=c:\test\test.SourceManifest.xml -dest:package=c:\test\test.zip

補足 : このコマンド (verb:sync) により、パッケージの再作成ではなく、変更箇所のみ同期されます。

parameters.xml には下記の通り接続文字列を設定します。

parameters.xml

<parameters>  <parameter name="IIS Web Application Name" defaultValue="MyTest" tags="IisApp"><parameterEntry kind="ProviderPath" scope="IisApp" match="^C:\Demo\WebApplication1\WebApplication1\obj\Release\Package\PackageTmp$" /><parameterEntry kind="ProviderPath" scope="setAcl" match="^C:\Demo\WebApplication1\WebApplication1\obj\Release\Package\PackageTmp$" />  </parameter>  <parameter name="DB Server" defaultValue="server" tags="">  </parameter>  <parameter name="DB User" defaultValue="sa" tags="">  </parameter>  <parameter name="DB Password" defaultValue="sa" tags="">  </parameter>  <parameter name="Connection String"defaultValue="Server={DB Server};Database=master;uid={DB User};Pwd={DB Password};"tags=""><parameterEntry type="ProviderPath" scope="dbfullsql" match="install.sql" />  </parameter></parameters>

このパッケージ (zip) に取り込まれた SQL ファイルも、上述の方法で Parameter を使って置換できるので (上述の TextFile を使います)、ARM template を使って必要な情報をユーザーに入力 (または設定) させて、この情報を使ってデータベース ユーザーやパスワードなどを動的に設定できます。

補足 : 今回は template の紹介はしませんが、実際には、Resource manager template で Database (SQL Database 含む) も配置して、配置先の接続文字列を設定すると良いでしょう。

 

※ (ISV 企業の皆さま) ソリューションを、是非、Azure Marketplace へご登録ください !

https://azure.microsoft.com/ja-jp/documentation/articles/marketplace-publishing-getting-started/

Categories: Uncategorized

Tagged as:

Leave a Reply