こんにちは。
Azure Resource Manager (ARM) の resource template を使って ISV 企業のカスタム ソリューションを展開する際に、「自分達のソリューションは展開できるか」、「どのようなことが可能か」などのご質問をよく受けます。
そこで、ここでは、Azure Resource Manager (ARM) の template を使用したソリューション展開 (配置) の実践的ノウハウのいくつかを解説します。
補足 : 現在、Azure のリソース構成は、Bicep という より簡易な DSL (Domain Specific Language) を使って記述することもできます。(Bicep は、煩雑な Json を生成するプリコンパイラのような役割をします。)
概要
Azure Resource Manager は、Microsoft Azure、Azure Stack で使用可能な Azure 上のリソース (service instance) 管理の基盤で、本稿で紹介するように、JSON ベースの Template-driven な展開 (宣言的な記述と展開) を提供します。後述の通り、複雑な構成も template を使って 1 つのまとまった resource group として展開と削除が可能です。
本投稿では template 作成のノウハウにフォーカスして掲載します。
template 作成の基礎 (ツール)
いきなり template の中身の説明に入る前に、まず準備として template 作成と展開の方法と利用可能なツールを紹介します。
基本的に、作成する template は UTF-8 の json ファイルなので、テキスト編集が可能なエディタであればツールは不要です。(ただし「メモ帳」は、BOM の関係で使用しないほうが良いかもしれません。)
しかし、Visual Studio や Visual Studio Code をお使いの場合、ツールの補助を受けながら、より生産性高く作成できます。
例えば、Visual Studio の場合は、下図のようにプロジェクト テンプレートの [Cloud] – [Azure リソース グループ] (Azure Resource Group) から作成できます。(あらかじめ、最新の Azure SDK をインストールしてください。)
このツールを使うと、template の Json ファイルは、下図左のような Visual な UI (Json Outline Tool Window) を使って resource (VM, VNet, Storage, DB 等々) の追加が可能なので、ある程度のひな形であれば、要素を手書きで編集せずに作成できます。(細かな編集は Json を直接編集しますが、その場合も Intellisense が補助してくれます。)
作成後は、Visual Studio から [New Deployment] (新しい配置) を選択して Azure 上に直接配置できます。(template の展開方法については次の節で詳述します。)
ARM template は Idempotent な性質も持っていますので、展開に失敗した場合などには、再展開により続きから展開をおこなうこともできます。(ただし、変更内容によっては、最初から作り直しが必要な場合もあるので注意してください。)
作成した json フォーマットの template を展開 (配置) すると、各 resource は Resource Group と呼ばれる単一の入れ物に入りますので (各 resource は、必ず、ただ 1 つの resource group に所属します)、また 1 からやりなおしたい場合には、この Resource Group を削除すればすべて元に戻ります。
Visual Studio Code も同様に、こうした Authoring の補助をツールがサポートします。
以降では順番に template の記述方法を解説しますが、Azure Resource Explorer という UI を使用すると、既存の作成済の構成から resource 定義の確認も可能です。
また下記の GitHub リポジトリには、豊富なサンプルも提供されていますので、再利用していただけます。(より応用的な構成が見たくなったら、是非これらを活用してください。)
Github – azure quickstart templates
https://github.com/Azure/azure-quickstart-templates
template 展開の複数の方法
上記では Visual Studio (または Visual Studio Code) から直接 template を展開しましたが、実運用では毎回 Visual Studio を使うわけにはいきません。
template を顧客や運用担当者に渡して使ってもらう場合、下記の方法で展開できます。
1. コマンドを使った展開
Azure PowerShell Command や Azure CLI を使って作成した template を展開 (配置) できます。
例えば、PowerShell を使って template を配置する場合は下記の通りです。コマンドラインから実行する場合は、入力パラメーター (後述の通り、template に parameter を渡すことができます) もあらかじめ指定するケースが多いと思いますが、そのような場合は、下記の通り parameter file を別で用意して指定できます。
補足 : 上述の Visual Studio のプロジェクトは、内部で、この PowerShell の Script を使って展開しています。
New-AzureResourceGroup -Name MyResourceGroup -Location "West US" -TemplateFile mytemplate.json -TemplateParameterFile myparam.json -Force -Verbose
Azure CLI を使った場合は下記の通りです。(Mac OS, Linux でも実行可能)
az group create "MyResourceGroup" "West US" -f mytemplate.json -d "myTest" -e myparam.json
2. SDK からの展開
カスタム アプリケーションなどに配置 (展開) 処理を組み込む場合は、例えば .NET library など、Azure のライブラリを使うことも可能です。(詳細は省略します。)
3. Azure Portal の Template Deployment からの展開
また、Azure Portal (UI) から配置する場合は、[New] – [Web + Mobile] – [Template Deployment] を使用して、Json フォーマットの構成情報を展開できます。(画面上に、作成した Json のテキストを貼り付けます。)
4. URL からの展開実行
また、Azure の利用者に展開を試してもらいたい場合には、下記の URL にアクセスすることで、下図の通り Azure Portal を使ったビジュアルな template 展開が開始されます。(開始前に Azure へのログインを要求されます。)
Azure Marketplace に提出しなくても、この方法を使って一般企業向けにソリューションを提供 (配布) できます。
補足 : 前述の Github の azure quickstart templates は、この方法を使って、Github (Wiki) 上のボタンをクリックすることで配置できるようになっています。
https://portal.azure.com/#create/Microsoft.Template/uri/{location url of json}
template の歩き方 (基本から応用まで)
では、本題に入ります。
ARM template はどう記述するのでしょう ? また、どこまで可能でしょうか ?
1. 基本構文
まず、resource template の基本的な構成ですが、下記の通り、4 つの要素で構成されています。
{ "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", "parameters": { ... }, "variables": { ... }, "resources": [ ... ], "outputs": { ... }}
上記の resources が本体となる記述部分で、ここに、Azure Virtual Machine (仮想マシン)、Azure Web App (Web アプリ)、Azure Storage、Azure SQL Database、Azure Redis Cache 等々の配置する resource 情報を定義します。(前述の通り、今後、Azure Machine Learning など他の resource も順次 対応予定です。)
例えば、Virtual Network を配置する場合には、下記のように記述します。
下記の通り、各 resource ごとに location (region) を個別に指定できるので、Disaster Recovery (災害対策) 構成のように、異なる location を単一の resource group に配置することも可能です。
{ "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", "parameters": { }, "variables": { }, "resources": [ { "name": "testvnet01", "type": "Microsoft.Network/virtualNetworks", "location": "West US", "apiVersion": "2017-04-01", "properties": {"addressSpace": { "addressPrefixes": [ "10.0.0.0/16" ]},"subnets": [ { "name": "testsubnet01", "properties": { "addressPrefix": "10.0.0.0/24" } }] } } ], "outputs": { }}
同様に、Azure Storage Account を作成する場合は以下になります。
{ "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", "parameters": { }, "variables": { }, "resources": [...,{ "name": "tsmatsuzteststorage01", "type": "Microsoft.Storage/storageAccounts", "location": "West US", "apiVersion": "2016-01-01", "properties": {"accountType": "Standard_GRS" }} ], "outputs": { }}
2. Parameter の受け取り
配置をおこなう template の利用者が値を設定できるようにするには、上記の parameters を指定します。
例えば、上記で作成した Virtual Network や Storage で、Location を利用者に選択させて配置したい場合、下記の通り記述します。
補足 : Location を指定する際は、下記の通り指定して、ユーザーがリソースグループに指定した location と同じ location にリソースを作成すると良いでしょう。ここでは、あくまでも例として parameter を使用しています。
"location": "[resourceGroup().location]"
{ "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", "parameters": {"test01loc": { "type": "string", "defaultValue": "West US", "allowedValues": ["East US","West US","West Europe","East Asia" ]} }, "variables": { }, "resources": [{ "name": "testvnet01", "type": "Microsoft.Network/virtualNetworks", "location": "[parameters('test01loc')]", "apiVersion": "2017-04-01", "properties": {"addressSpace": { "addressPrefixes": ["10.0.0.0/16" ]},"subnets": [ {"name": "testsubnet01","properties": { "addressPrefix": "10.0.0.0/24"} }] }},... ], "outputs": { }}
この template を上述の URI を使った方法 (Azure Portal のウィザードを使用する方法) で展開した場合、下図の通り、parameter の入力が UI で促されます。(なお、Windows PowerShell や Azure CLI を使った場合は、上述の通り parameter file を作成して指定できます。)
ここでは parameter を使って展開先の Location を入力させていますが、ISV のソフトウェア利用のためのライセンスコードを入力させるなど、さまざまな目的で使用できます。
3. リソースどうしの依存関係
上記の Virtual Network に接続する Virtual Machine を作成するには、下記の通り記述します。なお、作成している Virtual Machine は v2 (resource manager based) で、下記の通り NIC の resource も必要です。つまり、Virtual Network を使用して NIC を定義し、NIC を使用して Virtual Machine を定義します。
「作成の順序によっては失敗するのではないか」と気になるかもしれませんが、こうした点を解決するために、下記の通り dependsOn に依存関係を記述します。
複数の resource を依存させる場合は、作成後の resource id が必要になることがあります。例えば、Virtual Machine を Virtual Network (の Subnet) に接続するために Virtual Network の resource id が必要ですが、下記の通り resourceId 関数を使って作成後の id を指定できます。
{ "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", "parameters": { }, "variables": { }, "resources": [{ "name": "testvnet01", "type": "Microsoft.Network/virtualNetworks", "location": "West US", "apiVersion": "2017-04-01", "properties": {"addressSpace": { "addressPrefixes": ["10.0.0.0/16" ]},"subnets": [ {"name": "testsubnet01","properties": { "addressPrefix": "10.0.0.0/24"} }] }},{ "name": "testnic01", "type": "Microsoft.Network/networkInterfaces", "location": "West US", "apiVersion": "2017-04-01", "dependsOn": ["Microsoft.Network/virtualNetworks/testvnet01" ], "properties": {"ipConfigurations": [ {"name": "ipconfig01","properties": { "privateIPAllocationMethod": "Dynamic", "subnet": {"id": "[concat(resourceId('Microsoft.Network/virtualNetworks', 'testvnet01'), '/subnets/testsubnet01')]" }} }] }},{ "name": "testwin01", "type": "Microsoft.Compute/virtualMachines", "location": "West US", "apiVersion": "2017-03-30", "dependsOn": ["Microsoft.Network/networkInterfaces/testnic01" ], "properties": {"hardwareProfile": { "vmSize": "Basic_A1"},"osProfile": { "computername": "mycomputer01", "adminUsername": "demouser", "adminPassword": "P@ssw0rd01"},"storageProfile": { "imageReference": {"publisher": "MicrosoftWindowsServer","offer": "WindowsServer","sku": "2012-R2-Datacenter","version": "latest" }, "osDisk": {"createOption": "FromImage" }, "dataDisks": [{ "diskSizeGB": 250, "lun": 0, "createOption": "Empty"} ]},"networkProfile": { "networkInterfaces": [{ "id": "[resourceId('Microsoft.Network/networkInterfaces', 'testnic01')]"} ]} }} ], "outputs": { }}
上記で Virtual Machine や Virtual Network は構成されましたが、この構成では外界 (internet) との接続ポイントがないため、 RDP (Windows の場合) や SSH (Linux の場合) を使った接続は不可能です。
この問題を解決するには、さらに Public IP の resource を作成して、下記の通り関連付けます。このように構成すると、割り当てられた IP アドレスや、下記の domainNameLabel を使って、既定で {domainNameLabel}.{location}.cloudapp.azure.com (よって今回の場合は endpointtest01.westus.cloudapp.azure.com) のマシン名 (FQDN) で外からアクセスできます。
{ "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", "parameters": { }, "variables": { }, "resources": [...{ "apiVersion": "2017-04-01", "type": "Microsoft.Network/publicIPAddresses", "name": "testip01", "location": "West US", "properties": {"publicIPAllocationMethod": "Dynamic","dnsSettings": { "domainNameLabel": "endpointtest01"} }},...{ "name": "testnic01", "type": "Microsoft.Network/networkInterfaces", ... "dependsOn": ["Microsoft.Network/virtualNetworks/testvnet01","Microsoft.Network/publicIPAddresses/testip01" ], ... "properties": {"ipConfigurations": [ {"name": "ipconfig01","properties": { ... "publicIPAddress": {"id": "[resourceId('Microsoft.Network/publicIPAddresses', 'testip01')]" }} }] }},...
この他に、複数台構成の場合には、Load Balancer (Microsoft.Network/loadBalancers) や Availability Set (Microsoft.Compute/availabilitySets) などの resource も必要になるので、随時、追加してください。(2016/01 追記 : これらの構成方法については「Azure (ARM) の Load Balancer, Auto-Scaling の構成」に記載しました。)
つまり、現実の resource template の記述は、そこそこ複雑になってきますので、ここで紹介している基礎を抑えながら眺めておいてください。
2018/09 追記 : 新しい Azure Deployment Manager を使って Step Group を記述できるようになりました。(詳細は「Azure team blog : Azure Deployment Manager now in public preview」の発表を参照)
4. Custom Image の使用
では、ISV 企業が、自社のソフトウェアなどをプレインストールされた形で展開したい場合はどのようにすれば良いでしょう ?
まず、上記構成の imageReference を見てください。(上記のサンプルでは、Windows Server 2012 R2 Datacenter Edition をインストールしています。)
Virtual Machine の展開の際、このように Azure Marketplace に登録されているイメージを指定できるため、この方法で、例えば、SharePoint のインストールされた Windows イメージ、SQL Server のインストールされた Windows イメージ、Puppet (Master) のインストールされた Linux イメージなどを展開できます。
VM や ARM template を Azure Marketplace に登録 (発行) したい ISV 企業の方は「Azure Marketplace にプランを発行して管理する」を参照してください。
補足 : 利用可能な Image Publisher, Offer, Sku は PowerShell で確認できます。下記は、利用可能な Image Publisher を取得します。
Get-AzureRmVMImagePublisher -Location eastus | Where-Object { $_.PublisherName -match "oracle" }
下記は、取得した Image Publisher から、利用可能な Offer を取得します。Get-AzureRmVMImageOffer -Location eastus -PublisherName Oracle
下記は、取得した Image Publisher と Offer から Sku を取得します。Get-AzureRmVMImageSku -Location eastus -PublisherName Oracle -Offer Oracle-Linux-7
補足 : Microsoft 以外の 3rd party が提供する Image (Certified の Image) を展開する場合には、いくつかの注意点があります。この留意事項については「ARM template で Azure Marketplace の 3rd party image を展開する」にまとめましたので参照してください。(2016/02 追記)
また、独自に作成したカスタムの VM Image を元に VM を作成することもできます。下記の通り記述します。(この場合、imageReference は不要なので削除してください。)
下記では、OS Disk のみを Custom Image から作成し、Data Disk は空のものを新規作成しています。(Data Disk を Custom Image から展開することも可能です。)
注意 : Custom の VM Image を使用する場合、元となる .vhd は、スクリプト (PowerShell, Azure CLI) を使ってあらかじめ配置先と同じ (Azure Resource Manager の管理下にある) Storage Account にアップロードする必要があります。
この方法については「Upload the VHD to your storage account」を参照してください。補足 : 既に Azure 上 (同じリソースグループ内) にある Generalize (sysprep) された VM から直接 managed image を作成することもできます。(手順詳細は「Create a managed image of a VM」を参照してください。) この場合、Custom Image 作成は不要 (既に image は Azure 上に作成されています) なので、下記の Microsoft.Compute/images リソース定義は不要です。
また、Azure Service Manager で capture した image (旧 Azure Classic Portal で作成された v1 の image) は展開できません。
...{ "type": "Microsoft.Compute/images", "apiVersion": "2017-03-30", "name": "myImage", "location": "West US", "properties": {"storageProfile": { "osDisk": {"osType": "Windows","osState": "Generalized","blobUri": "http://sourcestorage01.blob.core.windows.net/vhds/originalsource.vhd","storageAccountType": "Standard_LRS" }} }},{ "name": "testwin01", "type": "Microsoft.Compute/virtualMachines", "location": "West US", "apiVersion": "2017-03-30", "dependsOn": ["Microsoft.Network/networkInterfaces/testnic01","Microsoft.Compute/images/myImage" ], "properties": {"hardwareProfile": { "vmSize": "Basic_A1"},"osProfile": { "computername": "mycomputer01", "adminUsername": "demouser", "adminPassword": "P@ssw0rd01"},"storageProfile": { "imageReference": {"id": "[resourceId('Microsoft.Compute/images', 'myImage')]" }, "osDisk": {"createOption": "FromImage" }, "dataDisks": [{ "diskSizeGB": 250, "lun": 0, "createOption": "Empty"} ]},"networkProfile": { "networkInterfaces": [{ "id": "[resourceId('Microsoft.Network/networkInterfaces', 'testnic01')]"} ]} }}...
5. Extension (カスタムのセットアップ)
ほとんどのソフトウェアはインストールするだけでは不充分で、インストール後に必要なセットアップや構成作業などをおこなう必要があります。
こうしたセットアップは、CustomScriptForLinux (sh コマンド)、CustomScriptExtension (Windows コマンド)、DSC (Windows の PowerShell Desired State Configuration) といった Azure Virtual Machine の extension resource が使用できます。実は、この方法で、ネットワーク インストールから構成までのすべてをセットアップする方法もアリです。
補足 : アプリケーションの構成に VM Applications を使うことも可能です。VM Applications を使うと、アプリケーションの定義を VM image とわけてパッケージ化して再利用できます。例えば、Apache Tomcat version 8.5 用のアプリケーション定義を VM Applications として保存しておき、これを virtual machine や virtual machine scale sets の展開時に指定できます。
補足 : また、Windows におけるバイナリ コマンドの配置と実行や、Ubuntu、CoreOS における cloud-init による構成の際には、
customData
を使うこともできます。
詳細は「Custom data and Cloud-Init on Azure Virtual Machines」を参照してください。
例えば、OS の設定変更、SQL の実行 (データベースの provisioning) など、簡単なスクリプトを実行したいだけなら下記の通り記述できます。前者は Windows、後者は Linux です。
inline コマンドの記述だけでなく、下記の通り、スクリプト ファイル (.ps1, .sh) を準備して実行し、parameter はコマンドの引数として渡すことができます。(例えば、配置したデータベースと Web サーバー間の接続を構成するケースなど、現実の構成では、こうした parameter の受け渡しは必要不可欠です。)
Windows の場合
. . .{ "type": "Microsoft.Compute/virtualMachines/extensions", "name": "testwin01/somesetup01", "apiVersion": "2017-03-30", "location": "West US", "dependsOn": ["[resourceId('Microsoft.Compute/virtualMachines', 'testwin01')]" ], "properties": {"publisher": "Microsoft.Compute","type": "CustomScriptExtension","typeHandlerVersion": "1.4","settings": { "fileUris": ["http://tsmatsuz-demo01.azurewebsites.net/somesetup.ps1" ], "commandToExecute": "[concat('powershell -ExecutionPolicy Unrestricted -file somesetup.ps1 -paramTest ', parameters('testdata01'))]"} }}. . .
Linux の場合
. . .{ "type": "Microsoft.Compute/virtualMachines/extensions", "name": "testubuntu01/somesetup01", "apiVersion": "2017-03-30", "location": "West US", "dependsOn": ["[resourceId('Microsoft.Compute/virtualMachines', 'testubuntu01')]" ], "properties": {"publisher": "Microsoft.OSTCExtensions", "type": "CustomScriptForLinux", "typeHandlerVersion": "1.2", "settings": { "fileUris": ["http://tsmatsuz-demo01.azurewebsites.net/somesetup.sh" ], "commandToExecute": "[concat('sh somesetup.sh ', parameters('testdata01'))]"} } } . . .
また、依存関係のある複数コンポーネント (ソフトウェア) のインストールや構成など、複雑なセットアップをおこなう場合は、PowerShell DSC、Puppet、Chef などの構成管理用の extension が使用できます。
補足 : PowerShell DSC は Windows だけでなく Linux でも使用できます (PowerShell DSC for Linux を参照)。
例えば、上記で配置した Windows Server 2012 R2 に、IIS と ASP.NET 4.5 をインストールするには、まず、PowerShell DSC を使って以下のスクリプト ファイル (.ps1 ファイル) を準備し、このファイルを zip 化してインターネット上の見える場所に置いておきます。(作成したアプリを展開する場合、Microsoft Web Deployment (msdeploy) の Package (zip ファイル) の展開も可能です。) なお、今回はサンプルを簡単にする目的で、Built-in Resource (下記の WindowsFeature) のみを使って 単に IIS と ASP.NET 4.5 をインストールしていますが、現実の構成では、例えば、Active Directory インストール後のドメイン昇格 (dcpromo) や、独自の構成設定 (configuration) などが必要になるでしょう。こうした場合、DSC の composite resource や custom resource を作成して、一緒に配置 (および zip 化) します。
つまり、今回は あえて簡単なサンプルにしていますが、通常は (現実の DSC の構成は)、もっと複雑になるので注意してください。
補足 : よく使う DSC resource (例えば、上述の AD の構成など) は、下記に open source として公開されているので活用してください。
https://github.com/PowerShell/DscResources補足 : PowerShell DSC for Linux で使用可能な Built-in resource については「Built-In Desired State Configuration Resources for Linux」を参照してください。
configuration ConfigureAspNet{### Specify parameters like this (This time, not needed)# param# (#[Parameter(Mandatory)]#[String]$MyParam01# )### Specify additional DSC resource (This time, not needed)# Import-DscResource -ModuleName xMyCustomResource01, xMyCustomResource02 Node localhost {### Install IISWindowsFeature IIS{ Name = "Web-Server" Ensure = "Present"}### Install ASP.NET 4.5WindowsFeature AspNet45{ Name = "Web-Asp-Net45" Ensure = "Present"}### When using custom resource#xMyCustomResource01 MySetup01#{# XXX = YYY# . . .#} }}
あとは、この zip ファイル (今回は InstallASPNET.zip と仮定します) を PowerShell DSC extension resource として template に設定します。
Virtual Machine に展開するため、下記の通り Virtual Machine resource に extension resource を記述します。
. . .{ "name": "testwin01", "type": "Microsoft.Compute/virtualMachines", ... "resources": [{ "type": "Microsoft.Compute/virtualMachines/extensions", "name": "testwin01/installaspnet", "apiVersion": "2017-03-30", "location": "West US", "dependsOn": ["[resourceId('Microsoft.Compute/virtualMachines', 'testwin01')]" ], "properties": {"publisher": "Microsoft.Powershell","type": "DSC","typeHandlerVersion": "2.19","settings": { "ModulesUrl": "http://tsmatsuz-demo01.azurewebsites.net/InstallASPNET.zip", "ConfigurationFunction": "InstallASPNET.ps1\ConfigureAspNet", "Properties": { }} }} ]}. . .
下記の通り、DSC の extension に対して parameter を渡すことも可能です。(DSC 側は、上述のコメント アウトの通り記述して、この parameter を受け取ります。)
. . .{ "name": "testwin01", "type": "Microsoft.Compute/virtualMachines", ... "resources": [{ "type": "Microsoft.Compute/virtualMachines/extensions", "name": "testwin01/installaspnet", "apiVersion": "2017-03-30", "location": "West US", "dependsOn": ["[resourceId('Microsoft.Compute/virtualMachines', 'testwin01')]" ], "properties": {"publisher": "Microsoft.Powershell","type": "DSC","typeHandlerVersion": "2.19","settings": { "ModulesUrl": "http://tsmatsuz-demo01.azurewebsites.net/InstallASPNET.zip", "ConfigurationFunction": "InstallASPNET.ps1\ConfigureAspNet", "Properties": {"MyParam01": "test data 01","MyParam02": "test data 02" }} }} ]}. . .
また、例えば、(Linux に対する) Docker container の配置の際には、MSOpenTech の DockerExtension が使用できます。
このように、既存の extension で使えるものも多数あるので、上記のように CustomScript や DSC でカスタムの構成 (セットアップ) を記述する前に、使用可能なイメージ (imageReference) や使える extension があるかどうか確認しておくと良いでしょう。
追記 : ネストされた Source Control リソース (type が sourcecontrols のリソース) を使用することで、Github などソース管理リポジトリからの展開 (発行) が可能になりました。
追記 (2018/05) : 新たに、type が
Microsoft.TerraformOSS
のリソース プロバイダ (Azure Terraform Resource Provider) が提供されました。このプロバイダを使用すると、Microsoft が管理する Terraform を経由して AKS (Kubernetes クラスタ) 上の Pod などの展開が記述できます。(アプリを含んだ Pod のイメージを展開できます。)
他のリソース プロバイダ同様、RBAC や Azure Policy が使用できます。
6. Template の Nest
resource を分けたい場合は template file のネスト (入れ子) も可能です。
例えば、下記は、上述と同様 Virtual Machine のセットアップをおこないますが、ネットワーク関連 (サブネット、IP アドレス、NIC など) の設定を netdeploy.json という子供の Template にわけて設定しています。
下記の通り、親の Template から子の Template に parameter を渡すことも可能ですし、逆に、outputs を使用して子の Template の結果を親の Template に渡すこともできます。下記では、作成された NIC の resourceId を親に渡しています。(作成された NIC のリソースそのものを渡すこともできます。この場合、Json Object として親に渡されます。)
Parent Template (.json)
{ "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", "parameters": { }, "variables": { }, "resources": [{ "name": "netdeploy", "type": "Microsoft.Resources/deployments", "apiVersion": "2016-06-01", "dependsOn": [ ], "properties": {"mode": "Incremental","templateLink": { "uri": "http://testdeploy.com/netdeploy.json", "contentVersion": "1.0.0.0"},"parameters": { "location": {"value": "East US" }} }},. . .{ "name": "testwin", "type": "Microsoft.Compute/virtualMachines", "location": "East US", "apiVersion": "2017-03-30", "dependsOn": ["Microsoft.Resources/deployments/netdeploy",. . . ], "properties": {. . ."networkProfile": { "networkInterfaces": [{ "id": "[reference('netdeploy').outputs.networkInterfaceResourceId.value]"} ]} }} ], "outputs": { }}
Child Template (.json)
{ "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", "parameters": {"location": { "type": "string"} }, "variables": { }, "resources": [{ "name": "testvnet", "type": "Microsoft.Network/virtualNetworks", "location": "[parameters('location')]", "apiVersion": "2017-04-01", "properties": {"addressSpace": { "addressPrefixes": ["10.0.0.0/16" ]},"subnets": [ {"name": "testsubnet","properties": { "addressPrefix": "10.0.0.0/24"} }] }},{ "apiVersion": "2017-04-01", "type": "Microsoft.Network/publicIPAddresses", "name": "testip", "location": "[parameters('location')]", "properties": {"publicIPAllocationMethod": "Dynamic","dnsSettings": { "domainNameLabel": "endpointtest"} }},{ "name": "testnic", "type": "Microsoft.Network/networkInterfaces", "location": "[parameters('location')]", "apiVersion": "2017-04-01", "dependsOn": ["Microsoft.Network/virtualNetworks/testvnet","Microsoft.Network/publicIPAddresses/testip" ], "properties": {"ipConfigurations": [ {"name": "ipconfig","properties": { "privateIPAllocationMethod": "Dynamic", "subnet": {"id": "[concat(resourceId('Microsoft.Network/virtualNetworks', 'testvnet'), '/subnets/testsubnet')]" }, "publicIPAddress": {"id": "[resourceId('Microsoft.Network/publicIPAddresses', 'testip')]" }} }] }} ], "outputs": {"networkInterfaceResourceId" : { "type" : "string", "value" : "[resourceId('Microsoft.Network/networkInterfaces', 'testnic')]"} }}
なお、Azure Resource Manager template では、方針上の理由から if などの条件分岐はできないようになっていますが (宣言的な性質のため。。。)、実は、上記のネストを使うと、例えば、ユーザーの入力結果 (parameter) に応じてネストする template の uri を変えることができるため、事実上の条件分岐が実装可能です。(お行儀の良し悪しは別として。。。)
7. copy / copyIndex による複数展開 (Resource Loop)
また、同じ構成を複数展開したい場合は、上記のネストではなく copy を使う方法もあります。
例えば、下記の通り記述すると、ユーザーが指定した台数の Virtual Machine を展開できます。(それぞれ、testwin0, testwin1, testwin2, … とネーミングしています。)
補足 : 負荷分散などの目的で同じ構成の Virtual Machine を複数台構成する場合は、Virtual Machine Scale Sets (VMSS) を使用すると便利です。VMSS を使うと、スケーラビリティ、構成変更時のパフォーマンス等、多くの恩恵を受けることができます。
Azure ARM template を使用して VMSS を構成する方法については「Azure Virtual Machine Scale Sets (VMSS) の構成方法」に記載しました。
{ "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", "parameters": { }, "variables": { }, "resources": [{ "name": "testvnet", "type": "Microsoft.Network/virtualNetworks", "location": "West US", "apiVersion": "2017-04-01", "properties": {"addressSpace": { "addressPrefixes": ["10.0.0.0/16" ]},"subnets": [ {"name": "testsubnet","properties": { "addressPrefix": "10.0.0.0/24"} }] }},{ "apiVersion": "2017-04-01", "type": "Microsoft.Network/publicIPAddresses", "name": "[concat('testip', copyIndex())]", "location": "West US", "properties": {"publicIPAllocationMethod": "Dynamic","dnsSettings": { "domainNameLabel": "[concat('endpointtest', copyIndex())]"} }, "copy": {"name": "testipcopy","count": 10 }},{ "name": "[concat('testnic', copyIndex())]", "type": "Microsoft.Network/networkInterfaces", "location": "West US", "apiVersion": "2017-04-01", "dependsOn": ["Microsoft.Network/virtualNetworks/testvnet","[concat('Microsoft.Network/publicIPAddresses/testip', copyIndex())]" ], "properties": {"ipConfigurations": [ {"name": "[concat('ipconfig', copyIndex())]","properties": { "privateIPAllocationMethod": "Dynamic", "subnet": {"id": "[concat(resourceId('Microsoft.Network/virtualNetworks', 'testvnet'), '/subnets/testsubnet')]" }, "publicIPAddress": {"id": "[resourceId('Microsoft.Network/publicIPAddresses', concat('testip', copyIndex()))]" }} }] }, "copy": {"name": "testniccopy","count": 10 }},{ "name": "[concat('testwin', copyIndex())]", "type": "Microsoft.Compute/virtualMachines", "location": "West US", "apiVersion": "2017-03-30", "dependsOn": ["[concat('Microsoft.Network/networkInterfaces/testnic', copyIndex())]" ], "properties": {"hardwareProfile": { "vmSize": "Basic_A1"},"osProfile": { "computername": "[concat('mycomputer', copyIndex())]", "adminUsername": "demouser", "adminPassword": "P@ssw0rd01"},"storageProfile": { "imageReference": {"publisher": "MicrosoftWindowsServer","offer": "WindowsServer","sku": "2012-R2-Datacenter","version": "latest" }, "osDisk": {"createOption": "FromImage" }},"networkProfile": { "networkInterfaces": [{ "id": "[resourceId('Microsoft.Network/networkInterfaces', concat('testnic',copyIndex()))]"} ]} }, "copy": {"name": "testwincopy","count": 10 }} ], "outputs": { }}
なお、上記の copy の名前 (testipcopy, testniccopy, testwincopy) をdependsOn に設定すると、この copy 関数で作成した複数の resource すべてに対して依存関係を設定できます。
※ 変更履歴 :
2017/09 Managed Disk を使用したサンプルに変更
2017/09 上記にあわせ、使用する API Version を 2015-06-15 から変更
Categories: Uncategorized