Help us understand the problem. What is going on with this article?

Azure Resource Manager(ARM)の小ネタ:仮想マシンのカスタムイメージをJSONテンプレートからデプロイ

More than 3 years have passed since last update.

はじめに

前回の記事で「Azure上でRed Hat Enterprise Linux 7.3を動かすためのVMイメージを作成する」というのを公開しましたが、その作成したカスタムイメージのをJSONテンプレート(と一部Azure Powershell)を使ってデプロイする手順についてまとめました。

Azure CLIを使ってデプロイするよ?って人は「Linux オペレーティング システムを格納した仮想ハード ディスクの作成とアップロード」を参照。
全部Powershellを使うし?という人は「Resource Manager デプロイメント向けに Windows VM イメージを Azure にアップロードする」あたりを参照ください。

ながれ

OSのカスタムイメージを使って仮想マシンをデプロイする際には「仮想マシンのOSイメージを格納するストレージアカウント上にカスタムイメージが保存されている」ことが必須となります。
コンテナ名は異なっていても良いのですが、事前にストレージアカウントを作成して、そこにカスタムイメージとなるVHDファイルを転送しておく必要があります。
なので流れとしては

  1. (カスタムイメージを作成)
  2. リソースグループを作成
  3. ストレージアカウントを作成
  4. ストレージアカウント上にカスタムイメージを転送
  5. 仮想マシン(及びその他必要なリソース)を作成

といった感じになります。

今回は1.の手順は省略しますが、2~5の手順をAzure PowershellとJSONテンプレートを使って構築してみます。

デプローイ!

先のながれで説明した手順のPowershellスクリプトを以下に示します。

New-AzureRmResourceGroup -Location japaneast -Name TEST-rg
New-AzureRmResourceGroupDeployment -ResourceGroupName TEST-rg -TemplateParameterFile .\vm-parameters-rhel-1.json -TemplateFile .\vm-template-rhel-1.json
Add-AzureRmVhd -ResourceGroupName TEST-rg -Destination https://<storageaccountname>.blob.core.windows.net/images/rhel-azure-image.vhd -LocalFilePath "C:\temp\rhel-azure-image.vhd"
New-AzureRmResourceGroupDeployment -ResourceGroupName TEST-rg -TemplateParameterFile .\vm-parameters-rhel-2.json -TemplateFile .\vm-template-rhel-2.json

JSONテンプレートはストレージアカウントを作成するvm-template-rhel-1.jsonと、仮想マシン(及びその他必要なリソース)を作成するvm-template-rhel-2.jsonを準備しました。それぞれのテンプレートおよびサンプルパラメータは後述します。

こちらのスクリプトを実行すると、カスタムイメージがローカルPCから転送され、仮想マシンの動作に必要なリソースがAzure上に作成されます。
image

今回の例ではRed Hat Enterprise Linux 7.3のカスタムイメージを使って仮想マシンを構築しました。
image

ssh経由のログインも無事できました。
image

サンプルファイル

以下にJSONテンプレート及びパラメータのサンプルを示します。
パラメータやテンプレートの中身については適宜修正して再利用頂ければと思います。

JSONテンプレート(ストレージアカウント)

vm-template-rhel-1.json
{
    "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "storageAccountName": {
            "type": "string"
        },
        "storageAccountType": {
            "type": "string"
        }
    },
    "variables": {},
    "resources": [
        {
            "name": "[parameters('storageAccountName')]",
            "type": "Microsoft.Storage/storageAccounts",
            "apiVersion": "2016-05-01",
            "location": "[resourceGroup().location]",
            "kind": "Storage",
            "sku": {
                "name": "[parameters('storageAccountType')]"
            }
        }
    ],
    "outputs": {}
}
vm-parameters-rhel-1.json
{
  "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "storageAccountName": {
      "value": "<storageaccountname>"
    },
    "storageAccountType": {
      "value": "Standard_LRS"
    }
  }
}

JSONテンプレート(仮想マシン他)

vm-template-rhel-2.json
{
    "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "addressPrefix": {
            "type": "string"
        },
        "adminPassword": {
            "type": "securestring"
        },
        "adminUsername": {
            "type": "string"
        },
        "networkInterfaceName": {
            "type": "string"
        },
        "networkSecurityGroupName1": {
            "type": "string"
        },
        "PublicIpAddressName": {
            "type": "string"
        },
        "storageAccountName": {
            "type": "string"
        },
        "imageName": {
            "type": "string"
        },
        "subnetName1": {
            "type": "string"
        },
        "subnetPrefix1": {
            "type": "string"
        },
        "virtualMachineName": {
            "type": "string"
        },
        "virtualMachineSize": {
            "type": "string"
        },
        "virtualNetworkName": {
            "type": "string"
        }
    },
    "variables": {
        "vnetId": "[resourceId('Microsoft.Network/virtualNetworks', parameters('virtualNetworkName'))]",
        "SubnetRef": "[concat(variables('vnetID'),'/subnets/',parameters('subnetName1'))]",
        "osDiskName": "[concat(parameters('virtualMachineName'), '-osdisk.vhd')]"
    },
    "resources": [
        {
            "name": "[parameters('virtualNetworkName')]",
            "type": "Microsoft.Network/virtualNetworks",
            "apiVersion": "2016-03-30",
            "location": "[resourceGroup().location]",
            "dependsOn": [
                "[concat('Microsoft.Network/networkSecurityGroups/', parameters('networkSecurityGroupName1'))]"
            ],
            "properties": {
                "addressSpace": {
                    "addressPrefixes": [
                        "[parameters('addressPrefix')]"
                    ]
                },
                "subnets": [
                    {
                        "name": "[parameters('subnetName1')]",
                        "properties": {
                            "addressPrefix": "[parameters('subnetPrefix1')]",
                            "networkSecurityGroup": {
                                "id": "[resourceId('Microsoft.Network/networkSecurityGroups', parameters('networkSecurityGroupName1'))]"
                            }
                        }
                    }
                ]
            }
        },
        {
            "name": "[parameters('networkSecurityGroupName1')]",
            "type": "Microsoft.Network/networkSecurityGroups",
            "apiVersion": "2016-10-01",
            "location": "[resourceGroup().location]",
            "properties": {
                "securityRules": [
                    {
                        "name": "allow-ssh",
                        "properties": {
                            "protocol": "Tcp",
                            "sourcePortRange": "*",
                            "destinationPortRange": "22",
                            "sourceAddressPrefix": "*",
                            "destinationAddressPrefix": "*",
                            "access": "Allow",
                            "priority": 1000,
                            "direction": "Inbound"
                        }
                    }
                ]
            }
        },
        {
            "type": "Microsoft.Network/publicIPAddresses",
            "apiVersion": "2016-10-01",
            "name": "[parameters('PublicIpAddressName')]",
            "location": "[resourceGroup().location]",
            "properties": {
                "publicIPAllocationMethod": "Dynamic"
            }
        },
        {
            "name": "[parameters('virtualMachineName')]",
            "type": "Microsoft.Compute/virtualMachines",
            "apiVersion": "2016-03-30",
            "location": "[resourceGroup().location]",
            "dependsOn": [
                "[concat('Microsoft.Network/networkInterfaces/', parameters('networkInterfaceName'))]"
            ],
            "properties": {
                "osProfile": {
                    "computerName": "[parameters('virtualMachineName')]",
                    "adminUsername": "[parameters('adminUsername')]",
                    "adminPassword": "[parameters('adminPassword')]"
                },
                "hardwareProfile": {
                    "vmSize": "[parameters('virtualMachineSize')]"
                },
                "storageProfile": {
                    "osDisk": {
                        "osType": "Linux",
                        "name": "[parameters('virtualMachineName')]",
                        "vhd": {
                            "uri": "[concat(concat(reference(resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName')), '2015-06-15').primaryEndpoints['blob'], 'vhds/'), variables('osDiskName'))]"
                        },
                        "image": {
                            "uri": "[concat('https://', parameters('storageAccountName'), '.blob.core.windows.net/images/',parameters('imageName'))]"
                        },
                        "createOption": "FromImage"
                    },
                    "dataDisks": []
                },
                "networkProfile": {
                    "networkInterfaces": [
                        {
                            "id": "[resourceId('Microsoft.Network/networkInterfaces', parameters('networkInterfaceName'))]"
                        }
                    ]
                }
            }
        },
        {
            "name": "[parameters('networkInterfaceName')]",
            "type": "Microsoft.Network/networkInterfaces",
            "apiVersion": "2016-10-01",
            "location": "[resourceGroup().location]",
            "dependsOn": [
                "[concat('Microsoft.Network/publicIpAddresses/', parameters('publicIpAddressName'))]",
                "[concat('Microsoft.Network/virtualNetworks/', parameters('virtualNetworkName'))]"
            ],
            "properties": {
                "ipConfigurations": [
                    {
                        "name": "ipconfig1",
                        "properties": {
                            "subnet": {
                                "id": "[variables('subnetRef')]"
                            },
                            "privateIPAllocationMethod": "Dynamic",
                            "publicIpAddress": {
                                "id": "[resourceId('Microsoft.Network/publicIpAddresses', parameters('publicIpAddressName'))]"
                            }
                        }
                    }
                ]
            }
        }
    ],
    "outputs": {}
}
vm-parameters-rhel-2.json
{
  "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "addressPrefix": {
      "value": "192.168.0.0/16"
    },
    "adminPassword": {
      "value": "<password>"
    },
    "adminUsername": {
      "value": "<username>"
    },
    "networkInterfaceName": {
      "value": "TESTVM-nic"
    },
    "networkSecurityGroupName1": {
      "value": "TEST-subnet1-nsg"
    },
    "PublicIpAddressName": {
      "value": "TESTVM01-pip"
    },
    "storageAccountName": {
      "value": "<storageaccountname>"
    },
    "imageName": {
      "value": "rhel-azure-image.vhd"
    },
    "subnetName1": {
      "value": "Subnet-1"
    },
    "subnetPrefix1": {
      "value": "192.168.0.0/24"
    },
    "virtualMachineName": {
      "value": "TESTVM01"
    },
    "virtualMachineSize": {
      "value": "Standard_F1s"
    },
    "virtualNetworkName": {
      "value": "TEST-vnet"
    }
  }
}

おわりに

カスタムイメージを使った場合、同一のストレージアカウントに先にVHDファイルを転送しておかないといけない(別のストレージアカウントを参照できない)のが、少しイマイチですが、将来の仕様改善に期待です!

yotan
Azureコンサルタント/イクメン/カワイイモノズキ/デジタルモノズキ/バイクノリ/Microsoft MVP for Azure
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした