そろそろ、リソースマネージャーの仮想マシン (仮想マシン v2) も触れるようにならないとなと思い、PowerShell で要素ごとに作成して勉強をしてみました。
今回の投稿は Azure PowerShell 1.0.1 を使用しています。
テンプレート展開する場合は、Azure リソース マネージャーのテンプレートを使用した、可用性の高い Active Directory ドメイン サービスのドメインのデプロイ あたりの内容が参考になる感じでしょうか。
PowerShell の個々のコマンドレットについては Azure PowerShell 1.0 から確認することができます。
今回の投稿を書くにあたって、以下の情報を参考にさせていただきました。
さすが我らのお義父さん? & マグナムさん!!
Azure リソース マネージャーの概要
リソース マネージャーと Azure PowerShell を使用して、Windows 仮想マシンを作成し、構成する
Azure リソース マネージャーでの Azure PowerShell の使用
Azure リソース マネージャーと PowerShell を使用した仮想マシンの管理
New-AzureRmVM
Manage virtual machines using Azure Resource Manager and PowerShell
Azure PowerShell で仮想マシンV2を作成する
仮想マシンV2 と ロードバランサーを作成するサンプルスクリプト
Microsoft Azure の ARM 版の仮想マシンで NIC を差し替えてみる
nmackenzie/LoadBalancedVM.ps1
ARM の場合、テンプレート展開をする機会もあるかと思いますが、テンプレートのサンプルについては、以下の情報を追う形でしょうか。
azure-quickstart-templates
Azure Resource Explorer
# リソースエクスプローラーはプレビューポータルの「参照」→「リソースエクスプローラー」からも開けます。
今回使用した構成と近いテンプレートは以下になるかと。
101-vm-with-rdp-port
201-2-vms-internal-load-balancer
仮想マシンの作成時にしか設定できないものを設定変更したい場合は、以下を参考に再作成をすればよいかと。
AzureRM – Reprovision existing VM into an Availability Set.ps1
■必須コンポーネントの作成
最初に
- リソースグループ
- 仮想ネットワーク
- ストレージアカウント
を作成します。
リソースマネージャーの仮想マシンは、リソースグループと仮想ネットワークへの参加が必須となるようですので、これらを作成し、仮想マシンのディスクを格納するストレージの作成も併せて行います。
まずは、RM 向けの Add-AzureAccount相当のコマンドレットでログインして、操作するサブスクリプションを選択します。
$azaccount = Login-AzureRmAccount $subscription = Get-AzureRmSubscription | Out-GridView -OutputMode Single Select-AzureRmSubscription -SubscriptionId $subscription.SubscriptionId # Set-AzureRmContext -SubscriptionId $Subscription.SubscriptionId
次に、各リソースを作成していきます。
最初にリソースグループを作成し、
# リソースグループの作成 $rgroup = "<リソースグループ名>" New-AzureRmResourceGroup -Location $location -Name $rgroup
# ストレージアカウントの作成 $storagename = "<ストレージアカウント名>" New-AzureRmStorageAccount -Location $location -ResourceGroupName $rgroup -Name $storagename -type Standard_LRS
# 仮想ネットワークの作成 $vnetname = "<仮想ネットワーク名>" $addressprefix = "<仮想ネットワーク IP プレフィックス (10.0.0.0/16)" $subnetname = "<サブネット名> $subnetprefix = "<サブネットプレフィックス (10.0.0.0/24)>" $vnet = New-AzureRmVirtualNetwork -Location $location -ResourceGroupName $rgroup -Name $vnetname -AddressPrefix $addressprefix Add-AzureRmVirtualNetworkSubnetConfig -VirtualNetwork $vnet -Name $subnetname -AddressPrefix $subnetprefix | Set-AzureRmVirtualNetwork
ここまでで、リソースグループ内に以下のようなリソースが作成された状態となります。
■仮想マシンの作成
次に仮想マシンを作成していきます。
リソースマネージャーの仮想マシンでは、NIC も独立したリソースとなっていますので、最初に NIC を作成します。
NIC は特定の仮想ネットワーク/サブネットに関連付ける必要がありますので、先ほど作成した仮想ネットワークを NIC に設定しています。
# NIC の設定 $interfacename = "vmv2test_vnic01" $subnet = (Get-AzureRmVirtualNetwork -ResourceGroupName $rgroup -Name $vnetname).Subnets[0] New-AzureRmNetworkInterface -Location $location -ResourceGroupName $rgroup -Name $interfacename -Subnet $subnet
次に仮想マシンを作成するためにコンフィグを設定しています。
最初に、仮想マシンのサイズと仮想マシンの設定上の名称を設定します。
# 今回は「$vm」という変数に仮想マシンのコンフィグを追加していきます。
最終的にロードバランサーを使うため「Basic」ではなく「Standard」を使用しています。
# VM サイズを設定 $vmname = "v2VM" $vm = New-AzureRmVMConfig -VMName $vmname -VMSize "Standard_A0"
次に、仮想マシンで使用する OS のイメージを設定します。
今回は、Windows Server 2012 R2 の最新のイメージを選択しています。
# OS 用イメージの選択 $vmimage = Get-AzureRmVMImagePublisher -Location $location | ? PublisherName -Like "*Microsoft*" | ` Get-AzureRmVMImageOffer | ? Offer -eq "WindowsServer"| ` Get-AzureRmVMImageSku | ? Skus -eq "2012-R2-Datacenter" | ` Get-AzureRmVMImage | Sort-Object Version -Descending | select -First 1 $vmimage | Set-AzureRmVMSourceImage -VM $vm
次に、仮想マシンの実際のコンピューター名や、管理者ユーザー名/パスワードを設定します。
# 「-Credential」に指定した内容が仮想マシンの管理者となります。
# 仮想マシンの設定 $computername = "V2TEST" $admincred = Get-Credential Set-AzureRmVMOperatingSystem -VM $vm -Windows -ComputerName $computername -ProvisionVMAgent -EnableAutoUpdate -Credential $admincred
次に、仮想マシンに先ほど作成した NIC を関連付けます。
# 仮想マシンに NIC を追加 $interface = Get-AzureRmNetworkInterface -ResourceGroupName $rgroup -Name $interfacename Add-AzureRmVMNetworkInterface -VM $vm -NetworkInterface $interface
最後の設定として、仮想マシンのイメージを保存するためのストレージの場所と仮想ディスクの名称を設定します。
# OS 用ディスクの保存場所の指定 $osdisk = $vmname + "_OSDisk" $storage = Get-AzureRmStorageAccount -ResourceGroupName $rgroup -Name $storagename $osdiskuri = $storage.PrimaryEndpoints.Blob.ToString() + "vhds/" + $osdisk + ".vhd" Set-AzureRmVMOSDisk -VM $vm -Name $osdisk -VhdUri $osdiskuri -CreateOption FromImage
ここまでの作業で、仮想マシンを作成するためのコンフィグが「$vm」という変数に設定できた状態となります。
この状態ではまだ仮想マシンは作成されていませんので、コンフィグを使用して仮想マシンを作成します。
# 仮想マシンの作成 New-AzureRmVM -Location $location -ResourceGroupName $rgroup -VM $vm
現状の仮想マシンでは、仮想マシンの作成時にのみ可用性セットが設定できるため、可用性セットを使用する場合は、仮想マシンの作成時に設定します。
$avName="<availability set name>" $rgName="<resource group name>" $locName="<location name, such as West US>" New-AzureRmAvailabilitySet ?Name $avName ?ResourceGroupName $rgName -Location $locName New-AzureRmVMConfig -Location $location -ResourceGroupName $rgroup -VM $vm -AvailabilitySetId $avset.Id
これで仮想マシンのベースの部分の作成は完了した形となります。
ここまでのリソースグループの内容がこちらになります。
■パブリック IP の設定
ここまでで仮想マシンの作成は完了しているのですが、ここまでの作業で作成した仮想マシンにはパブリック IP が割り当てられていません。
リソースマネージャーの仮想マシンですが、パブリック IP を割り当てなくても作成をすることができます。
同一の仮想ネットワーク内に、パブリック IP が割り当てられている踏み台のようなサーバーがあればよいのですが、今回はないため、外部からアクセスをする場合には、NIC にパブリック IP を割り当てます。
# 現状は、パブリック IP が設定されていないため、「接続」がグレーアウトしています。
パブリック IP 自体も一つのリソースとなりますので、最初にパブリック IP のリソースを作成します。
# パブリック IP の設定 $pipname = "<パブリック IP リソース名>" New-AzureRmPublicIpAddress -Location $location -ResourceGroupName $rgroup -Name $pipname -AllocationMethod Dynamic
# NIC に PIP を設定 $pip = Get-AzureRmPublicIpAddress -ResourceGroupName $rgroup -Name $pipname $interface.IpConfigurations[0].PublicIpAddress = $pip Set-AzureRmNetworkInterface -NetworkInterface $interface
NIC に対してパブリック IP を関連付けられていることが確認できますね。
その NIC を使用している仮想マシンについてもパブリック IP アドレスのリソースから確認することができます。
これで、NIC がパブリック IP を持ちましたので、「接続」をクリックできるようになります。
接続をするとパブリック IP の「3389」に対して接続を行いに行きます。
クラシックな仮想マシンの場合は、「hogehoge.cloudapp.net」に対して接続が行われていたかと思います。
リソースマネージャーでは「DNS 名ラベル」はオプション扱となっており、必要な場合は、パブリック IP のアドレスのリソースで設定することができます。
今回は西日本に作成していますので「hogehoge.japanwest.cloudapp.azure.com」というDNS 名ラベルを使用することができます。
# DNS 名ラベルを設定 $domainlabel = "<DNS ラベル名>" $dnssetting = New-object Microsoft.Azure.Commands.Network.Models.PSPublicIpAddressDnsSettings $dnssetting.DomainNameLabel = $domainlabel $pip = Get-AzureRmPublicIpAddress -ResourceGroupName $rgroup -Name $pipname $pip.DnsSettings = $dnssetting Set-AzureRmPublicIpAddress -PublicIpAddress $pip
これで、パブリック IP だけでなく、DNS 名でも接続ができるようになります。
ここまでのリソースグループの内容がこちらになります。
■ロードバランサー経由でアクセスする
先ほどのアクセスは、パブリック IP が割り当てられている NIC を仮想マシンに関連付けして、仮想マシン自体を直接インターネットに出す方法で接続をしていました。
検証環境で使用する場合はこれでもよいですが、実際に使用する場合、このパターンではなくロードバランサー経由でアクセスすることが多いかと思います。
最後にロードバランサー経由でリモートデスクトップする設定を行ってみたいと思います。
先ほど使用したパブリック IP をロードバランサーにつけたいと思いますので、まずは NIC からパブリック IP の関連付けを削除します。
# NIC から パブリック IP 削除 $interface.IpConfigurations[0].PublicIpAddress = $null Set-AzureRmNetworkInterface -NetworkInterface $interface
次にロードバランサーを作成します。
リソースマネージャーではロードバランサーも一つのリソースとして定義されます。
# ロードバランサーの作成 $lbname = "<ロードバランサー名>" New-AzureRmLoadBalancer -Location $location -ResourceGroupName $rgroup -Name $lbname
次にロードバランサーにアクセスする際のフロンドエンドの IP アドレスとしてパブリック IP を設定します。
# フロントエンド IP の設定 $lbfipname = "<フロントエンド IP 名>" $pip = Get-AzureRmPublicIpAddress -ResourceGroupName $rgroup -Name $pipname $fip = New-AzureRmLoadBalancerFrontendIpConfig -Name $lbfipname -PublicIpAddress $pip $lb = Get-AzureRmLoadBalancer -ResourceGroupName $rgroup -Name $lbname $lb.FrontendIpConfigurations = $fip Set-AzureRmLoadBalancer -LoadBalancer $lb
この状態では、ロードバランサー配下で起動している仮想マシンがありませんので、パブリック IP アドレスのリソースはロードバランサーに関連付けられている状態なのですが、パブリック IP は割り当てられていません。
# 関連付けがロードバランサーになっていることは確認できます。
次にロードバランサーの特定のポートにアクセスされた場合、仮想マシンにリダイレクトする NAT のルールを作成します。
今回は、ロードバランサーの「33389」のアクセスを、仮想マシンの「3389」にリダイレクトするルールを設定しています。
# NAT ルールの設定 $rdprule = "NAT ルール名" $lb = Get-AzureRmLoadBalancer -ResourceGroupName $rgroup -Name $lbname $fip = New-AzureRmLoadBalancerFrontendIpConfig -Name $lbfipname -PublicIpAddress $pip $natrule = New-AzureRmLoadBalancerInboundNatRuleConfig -Name $rdprule -FrontendIpConfiguration $fip -Protocol TCP -FrontendPort 33389 -BackendPort 3389 $lb.InboundNatRules = $natrule Set-AzureRmLoadBalancer -LoadBalancer $lb
最後に、ロードバランサーの背後に存在する仮想マシンを含める、バックエンドアドレスプールを作成します。
この段階では、バックエンドアドレスプールという設定を加えるだけで、プールに仮想マシンの登録は行っていません。
# バックエンドアドレスプールの設定 $bapoolname = "<バックエンドアドレスプール名>" $bapool = New-AzureRmLoadBalancerBackendAddressPoolConfig -Name $bapoolname $lb = Get-AzureRmLoadBalancer -ResourceGroupName $rgroup -Name $lbname $lb.BackendAddressPools = $bapool Set-AzureRmLoadBalancer -LoadBalancer $lb
ここまででロードバランサーの設定は完了しました。
最終的に作成されたリソースがこちらになります。
ロードバランサーへの関連付けは NIC 単位で実施しますので、先ほどまで使用していた NIC をロードバランサーに関連付け、NAT ルールも併せて NIC に付与します。
# ロードバランサーと NAT ルールに関連づいた NIC に設定変更 $interface = Get-AzureRmNetworkInterface -ResourceGroupName $rgroup -Name $interfacename $lb = Get-AzureRmLoadBalancer -ResourceGroupName $rgroup -Name $lbname $interface.IpConfigurations[0].LoadBalancerBackendAddressPools = $lb.BackendAddressPools $interface.IpConfigurations[0].LoadBalancerInboundNatRules = $lb.InboundNatRules Set-AzureRmNetworkInterface -NetworkInterface $interface
これで、仮想マシンがロードバランサー/NAT ルールに関連づきましたので、仮想マシンの接続を行うと、ロードバランサーに割り当てられているパブリック IP の NAT ルールのポートに接続がされる RDP ファイルがダウンロードされます。
今回は単純な一台構成の仮想マシンではありますが、PowerShell で構成要素ごとに作成して、少し流れがわかった気がします。
今回使ったスクリプトのサンプルの設定値を含めた全体はこちら。
# https://msdn.microsoft.com/en-us/library/azure/mt619274.aspx # https://msdn.microsoft.com/en-us/library/azure/mt603754.aspx # http://statemachine.hatenablog.com/entry/2015/07/06/183650 # http://statemachine.hatenablog.com/entry/2015/07/22/183239 # https://azure.microsoft.com/ja-jp/documentation/articles/resource-group-overview/ # https://gist.github.com/nmackenzie/54e9fe4bb34f8d6bce2e $azaccount = Login-AzureRmAccount $subscription = Get-AzureRmSubscription | Out-GridView -OutputMode Single Select-AzureRmSubscription -SubscriptionId $subscription.SubscriptionId # Set-AzureRmContext -SubscriptionId $Subscription.SubscriptionId $location = "japanwest" # リソースグループの作成 $rgroup = "ARMTestRG" New-AzureRmResourceGroup -Location $location -Name $rgroup # ストレージアカウントの作成 $storagename = "armvmteststorage001" New-AzureRmStorageAccount -Location $location -ResourceGroupName $rgroup -Name $storagename -type Standard_LRS # 仮想ネットワークの作成 $vnetname = "vmv2testnw" $addressprefix = "10.0.0.0/16" $subnetname = "vmv2testnw_subnet01" $subnetprefix = "10.0.0.0/24" $vnet = New-AzureRmVirtualNetwork -Location $location -ResourceGroupName $rgroup -Name $vnetname -AddressPrefix $addressprefix Add-AzureRmVirtualNetworkSubnetConfig -VirtualNetwork $vnet -Name $subnetname -AddressPrefix $subnetprefix | Set-AzureRmVirtualNetwork # NIC の設定 $interfacename = "vmv2test_vnic01" $subnet = (Get-AzureRmVirtualNetwork -ResourceGroupName $rgroup -Name $vnetname).Subnets[0] New-AzureRmNetworkInterface -Location $location -ResourceGroupName $rgroup -Name $interfacename -Subnet $subnet # VM サイズを設定 $vmname = "v2VM" $vm = New-AzureRmVMConfig -VMName $vmname -VMSize "Standard_A0" # OS 用イメージの選択 $vmimage = Get-AzureRmVMImagePublisher -Location $location | ? PublisherName -Like "*Microsoft*" | ` Get-AzureRmVMImageOffer | ? Offer -eq "WindowsServer"| ` Get-AzureRmVMImageSku | ? Skus -eq "2012-R2-Datacenter" | ` Get-AzureRmVMImage | Sort-Object Version -Descending | select -First 1 $vmimage | Set-AzureRmVMSourceImage -VM $vm # 仮想マシンの設定 $computername = "V2TEST" $admincred = Get-Credential Set-AzureRmVMOperatingSystem -VM $vm -Windows -ComputerName $computername -ProvisionVMAgent -EnableAutoUpdate -Credential $admincred # 仮想マシンに NIC を追加 $interface = Get-AzureRmNetworkInterface -ResourceGroupName $rgroup -Name $interfacename Add-AzureRmVMNetworkInterface -VM $vm -NetworkInterface $interface # OS 用ディスクの保存場所の指定 $osdisk = $vmname + "_OSDisk" $storage = Get-AzureRmStorageAccount -ResourceGroupName $rgroup -Name $storagename $osdiskuri = $storage.PrimaryEndpoints.Blob.ToString() + "vhds/" + $osdisk + ".vhd" Set-AzureRmVMOSDisk -VM $vm -Name $osdisk -VhdUri $osdiskuri -CreateOption FromImage # 仮想マシンの作成 New-AzureRmVM -Location $location -ResourceGroupName $rgroup -VM $vm # パブリック IP の設定 $pipname = "vmv2test_pip" New-AzureRmPublicIpAddress -Location $location -ResourceGroupName $rgroup -Name $pipname -AllocationMethod Dynamic #-DomainNameLabel $domainlabel # NIC に PIP を設定 $pip = Get-AzureRmPublicIpAddress -ResourceGroupName $rgroup -Name $pipname $interface.IpConfigurations[0].PublicIpAddress = $pip Set-AzureRmNetworkInterface -NetworkInterface $interface # DNS 名ラベルを設定 $domainlabel = "vmtestaccesspoint" $dnssetting = New-object Microsoft.Azure.Commands.Network.Models.PSPublicIpAddressDnsSettings $dnssetting.DomainNameLabel = $domainlabel $pip = Get-AzureRmPublicIpAddress -ResourceGroupName $rgroup -Name $pipname $pip.DnsSettings = $dnssetting Set-AzureRmPublicIpAddress -PublicIpAddress $pip # NIC から パブリック IP 削除 $interface.IpConfigurations[0].PublicIpAddress = $null Set-AzureRmNetworkInterface -NetworkInterface $interface # ロードバランサーの作成 $lbname = "v2VMLB" New-AzureRmLoadBalancer -Location $location -ResourceGroupName $rgroup -Name $lbname # フロントエンド IP の設定 $lbfipname = "v2VMLB_FIP" $pip = Get-AzureRmPublicIpAddress -ResourceGroupName $rgroup -Name $pipname $fip = New-AzureRmLoadBalancerFrontendIpConfig -Name $lbfipname -PublicIpAddress $pip $lb = Get-AzureRmLoadBalancer -ResourceGroupName $rgroup -Name $lbname $lb.FrontendIpConfigurations = $fip Set-AzureRmLoadBalancer -LoadBalancer $lb # NAT ルールの設定 $rdprule = "v2VMRDP" $lb = Get-AzureRmLoadBalancer -ResourceGroupName $rgroup -Name $lbname $fip = New-AzureRmLoadBalancerFrontendIpConfig -Name $lbfipname -PublicIpAddress $pip $natrule = New-AzureRmLoadBalancerInboundNatRuleConfig -Name $rdprule -FrontendIpConfiguration $fip -Protocol TCP -FrontendPort 33389 -BackendPort 3389 $lb.InboundNatRules = $natrule Set-AzureRmLoadBalancer -LoadBalancer $lb # バックエンドアドレスプールの設定 $bapoolname = "v2VMBApool" $bapool = New-AzureRmLoadBalancerBackendAddressPoolConfig -Name $bapoolname $lb = Get-AzureRmLoadBalancer -ResourceGroupName $rgroup -Name $lbname $lb.BackendAddressPools = $bapool Set-AzureRmLoadBalancer -LoadBalancer $lb # ロードバランサーと NAT ルールに関連づいた NIC に設定変更 $interface = Get-AzureRmNetworkInterface -ResourceGroupName $rgroup -Name $interfacename $lb = Get-AzureRmLoadBalancer -ResourceGroupName $rgroup -Name $lbname $interface.IpConfigurations[0].LoadBalancerBackendAddressPools = $lb.BackendAddressPools $interface.IpConfigurations[0].LoadBalancerInboundNatRules = $lb.InboundNatRules Set-AzureRmNetworkInterface -NetworkInterface $interface