ARM Template の書き方 その2 Prameters,Variables
前回「ARM Template の書き方 その1 基本構文」ということで、Templete ファイルの構造や基本的な書き方、構文の説明を行いました。今回は、実際に VirtualNetwork, PublicIP を作って "parameters" と "variables" がどのようなものか確認したいと思います。
用意するもの
以下のものを用意します。
- PowerShell(インストール手順)
- Azure AD Account
- テンプレートファイル(network.json)
- パラメータファイル(arm.parameters.json)
PowerShell をインストールして、Azure AD Account を用意するところまでの説明は省きます。テンプレートファイルとパラメータファイルについて、以下に解説します。
テンプレートファイル(network.json)
ポイントは "parameters" と "variables" の使用方法です。
"parameters" で「データ型(type)」と「デフォルト値(defaultValue)」は定義していますが、「値(value)」は定義していません。これは、パラメータファイル(arm.parameters.json)に書き出しているためです。
テンプレートファイルで "parameters" を定義するとき、「データ型(type)」の指定は必須です。しかし、中身の「値(value)」は必須ではありません。外部ファイルで定義することが可能となっているためです。その一方、テンプレートファイルで "parameters" を定義しなかった場合、外部ファイルでパラメータを定義することはできません。
この辺りに仕様は実際に自分で書いてみないと実感できないところでした。
"variables" の使用方法は、オブジェクト型のデータを定義したり、関数を使った値を記述するときに使用します。詳しくはパラメータ変数の概要を参照ください。
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"location": {
"type": "string",
"defaultValue": "[resourceGroup().location]",
"metadata": {
"description": "Location for all resources."
}
},
"PublicDNSLabel" : {
"type": "string",
"metadata": {
"description": "Define Public DNS Name"
}
}
},
"variables": {
"tags": "[resourceGroup().tags]",
"virtualNetwork01": {
"Name": "vnet01",
"Prefix": "10.1.0.0/16"
},
"subnet01": {
"Name": "subnet01",
"Prefix": "10.1.1.0/24"
},
"subnet02": {
"Name": "subnet02",
"Prefix": "10.1.2.0/24"
},
"PublicIP": {
"Name": "public01"
}
},
"resources": [
{
"type": "Microsoft.Network/virtualNetworks",
"name": "[variables('virtualNetwork01').Name]",
"apiVersion": "2020-05-01",
"location": "[parameters('location')]",
"comments": "This will build a Virtual Network.",
"tags": "[variables('tags')]",
"properties": {
"addressSpace": {
"addressPrefixes": [
"[variables('virtualNetwork01').Prefix]"
]
},
"subnets": [
{
"name": "[variables('subnet01').Name]",
"properties": {
"addressPrefix": "[variables('subnet01').Prefix]",
"privateEndpointNetworkPolicies": "Enabled",
"privateLinkServiceNetworkPolicies": "Enabled"
}
},
{
"name": "[variables('subnet02').Name]",
"properties": {
"addressPrefix": "[variables('subnet02').Prefix]",
"privateEndpointNetworkPolicies": "Enabled",
"privateLinkServiceNetworkPolicies": "Enabled"
}
}
]
}
},
{
"name": "[variables('PublicIP').Name]",
"type": "Microsoft.Network/publicIPAddresses",
"apiVersion": "2020-05-01",
"location": "[parameters('location')]",
"comments": "Public IP for your Primary NIC",
"properties": {
"dnsSettings": {
"domainNameLabel": "[parameters('PublicDNSLabel')]"
},
"publicIPAllocationMethod": "Dynamic"
},
"tags": "[variables('tags')]"
}
]
}
パラメータファイル(arm.parameters.json)
こちらのファイルは短い内容となっています。location はリソースグループの値を継承させたいのでそのままです。PublicIP 用の PublicDNSLabel だけ値を定義します。
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"PublicDNSLabel": {
"value": "azwin2019"
}
}
}
ファイルの準備はこれで完了です。
試してみる
デプロイコマンド
以下の PowerShell コマンドを使って VirtualNetwork をデプロイします。
- Connect-AzAccount
- New-AzResourceGroup
- New-AzResourceGroupDeployment -WhatIf
- New-AzResourceGroupDeployment
3番目の "-WhatIf" とは、デプロイ前のテスト実行を意味しています。このオプションをつけて実行することで、どのような結果が得られるのかを先に知ることができます。その内容から、デプロイが問題ないか判断した上で実行するようにします。
ただ、これらのコマンドについて毎回手打ちするのは面倒です。そこで、簡単なスクリプト(deployment.ps1)を用意して一連の処理を実行するようにしました。また、処理結果はログファイルに出力するようにしています。これで、デプロイ履歴も自然にログファイルに蓄積されていきます。
Connect-AzAccount
まずは、ログインします。
deployment.ps1
スクリプトの内容は以下です。
# version 1.0.0
<#
.SYNOPSIS
ARM Template を Deploy するにあたって、本スクリプトを実行します。
.DESCRIPTION
以下の順で処理が実行されます。
1. リソースグループの作成
2. $TemplateListに記述したテンプレートに対して順次実施(スキップ可)
2-1. テンプレートのテスト
2-2. テンプレートのデプロイ
3. デプロイ結果をログに保存
.PARAMETER
デプロイ対象となるのは $TemplateList に記述したテンプレートのみです。
パラメータファイルは $PrametersFile で固定です。
#>
# Environments
$ResouceGroupName = "atsushi.koizumi.arm"
$location = "eastus"
$Owner_tag = "atsushi.koizumi"
$Env_tag = "arm.templete"
$TemplateList = ("network","virtualmachine") # 配列
$PrametersFile = "arm.parameters.json"
$Logfile = "mydeployments.log"
# error handling
$ErrorActionPreference = "Stop"
################
# Script Start #
################
# create resource group
try {
$rgstate = Get-AzResourceGroup -Name $ResouceGroupName
if ($rgstate.ProvisioningState -eq "Succeeded") {
Write-Output "Resource Group Exists. Start ARM Templete Deploy."
} else {
Write-Output "Resource Group Exists. But State is not Succeeded."
}
}
catch {
New-AzResourceGroup `
-Name $ResouceGroupName `
-Location $location `
-Tag @{Owner=$Owner_tag; Env=$Env_tag} `
| Out-File -Append $Logfile
}
# get datetime
$Datetime = Get-date -format "yyyyMMddHHmmss"
# deploy
foreach ($item in $TemplateList) {
$CurrentFiles = Get-ChildItem $PSScriptRoot -Name
# filecheck
if($CurrentFiles -ccontains "$item.json") {
# gain permission to test
Write-Host "Test the templete ""$item.json"" ?"
$YesNo = Read-Host "yes or no "
while (($YesNo -ne "yes") -And ($YesNo -ne "no")) {
$YesNo = Read-Host "yes or no "
}
Write-Host ""
# test templete
if ($YesNo -eq "yes") {
New-AzResourceGroupDeployment `
-Name "$item-$Datetime" `
-ResourceGroupName $ResouceGroupName `
-WhatIf `
-TemplateFile "$item.json" `
-TemplateParameterFile $PrametersFile
} elseif ($YesNo -eq "no") {
Write-Host "Skip ""$item.json"""
Continue
}
# gain permission to deploy
Write-Host "Deploy the templete ""$item.json"" ?"
$YesNo = Read-Host "yes or no "
while (($YesNo -ne "yes") -And ($YesNo -ne "no")) {
$YesNo = Read-Host "yes or no "
}
Write-Host ""
# deeploy start
if ($YesNo -eq "yes") {
New-AzResourceGroupDeployment `
-Name "$item-$Datetime" `
-ResourceGroupName $ResouceGroupName `
-Mode Incremental `
-TemplateFile "$item.json" `
-TemplateParameterFile $PrametersFile `
| Out-File -Append $Logfile
} elseif ($YesNo -eq "no") {
Write-Host "Skip ""$item.json"""
}
Write-Host ""
} else {
Write-Host "[Warning] ""$PSScriptRoot\$item"" does not exist."
}
}
スクリプト実行
では、スクリプトを実行してみます。
処理結果
ログファイルの中身を参照してみます。
ResourceGroupName : atsushi.koizumi.arm
Location : eastus
ProvisioningState : Succeeded
Tags :
Name Value
===== ===============
Env arm.templete
Owner atsushi.koizumi
ResourceId : /subscriptions/000000000-0000-0000-00000000/resourceGroups/atsushi.koizumi.arm
DeploymentName : network-20210115214249
ResourceGroupName : atsushi.koizumi.arm
ProvisioningState : Succeeded
Timestamp : 1/15/2021 12:43:38 PM
Mode : Incremental
TemplateLink :
Parameters :
Name Type Value
================ ========================= ==========
location String eastus
publicDNSLabel String azwin2019
Outputs :
DeploymentDebugLogLevel :
うまく作成できました。
最後に
ARM Templete の基本操作はこれで把握できたと思います。あとは、各リソース毎の記述方法を参照しつつ自作テンプレートを書けるようになっていきたいと思います。