Azure PowerShell に初めて挑戦する人のための手引き②【基礎編】
2020-04-10
azblob://2022/11/11/eyecatch/2020-04-09-tutorial2nd-for-azure-powershell-000.jpg

FIXER 藤井です。
Microsoft Azureで提供される純正のCUI( Command-Line User Interface )のうち、 「Azure PowerShell」に初めて挑戦する人に向けての手引きを解説するシリーズの第二回です。

本記事はAzure PowerShell に初めて挑戦する人のための手引き①【入門編】を、すでにお読みいただいていることを前提としております。まだの方は先に①【入門編】のチュートリアルを完了させてください。

チュートリアル

本記事ではチュートリアル(基礎編)としてWindows VMの1台構成の環境を題材として扱います。VMの構築からRDPによる接続の確認まで一連の作業全てを、Azure Portalを一切使わずにAzure PowerShellだけで完結させます。

準備

チュートリアルの中身に入る前に、 Azure PowerShell に初めて挑戦する人のための手引き①【入門編】より「準備①~準備③」 を参考に以下のコマンドを実行して、fixer-002-rgの名前でリソースグループを作成します。

New-AzResourceGroup -Name "fixer-002-rg" -Location "japaneast"

チュートリアル(基礎編)

Azure PowerShellを使って現場で作業するために身に着けておくべき概念や手法ごとに、VM構築に関する一連の作業を区切って、 以下の各チュートリアルのテーマとして設定しています。各チュートリアルはネットワークセキュリティグループや仮想ネットワークなど、前段までのチュートリアルで作成したリソースを使用する前提のため、途中をスキップすることはできません。

  • チュートリアル(基礎編)①:作成済みの親リソースに子リソースを追加する
  • チュートリアル(基礎編)②:親子関係のあるリソースを同時に作成する
  • チュートリアル(基礎編)③: 子リソースの設定を更新する
  • チュートリアル(基礎編)④: リソースIDを指定して参照先を特定する
  • チュートリアル(基礎編)⑤: VMのログオンパスワードを安全に格納する
  • チュートリアル(基礎編)⑥: パイプライン処理を用いてVMをデプロイする
  • チュートリアル(基礎編)【オマケ】: Azure PowerShellからRDPファイルを取得し起動する。

チュートリアル(基礎編)①~③の「親リソース/子リソース」、チュートリアル(基礎編)④の「リソースID」についてそれぞれ捕捉します。

  • 親リソース/子リソースについて:
    Azure上で作成するリソースは、「リソースグループに所属するリソース」と「上位のリソースに所属している子リソース」に分類できます。l「子リソースから見た上位のリソース」が「親リソース」です。Azure PowerShellで操作をするときに、「子リソース」は「リソースグループに所属するリソース」 と異なる考え方が必要になるため、チュートリアルのテーマとして取り上げます。「リソースグループに所属するリソース」については、Azure PowerShell に初めて挑戦する人のための手引き①【入門編】にて解説済みです。
    わかりやすい例としては、Azure PowerShell に初めて挑戦する人のための手引き①【入門編】および、後述の「チュートリアル(基礎編)①」で取り上げる「ネットワークセキュリティグループ」と「受信セキュリティ規則」の関係です。「ネットワークセキュリティグループ」が「親リソース」であり、「受信セキュリティ規則」が「子リソース」です。
  • リソースIDについて:
    Azure上で全て作成される全てのリソースはリソースIDと呼ばれる一意のIDを持ちます。Azure上のリソースから他の Azure上のリソースを参照するときに、 リソースID を使ってアクセス先を特定します。複数のリソースを組み合わせて構築するときに、リソースIDは必須となるためチュートリアルのテーマとして取り上げます。
    リソースIDは以下のような階層構造で構成されています。
    /subscriptions/【①サブスクリプションID】/resourceGroups/【②リソースグループ名】/providers/【③リソースプロバイダー名】/【④リソース種別】/【⑤リソース名】
    例えば「チュートリアル(基礎編)①」にて「fixer-nsg-for-rdp」の名前で作成するネットワークセキュリティーグループの場合、リソースIDは、 【②リソースグループ名】 より下の階層について以下のような値になります。
    /subscriptions/【①サブスクリプションID】/resourceGroups/fixer-002-rg /providers/Microsoft.Network/networkSecurityGroups/fixer-nsg-for-rdp
    「子リソース」のリソースIDも存在します。「チュートリアル(基礎編)①」で permmitInboundRDP の名前で作成する受信セキュリティ規則のリソースIDは以下のようになります。
    /subscriptions/【①サブスクリプションID】/resourceGroups/fixer-002-rg /providers/Microsoft.Network/networkSecurityGroups/ fixer-nsg-for-rdp/securityRules/permmitInboundRDP

チュートリアル(基礎編)① :作成済みの親リソースに子リソースを追加する

ネットワークセキュリティグループ(親リソース)を先に作成した状態で、受信セキュリティ規則 (子リソース) を追加します。 追加 する受信セキュリティ規則では、「自身のグローバルIPアドレス」を許可対象のアクセス元に指定して、 3389番ポート (RDPプロトコル )を開放します。 3389番ポート (RDPプロトコル )をインターネットに対して全開放する設定は、たとえ学習用の環境やテスト環境であっても絶対にお止めください。

  1. 以下のコマンドを実行して、fixer-nsg-for-rdpの名前でネットワークセキュリティーグループを作成します。
    New-AzNetworkSecurityGroup -Name "fixer-nsg-for-rdp" -Location "japaneast" -ResourceGroupName "fixer-002-rg"
  2. "ProvisioningState"が"Succeeded"で表示されればOKです。
  3. 以下のコマンドを実行し、作成したネットワークセキュリティーグループのリソース情報を取得します。
    $nsgObject = Get-AzNetworkSecurityGroup -Name "fixer-nsg-for-rdp" -ResourceGroupName "fixer-002-rg"
  4. 以下のURLにアクセスし、「自身のグローバルIPアドレス」を確認します。下図で黒塗りされている場所に、表示されます。
    https://www.cman.jp/network/support/go_access.cgi
  5. 以下のコマンドについて【グローバルアドレスIPアドレス】を手順4で確認した値で置き換えて実行します。この段階では端末側で$nsgObjectの変数が更新されただけで、まだAzure上のネットワークセキュリティグループには反映されていません。
    $nsgObject = Add-AzNetworkSecurityRuleConfig -NetworkSecurityGroup $nsgObject -Direction Inbound -SourceAddressPrefix 【グローバルアドレスIPアドレス】-SourcePortRange * -DestinationAddressPrefix * -DestinationPortRange 3389 -Priority 100 -Protocol Tcp -Access Allow -Name permmitInboundRDP -Description "Tech Blog"
  6. 以下のコマンドにより、Azure上のネットワークセキュリティグループの設定を更新します。
    Set-AzNetworkSecurityGroup -NetworkSecurityGroup $nsgObject
  7. 以下のコマンドにより"SourceAddressPrefix"の値として自身のグローバルIPアドレスが設定されていることを確認します。
    Get-AzNetworkSecurityGroup -Name "fixer-nsg-for-rdp" -ResourceGroupName "fixer-002-rg"

チュートリアル(基礎編)②: 親子関係のあるリソースを同時に作成する

仮想ネットワーク(親リソース)とサブネット(子リソース)を同時に作成します。サブネットに関する設定値一式をオブジェクト型変数に格納した状態で、引数の1つとして仮想ネットワークを作成するコマンドに渡します。

  1. 以下のコマンドにより、仮想ネットワーク内に作成するサブネットの設定を変数$subnetObjectに格納します。
    $subnetObject = New-AzVirtualNetworkSubnetConfig -Name subnet -AddressPrefix "10.0.1.0/24"
    各パラメーターは以下を意味します。
    -Name:作成するサブネットの名前
    -AddressPrefix :作成するサブネットのアドレス範囲
  2. 以下のコマンドにより、仮想ネットワークの作成を実行します。
    New-AzVirtualNetwork -Name "fixer-vnet-for-rdp" -ResourceGroupName "fixer-002-rg" -Location "japaneast" -AddressPrefix "10.0.0.0/16" -Subnet $subnetObject
    各パラメーターは以下を意味します。
    -Name : 作成する仮想ネットワークの名前
    -ResourceGroupName :仮想ネットワークを作成するリソースグループを指定
    -Location :仮想ネットワークを作成するリージョン
    -AddressPrefix :作成する 仮想ネットワーク のアドレス空間
  3. "ProvisioningState"が"Succeeded"で表示されればOKです。

チュートリアル(基礎編)③: 子リソースの設定を更新する

仮想ネットワーク(親リソース)配下のサブネット(子リソース)を、ネットワークセキュリティグループに所属させます。実行するコマンドの処理としては、ネットワークセキュリティグループの情報を取得し、サブネットに対して参照先として指定します。
ポイントは最後に Set-AzVirtualNetworkコマンドを実行する必要があることです。サブネット(子リソース)だけではなく仮想ネットワーク(親リソース)に対しても更新を実行することで、完了するということです。

  1. 以下のコマンドにより、ネットワークセキュリティグループの情報を取得します。
    $nsgObject = Get-AzNetworkSecurityGroup -Name "fixer-nsg-for-rdp" -ResourceGroupName "fixer-002-rg"
    -Name :対象のネットワークセキュリティーグループの名前(上の例では チュートリアル(基礎編)①で作成したfixer-nsg-for-rdp )
    -ResourceGroupName :対象のネットワークセキュリティーグループが所属するリソースグループ
  2. 以下のコマンドにより仮想ネットワークの情報を取得します。
    $vnetObject = Get-AzVirtualNetwork -Name "fixer-vnet-for-rdp" -ResourceGroupName "fixer-002-rg"
  3. 以下のコマンドによりサブネットの設定を更新します。
    Set-AzVirtualNetworkSubnetConfig -Name subnet -VirtualNetwork $vnetObject -AddressPrefix "10.0.1.0/24" -NetworkSecurityGroup $nsgObject
  4. 以下のコマンドにより仮想ネットワークの設定も更新します。
    Set-AzVirtualNetwork -VirtualNetwork $vnetObject
  5. "NetworkSecurityGroup"に"fixer-nsg-for-rdp" が表示されていればOKです。

チュートリアル(基礎編)④: リソースIDを指定して参照先を特定する

Azure PowerShellにおいて他のリソースを参照するときに、参照先を特定する方法は以下の2つがあります。チュートリアル(基礎編)④では、2つ目の「リソースID」を用いる方法を実施します。チュートリアル(基礎編)③の手順は、1つ目のオブジェクト型変数を用いる方法に相当します。

  • 参照先のリソース情報一式をオブジェクト型変数に格納し引数としてAzure PowerShellコマンドに渡す。
  • 参照先のリソースについて「リソースID」と呼ばれる一意の値を、文字列型変数に格納し、 引数としてAzure PowerShellコマンドに渡す。

チュートリアルでは「パブリックIPアドレス(上位の親リソースを持たない)」と、「サブネット(仮想ネットワークの子リソース)」それぞれについてリソースIDを用いて、仮想NICからの参照を設定します。手を動かしてみると以下の差異が実感できます。

  • パブリックIPアドレス :パブリックIPアドレスのリソース名とリソースグループ名の2点でリソースIDを取得できる。
  • サブネット: サブネットのリソース名と仮想ネットワークのリソース名とリソースグループ名の3点でリソースIDを取得できる。
  1. 以下のコマンドによりパブリックIPアドレスを作成します。
    New-AzPublicIpAddress -Name "fixer-pip-for-rdp" -ResourceGroupName "fixer-002-rg" -AllocationMethod Static -Location japaneast -IdleTimeoutInMinutes 4 -IpAddressVersion IPv4 -Sku Basic -Force
    各パラメータは以下の意味です。
    -Name : 作成する パブリックIPアドレス の名前
    -ResourceGroupName : パブリックIPアドレス を作成するリソースグループを指定
    -AllocationMethod :パブリックIPアドレスの割り当てが動的か静的かを決定します。
    -Location : パブリックIPアドレスを作成するリージョン
    -IdleTimeoutInMinutes : クライアントからキープアライブ メッセージを送信しなくても TCP 接続または HTTP 接続が開いたまま維持される時間 (分)
    -IpAddressVersion : IPv4もしくはIPv6を選択します。
    -Sku :価格がBasic/Standardを選択します。
    -Force :コマンド実行時の確認メッセージを省略
  2. "ProvisioningState"が"Succeeded"で表示されればOKです。
  3. 以下のコマンドによりパブリックIPアドレスのリソースIDを変数$pipIdに格納します。
    $pipId = (Get-AzPublicIpAddress -Name "fixer-pip-for-rdp" -ResourceGroupName "fixer-002-rg").Id
  4. 以下のコマンドにより仮想ネットワークのリソース情報一式を取得します。
    $vnetObject = Get-AzVirtualNetwork -Name "fixer-vnet-for-rdp" -ResourceGroupName "fixer-002-rg"
  5. 以下のコマンドによりサブネットのリソースIDを取得します。
    $subnetId = (Get-AzVirtualNetworkSubnetConfig -Name "subnet" -VirtualNetwork $vnetObject).Id
  6. 以下のコマンドにより、パブリックIPアドレスとサブネットのリソースIDをそれぞれ指定して、仮想NICを作成します。
    New-AzNetworkInterface -Name "nic_fixer_for_rdp" -ResourceGroupName "fixer-002-rg" -Location "japaneast" -SubnetId $subnetId -PublicIpAddressId $pipId
    各パラメータは以下の意味です。
    -Name : 作成する 仮想NIC の名前
    -ResourceGroupName : 仮想NIC を作成するリソースグループを指定
    -Location : 仮想NIC を作成するリージョン
    -SubnetId : 仮想NIC を登録するサブネットのリソースID
    - PublicIpAddressId: 仮想NIC に割り当てるパブリックIPアドレスのリソースID
  7. "ProvisioningState"が"Succeeded"で表示されればOKです。 また"Subnet"として"subnet"が、"PublicIpAddress"として"fixer-pip-for-rdp"が表示されています。

チュートリアル(基礎編)⑤: VMのログオンパスワードを安全に格納する

チュートリアル(基礎編)③のテーマは「PSCredentialを使用して、パスワード値を取り扱うこと」です。端末側でPoweshellターミナル内でパスワード文字列を暗号化することで、安全にAzure側へ送信できます。

  1. 以下のコマンドを実行します。
    $cred = Get-Credential
  2. 表示されたダイアログにて「アカウント名」として「techBlog」を「パスワード」として各自で設定した値を入力し、「OK」をクリックします。
  3. 「Credential」が表示されればOKです。

チュートリアル(基礎編)⑥:パイプライン処理を用いてVMをデプロイする

Azure PowerShellに限らず、PowerShellには「パイプライン処理」と呼ばれる記述法があり、よく利用されます。パイプラインを用いることで、複雑なオブジェクト構造の変数を引数にとるコマンドを簡便に記述できます。
本チュートリアルではVM構築時に使用される、複雑な構造のオブジェクト変数について、一連の手順にて以下の3通りの方法でコマンドを実行し、パイプラインの使用感を確かめます。

  • (A)パイプラインを用いない場合
  • (B)単一のコマンドについてパイプラインを用いる場合
  • (C)複数のコマンドについて連結してパイプラインを用いる場合
  1. 以下のコマンドによりVMのリソース名と仮想マシンサイズを指定して、以後の処理で各値を格納するオブジェクト変数を生成します。
    $vmConfig = New-AzVMConfig -VMName "vm-fixer-for-rdp" -VMSize "Standard_D2s_v3"
  2. 以下のコマンドによりチュートリアル(基礎編)⑤でPSCredentialに格納した値を使って、VMのログオンアカウントを設定し、またほかにコンピューター名とOSの種別(Windows / Linux) も指定します。
    $vmConfig = Set-AzVMOperatingSystem -VM $vmConfig -Credential $cred -ComputerName "fixer" -Windows
    上記は「 (A)パイプラインを用いない場合 」の記述です。右辺で-VMの引数として渡された $vmConfig の値を、更新した結果が左辺の $vmConfig に格納されています。
  3. 以下のコマンドにより、OSのイメージ取得元としてマーケットプレイスのWindows Server 2019を指定します。
    $vmConfig | Set-AzVMSourceImage -PublisherName 'MicrosoftWindowsServer' -Offer 'WindowsServer' -Skus '2019-Datacenter' -Version latest
    上記は「 (B)単一のコマンドについてパイプラインを用いる場合 」です。もしパイプラインを用いない場合、右辺と左辺の両方に $vmConfigが登場します。
  4. 以下のコマンドにより、 チュートリアル(基礎編)④で作成した仮想NICのリソースIDを取得します。
    $nicId = (Get-AzNetworkInterface -Name "nic_fixer_for_rdp" -ResourceGroupName "fixer-002-rg").Id
  5. 以下のコマンドにより、仮想マシンを作成します。
    $vmConfig | Add-AzVMNetworkInterface -Id $nicId | New-AzVm -ResourceGroupName "fixer-002-rg" -Location "japaneast"
    上記は「 (C)複数のコマンドについて連結してパイプラインを用いる場合 」です。「仮想NICの追加」と「VMの構築」の2つの処理を連結しています。
  6. "IsSuccessStatusCode"が"True"で表示されればOKです。

チュートリアル(基礎編)【オマケ】: Azure PowerShellからRDPファイルを取得し起動する。

Azure上に構築したWindows VMにRDP接続するときは、Azure PortalからダウンロードしたRDPファイルを利用すると便利ですが、本記事ではあえてAzure PowerShell から RDPファイルを 取得する方法をご紹介します。
※以前に藤井が参画したプロジェクトで、「GUIツールを一切使わずに、CLIツールだけですべてが完結するようにオペレーションを設計せよ」という要件があり、調べた結果です。もし同じ要件に向き合っている方がいたらご参照ください。

  1. 以下のコマンドを実行します。
    Get-AzRemoteDesktopFile -ResourceGroupName "fixer-002-rg" -Name "vm-fixer-for-rdp" -Launch
  2. RDPクライアントが起動します。
  3. チュートリアル(基礎編)⑤で設定した資格情報を入力します。
  4. 証明書の警告が出たら「はい」をクリックします。
  5. Windows Serverのデスクトップにログオンが成功したらOKです。

解説

Azure PowerShellに初めて取り組むと、一見するとサービスの種別によって操作の流れが異なっていて、しかも「別解」がMSの公式サイトに複数存在していて、「文法」が存在せず1つ1つを暗記しなければいけないような印象を受けるかもしれません。実際は本記事で取り上げた以下のパターンの組み合わせで対処できるケースが多く、全てを暗記しないといけないというわけではありません。

  • 「リソースグループに所属するリソース」と「上位のリソースに所属している子リソース」の違い:前者は対象のリソースの操作のみを意識していればよく、後者は所属している親リソースの存在を意識する必要があります。
  • 設定項目の数が多かったり、オブジェクト構造の階層数が多い場合(VMが代表例):基本的には「(1)オブジェクト変数の生成」→「(2)オブジェクト変数を操作する各コマンドの実行」→「(3)Azureへの実行コマンド」の流れです。パイプラインを使えば一行の処理として連結させることも可能です。

後はこれを読んだ皆さんが手を動かして実行していただくのみです。どうかひるまずにチャレンジしてください。