Azure コラム 第4回 「Azure Resource ManagerによるWebアプリケーション環境の展開~IaaS~」


さて第3回までは座談と言う感じで進んできましたが、ここらでお隣のWindows10コラムにも倣って実際の画面などお見せしつつ、何回かに分けて実践のご紹介をしていこうかと思います。
今回は入門編、「Azure Resource ManagerによるWebアプリケーション環境の展開~IaaS~」です。

システムの構成

システム構成は動作確認までの所要時間優先でLAMP(Linux+Apache+MySQL+PHP)を例に取りたいと思います。
まずシステム構成図です、図に全部盛りだとごちゃごちゃしてしまいましたので一部のリソースは省いています。

システム構成図

次にリソースの一覧です。

仮想マシンStandard_A2×4(AP×2/DB×2)
可用性セット ×2(AP×1/DB×1)
ストレージアカウントStandard_LRS×1
仮想ネットワーク ×1
ネットワークインターフェース ×4(AP×2/DB×2)
パブリックIPアドレス ×5(AP×2/DB×2/LB×1)
ネットワークセキュリティグループ ×2(AP×1/DB×1)
ロードバランサーExternal Load Balancer×1

テンプレートの作成

ARMの構成要素はただ一つリソースを定義するテンプレートファイル(json)だけです、このテンプレートファイルAzure PowerShellに食わせることでデプロイを行います。
テンプレートファイルですが、基本的にはパラメータ/変数/リソースを宣言するだけでコピペでも結構行けちゃいます。あとリソース間の依存関係はARM側で制御してくれますので、リソースの記述順を意識しなくて良いのがすごく楽です。

そして今回作成したテンプレートファイルです、ちょっと長いですが全文掲載します。

{
  "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "AP-VmPrefix": {
      "type": "string",
      "defaultValue": "AP",
      "metadata": {
        "description": "This is the name of the your VM"
      }
    },
    "DB-VmPrefix": {
      "type": "string",
      "defaultValue": "DB",
      "metadata": {
        "description": "This is the name of the your VM"
      }
    },
    "StorageAccountName": {
      "type": "string",
      "defaultValue": "azurecolumn04",
      "metadata": {
        "description": "This is the name of the your storage account"
      }
    },
    "AP-dnsLabelPrefix": {
      "type": "string",
      "defaultValue": "azurecolumn04-ap",
      "metadata": {
        "description": "DNS Label for the Public IP. Must be lowercase. It should match with the following regular expression: ^[a-z][a-z0-9-]{1,61}[a-z0-9]$ or it will raise an error."
      }
    },
    "AP-NLB-dnsLabelPrefix": {
      "type": "string",
      "defaultValue": "azurecolumn04-lb",
      "metadata": {
        "description": "DNS Label for the Public IP. Must be lowercase. It should match with the following regular expression: ^[a-z][a-z0-9-]{1,61}[a-z0-9]$ or it will raise an error."
      }
    },
    "DB-dnsLabelPrefix": {
      "type": "string",
      "defaultValue": "azurecolumn04-db",
      "metadata": {
        "description": "DNS Label for the Public IP. Must be lowercase. It should match with the following regular expression: ^[a-z][a-z0-9-]{1,61}[a-z0-9]$ or it will raise an error."
      }
    },
    "AP-vmSize": {
      "type": "string",
      "defaultValue": "Standard_A2",
      "metadata": {
        "description": "This is the size of your VM"
      }
    },
    "DB-vmSize": {
      "type": "string",
      "defaultValue": "Standard_A2",
      "metadata": {
        "description": "This is the size of your VM"
      }
    },
    "adminUserName": {
      "type": "string",
      "metadata": {
        "description": "User Name for the Virtual Machine"
      }
    },
    "adminPassword": {
      "type": "securestring",
      "metadata": {
        "description": "Password for the Virtual Machine"
      }
    },
    "virtualNetworkName": {
      "type": "string",
      "defaultValue": "azurecolumn04-vnet",
      "metadata": {
        "description": "VNet Name"
      }
    },
    "subnetName": {
      "type": "string",
      "defaultValue": "subnet-01",
      "metadata": {
        "description": "Subnet Name"
      }
    },
    "ubuntuOSVersion": {
      "type": "string",
      "defaultValue": "14.04.2-LTS",
      "allowedValues": [
        "12.04.5-LTS",
        "14.04.2-LTS"
      ],
      "metadata": {
        "description": "The Ubuntu version for the VM. This will pick a fully patched image of this given Ubuntu version. Allowed values: 12.04.5-LTS, 14.04.2-LTS."
      }
    }
  },
  "variables": {
    "location": "[resourceGroup().location]",
    "vnetID": "[resourceId('Microsoft.Network/virtualNetworks',parameters('virtualNetworkName'))]",
    "subnetRef": "[concat(variables('vnetID'),'/subnets/', parameters('subnetName'))]",
    "storageAccountType": "Standard_LRS",
    "publicIPAddressType": "Dynamic",
    "AP-LB-PIPName": "AP-LB-PIP",
    "AP-LBName": "AP-LB",
    "AP-LB-FEName": "AP-LB-FE",
    "AP-LB-PIP-Id": "[resourceId('azurecolumn04', 'Microsoft.Network/publicIPAddresses', variables('AP-LB-PIPName'))]",
    "AP-PoolName": "AP-Pool",
    "AP-LB-ProbeName-80": "AP-LB-Probe-80",
    "AP-LB-ProbeName-443": "AP-LB-Probe-443",
    "AP-FIP-Id": "[concat(variables('AP-LB-Id'), '/frontendIPConfigurations/',variables('AP-LB-FEName'))]",
    "AP-Pool-Id": "[concat(variables('AP-LB-Id'), '/backendAddressPools/', variables('AP-PoolName'))]",
    "AP-LB-RuleName-80": "AP-LB-Rule-80",
    "AP-Probe-Id-80": "[concat(variables('AP-LB-Id'), '/probes/', variables('AP-LB-ProbeName-80'))]",
    "AP-LB-RuleName-443": "AP-LB-Rule-443",
    "AP-Probe-Id-443": "[concat(variables('AP-LB-Id'), '/probes/', variables('AP-LB-ProbeName-443'))]",
    "AP-NSGName": "AP-NSG",
    "DB-NSGName": "DB-NSG",
    "AP-ASName": "AP-AS",
    "DB-ASName": "DB-AS",
    "AP-Count": 2,
    "DB-Count": 2,
    "AP-LB-Id": "[resourceId('Microsoft.Network/loadBalancers', variables('AP-LBName'))]",
    "imagePublisher": "Canonical",
    "imageOffer": "UbuntuServer"
  },
  "resources": [
    {
      "type": "Microsoft.Storage/storageAccounts",
      "name": "[parameters('StorageAccountName')]",
      "apiVersion": "2015-06-15",
      "location": "[resourceGroup().location]",
      "tags": {
        "displayName": "StorageAccount"
      },
      "properties": {
        "accountType": "[variables('storageAccountType')]"
      }
    },
    {
      "type": "Microsoft.Network/publicIPAddresses",
      "name": "[variables('AP-LB-PIPName')]",
      "apiVersion": "2016-03-30",
      "location": "[resourceGroup().location]",
      "properties": {
        "publicIPAllocationMethod": "[variables('publicIPAddressType')]",
        "dnsSettings": {
          "domainNameLabel": "[parameters('AP-NLB-dnsLabelPrefix')]"
        }
      }
    },
    {
      "type": "Microsoft.Network/loadBalancers",
      "name": "[variables('AP-LBName')]",
      "apiVersion": "2016-03-30",
      "location": "[resourceGroup().location]",
      "dependsOn": [
        "[concat('Microsoft.Network/publicIPAddresses/', variables('AP-LB-PIPName'))]"
      ],
      "properties": {
        "frontendIPConfigurations": [
          {
            "name": "[variables('AP-LB-FEName')]",
            "properties": {
              "publicIPAddress": {
                "id": "[variables('AP-LB-PIP-Id')]"
              }
            }
          }
        ],
        "backendAddressPools": [
          {
            "name": "[variables('AP-PoolName')]"
          }
        ],
        "probes": [
          {
            "name": "[variables('AP-LB-ProbeName-80')]",
            "properties": {
              "protocol": "Http",
              "port": 80,
              "requestPath": "/",
              "intervalInSeconds": 5,
              "numberOfProbes": 2
            }
          },
          {
            "name": "[variables('AP-LB-ProbeName-443')]",
            "properties": {
              "protocol": "Http",
              "port": 443,
              "requestPath": "/",
              "intervalInSeconds": 5,
              "numberOfProbes": 2
            }
          }
        ],
        "loadBalancingRules": [
          {
            "name": "[variables('AP-LB-RuleName-80')]",
            "properties": {
              "frontendIPConfiguration": {
                "id": "[variables('AP-FIP-Id')]"
              },
              "backendAddressPool": {
                "id": "[variables('AP-Pool-Id')]"
              },
              "probe": {
                "id": "[variables('AP-Probe-Id-80')]"
              },
              "frontendPort": 80,
              "backendPort": 80,
              "enableFloatingIP": false,
              "idleTimeoutInMinutes": 4,
              "protocol": "Tcp",
              "loadDistribution": "Default"
            }
          },
          {
            "name": "[variables('AP-LB-RuleName-443')]",
            "properties": {
              "frontendIPConfiguration": {
                "id": "[variables('AP-FIP-Id')]"
              },
              "backendAddressPool": {
                "id": "[variables('AP-Pool-Id')]"
              },
              "probe": {
                "id": "[variables('AP-Probe-Id-443')]"
              },
              "frontendPort": 443,
              "backendPort": 443,
              "enableFloatingIP": false,
              "idleTimeoutInMinutes": 4,
              "protocol": "Tcp",
              "loadDistribution": "Default"
            }
          }
        ]
      }
    },
    {
      "apiVersion": "2016-03-30",
      "type": "Microsoft.Network/networkSecurityGroups",
      "name": "[variables('AP-NSGName')]",
      "location": "[resourceGroup().location]",
      "properties": {
        "securityRules": [
          {
            "name": "SSH",
            "properties": {
              "description": "Allow SSH",
              "protocol": "Tcp",
              "sourcePortRange": "*",
              "destinationPortRange": "22",
              "sourceAddressPrefix": "*",
              "destinationAddressPrefix": "*",
              "access": "Allow",
              "priority": 100,
              "direction": "Inbound"
            }
          },
          {
            "name": "HTTP",
            "properties": {
              "description": "Allow HTTP",
              "protocol": "Tcp",
              "sourcePortRange": "*",
              "destinationPortRange": "80",
              "sourceAddressPrefix": "*",
              "destinationAddressPrefix": "*",
              "access": "Allow",
              "priority": 101,
              "direction": "Inbound"
            }
          },
          {
            "name": "HTTPS",
            "properties": {
              "description": "Allow HTTPS",
              "protocol": "Tcp",
              "sourcePortRange": "*",
              "destinationPortRange": "443",
              "sourceAddressPrefix": "*",
              "destinationAddressPrefix": "*",
              "access": "Allow",
              "priority": 102,
              "direction": "Inbound"
            }
          }
        ]
      }
    },
    {
      "apiVersion": "2016-03-30",
      "type": "Microsoft.Network/networkSecurityGroups",
      "name": "[variables('DB-NSGName')]",
      "location": "[resourceGroup().location]",
      "properties": {
        "securityRules": [
          {
            "name": "SSH",
            "properties": {
              "description": "Allow SSH",
              "protocol": "Tcp",
              "sourcePortRange": "*",
              "destinationPortRange": "22",
              "sourceAddressPrefix": "*",
              "destinationAddressPrefix": "*",
              "access": "Allow",
              "priority": 100,
              "direction": "Inbound"
            }
          },
          {
            "name": "MySQL",
            "properties": {
              "description": "Allow MySQL",
              "protocol": "Tcp",
              "sourcePortRange": "*",
              "destinationPortRange": "3306",
              "sourceAddressPrefix": "*",
              "destinationAddressPrefix": "*",
              "access": "Allow",
              "priority": 101,
              "direction": "Inbound"
            }
          }
        ]
      }
    },
    {
      "apiVersion": "2016-03-30",
      "type": "Microsoft.Network/virtualNetworks",
      "name": "[parameters('virtualNetworkName')]",
      "location": "[resourceGroup().location]",
      "properties": {
        "addressSpace": {
          "addressPrefixes": [ "10.0.0.0/16" ]
        },
        "subnets": [
          {
            "name": "[parameters('subnetName')]",
            "properties": {
              "addressPrefix": "10.0.0.0/24"
            }
          }
        ]
      }
    },
    {
      "apiVersion": "2015-06-15",
      "type": "Microsoft.Compute/availabilitySets",
      "name": "[variables('AP-ASName')]",
      "location": "[variables('location')]"
    },
    {
      "apiVersion": "2015-06-15",
      "type": "Microsoft.Compute/availabilitySets",
      "name": "[variables('DB-ASName')]",
      "location": "[variables('location')]"
    },
    {
      "apiVersion": "2016-03-30",
      "type": "Microsoft.Network/publicIPAddresses",
      "location": "[variables('location')]",
      "copy": {
        "name": "AP-PIP-Copy",
        "count": "[variables('AP-Count')]"
      },
      "name": "[concat(parameters('AP-VmPrefix'), add(copyIndex(), 1), '-PIP')]",
      "properties": {
        "publicIPAllocationMethod": "[variables('publicIPAddressType')]",
        "dnsSettings": {
          "domainNameLabel": "[concat(parameters('AP-dnsLabelPrefix'), add(copyIndex(), 1))]"
        }
      }
    },
    {
      "apiVersion": "2016-03-30",
      "type": "Microsoft.Network/publicIPAddresses",
      "location": "[variables('location')]",
      "copy": {
        "name": "DB-PIP-Copy",
        "count": "[variables('DB-Count')]"
      },
      "name": "[concat(parameters('DB-VmPrefix'), add(copyIndex(), 1), '-PIP')]",
      "properties": {
        "publicIPAllocationMethod": "[variables('publicIPAddressType')]",
        "dnsSettings": {
          "domainNameLabel": "[concat(parameters('DB-dnsLabelPrefix'), add(copyIndex(), 1))]"
        }
      }
    },
    {
      "apiVersion": "2016-03-30",
      "type": "Microsoft.Network/networkInterfaces",
      "location": "[variables('location')]",
      "copy": {
        "name": "AP-NIC-Copy",
        "count": "[variables('AP-Count')]"
      },
      "name": "[concat(parameters('AP-VmPrefix'), add(copyIndex(), 1), '-Nic')]",
      "dependsOn": [
        "[concat('Microsoft.Network/publicIPAddresses/', concat(parameters('AP-VmPrefix'), add(copyIndex(), 1), '-PIP'))]",
        "[concat('Microsoft.Network/virtualNetworks/', parameters('virtualNetworkName'))]",
        "[concat('Microsoft.Network/networkSecurityGroups/', variables('AP-NSGName'))]",
        "[concat('Microsoft.Network/loadBalancers/', variables('AP-LBName'))]"
      ],
      "properties": {
        "ipConfigurations": [
          {
            "name": "ipconfig1",
            "properties": {
              "privateIPAllocationMethod": "Dynamic",
              "publicIPAddress": {
                "id": "[resourceId('Microsoft.Network/publicIPAddresses', concat(parameters('AP-VmPrefix'), add(copyIndex(), 1), '-PIP'))]"
              },
              "subnet": {
                "id": "[variables('subnetRef')]"
              },
              "primary": true,
              "loadBalancerBackendAddressPools": [
                {
                  "id": "[concat(variables('AP-LB-Id'), '/backendAddressPools/',variables('AP-PoolName'))]"
                }
              ]
            }
          }
        ],
        "networkSecurityGroup": {
          "id": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('AP-NSGName'))]"
        }
      }
    },
    {
      "apiVersion": "2016-03-30",
      "type": "Microsoft.Network/networkInterfaces",
      "location": "[variables('location')]",
      "copy": {
        "name": "DB-NIC-Copy",
        "count": "[variables('DB-Count')]"
      },
      "name": "[concat(parameters('DB-VmPrefix'), add(copyIndex(), 1), '-Nic')]",
      "dependsOn": [
        "[concat('Microsoft.Network/publicIPAddresses/', concat(parameters('DB-VmPrefix'), add(copyIndex(), 1), '-PIP'))]",
        "[concat('Microsoft.Network/virtualNetworks/', parameters('virtualNetworkName'))]",
        "[concat('Microsoft.Network/networkSecurityGroups/', variables('DB-NSGName'))]"
      ],
      "properties": {
        "ipConfigurations": [
          {
            "name": "ipconfig1",
            "properties": {
              "privateIPAllocationMethod": "Dynamic",
              "publicIPAddress": {
                "id": "[resourceId('Microsoft.Network/publicIPAddresses', concat(parameters('DB-VmPrefix'), add(copyIndex(), 1), '-PIP'))]"
              },
              "subnet": {
                "id": "[variables('subnetRef')]"
              }
            }
          }
        ],
        "networkSecurityGroup": {
          "id": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('DB-NSGName'))]"
        }
      }
    },
    {
      "apiVersion": "2015-06-15",
      "type": "Microsoft.Compute/virtualMachines",
      "name": "[concat(parameters('AP-VmPrefix'), add(copyIndex(), 1))]",
      "location": "[resourceGroup().location]",
      "copy": {
        "name": "AP-VM-Copy",
        "count": "[variables('AP-Count')]"
      },
      "tags": {
        "displayName": "VirtualMachine"
      },
      "dependsOn": [
        "[concat('Microsoft.Storage/storageAccounts/', parameters('StorageAccountName'))]",
        "[concat('Microsoft.Compute/availabilitySets/', variables('AP-ASName'))]",
        "[concat('Microsoft.Network/networkInterfaces/', concat(parameters('AP-VmPrefix'), add(copyIndex(), 1), '-Nic'))]"
      ],
      "properties": {
        "availabilitySet": {
          "id": "[resourceId('Microsoft.Compute/availabilitySets/', variables('AP-ASName'))]"
        },
        "hardwareProfile": {
          "vmSize": "[parameters('AP-vmSize')]"
        },
        "osProfile": {
          "computerName": "[concat(parameters('AP-VmPrefix'), add(copyIndex(), 1))]",
          "adminUsername": "[parameters('adminUsername')]",
          "adminPassword": "[parameters('adminPassword')]"
        },
        "storageProfile": {
          "imageReference": {
            "publisher": "[variables('imagePublisher')]",
            "offer": "[variables('imageOffer')]",
            "sku": "[parameters('ubuntuOSVersion')]",
            "version": "latest"
          },
          "osDisk": {
            "name": "osdisk",
            "vhd": {
              "uri": "[concat('http://',parameters('StorageAccountName'),'.blob.core.windows.net/vhds/', parameters('AP-VmPrefix'), add(copyIndex(), 1) ,'-osDisk.vhd')]"
            },
            "caching": "ReadWrite",
            "createOption": "FromImage"
          }
        },
        "networkProfile": {
          "networkInterfaces": [
            {
              "id": "[resourceId('Microsoft.Network/networkInterfaces', concat(parameters('AP-VmPrefix'), add(copyIndex(), 1), '-Nic'))]"
            }
          ]
        }
      },
      "resources": [
        {
          "type": "extensions",
          "name": "Microsoft.Insights.VMDiagnosticsSettings",
          "apiVersion": "2015-06-15",
          "location": "[resourceGroup().location]",
          "tags": {
            "displayName": "AzureDiagnostics"
          },
          "dependsOn": [
            "[concat(parameters('AP-VmPrefix'), add(copyIndex(), 1))]"
          ],
          "properties": {
            "publisher": "Microsoft.OSTCExtensions",
            "type": "LinuxDiagnostic",
            "typeHandlerVersion": "2.3",
            "autoUpgradeMinorVersion": true,
            "settings": {
              "ladCfg": {
                "diagnosticMonitorConfiguration": {
                  "performanceCounters": {
                    "performanceCounterConfiguration": [
                      {
                        "namespace": "root/scx",
                        "class": "Memory",
                        "counterSpecifier": "AvailableMemory",
                        "table": "LinuxMemory"
                      },
                      {
                        "namespace": "root/scx",
                        "class": "Memory",
                        "counterSpecifier": "PercentAvailableMemory",
                        "table": "LinuxMemory"
                      },
                      {
                        "namespace": "root/scx",
                        "class": "Memory",
                        "counterSpecifier": "UsedMemory",
                        "table": "LinuxMemory"
                      },
                      {
                        "namespace": "root/scx",
                        "class": "Memory",
                        "counterSpecifier": "PercentUsedMemory",
                        "table": "LinuxMemory"
                      },
                      {
                        "namespace": "root/scx",
                        "class": "Memory",
                        "counterSpecifier": "PercentUsedByCache",
                        "table": "LinuxMemory"
                      },
                      {
                        "namespace": "root/scx",
                        "class": "Memory",
                        "counterSpecifier": "PagesPerSec",
                        "table": "LinuxMemory"
                      },
                      {
                        "namespace": "root/scx",
                        "class": "Memory",
                        "counterSpecifier": "PagesReadPerSec",
                        "table": "LinuxMemory"
                      },
                      {
                        "namespace": "root/scx",
                        "class": "Memory",
                        "counterSpecifier": "PagesWrittenPerSec",
                        "table": "LinuxMemory"
                      },
                      {
                        "namespace": "root/scx",
                        "class": "Memory",
                        "counterSpecifier": "AvailableSwap",
                        "table": "LinuxMemory"
                      },
                      {
                        "namespace": "root/scx",
                        "class": "Memory",
                        "counterSpecifier": "PercentAvailableSwap",
                        "table": "LinuxMemory"
                      },
                      {
                        "namespace": "root/scx",
                        "class": "Memory",
                        "counterSpecifier": "UsedSwap",
                        "table": "LinuxMemory"
                      },
                      {
                        "namespace": "root/scx",
                        "class": "Memory",
                        "counterSpecifier": "PercentUsedSwap",
                        "table": "LinuxMemory"
                      },
                      {
                        "namespace": "root/scx",
                        "class": "Processor",
                        "counterSpecifier": "PercentIdleTime",
                        "table": "LinuxProcessor"
                      },
                      {
                        "namespace": "root/scx",
                        "class": "Processor",
                        "counterSpecifier": "PercentUserTime",
                        "table": "LinuxProcessor"
                      },
                      {
                        "namespace": "root/scx",
                        "class": "Processor",
                        "counterSpecifier": "PercentNiceTime",
                        "table": "LinuxProcessor"
                      },
                      {
                        "namespace": "root/scx",
                        "class": "Processor",
                        "counterSpecifier": "PercentPrivilegedTime",
                        "table": "LinuxProcessor"
                      },
                      {
                        "namespace": "root/scx",
                        "class": "Processor",
                        "counterSpecifier": "PercentInterruptTime",
                        "table": "LinuxProcessor"
                      },
                      {
                        "namespace": "root/scx",
                        "class": "Processor",
                        "counterSpecifier": "PercentDPCTime",
                        "table": "LinuxProcessor"
                      },
                      {
                        "namespace": "root/scx",
                        "class": "Processor",
                        "counterSpecifier": "PercentProcessorTime",
                        "table": "LinuxProcessor"
                      },
                      {
                        "namespace": "root/scx",
                        "class": "Processor",
                        "counterSpecifier": "PercentIOWaitTime",
                        "table": "LinuxProcessor"
                      },
                      {
                        "namespace": "root/scx",
                        "class": "PhysicalDisk",
                        "counterSpecifier": "BytesPerSecond",
                        "table": "LinuxPhysicalDisk"
                      },
                      {
                        "namespace": "root/scx",
                        "class": "PhysicalDisk",
                        "counterSpecifier": "ReadBytesPerSecond",
                        "table": "LinuxPhysicalDisk"
                      },
                      {
                        "namespace": "root/scx",
                        "class": "PhysicalDisk",
                        "counterSpecifier": "WriteBytesPerSecond",
                        "table": "LinuxPhysicalDisk"
                      },
                      {
                        "namespace": "root/scx",
                        "class": "PhysicalDisk",
                        "counterSpecifier": "TransfersPerSecond",
                        "table": "LinuxPhysicalDisk"
                      },
                      {
                        "namespace": "root/scx",
                        "class": "PhysicalDisk",
                        "counterSpecifier": "ReadsPerSecond",
                        "table": "LinuxPhysicalDisk"
                      },
                      {
                        "namespace": "root/scx",
                        "class": "PhysicalDisk",
                        "counterSpecifier": "WritesPerSecond",
                        "table": "LinuxPhysicalDisk"
                      },
                      {
                        "namespace": "root/scx",
                        "class": "PhysicalDisk",
                        "counterSpecifier": "AverageReadTime",
                        "table": "LinuxPhysicalDisk"
                      },
                      {
                        "namespace": "root/scx",
                        "class": "PhysicalDisk",
                        "counterSpecifier": "AverageWriteTime",
                        "table": "LinuxPhysicalDisk"
                      },
                      {
                        "namespace": "root/scx",
                        "class": "PhysicalDisk",
                        "counterSpecifier": "AverageTransferTime",
                        "table": "LinuxPhysicalDisk"
                      },
                      {
                        "namespace": "root/scx",
                        "class": "PhysicalDisk",
                        "counterSpecifier": "AverageDiskQueueLength",
                        "table": "LinuxPhysicalDisk"
                      },
                      {
                        "namespace": "root/scx",
                        "class": "NetworkInterface",
                        "counterSpecifier": "BytesTransmitted",
                        "table": "LinuxNetworkInterface"
                      },
                      {
                        "namespace": "root/scx",
                        "class": "NetworkInterface",
                        "counterSpecifier": "BytesReceived",
                        "table": "LinuxNetworkInterface"
                      },
                      {
                        "namespace": "root/scx",
                        "class": "NetworkInterface",
                        "counterSpecifier": "PacketsTransmitted",
                        "table": "LinuxNetworkInterface"
                      },
                      {
                        "namespace": "root/scx",
                        "class": "NetworkInterface",
                        "counterSpecifier": "PacketsReceived",
                        "table": "LinuxNetworkInterface"
                      },
                      {
                        "namespace": "root/scx",
                        "class": "NetworkInterface",
                        "counterSpecifier": "BytesTotal",
                        "table": "LinuxNetworkInterface"
                      },
                      {
                        "namespace": "root/scx",
                        "class": "NetworkInterface",
                        "counterSpecifier": "TotalRxErrors",
                        "table": "LinuxNetworkInterface"
                      },
                      {
                        "namespace": "root/scx",
                        "class": "NetworkInterface",
                        "counterSpecifier": "TotalTxErrors",
                        "table": "LinuxNetworkInterface"
                      },
                      {
                        "namespace": "root/scx",
                        "class": "NetworkInterface",
                        "counterSpecifier": "TotalCollisions",
                        "table": "LinuxNetworkInterface"
                      }
                    ]
                  }
                }
              },
              "storageAccount": "[parameters('storageAccountName')]"
            },
            "protectedSettings": {
              "storageAccountName": "[parameters('storageAccountName')]",
              "storageAccountKey": "[listkeys(resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName')), '2015-06-15').key1]",
              "storageAccountEndPoint": "https://core.windows.net"
            }
          }
        }
      ]
    },
    {
      "apiVersion": "2015-06-15",
      "type": "Microsoft.Compute/virtualMachines",
      "name": "[concat(parameters('DB-VmPrefix'), add(copyIndex(), 1))]",
      "location": "[resourceGroup().location]",
      "copy": {
        "name": "DB-VM-Copy",
        "count": "[variables('DB-Count')]"
      },
      "tags": {
        "displayName": "VirtualMachine"
      },
      "dependsOn": [
        "[concat('Microsoft.Storage/storageAccounts/', parameters('StorageAccountName'))]",
        "[concat('Microsoft.Compute/availabilitySets/', variables('DB-ASName'))]",
        "[concat('Microsoft.Network/networkInterfaces/', concat(parameters('DB-VmPrefix'), add(copyIndex(), 1), '-Nic'))]"
      ],
      "properties": {
        "availabilitySet": {
          "id": "[resourceId('Microsoft.Compute/availabilitySets/', variables('DB-ASName'))]"
        },
        "hardwareProfile": {
          "vmSize": "[parameters('DB-vmSize')]"
        },
        "osProfile": {
          "computerName": "[concat(parameters('DB-VmPrefix'), add(copyIndex(), 1))]",
          "adminUsername": "[parameters('adminUsername')]",
          "adminPassword": "[parameters('adminPassword')]"
        },
        "storageProfile": {
          "imageReference": {
            "publisher": "[variables('imagePublisher')]",
            "offer": "[variables('imageOffer')]",
            "sku": "[parameters('ubuntuOSVersion')]",
            "version": "latest"
          },
          "osDisk": {
            "name": "osdisk",
            "vhd": {
              "uri": "[concat('http://',parameters('StorageAccountName'),'.blob.core.windows.net/vhds/', parameters('DB-VmPrefix'), add(copyIndex(), 1) ,'-osDisk.vhd')]"
            },
            "caching": "ReadWrite",
            "createOption": "FromImage"
          }
        },
        "networkProfile": {
          "networkInterfaces": [
            {
              "id": "[resourceId('Microsoft.Network/networkInterfaces', concat(parameters('DB-VmPrefix'), add(copyIndex(), 1), '-Nic'))]"
            }
          ]
        }
      },
      "resources": [
        {
          "type": "extensions",
          "name": "Microsoft.Insights.VMDiagnosticsSettings",
          "apiVersion": "2015-06-15",
          "location": "[resourceGroup().location]",
          "tags": {
            "displayName": "AzureDiagnostics"
          },
          "dependsOn": [
            "[concat(parameters('DB-VmPrefix'), add(copyIndex(), 1))]"
          ],
          "properties": {
            "publisher": "Microsoft.OSTCExtensions",
            "type": "LinuxDiagnostic",
            "typeHandlerVersion": "2.3",
            "autoUpgradeMinorVersion": true,
            "settings": {
              "ladCfg": {
                "diagnosticMonitorConfiguration": {
                  "performanceCounters": {
                    "performanceCounterConfiguration": [
                      {
                        "namespace": "root/scx",
                        "class": "Memory",
                        "counterSpecifier": "AvailableMemory",
                        "table": "LinuxMemory"
                      },
                      {
                        "namespace": "root/scx",
                        "class": "Memory",
                        "counterSpecifier": "PercentAvailableMemory",
                        "table": "LinuxMemory"
                      },
                      {
                        "namespace": "root/scx",
                        "class": "Memory",
                        "counterSpecifier": "UsedMemory",
                        "table": "LinuxMemory"
                      },
                      {
                        "namespace": "root/scx",
                        "class": "Memory",
                        "counterSpecifier": "PercentUsedMemory",
                        "table": "LinuxMemory"
                      },
                      {
                        "namespace": "root/scx",
                        "class": "Memory",
                        "counterSpecifier": "PercentUsedByCache",
                        "table": "LinuxMemory"
                      },
                      {
                        "namespace": "root/scx",
                        "class": "Memory",
                        "counterSpecifier": "PagesPerSec",
                        "table": "LinuxMemory"
                      },
                      {
                        "namespace": "root/scx",
                        "class": "Memory",
                        "counterSpecifier": "PagesReadPerSec",
                        "table": "LinuxMemory"
                      },
                      {
                        "namespace": "root/scx",
                        "class": "Memory",
                        "counterSpecifier": "PagesWrittenPerSec",
                        "table": "LinuxMemory"
                      },
                      {
                        "namespace": "root/scx",
                        "class": "Memory",
                        "counterSpecifier": "AvailableSwap",
                        "table": "LinuxMemory"
                      },
                      {
                        "namespace": "root/scx",
                        "class": "Memory",
                        "counterSpecifier": "PercentAvailableSwap",
                        "table": "LinuxMemory"
                      },
                      {
                        "namespace": "root/scx",
                        "class": "Memory",
                        "counterSpecifier": "UsedSwap",
                        "table": "LinuxMemory"
                      },
                      {
                        "namespace": "root/scx",
                        "class": "Memory",
                        "counterSpecifier": "PercentUsedSwap",
                        "table": "LinuxMemory"
                      },
                      {
                        "namespace": "root/scx",
                        "class": "Processor",
                        "counterSpecifier": "PercentIdleTime",
                        "table": "LinuxProcessor"
                      },
                      {
                        "namespace": "root/scx",
                        "class": "Processor",
                        "counterSpecifier": "PercentUserTime",
                        "table": "LinuxProcessor"
                      },
                      {
                        "namespace": "root/scx",
                        "class": "Processor",
                        "counterSpecifier": "PercentNiceTime",
                        "table": "LinuxProcessor"
                      },
                      {
                        "namespace": "root/scx",
                        "class": "Processor",
                        "counterSpecifier": "PercentPrivilegedTime",
                        "table": "LinuxProcessor"
                      },
                      {
                        "namespace": "root/scx",
                        "class": "Processor",
                        "counterSpecifier": "PercentInterruptTime",
                        "table": "LinuxProcessor"
                      },
                      {
                        "namespace": "root/scx",
                        "class": "Processor",
                        "counterSpecifier": "PercentDPCTime",
                        "table": "LinuxProcessor"
                      },
                      {
                        "namespace": "root/scx",
                        "class": "Processor",
                        "counterSpecifier": "PercentProcessorTime",
                        "table": "LinuxProcessor"
                      },
                      {
                        "namespace": "root/scx",
                        "class": "Processor",
                        "counterSpecifier": "PercentIOWaitTime",
                        "table": "LinuxProcessor"
                      },
                      {
                        "namespace": "root/scx",
                        "class": "PhysicalDisk",
                        "counterSpecifier": "BytesPerSecond",
                        "table": "LinuxPhysicalDisk"
                      },
                      {
                        "namespace": "root/scx",
                        "class": "PhysicalDisk",
                        "counterSpecifier": "ReadBytesPerSecond",
                        "table": "LinuxPhysicalDisk"
                      },
                      {
                        "namespace": "root/scx",
                        "class": "PhysicalDisk",
                        "counterSpecifier": "WriteBytesPerSecond",
                        "table": "LinuxPhysicalDisk"
                      },
                      {
                        "namespace": "root/scx",
                        "class": "PhysicalDisk",
                        "counterSpecifier": "TransfersPerSecond",
                        "table": "LinuxPhysicalDisk"
                      },
                      {
                        "namespace": "root/scx",
                        "class": "PhysicalDisk",
                        "counterSpecifier": "ReadsPerSecond",
                        "table": "LinuxPhysicalDisk"
                      },
                      {
                        "namespace": "root/scx",
                        "class": "PhysicalDisk",
                        "counterSpecifier": "WritesPerSecond",
                        "table": "LinuxPhysicalDisk"
                      },
                      {
                        "namespace": "root/scx",
                        "class": "PhysicalDisk",
                        "counterSpecifier": "AverageReadTime",
                        "table": "LinuxPhysicalDisk"
                      },
                      {
                        "namespace": "root/scx",
                        "class": "PhysicalDisk",
                        "counterSpecifier": "AverageWriteTime",
                        "table": "LinuxPhysicalDisk"
                      },
                      {
                        "namespace": "root/scx",
                        "class": "PhysicalDisk",
                        "counterSpecifier": "AverageTransferTime",
                        "table": "LinuxPhysicalDisk"
                      },
                      {
                        "namespace": "root/scx",
                        "class": "PhysicalDisk",
                        "counterSpecifier": "AverageDiskQueueLength",
                        "table": "LinuxPhysicalDisk"
                      },
                      {
                        "namespace": "root/scx",
                        "class": "NetworkInterface",
                        "counterSpecifier": "BytesTransmitted",
                        "table": "LinuxNetworkInterface"
                      },
                      {
                        "namespace": "root/scx",
                        "class": "NetworkInterface",
                        "counterSpecifier": "BytesReceived",
                        "table": "LinuxNetworkInterface"
                      },
                      {
                        "namespace": "root/scx",
                        "class": "NetworkInterface",
                        "counterSpecifier": "PacketsTransmitted",
                        "table": "LinuxNetworkInterface"
                      },
                      {
                        "namespace": "root/scx",
                        "class": "NetworkInterface",
                        "counterSpecifier": "PacketsReceived",
                        "table": "LinuxNetworkInterface"
                      },
                      {
                        "namespace": "root/scx",
                        "class": "NetworkInterface",
                        "counterSpecifier": "BytesTotal",
                        "table": "LinuxNetworkInterface"
                      },
                      {
                        "namespace": "root/scx",
                        "class": "NetworkInterface",
                        "counterSpecifier": "TotalRxErrors",
                        "table": "LinuxNetworkInterface"
                      },
                      {
                        "namespace": "root/scx",
                        "class": "NetworkInterface",
                        "counterSpecifier": "TotalTxErrors",
                        "table": "LinuxNetworkInterface"
                      },
                      {
                        "namespace": "root/scx",
                        "class": "NetworkInterface",
                        "counterSpecifier": "TotalCollisions",
                        "table": "LinuxNetworkInterface"
                      }
                    ]
                  }
                }
              },
              "storageAccount": "[parameters('storageAccountName')]"
            },
            "protectedSettings": {
              "storageAccountName": "[parameters('storageAccountName')]",
              "storageAccountKey": "[listkeys(resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName')), '2015-06-15').key1]",
              "storageAccountEndPoint": "https://core.windows.net"
            }
          }
        }
      ]
    }
  ]
}

デプロイ

デプロイは下のようなPowerShellスクリプトで行います。

cd "C:\AzureColumn04"

Login-AzureRmAccount
Select-AzureRmSubscription -SubscriptionName "サブスクリプション名"

New-AzureRmResourceGroup -Name "azurecolumn04" -Location japanwest

# 展開用パラメータの設定
$parameter = @{
"adminUserName" = "管理者ユーザー"
"adminPassword" = "管理者パスワード"
}

# テンプレートのテスト
Test-AzureRmResourceGroupDeployment -ResourceGroupName "azurecolumn04" -TemplateFile .\azurecolumn04.json -TemplateParameterObject $parameter -Debug

# テンプレートを使用した展開
New-AzureRmResourceGroupDeployment -Name "azurecolumn04.deploy" -ResourceGroupName "azurecolumn04"  -TemplateFile .\azurecolumn04.json -TemplateParameterObject $parameter -Debug 

では実行してみましょう。

ログインアカウントの入力

Login-AzureRmAccountのところでAzureへのログインアカウントの入力が求められます。権限を絞り込むことも出来ると思いますが、すいません今回はサービス管理者権限を保持するユーザーで実行しています。

デプロイ中

デプロイ中は進行状況が逐一表示されます、が追いきれないので基本眺めているだけです。

ポータルではこんな感じです。

デプロイ完了

デプロイが完了すると、前回のデプロイに「成功」と表示されます

動作確認 (1)

ここまでではまだミドルウェアが入っていませんのでWebアプリケーションの確認は出来ませんが、仮想マシンの情報などを見て本当にデプロイが行われているかを確認してみましょう。

Get-AzureRMVMでリソースグループに4台の仮想マシンが作成されていることが確認できました。
では次は仮想マシン(AP1)へのSSHを確認してみましょう、IPアドレスはポータルまたはGet-AzureRmPublicIpAddressで取得してください。

SSHも無事行うことが出来ました、ひとまず仮想マシンは正常にデプロイされているようです。

ミドルウェアインストール&設定

ではあと一息ミドルウェアのインストール&設定を行って、Webアプリケーションの動作確認をしてみましょう。
実際に使用したコマンドと手順のサンプルを掲載します。

APサーバ

1. ミドルウェアのインストール

  • (1)  sudo apt-get update
  • (2)  sudo apt-get install mysql-server

2. AP用MySQLユーザーの作成

  • (1)  mysql -u root -p
     →  rootのパスワードを入力
  • (2)  create user mysqladmin identified by ‘パスワード';
  • (3)  grant all privileges on mysql.* to 'mysqladmin'@'%';

3. my.cnfの設定

  • (1)  sudo vi /etc/mysql/my.cnf
  • (2)  bindaddress行をコメントアウト

4. MySQL再起動

  • (1)  sudo /etc/init.d/mysql restart

動作確認 (2)

さあ最終動作確認です、ブラウザからロードバランサーのDNS名/テストモジュール名(本件では http://azurecolumn04-lb.japanwest.cloudapp.azure.com/phptest.php)にアクセスしてください。

成功です!ちょっとしょぼいですが一応MySQLから読み取った情報を表示できています。
念のためMySQLのクエリでも確認してみましょう。

一致が確認できました、これでAPからDBの情報が正しく読み取れていることが確認できましたね。

所要時間

テンプレートの作成秘密
デプロイ5分くらい
ミドルウェアインストール&設定30分くらい
削除5分くらい

まとめ

デプロイ~ミドルウェアインストール&設定~動作確認までの所要時間60分弱、いかがでしょうか?
しょぼくれたデモですので実際はもう少し時間かかると思いますがそれを差し引いてもやはり速いと思います。多分仮想マシンの払い出しくらいならオンプレミスでも同じくらいでできる可能性があると思いますが、ストレージやネットワークも込みとなるとさすがに無理でしょう。この速さがパブリッククラウドの最大の利点なのは間違いないですね。
次にテンプレートの作成について、これは最初から簡単とは言いませんが習熟による生産性の向上は期待できると言う感覚を持っています。あととにかく依存関係をARMで制御してくれるのが大きいです、これはクラシック時代のロジック込みのPowerShellスクリプトに比べて格段の進歩を感じた部分です。

次回予告

さて次回は「Azure Resource ManagerによるWebアプリケーション環境の展開~PaaS~」をお送りいたします。
PaaSでAPとDBだけだと多分面白くないと思いますので、SendGridやTraffic Managerなどの周辺リソースも組み合わせたいなとは考えています、がそこは苦戦具合に引っ張られますのでこうご期待と言う事で。

第5回コラム公開しました。


Azure コラム 第4回 「Azure Resource ManagerによるWebアプリケーション環境の展開~IaaS~」