Azure VMの割り当て解除、停止忘れ対策

 

今回は、Azure Virtual Machine(VM)を止めたつもりなのに、停止し忘れて課金が発生しているVMを一覧出力して停止するPower Shellを作ってみました。

Azureを触り始めて最初の頃に非常に戸惑ったのですが、AzureのVMでは、OSでシャットダウンコマンドを発行しても課金が停止しません。

VMの起動状態には、大きく分けてVM自体の起動状態とOSの起動状態という2つの考え方があります。

電源ON、OS停止、電源オフという流れを具体的に書くとこんな感じになります。

    • 電源ON(Azure Portalで開始をクリックする) 1→3
    • OSでシャットダウンコマンド発行 3→5
    • 電源Off(Azure Portalで停止をクリックする) 5→7
  VMの状態 状態 PowerState 課金

1

停止済み(割り当て解除)

電源Off VM deallocated 課金されない
2 起動中 VM、OS起動中 VM starting 課金される
3 起動済み OS起動済み VM running 課金される
4 停止中 OS停止中 VM stopping 課金される
5 停止済み OS停止 VM stopped 課金される

6

停止中(割り当て解除中)

VM停止中 VM deallocating 課金される

7

停止済み(割り当て解除)

電源Off VM deallocated 課金されない

OSでシャットダウンコマンドを発行しても、OSは停止するのですが、VMのリソース解放はされてない状態(OS停止、VM起動)になります。その為継続して課金が発生します。

OSのみシャットダウンして、VM停止し忘れて課金が発生し続けるという事が結構ありました。

そこで、VMの課金が発生し続ける事態を防ぐために、OSのみがシャットダウンされている状態のVM一覧を取得し停止するPower Shellを作ってみました。

Azure VM停止時にディスクタイプを変更するPower Shellも作っておりますので、こちらも見て頂ければと。

Power ShellでAzure VM起動/停止と一緒にディスクタイプを変更する

1 .Azure Portal上でVMの電源状態を確認してみる。

最初にAzure PortalでVMの電源状態を確認してみました。VMのメニューの概要(VMを選択すると一番最初に表示される画面)の状態が電源状態を示すます。

 1) VMが完全に停止している状態(1の状態)(課金が発生しない状態)

 

 2) VMが実行されている状態(3の状態)

 

 3) OSのみがシャットダウンしている状態(5の状態)(課金が発生している状態)

 

 また、Virtual Machinesのメニューでも一覧で確認する事ができます。

 

.Power Shellを使ってVMの電源状態を確認するにはGet-AzVM -status

PowerShellでVMの電源状態を確認するには、Get-AzVM コマンドを利用します。

Get-AzVM -statusのPowerStateが電源状態に対応します。

VM名とVMのステータスのみを取得する場合の例を示します。ftでコマンドの実行結果の中で表示される内容をVM名(Name)と電源状態(PowerState)に絞ってます。

#見れるVMのすべての電源状態を見る場合

PS> Get-AzVM -Status |ft Name,PowerState

Name PowerState
—- ———-
VM1 VM deallocated
VM2 VM deallocated

#リソースグループを指定してVMの電源状態を見る場合

PS> Get-AzVM -Status -ResourceGroupName “リソースグループ名” |ft Name,PowerState

.VMの電源状態を取得して電源オフにするPower Shell(無駄な課金が発生してるVMの一覧を取得する)

不必要な課金が発生しているVMはPowerState が “VM Stoppe”になっているVMになります。

そこでPowerState が “VM Stoppe”の一覧取得しPower Shellで実施してみました。併せてVM停止をするようにしています。

    • #VMの状態を取得部分で、PowerState が “VM Stopped”の一覧を取得しています。
    • リソースグループを指定して実施するようにしています。
    • $vmstoporcheckを指定する事で、確認のみか停止するかを選択できるようにしています。
    • Stop-AzVMに-Forceをつける事で停止時の確認メッセージが表示されないようにしています。

#VM 割り当て解除忘れ漏れ対策 PowerShell

#RGを指定します。(RGを指定しない場合は下記3行をコメントアウトします。)
param (
        [string] [Parameter(Mandatory=$true)]  $resourceGroupName
      )

#確認のみの場合は0を選択する
$vmstoporcheck=1

#VM の状態を取得
    $vmstat = (Get-AzVM -Status `
    | Select-Object ResourceGroupName,Name,PowerState `
    | Where-Object { $_.PowerState -eq “VM Stopped” } )

#RGを指定する場合
    foreach ($vmstatus in $vmstat | Where-Object {$_.ResourceGroupName -eq $resourceGroupName })

#RGを指定しない場合
#   foreach ($vmstatus in $vmstat)

{
    if($vmstoporcheck -eq 1){
  
        Write-Host “Stop VM Name: $($vmstatus.Name)”
        Stop-AzVM -ResourceGroupName $vmstatus.resourceGroupName -Name $vmstatus.Name -Force
    
    }else{

        Write-Host “Stop VM Name: $($vmstatus.Name)”

    }
}

作成したPowerShellはGitHubにも公開しています。

https://github.com/Tama-negi/Li-akb-branch-office/tree/PowerShell_Azure/VmPowerStatusCheck_20200607

※VMのPowerState が “VM Stopped”になっていても、意図的にその状態で置かれているケースもあるかと思います。その編は実際の利用環境に合わせて注意願います。

※マイクロソフトサポート様より教えて頂いたサンプルをもとに作成しています。

Azure Front Doorのキャッシュを更新する

 

Azure Front Doorにはコンテンツキャッシュの機能があります。

https://docs.microsoft.com/ja-jp/azure/frontdoor/front-door-caching

キャッシュの機能を利用する事により、バックエンドプール側の負荷を下げたり、レスポンスタイムの向上が期待できます。

キャッシュ自体は、アクセスされたURLパスを保持します。同じURLに対して2回目のアクセスからキャッシュが使用される動きとなります。

一方で、Front Door自体はバックエンドプール側のサイト更新を能動的に検知する事はありません。

Front Doorでコンテンツがキャッシュされてしまうと、WEBサーバ側でサイトが更新しても反映されない事態が起こります。

Front Doorでキャッシュを有効にしていた場合、Webサイトの更新に合わせて、FrontDoor側のキャッシュクリアを行う事が必要になります。

今回は、Azure Front Doorのキャッシュクリア方法について確認してみました。

Azure Front Doorのキャッシュ期間についてはこちらの記事も併せて見て頂ければと。

Azure Front Doorのキャッシュ期間が指定出来るようになったようです

1.Azure Froot Doorのキャッシュはクリアだけできる

Azure Front DoorのキャッシュをAzure Portal上で更新する事は出来ません。その為今回はPower Shellを使って実施してみました。

キャッシュを更新するには、以下のようにサイト更新後にキャッシュクリアを行う必要があります。

    1. サイト更新
    2. キャッシュクリア
    3. サイトへのアクセス

Front Doorのキャッシュクリアには、Remove-AzFrontDoorContentコマンドを使用します。

https://docs.microsoft.com/ja-jp/powershell/module/az.frontdoor/Remove-AzFrontDoorContent?view=azps-3.8.0

今回はサンプルで以下のようなPowerShellを作成してみました。(GitHubにも公開しています。)

#Front DoorのキャッシュクリアをするPower Shell

param (
    [String] [Parameter(Mandatory=$true)]  $ResourceGroupName ,
    [String] [Parameter(Mandatory=$true)]  $FrontDoorName ,
    [String] [Parameter(Mandatory=$true)]  $ContentPath
    )

Remove-AzFrontDoorContent -ResourceGroupName $ResourceGroupName -Name $FrontDoorName -ContentPath $ContentPath
| where Category == “FrontdoorWebApplicationFirewallLog”
 

以下のように実行して頂く事で、キャッシュのクリアが可能です。

c:\FrontDoorのキャッシュをクリアする.ps1 -ResourceGroupName “リソースグループ名” -FrontDoorName “フロントドア名” -ContentPath “削除するパス (例:/*)”

サイト更新後に、今回のようなPower Shellを利用してキャッシュクリアする事により、更新したけど反映されないという事が防げるかと思います。

※マイクロソフトサポート様に色々ご教授頂きながら進めさせて頂きました。本当に有難うございます。

Azure VMの稼働ステータスやIPアドレス、ディスク情報を纏めて取得

 

Azure Portal上で、Virtual Machineの設定を確認しようとすると、ディスクの情報はディスクのメニューを開き、ネットワークインターフェースの情報は、ネットワークインターフェースのメニューを開きという事で少し面倒だったりします。

これをまとめて見れないかなぁという事で、Power Shellで情報取得する事に挑戦してみました。

作成にあたっては以下の各コマンド(Get-AzDisk、Get-AzNetworkInterface)ガイドをサイトを参考に進めました。

https://docs.microsoft.com/en-us/powershell/module/az.network/get-aznetworkinterface?view=azps-3.8.0

https://docs.microsoft.com/en-us/powershell/module/az.compute/get-azdisk?view=azps-3.8.0

今回作成したものは GitHub上に公開しています。

https://github.com/Tama-negi/Li-akb-branch-office/tree/PowerShell_Azure/VM-Status-Get-20200424

1.Azure VMに関して使って取得する情報

今回は指定したVMについて稼働状況、DISK情報、ネットワークインターフェースの下記情報を取得してみました。

    • Virtual Machine名
    • PowerState
    • VMSize
    • DISK名
    • DISKサイズ
    • DSIKのTier
    • Network Interface名
    • Private IP Address
    • 静的IP or 動的IP

2.Azure VMの情報を取得するPower Shell

Get-AzVM でVirtual Machineの情報を取得し、その中にあるVM固有のIDを特定します。

Virtual Machineにディスクがアタッチされている場合は、このIDがディスクの情報に含まれます。そこで合致するディスクのディスク情報をGet-AzDiskで取得します。同じく ネットワークインターフェース情報はGet-AzNetworkInterfaceで取得しています。

また、Get-AzVMに-Statusオプションがないと、VMの稼働状況が取得出来ません。

一方で、-StatusオプションをつけるとVmSizeが取得出来ません。

その為、VmSizeの方は@{n=”VMSize”; e={$vm.HardwareProfile.VmSize}}とし、-Status無しの結果から値を取得しています。

#VMの情報を取得するPowerShell(基本編)

#VM名を指定して、IF名、IP、DISK名、サイズ、SKU等を取得

#パラメータ指定
param (
    [String] [Parameter(Mandatory=$true)] $VMName
    )

# VM Status 取得

$vm = Get-AzVM -name $VMName

# サブスクリプションID指定

$SubscriptionId =“サブスクリプションID”
Select-AzSubscription -SubscriptionId $SubscriptionId 

# VMの各情報を取得

Get-AzVm -ResourceGroupName $vm.ResourceGroupName -Name $vm.Name -Status `
| select-Object Name,@{n=”Status”; e={$_.Statuses[1].Code}},@{n=”VMSize”; e={$vm.HardwareProfile.VmSize}}
& `
Get-AzDisk -ResourceGroupName $vm.ResourceGroupName`
| Where { $_.ManagedBy -contains $VM.id }`
| Select-Object @{n=”DiskNmae”; e={$_.Name}},DiskSizeGB,@{n=”Tier”; e={$_.sku.Name}}
& `
Get-AzNetworkInterface `
| Where { $_.VirtualMachine.id -contains $VM.id}`
| Select-Object @{n=”NWInterFaceNmae”; e={$_.Name}},`
@{n=”PrivateIP”; e={$_.IpConfigurations.PrivateIpAddress}},`
@{n=”PrivateIpAllocation”; e={$_.IpConfigurations.PrivateIpAllocationMethod}}

※なぜか、サブスクリプションIDの指定をしないと情報取得出来なかったので、今回は、Select-AzSubscriptionでサブスクリプションIDの指定を行っています。

3.Azure VMの稼働ステータスやIPアドレス、ディスクの情報の取得結果

実際にPower Shellを実行してみると、以下のような結果が得られます。(今回はディスクを2本ついたVirtual Machineなので2つ表示されます。)

PS> c:\PowerShell\VMの情報を取得する(基本編)(公開用).ps1 -VMname VM名

Name : VM名
Status : PowerState/running
VMSize : Standard_B1ms


DiskNmae : OSディスク名
DiskSizeGB : 30
Tier : Standard_LRS


DiskNmae : データDISK名
DiskSizeGB : 30
Tier : StandardSSD_LRS


NWInterFaceNmae : ネットワークインターフェース名
PrivateIP : PrivateIP
PrivateIpAllocation : Static

※作成にあたって、躓くことがあり、マイクロソフトサポート様に大変貴重なアドバイスをいただいております。有難うございました。

Azure Application GatewayのARMテンプレートをPower Shell使ってエクスポートする

 

Azure Application Gatewayの設定情報のダウンロードを試してみました。

Azure Application Gatewayは設定項目が多く、いろいろな所の設定変更していくと、どこを変更した分からなくなり、元に戻せてなくて設定がうまく行かないケースがありました。

Azure PortalでARMテンプレートをPower Shellでエクスポートをという事を試してみました。併せてGet-AzApplicationGatewayで設定情報を取得も実施してみました。

実施にあたっては以下のサイトを参考に進めました。

https://docs.microsoft.com/en-us/powershell/module/az.resources/export-azresourcegroup?view=azps-3.8.0
https://docs.microsoft.com/en-us/powershell/module/az.network/get-azapplicationgatewayhttplistener?view=azps-3.8.0

今回作成したものは GitHub上に公開しています。

https://github.com/Tama-negi/Li-akb-branch-office/tree/PowerShell_Azure/ApllicationGateway-Template-Export-20200422

1.Azure Application Gatewayのテンプレートエクスポート+情報取得

Get-AzApplicationGateway でApplication Gatewayの情報を取得しています。

また、Export-AzResourceGroupで、テンプレートのエクスポートを行います。Application Gateway名を指定することで、Application Gatewayのみのテンプレートをエクスポートします。

#Application Gateway Template Export

#取得するApplication Gatewayのパラメータ

$SubscriptionId = “サブスクリプションID”
$RG = “リソースグループ名”
$APGW = “Application Gateway名”
$TemplatePath =“テンプレートのパス(例:C:\temp)”

#Getコマンドで情報取得
Get-AzApplicationGateway -Name $APGW -ResourceGroupName $RG

#テンプレートをエクスポートする
Export-AzResourceGroup `
-ResourceGroupName $RG `
-Resource “/subscriptions/$SubscriptionId/resourceGroups/$RG/providers/Microsoft.Network/applicationGateways/$APGW”`
-Path $TemplatePath

なお、上記サンプルのように、Get-AzApplicationGatewayだけでそのまま情報を取得した場合、子に入っているSKUの情報等が取得出来ません。適時必要に応じて表示するようにして下さい。注意願います。

Azure Logic AppをARMテンプレートを使ってデプロイ(箱のみ)

 

Azure Logic AppをARMテンプレートを利用して一括してデプロイする事を試してみました。
ARMテンプレートで指定するParameterをCSVファイルから読み込む事により複数纏めてデプロイ出来ないかなぁという事で試してました。

Logic Appのデプロイ自動化については、下記サイトに記載があります。今回は下記サイトを参考にLogic Appの一番基本的な部分だけを作るまでをやってみました。

https://docs.microsoft.com/ja-jp/azure/logic-apps/logic-apps-azure-resource-manager-templates-overview

ARMテンプレートを使ったデプロイに関しては以下の前提条件で試してみました。

    • Logic Appを2つ作成する
    • Logic Appのテンプレートを使う
    • Logic Appは基本設定のみ
    • パラメータの指定はCSVファイルを利用する
    • デプロイ先のリソースグループはデプロイ時に指定する

今回作成したものは GitHub上に公開しています。

https://github.com/Tama-negi/Li-akb-branch-office/tree/PowerShell_Azure/LogicApp_Deploy_Basic_20200418

1 .Logic Appで設定が必要な項目を確認してARMテンプレートを作成してみる

Azure Portalでの設定内容を確認してみます。

Azure Portalで確認してみた所Logic Appのデプロイを行う場合以下の内容を指定が必要な事が分かりました。この内容を指定するようにARMテンプレートを作ってみました。

    • ロジックアプリ名
    • リソースグループ名
    • 場所(ロケーション)
    • Tag(division;指定)
    • Log Analyticsの使用可否、ワークスペース名(今回は無しにしています。)

LogicApp-template-Basic-01.json

{
    “$schema”: “https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#”,
    “contentVersion”: “1.0.0.0”,
    “parameters”: {
        “workflows_LogicApp_name”: {
            “type”: “String”,
            “metadata”: {}
        },
        “location”: {
            “type”: “String”,
            “defaultValue”: “japaneast”,
            “metadata”:{} 
        },
        “tag”: {
            “type”: “String”,
            “defaultValue”:”notag”,
            “metadata”:{} 
        }
    },
    “variables”: {},
    “resources”: [
        {
            “type”: “Microsoft.Logic/workflows”,
            “apiVersion”: “2017-07-01”,
            “name”: “[parameters(‘workflows_LogicApp_name’)]”,
            “location”: “[parameters(‘location’)]”,
            “tags”: {
                “division”: “[parameters(‘tag’)]”
            },
            “properties”: {
                “state”: “Enabled”,
                “definition”: {
                    “$schema”: “https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#”,
                    “contentVersion”: “1.0.0.0”,
                    “parameters”: {},
                    “triggers”: {},
                    “actions”: {},
                    “outputs”: {}
                },
                “parameters”: {}
            }
        }
    ]
}

.Logic App のARMテンプレートのパラメータ設定用のCSVファイルを作成する

Logic App を作成する為にCSVから読み込むパラメータは以下の3つになります。この3つを指定するCSVを作成します。

    • ロジックアプリ名
    • 場所(ロケーション)
    • Tag

LogicApp-Basic.csv

LogicAppName,location,tag
LogicApp-Test01,japaneast,,
LogicApp-Test02,japaneast,TAG-Test,

3. Logic AppのARMテンプレートをPower Shellでデプロイする

デプロイ先のリソースグループ名、テンプレートファイルのパス、CSVファイルのパスを指定してデプロイを実施します。

TemplateDeploy_ImportCSV(LogicApp用)_01(公開用).ps1

#Logic App Template Deploy
#基本設定(RG名、LogicApp名、Location、Tagのみ指定)

param (
[String] [Parameter(Mandatory=$true)] $ResourceGroupName
)

$TemplateFilePath = “テンプレートファイルのパス名”
$ImportCSVPath = “CSVファイルのパス名”

# Inclued Configure Entries
$csv = Import-Csv -path $ImportCSVPath

# Template Deploy
foreach( $c in $csv ){

New-AzResourceGroupDeployment -ResourceGroupName $ResourceGroupName `
-TemplateFile $TemplateFilePath `
-workflows_LogicApp_name $c.LogicAppName `
-location $c.location `
-tag $c.tag
}

作成が成功すると、以下の通りにLogic Appが作成されたログが表示されます。

Outputs :

eploymentName : LogicApp-template-Basic-01
ResourceGroupName : リソースグループ名
ProvisioningState : Succeeded
Timestamp : 作成時刻
Mode : Incremental
TemplateLink :
Parameters :
Name Type Value
========================= ========================= ==========
workflows_LogicApp_name String LogicApp-Test01
location String japaneast
tag String

DeploymentName : LogicApp-template-Basic-01
ResourceGroupName : リソースグループ名
ProvisioningState : Succeeded
Timestamp : 作成時刻
Mode : Incremental
TemplateLink :
Parameters :
Name Type Value
========================= ========================= ==========
workflows_LogicApp_name String LogicApp-Test02
location String japaneast
tag String TAG-Test

CSVで指定した値で作成した値で作成されている事が確認できます。

ARMテンプレート使ってNSGをデプロイ

 

Azure Network Security Group(NSG)のデプロイをARMテンプレート使ってやってみました。

今回は一番初期に使うパターンとして多そうな、RDP(ポート番号3389)を特定のIPからのみ受信許可する設定を試してみました。

1 .NSGの設定項目を確認する

まず、Azure PortalでNSGのセキュリティ規則設定で必要な項目を確認してみました。必須項目は以下の内容となっている事が確認できます。

      • ソース
      • ソースIPアドレス
      • ソースポート範囲
      • 宛先
      • 宛先ポート範囲
      • プロトコル
      • アクション
      • 優先度
      • 名前

 

.NSGのARMテンプレートサンプル(特定のIPからのみRDPを受信許可する)

今回のARMテンプレートで実施する内容は以下の通りになります。

      • NSGの作成
      • セキュリティ規則の作成

NSGのセキュリティ規則については、ソースIP以外をARMテンプレート内のresourcesで指定しています。

RDPをすべてのプロトコルで受信許可し、優先度100とする内容としています。

パラメータとして以下の値を指定するようにしています。

      • NSG名
      • ロケーション(デフォルト値を東日本としています)
      • NSGのセキュリティ規則名(デフォルト値をRDP-Permitとしています)
      • ソースIPアドレス(RDPを許可するIP)
{

    “$schema”: “https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#”,
    “contentVersion”: “1.0.0.0”,
    “parameters”: {
        “NSGName”: {
            “type”: “String”,
            “metadata”: {}
        },
        “location”: {
            “type”: “String”,
            “defaultValue”: “japaneast”,
            “metadata”:{} 
        },
        “NSGRuleName”: {
            “type”: “String”,
            “defaultValue”: “RDP-Permit”,
            “metadata”:{} 
        },
        “PermitIP”: {
           “type”: “String”,
           “metadata”:{} 
        }
    },
    “variables”: {},
    “resources”: [
        {
            “type”: “Microsoft.Network/networkSecurityGroups”,
            “apiVersion”: “2019-11-01”,
            “name”: “[parameters(‘NSGName’)]”,
            “location”: “[parameters(‘location’)]”,
            “properties”: {
                “securityRules”: [
                    {
                        “name”: “[parameters(‘NSGRuleName’)]”,
                        “properties”: {
                            “protocol”: “*”,
                            “sourcePortRange”: “*”,
                            “destinationPortRange”: “3389”,
                            “sourceAddressPrefix”: “[parameters(‘PermitIP’)]”,
                            “destinationAddressPrefix”: “VirtualNetwork”,
                            “access”: “Allow”,
                            “priority”: 100,
                            “direction”: “Inbound”,
                            “sourcePortRanges”: [],
                            “destinationPortRanges”: [],
                            “sourceAddressPrefixes”: [],
                            “destinationAddressPrefixes”: []
                        }
                    }
                ]
            }
        },
        {
            “type”: “Microsoft.Network/networkSecurityGroups/securityRules”,
            “apiVersion”: “2019-11-01”,
            “name”: “[concat(parameters(‘NSGName’), ‘/’, parameters(‘NSGRuleName’))]”,
            “dependsOn”: [
                “[resourceId(‘Microsoft.Network/networkSecurityGroups’, parameters(‘NSGName’))]”
            ],
            “properties”: {
                “protocol”: “*”,
                “sourcePortRange”: “*”,
                “destinationPortRange”: “3389”,
                “sourceAddressPrefix”: “[parameters(‘PermitIP’)]”,
                “destinationAddressPrefix”: “VirtualNetwork”,
                “access”: “Allow”,
                “priority”: 100,
                “direction”: “Inbound”,
                “sourcePortRanges”: [],
                “destinationPortRanges”: [],
                “sourceAddressPrefixes”: [],
                “destinationAddressPrefixes”: []
            }
        }
    ]
}

 

※デフォルトルールは、テンプレートには必要無いようです。

.NSGのARMテンプレートをPower Shell使ってデプロイする

1.で作成したNSGのARMテンプレートをPower Shell使ってデプロイします。
今回のサンプルではリソースグループ名、ロケーション名、セキュリティ規則名はデプロイ用Power Shellに直接記載しています。

Power Shellでデプロイ時にNSGの名前、RDPを許可するIPは指定するようにしています。

#NSG Template Deploy

param (
  [String] [Parameter(Mandatory=$true)]  $NSGName ,
  [String] [Parameter(Mandatory=$true)]  $Address
    )

$resourceGroupName = “リソースグループ名”
$location = “ロケーション名”
$NSGRuleName =“セキュリティ規則名”
$TemplateFilePath = “テンプレートのパス”

New-AzResourceGroupDeployment -ResourceGroupName $resourceGroupName `
  -TemplateFile $TemplateFilePath `
  -NSGName $NSGName `
  -NSGRuleName $NSGRuleName `
  -PermitIP $Address `
  -location $location

NSGが出来た後に、SubnetやNetwork Interfaceとの関連付けを行ってください。

これをデフォルト適用すれば、間違ってRDPをInterNetにAnyで公開する事を防げないかなぁと思っていたします。

今後は、サービスタグの指定、複数のセキュリティ規則を一括して作成するなど、環境に合わせて作成できるようにしていきたい所です。

Log Analyticsワークスペースを複数まとめてデプロイ

 

Log Analyticsのワークスペースのデプロイを以下の2パターンでデプロイしてみました。

      • Azure Portalを使ってデプロイ
      • ARMテンプレート+CSVファイルで複数纏めてデプロイ

まず最初に、Azure Portalを使ってデプロイしてみました。

その次に、ARMテンプレートを利用して実施してみました。パラメータをCSVファイルから読み込み、複数のLog Analyticsワークスペースを一括してデプロイ出来るようしてみました。

テンプレートを使ったデプロイは、下記条件で実施しています。

    • Log Analyticsワークスペースを3つ作成する
    • Log Analyticsワークスペースをテンプレートファイルを利用してデプロイする
    • パラメータはCSVファイルを利用する
    • パラメータはデプロイ時に指定する

※サンプルはGitHubにも公開しています。

1 .Azure Portalを使ってLog Analytics ワークスペースを作る

まず、Azure Portalを使ってLog Analyticsワークスペースをデプロイしてみます。

1)Log Analyticsワークスペースのメニュー画面で追加をクリックします。

2)作成画面になりますので、リソースグループ、名前、地域(Location)を設定します。地域はLog Analyticsの転送元のリソースがある地域(Location)と同じ場所を選択します。

3)価格レベルを設定します。価格レベルは従量課金制を選択します。

4)タグを設定する場合はタグの設定を行います。設定しない場合は確認および作成を選択し作成します。

これでLog Analyticsワークスペースの作成は完了です。

2.Log Analytics ワークスペースのARMテンプレートを作成する

Log AnalyticsワークスペースのARMテンプレートを作成します。

マイクロソフト様の下記サイトに記載の内容を参考(ほとんどそのままです)にしています。

https://docs.microsoft.com/ja-jp/azure/azure-monitor/learn/quick-create-workspace-posh#create-a-workspace

defaultValue値は環境に合わせて変更してください。

{

“$schema”: “https://schema.management.azure.com/schemas/2014-04-01-preview/deploymentTemplate.json#”,
“contentVersion”: “1.0.0.0”,
 ”parameters”: {
  ”workspaceName”: {
   ”type”: “String”,
   ”metadata”: {}
 },
 ”location”: {
  ”type”: “String”,
   ”defaultValue”: “eastus2”,
    ”metadata”: {}
 },
 ”sku”: {
  ”type”: “String”,
   ”allowedValues”: [
    ”PerGB2018″
   ],
   ”defaultValue”: “PerGB2018”,
    ”metadata”: {}
   }
 },
“resources”: [
 {
 ”type”: “Microsoft.OperationalInsights/workspaces”,
  ”name”: “[parameters(‘workspaceName’)]”,
  ”apiVersion”: “2015-11-01-preview”,
  ”location”: “[parameters(‘location’)]”,
  ”properties”: {
  ”sku”: {
  ”Name”: “[parameters(‘sku’)]”
 },
 ”features”: {
 ”searchVersion”: 1
}}}]}

3.Log Analyticsのパラメータを指定するCSVファイルを作成する

Azure Portalを使ってLog Analyticsワークスペースを作成した場合と同様に、パラメータは以下の3つになります。

      • ワークスペース名 (変数名;workspaceName)
      • ロケーション (変数名;location)
      • SKU (変数名;sku)

テスト用のパラメータCSVファイルは下記通り作成しています。

workspaceName,location,sku

test-201-20200328,eastus2,PerGB2018
test-202-20200328,eastus2,PerGB2018
test-203-20200328,japaneast,PerGB2018

4. Power ShellでLog AnalyticsワークスペースのARMテンプレートをデプロイする

デプロイ先のリソースグループ名、ARMテンプレートファイルのパス、CSVファイルのパスを指定してPower Shellを実行します。

#Log Analyitcs ワークスペースデプロイ用Power Shell

$resourceGroupName = “デプロイ先のリソースグループ名”
$TemplateFilePath = “テンプレートファイルのパス”
$ImportCSVPath = “CSVのファイルのパス”

# Import Parameter Csv
$csv = Import-Csv -path $ImportCSVPath

# Template Deploy
foreach( $c in $csv ){

New-AzResourceGroupDeployment -ResourceGroupName $resourceGroupName `
 -TemplateFile $TemplateFilePath `
 -workspaceName $c.workspaceName `
 -location $c.location `
 -sku $c.sku
}

作成が成功すると、以下の通りにLog Analyticsのワークスペースが作成されたログが表示されます。

Outputs :

DeploymentDebugLogLevel :

DeploymentName : LogAnalytics_WorkSpace
ResourceGroupName : リソースグループ名
ProvisioningState : Succeeded
Timestamp : 作成時刻
Mode : Incremental
TemplateLink :
Parameters :
Name        Type          Value
=============== ================= ==========
workspaceName    String          test-203-20200328
location       String         japaneast
sku         String                                  PerGB2018

CSVで指定した値で作成した値で作成されている事が確認できます。

Azure MonitorのアクショングループをARMテンプレートを使ってデプロイ

 

Azure Monitorでアラートが発生した場合に、どのように通知を行うのかを定義する機能として、アクショングループがあります。

アクショングループにはメールやSMS、Webhookなどがあります。

今回はアクショングループの作成をAzure PortalとARMテンプレートを利用してメール送信のアクショングループを作成してみました。

ARMテンプレートはマイクロソフト様のサイトを参考に作成しています。

https://docs.microsoft.com/ja-jp/azure/azure-monitor/platform/action-groups-create-resource-manager-template

今回作成した内容はGithubにも公開しています。

アクションルールについては、Azure Portalを使った設定を試しております。こちらは下記記事に纏めております。

Azure Monitorのアクションルールを使って非監視設定(非通知)を試す

.Azure Monitorのアクショングループで設定する内容

Azure Monitorのメニューでアラートを選択します。

アクションの管理が表示されるので選択し、表示されるアクショングループの追加をクリックすると、下記画面が表示されます。

画面を確認した結果、アクショングループ作成時に指定が必要になる内容が分かりました。

      • アクショングループ名
      • 短い名前
      • サブスクリプション(デプロイ時に指定します)
      • リソースグループ(デプロイ時に指定します)
      • 操作名
      • アクションの種類(今回は電子メールを想定します。)
      • 電子メールアドレス(アクションの種類で電子メールを選択すると入力できます)

.アクショングループのARMテンプレートを作成する

電子メールを送信するアクショングループのテンプレートは下記のようになります。

ARMテンプレート内のvariables 関数で以下の内容を変数を指定するようにしてます。

      • アクショングループ名
      • 短い名前
      • 操作名 
      • 電子メールアドレス(アクションの種類で電子メールを選択すると入力できます)

電子メールに関するアクションの指定は、テンプレート内のemailReceivers項目を利用する事で定義されます。

{
 ”$schema”: “https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#”,
 ”contentVersion”: “1.0.0.0”,
 ”variables”: {
   “actionGroupName”: “アクショングループ名”,
   “actionGroupShortName”: “短い名前”,
   “OperationName”: “操作名”,
   “emailAddress”: “送信先の電子メールアドレス”
    },

  },
  ”resources”: [
  {
   ”type”: “Microsoft.Insights/actionGroups”,
   ”apiVersion”: “2018-03-01”,
   ”name”: “[variables(‘actionGroupName’)]”,
   ”location”: “Global”,
   ”properties”: {
    ”groupShortName”: “[variables(‘actionGroupShortName’)]”,
    ”enabled”: true,
    ”emailReceivers”: [
     {
     ”name”: “[variables(‘OperationName’)]”,
     ”emailAddress”: “[variables(‘emailAddress’)]”
     }
    ]
   }
  }
 ],
 ”outputs”:{
  ”actionGroupId”:{
  ”type”:”string”,
  ”value”:”[resourceId(‘Microsoft.Insights/actionGroups’,variables(‘actionGroupName’))]”
  }
 }
}

.Power ShellでARMテンプレートをデプロイする

最後に、作成したARMテンプレートをPower Shellでデプロイします。デプロイ方法は下記を参考にしています。Power Shell実行時に、Action Groupを作成するリソースグループ名を指定します。

https://docs.microsoft.com/ja-jp/azure/azure-resource-manager/templates/deploy-powershell#deploy-local-template

#テンプレートをデプロイするPowerShell
$resourceGroupName = Read-Host -Prompt “Enter the Resource Group name”
$TemplateFilePath = “テンプレートファイルのパス(ex;”C:\tmp\ActionGroup_templete.json”)”

New-AzResourceGroupDeployment -ResourceGroupName $resourceGroupName `
-TemplateFile $TemplateFilePath
 

最後に以下のPower Shellで実際にAction Groupができているか確認します。

$resourceGroupName = “リソースグループ名”
$actionGroupName = “アクショングループ名”

Get-AzActionGroup -ResourceGroupName $resourceGroupName -Name $actionGroupName

Azure Log Analytics ワークスペースの復活から完全削除をやってみた

 

Azure Log Analytics ワークスペースの復活から完全削除を試してみました。

Log Analyticsのワークスペース削除を行った後に、同じ名前で作成しようとした所、エラーになりました。
何故?という事で色々確認させて頂いた所、Log Analyticsのワークスペースについては、論理削除されて14日間は同じワークスペース名で作成しようとしてもエラーになる事がわかりました。

https://docs.microsoft.com/ja-jp/azure/azure-monitor/platform/delete-workspace

ホームページを確認した所、一度復活したのちに、REST APIで削除する必要がわる事がわかったので試してみました。

Log Analyticsワークスペース作成はこちらに記載しております。

Log Analyticsワークスペースを複数まとめてデプロイ

1 .Log Analytics ワークスペースの復活を行う

REST APIを用いた削除は、Log Analyticsのワークスペースが存在する状態でないとできません。
そこでワークスペースの復活を行います。以下のPower Shellで実行が可能です。

Power Shell実行時は、ファイル名.ps1 -workspacename “復活するワークスペース名”で実行して下さい。(REST APIでも可能です。)

#LogAnalyticsワークスペースを復活する。
#参考URL
#https://docs.microsoft.com/ja-jp/azure/azure-monitor/platform/delete-workspace

param (
[String] [Parameter(Mandatory=$true)] $workspacename
)

$ResourceGroupName = “RG名”
$location = “ロケーション名”

New-AzOperationalInsightsWorkspace -ResourceGroupName $ResourceGroupName -Name $workspacename -Location $location

2.改めてワークスペースの削除を行う。

2020年1月末時点では、ワークスペースの完全削除については、REST APIを用いた削除しか提供されていません。マイクロソフト様の以下のホームページにREST APIが提供されています。こちらを利用して完全削除します。まず、以下のホームページへ移動し、Try Itの部分をクリックします。

https://docs.microsoft.com/en-us/rest/api/loganalytics/workspaces/delete

Try Itをクリックすると、以下のページが表示されますので、サブスクリプションID、リソースグループ名、削除するワークスペース名、ロケーション名を入力します。
併せて以下のように、name部分にforceと入力し、値部分にtrueと入力します。

Runをクリックし、実行します。
成功するとステータスコードに200 OKが戻ってきます。これで完全削除完了です。

ホームページにも記載の通り、完全に削除すると復活できないので注意して下さい。

※本件、コマンド等については、マイクロソフトサポート様にご教授頂いております。有難うございました。

Azure Application Gatewayのエラーページ設定更新

 

Application Gatewayでシステムメンテナンス等でWEBサーバを全部停止した場合は、デフォルトの502エラーページが表示されます。

Application Gatewayのリスナーにカスタムのエラーページを設定する事でユーザー作成のエラーページを表示する事が出来ます。

WEBサイト等のシステムメンテナンスを案内する場合等には、リスナーにメンテナンス案内をエラーページを設定することで、Application Gatewayの機能でメンテナンス案内を表示が可能になります。

エラーページは、Blobストレージのパス等固定のURLを指定する事で設定できます。

最初にAzure Portal上でエラーページの設定を行いました。その次にカスタムエラーページのBlobストレージへのアップロード、Application Gateway側での設定更新をPower Shellでやってみました。

1 .Azure PortalでApplication Gatewayのエラーページ設定をしてみる

今回は以下の前提で試してみました。

      • エラーページはBlobストレージにアップしたHTMLファイルを利用する
      • エラー用のHTMLファイルは事前にアップロード済みである

まず、最初にBLOBストレージにアップロードしたエラーページのURLを確認します。

ストレージアカウントのStorage Explorerを選択すると下記画面が表示させますので、Blobコンテナのエラーファイルを置いたディレクトリに移動します。

ファイルを選択し右クリックしプルダウンでプロパティを選択します。

プロパティを選択すると下記画面が表示されますので、Uriの行がエラーページで指定する内容にあんります。Uriをコピーします

次にAzure Portal上Application Gatewayの設定を行います。

Application Gatewayのメニューで設定対象のApplication Gatewayを選択します。

Application Gatewayのメニューでリスナーを選択すると下記画面が表示されます。設定対象のリスナーを選択します。

リスナーの設定画面が表示されます。

エラーページのURLの項目ではいを選択します。

無効なゲートウェイ-502と禁止-403のエラーページが設定できます。先ほどストレージアカウントで確認したエラーページのUriを入力します。

これでAzure Portalを利用したエラーページの設定が完了です。

.Power Shellを使ってBlobストレージにファイルをアップロードする

次にPower Shellでのエラーページの更新を試してみます。実施する手順は2つになります。

      • エラーページのBlobストレージへのアップロード
      • Application Gatewayのエラーページパスを変更する。

まず、エラーページのHTMLファイルをBlobストレージを行います。

以下のページを参考に、HTMLファイルのBlobストレージアップロード用Power Shellを作ってみました。

https://docs.microsoft.com/en-us/powershell/module/az.storage/set-azstorageblobcontent?view=azps-3.3.0

※試してみた所、Content Typeを指定しないと、ファイルとしてアップロードはできますが、エラーページとして表示出来ませんでした。明示的にContent Typeを指定います。

※同じファイル名でアップロードしてもエラーページは更新されません。別名でのアップロードが必要です。

# Blobストレージにファイルをuploadする
# 参考URL
# https://docs.microsoft.com/ja-jp/azure/storage/blobs/storage-quickstart-blobs-powershell#upload-blobs-to-the-container

# パラメータ
$resourceGroupName = “ストレージアカウントのリソースグループ名”
$StorageAccountName = “ストレージアカウント名”
$containerName = “コンテナ名”
$LocalFilePath = “アップロードするファイルパス”

# 処理部分
$storageAccount = Get-AzStorageAccount -ResourceGroupName $resourceGroupName -Name $StorageAccountName
$ctx = $storageAccount.Context

Set-AzStorageBlobContent -File $LocalFilePath `
-Container $containerName `
-Properties @{“ContentType” = “text/html”} `
-Context $ctx

3.Power Shellを使ってApplication Gatewayのエラーページを更新する

Application Gatewayのエラーページの更新は、エラーページのパスを変更する事で実現しています。Power Shell作成にあたっては以下のページを参考にしました。

https://docs.microsoft.com/ja-jp/powershell/module/az.network/set-azapplicationgatewayhttplistenercustomerror?view=azps-3.3.0&viewFallbackFrom=azps-2.4.0

# APGW Custom error Page Update
# 参考URL
# https://docs.microsoft.com/ja-jp/powershell/module/az.network/set-azapplicationgatewayhttplistenercustomerror?view=azps-3.3.0&viewFallbackFrom=azps-2.4.0

#パラメータ
$resourceGroupName = “Application GatewayのRG名”
$APGWName =“Application Gateway名”
$ListenerName = “リスナー名”
$StatusCode = “更新対象のエラーコード(ex;HttpStatus403)”
$customErrorUrl = “ErrorページのURL(ex;https://Blobストレージ名.blob.core.windows.net/コンテナ名/ファイル名)”

#処理部分
$AppGw = Get-AzApplicationGateway -Name $APGWName -ResourceGroupName $resourceGroupName
$httplistner = Get-AzApplicationGatewayHttpListener -Name $ListenerName -ApplicationGateway $Appgw
$updatelistener = Set-AzApplicationGatewayHttpListenerCustomError -HttpListener $httplistner -StatusCode $StatusCode -CustomErrorPageUrl $customErrorUrl
Set-AzApplicationGateway -ApplicationGateway $AppGw

※マイクロソフトサポート様に指摘/修正頂き完成しています。本当にありがとうございます。

4.留意点

Application Gatewayはエラーページをキャッシュで保持します。

キャッシュの更新は、エラーページのパス変更かApplication Gatewayの再起動でできます。

Application Gatewayの再起動の場合は同じファイル名でもエラーページのキャッシュ更新が可能ですが、Application Gateway再起動分の停止時間が発生します。

パスの変更の場合は設定変更の反映だけになる為停止時間が発生しません。

エラーページの更新は、事前にBlobストレージに別ファイル名でアップしておき、エラーページのパス名を切り替えるのが良さそうです。

Application  Gatewayの再起動については以下の記事に記載しております。

Power ShellでAzure Application Gatewayの起動停止

Power ShellでAzure Application Gatewayの起動停止

 

Azure Application Gatewayの起動停止を試してみました。

Application Gatewayで403エラーページを更新した際に反映されないという事象があったのですが、Application Gatewayを停止、起動したら改善するんじゃない?という事で確認してみました。

Azure Portal上で確認してみた所Application Gatewayの再起動は出来ませんでした。

そこで調べてみた所、Power Shellで出来そうだったので試してみた所上手く行きました。

今回はPower Shellでの再起動手順を残しておきます。

1 .Azure Application Gatewayの停止、起動を行う

Application Gatewayの再起動はAzure Portalでは出来ない為、Power Shellを使って実施します。

      • 停止時:Stop-AzApplicationGateway 

      • 起動時:Start-AzApplicationGateway

#Application Gateway Restart PowerShell

# APGW Parameter

$ResourceGroupName = “Application Gatewayが所属するリソースグループ名”
$APGWName = “Application Gateway名”
 
$ag = Get-AzApplicationGateway -Name $APGWName -ResourceGroupName $ResourceGroupName

# APGW Stop

Stop-AzApplicationGateway -ApplicationGateway $ag

# APGW Start

Start-AzApplicationGateway -ApplicationGateway $ag

マイクロソフトサポート様から教えて頂いたコマンドになります。(有難うございました。)

.Azure Application Gateway再起動時の重要な注意点

注意点として再起動後のグローバルIPが変わる事があります。

V1の場合グローバルIPが動的であるため、Application Gateway再起動により、グローバルIPが変わります。3回ほど実施してみましたが、100%変わりました。

対応としてはDNS登録時は、グローバルIPのFQDNをCNAMEで登録する事になります。

これが推奨なので通常はそういう設定されているかと思いますが、自分はIPアドレスをAレコードで登録していた為、接続できなくなり少し焦りました。

もう1点の注意点として、Application Gatewayを停止しても、課金は停止しない事があります。この点も注意が必要です。

.Azure Application Gatewayのエラーページ更新について

今回、Application Gatewayの再起動でエラーページの更新をやったのですが、自分のやり方が間違ってました。

Application Gateway側にカスタムエラーページのキャッシュを持っており、これはカスタムエラーページのファイル名(もしくはパス)を変更して保存しない限り更新されないそうです。(公開情報にも記載がありました。)

Application Gatewayのエラーページの更新について、こちらにも記載しております。

Azure Application Gatewayのエラーページを更新するPower Shell

Azure Virtual Machineを別テナントに移してみた

 

今回は、Azure VMをAzureの別テナントへ移行してみました。

実際に試行錯誤して実施してみたのですが、最終的には以下のような段取りになりました。

      • Azure VMのManaged Disksを別テナントのBlobストレージにコピーする
      • コピーしたファイルをManaged Disksに戻す
      • Managed DisksからVMを作成する

実施してみた所、Azure VMのManaged Disksを移行先のテナントのBLOBストレージにVHDファイルとして保管する必要があるようでした。移行先テナントでVHDファイルをManaged Disksに戻すことで仮想マシンを作成することで実現出来ました。

今回作業にあたっては、PowerShellを利用して実施してみました。

※なお、同じテナントの別サブスクリプションへは、Managed Disksのまま移行が可能です。

1 .Azure VMのManaged Disksを移行先テナントのBlobストレージにコピーする

まず事前に以下の準備をしておきます。

      • 移行先のテナントに、ストレージアカウントとBlobストレージのコンテナを準備しておく
      • 移行対象の仮想マシンを停止しておく。(Managed DisksにAzure VMをアタッチしていない場合はそのままで実行可能です。)

Managed Disksを一旦ローカルにダウンロードして、移行先のストレージアカウントにアップロードする事でも対応可能です。

ただ作業が面倒なので、以下のサイトを参考に、Managed Disksをダウンロードせずに、直接移行先のBlobストレージにコピーする方法を試してみました。

サイト記載のサンプルをAz化しています。

https://docs.microsoft.com/ja-jp/archive/blogs/jpaztech/export-managed-disks-to-vhd

Power Shell実行時には各テナントへのログイン画面が表示されます。適時ログインして下さい。

※サイト記載のサンプルをAz化しています。

#Managed Disk Copy PowerShell

# コピー元へのログイン
Login-AzAccount
Select-AzSubscription -SubscriptionId  “コピー元のサブスクリプション ID”

# コピー元のディスクパラメータ
$sourcergname = “コピー元リソースグループ名”
$diskname = “コピー対象のManagedDisk名”

# SAS URL の作成(有効時間を1時間にしています。タイムアウトになる場合は適時調整します。)
$mdiskURL = Grant-AzDiskAccess -ResourceGroupName $sourcergname -DiskName $diskname -Access Read -DurationInSecond 3600

# コピー先の情報
# コピー先テナントにログイン

Login-AzAccount
Select-AzSubscription -SubscriptionId  “コピー先のサブスクリプション ID”

# コピー先の各種パラメーター
$targetrgname = “コピー先リソースグループ名”
$storageacccountname = “コピー先ストレージアカウント名”
$countainername = “コピー先コンテナ名”

$storageacccountkey = Get-AzStorageAccountKey -ResourceGroupName $targetrgname -Name $storageacccountname
$storagectx = New-AzStorageContext -StorageAccountName $storageacccountname -StorageAccountKey $storageacccountkey[0].Value
$targetcontainer = Get-AzStorageContainer -Name $countainername -Context $storagectx

$destdiskname = “コピー後のファイル名”
$sourceSASurl = $mdiskURL.AccessSAS

# コピー
$ops = Start-AzStorageBlobCopy -AbsoluteUri $sourceSASurl -DestBlob $destdiskname -DestContainer $targetcontainer.Name -DestContext $storagectx
Get-AzStorageBlobCopyState -Container $targetcontainer.Name -Blob $destdiskname -Context $storagectx -WaitForComplete

コマンドが完了したら、移行先のBlobストレージ内にファイルが生成されているの確認してください。生成されていたら作業は完了です。

.コピーされたVHDファイルをManaged Disksに変換する

コピーされたファイルをコピー先のテナントでManaged Disksに変換します。

以下のサイトを参考に戻すPower Shellを作ってみました。

https://docs.microsoft.com/ja-jp/archive/blogs/jpaztech/convertvhdtomanageddiskdeployvm

本Power Shellの重要な注意点ですが、OS Typeを指定しないと、変換自体は出来るのですが、後の作業で仮想マシン作成ボタンが押せない状態となります。これでドはまりしました。

Power Shell内で指定するVHDファイルのURLは、VHDファイルが保管されているBlobストレージにて確認します。

Storage ExplorerにてVHDファイルを選択します。右クリックするとプロパティという項目が表示されますので選択します。下記画面が表示されますので、Uriに表示されている内容をコピーします、Power Shell実行時に指定するVHDファイルのURLになります。

実際に実行するPower Shellは下記の通りになりました。

# VHD→ManagedDisk PowerShell

#Select Subscription
$SubscriptionId =“コピー先のサブスクリプションID”
Select-AzSubscription -SubscriptionId $SubscriptionId

#Parameter
$ResourceGroupName = “ManagedDiskのRG名”
$location = “ManagedDiskのロケーション”
$DiskName = “作成するManagedDisk名”
$vhdUri = “コピーしたファイルのURL”
$AccountType =“ストレージアカウントのType (ex; Standard_LRS)”<
$OsType = ”ManagedDiskのOS Type (ex; Linux)”

#Disk Config
$DiskConfig = New-AzDiskConfig `
-AccountType $AccountType `
-Location $Location `
-CreateOption Import `
-SourceUri $vhdUri `
-OsType $OsType

#VHD → Managed Disk
New-AzDisk `
-DiskName $DiskName `
-Disk $DiskConfig `
-ResourceGroupName $ResourceGroupName

※複数のサブスクリプションにログインした状態での作業となるため、作業ミス防止用に明示的にサブスクリプションを指定を追加しています。

Power Shellを実行し完了すると、新たにManaged Disksができています。確認はディスクのメニューでできます。

変換が終了したManaged Disksを選択すると、VMの作成というボタンが表示されてますのでクリックします。そうすると仮想マシンの作成画面に遷移しますので、そのまま作成を進めればAzure VMが作成できます。

※オペレーティングシステムが空白の場合はVMの作成ボタンがクリックできません。

.移行後のAzure VMで作業が必要そうです

なお、OMSエージェントを含む、拡張機能は接続先のテナントが異なる為、再度設定が必要になります。この編でドはまりする事もあるので注意が必要になります。

別件にはなりますが参考程度で見て頂ければと。(結果、関連パッケージのアンインストール、インストールを実施しました。)

Log AnalyticsでLogやリソース情報が取得出来なくなった時にやった事

 

 

Azure VPN Gatewayを使ってテナント間を接続をしてみた

 

Azureの別テナント間を直接接続を、Azure VPN Gatewayのサイト間接続を使ってやってみました。

今回は以下のサイトを参考に、Azureテナント間の接続をPower Shellで実施しました。

https://docs.microsoft.com/ja-jp/azure/vpn-gateway/vpn-gateway-tutorial-create-gateway-powershell

作成手順はこんな感じになっています。

      • VPN Gatewayの作成(各テナントで実施)
      • VPN Gateway内での接続を作成(各テナントで実施)

※自分の手順が悪いのか、Azure Portal上では接続が作成できずPower Shell等のCLIでの操作が必須でした。。。

1 .Azure VPN Gatewayを作成する為のPower Shell

最初に、VPN Gateway自体の作成を行います。VPN Gatewayには専用のグローバルIPやSubnetが必要になります。

      • グローバルIPやVPN Gateway用のSubnetは新規に作成
      • SKUはBasicを指定
      • ルートベースを指定

設定内容を環境に合わせて設定し、各テナントでPower Shellを実行します。

#VPN GW Create PowerShell

#RG Name Location
$resourceGroupName = “リソースグループ名”
$location = “Location(ex;eastjapan)”

#VNET Subnet
$VnetName = “Virtual Network Name”
$SubAddress =“XXX.XXX.XXX.XXX/XX”

#Public IP
$PubIPName = “Public Ip Name”

#VPN GW
$GwName = “VPN GW Name”
$gatewayType = “GW Type(ex;Vpn)”
$VpnType = “RouteBased”
$GatewaySKU = “Basic”

#PubIP Create

$Pubip = New-AzPublicIpAddress `
-Name $PubIPName `
-ResourceGroupName $resourceGroupName `
-Location $location `
-AllocationMethod Dynamic

#Subnet Create
$virtualNetwork = get-AzVirtualNetwork `
-Name $VnetName `
-ResourceGroupName $resourceGroupName

Add-AzVirtualNetworkSubnetConfig `
-Name ‘GatewaySubnet’ `
-AddressPrefix $SubAddress `
-VirtualNetwork $virtualNetwork `

$virtualNetwork | Set-AzVirtualNetwork

$subnet = Get-AzVirtualNetworkSubnetConfig `
-Name ‘GatewaySubnet’ `
-VirtualNetwork $virtualNetwork `

#GW Create

$gwipconf = New-AzVirtualNetworkGatewayIpConfig `
-Name $GwName `
-Subnet $subnet `
-PublicIpAddress $Pubip

New-AzVirtualNetworkGateway `
-Name $GwName `
-ResourceGroupName $resourceGroupName `
-Location $location `
-IpConfigurations $gwipconf `
-GatewayType $gatewayType `
-VpnType $VpnType `
-GatewaySku $GatewaySKU

.Power Shellを使ってVPN Gatewayの接続を作成する

異なるテナント間の接続を作成する場合、Azure Portal上ではできませんでした。。。今回はPower Shellで作成しています。

設定にあたっては、接続先(対抗側)のVPN GatewayのIDが必要になります。以下のコマンドで確認します。(注:今回接続を作成する対抗側のサブスクリプションで下記コマンドを実行します。)

Get-AzVirtualNetworkGateway -Name “VPN GW Name” -ResourceGroupName “Resouece Gropu Name” |fl id

Id : /subscriptions/・・・・

上記コマンドのId:で表示される値を、$GwId2の部分に埋めて以下のPower Shellを実行します。(注:接続元と接続先の情報を混同しないように注意します。)

#接続を作成する側の情報
$resourceGroupName1 = “接続元リソースグループ名”
$location1 = “接続元ロケーション(ex;japaneast)”
$GwName1 = “接続先VPN GW 名”
$ConnectionName = “接続名”
$SharedKey = “共有キー (PSK)”

#接続先の情報
$GwName2 = “接続先VPN GW Name”
$GwId2 = “/subscriptions/・・・・/接続先VPN GW 名”

#接続先の情報を作成する
$vnet2gw = New-Object -TypeName Microsoft.Azure.Commands.Network.Models.PSVirtualNetworkGateway
$vnet2gw.Name = $GwName2
$vnet2gw.Id = $GwId2

#接続を作成する
$vnet1gw = Get-AzVirtualNetworkGateway -Name $GWName1 -ResourceGroupName $resourceGroupName1
New-AzVirtualNetworkGatewayConnection `
-Name $ConnectionName `
-ResourceGroupName $resourceGroupName1 `
-VirtualNetworkGateway1 $vnet1gw `
-VirtualNetworkGateway2 $vnet2gw `
-Location $location1 `
-ConnectionType Vnet2Vnet `
-SharedKey $SharedKey

これで接続が作成されますので、接続先側でも同様に上記Power Shellを実行すると、接続が完了します。

Azure Portal上で、仮想ネットワーク ゲートウェイの接続を選択し、今回作成した接続名をクリックすると、以下のように状態が接続中になるかと思います。

※片方のみ作成されている場合は状態がupdatingになります。

NSGの既存ルールにIPを追加するPower Shell

 

AzureではAzure VM等へのアクセス制限をNetwork Security Group(NSG)を使って行います。

NSGでは接続元、接続先、ポート等を指定してルール設定を行いますが、IPアドレスを指定してルールを作成する事もあるかと思います。

このルールの設定変更を簡単にできないか?と言う事でPower Shellでやってみました。

今回はNSGの既存ルールにアクセス元のIPを追をPower Shellで行ってみました。

1 .既存NSGルールにIPを追加するPower Shell

今回は接続元IP(Source Address Prefix)にIPを追加しています。
Power Shell実行時に3つの変数を指定する事で、既存ルールの設定変更を行うようにしています。

      • NSG名
      • NSGルール名
      • 追加するAddress

リソースグループ名はPower Shellの中で設定するようにしていますので、環境に合わせて設定します。

#NSG Rule Update(SourceAddressPrefix)

param (
[string] [Parameter(Mandatory=$true)] $NSGName,
[string] [Parameter(Mandatory=$true)] $NSGRuleName,
[string] [Parameter(Mandatory=$true)] $Address
)

$resourceGroupName = “リソースグループ名”

# Get the NSG resource
$nsg = Get-AzNetworkSecurityGroup -Name $NSGName -ResourceGroupName $resourceGroupName

# New Prefix List
$newPrefix = New-Object ‘System.Collections.Generic.List[string]’

# Existing Prefix Add
($nsg.SecurityRules | where {$_.Name -eq $NSGRuleName}).SourceAddressPrefix | foreach { $newPrefix.Add($_) }

# New Prefix Add
$newPrefix.Add($Address)

# New Prefix Rewrite
($nsg.SecurityRules | where {$_.Name -eq $NSGRuleName}).SourceAddressPrefix = $newPrefix

# Reflect changes
$nsg | Set-AzNetworkSecurityGroup

3つのパラメータを指定しPower Shellを実行します。

      • NSG名
      • NSGルール名
      • 追加するAddress

今回はPower Shell名を、NSG_Rule_Update_SourceIP.ps1としています。

c:\./NSG_Rule_Update_SourceIP.ps1 -NSGName NSG名 -NSGRuleName NSGルール名 -Address 追加するIPアドレス

その他にもNSGをARMテンプレートを使ってデプロイする事を試しています。併せて見て頂ければと。

ARMテンプレートを使って、Network Security Groupのデプロイしてみた(特定のIPからRDPを許可)

 

SQL Serverのデータディスクサイズを指定してデプロイ

 

Azure Portalを使ってMarket Placeから直接Windows SQL Serverをデプロイするとデータディスクが1TBで作成されてしまいます。

後でデータディスクを削除、追加して修正する事も可能なのですが、デプロイ時からディスクサイズを指定した方が便利かと思われます。

そこでデプロイ時にデータディスクのサイズを指定出来るように、ARMテンプレートを作成してみました。

Cent OSの場合のテンプレート作成、デプロイはこちらに記載しております。

テンプレート機能woAzure VMをデプロイする

1 .Windows SQL Serverをデプロイする為のJsonファイルを作成する。

基本的なVM設定としています。

データディスクのサイズは、diskSizeGBの値で指定します。(今回は128GBで設定しています。)

まず、最初にWindows SQL ServerのVMイメージ(SKU)を確認します。

#Image List get

$location=“japaneast”

#pubName Get
#Get-AzVMImagePublisher -Location $location

$pubName=“MicrosoftSQLServer”

#offer Name Get
#Get-AzVMImageOffer -Location $location -Publisher $pubName

$offerName=“SQL2008R2SP3-WS2008R2SP1”
Get-AzVMImageSku -Location $location -Publisher $pubName -Offer $offerName

確認したSKUを指定して、Windows SQL ServerのARMテンプレートを作ってみるとこんな感じになりました。(今回はSQL Server 2008を選択しています。)

{
“$schema”: “https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#”,
“contentVersion”: “1.0.0.0”,
“variables”: {
  “location”: “japaneast”,

  “vmName”: “VM名”,
  “vmSize”: “Standard_B2s”,

  “adminUsername”: “User Name”,
  “adminPassword”: “Password”,

  “publisher”: “MicrosoftSQLServer”,
  “offer”: “SQL2008R2SP3-WS2008R2SP1”,
  “sku”: “Standard”,

  “nicName”: “[concat(variables(‘vmName’),’_nic’)]”,
  “addressPrefix”: “XXX.XXX.XXX.XXX/XX”,
  “subnetName”: “Subnet Name”,
  “subnetPrefix”: “XXX.XXX.XXX.XXX/XX”,
  “virtualNetworkName”: “VNET Name”,
  “subnetRef”: “[resourceId(‘Microsoft.Network/virtualNetworks/subnets’, variables(‘virtualNetworkName’), variables(‘subnetName’))]”,

  “diskName”: “[concat(variables(‘vmName’),’_os_disk’)]”,
  “DatadiskName”: “[concat(variables(‘vmName’),’_Data_disk’)]”,
  “storageAccountType”: “Standard_LRS”,

  “storageAccountName”: “Storage Account Name”

},
 “resources”: [
 {
  “type”: “Microsoft.Network/virtualNetworks”,
  “apiVersion”: “2018-11-01”,
  “name”: “[variables(‘virtualNetworkName’)]”,
  “location”: “[variables(‘location’)]”,
  “properties”: {
  “addressSpace”: {
  “addressPrefixes”: [
  “[variables(‘addressPrefix’)]”
  ]
},
 “subnets”: [
 {
  ”name”: “[variables(‘subnetName’)]”,
  ”properties”: {
  ”addressPrefix”: “[variables(‘subnetPrefix’)]”
    }
   }
  ]
 }
},
{
 ”type”: “Microsoft.Network/networkInterfaces”,
 ”apiVersion”: “2018-11-01”,
 ”name”: “[variables(‘nicName’)]”,
 ”location”: “[variables(‘location’)]”,
 ”dependsOn”: [
 ”[resourceId(‘Microsoft.Network/virtualNetworks/’, variables(‘virtualNetworkName’))]”
],
“properties”: {
 ”ipConfigurations”: [
 {
 ”name”: “ipconfig1”,
 ”properties”: {
 ”privateIPAllocationMethod”: “Dynamic”,
 ”subnet”: {
 ”id”: “[variables(‘subnetRef’)]”
     }
    }
   }
  ]
 }
},
{
 ”type”: “Microsoft.Compute/virtualMachines”,
 ”apiVersion”: “2018-10-01”,
 ”name”: “[variables(‘vmName’)]”,
 ”location”: “[variables(‘location’)]”,
 ”dependsOn”: [
 ”[resourceId(‘Microsoft.Network/networkInterfaces/’, variables(‘nicName’))]”
 ],
 ”properties”: {
 ”hardwareProfile”: {
 ”vmSize”: “[variables(‘vmSize’)]”
 },
 ”osProfile”: {
 ”computerName”: “[variables(‘vmName’)]”,
 ”adminUsername”: “[variables(‘adminUsername’)]”,
 ”adminPassword”: “[variables(‘adminPassword’)]”
 },
 ”storageProfile”: {
 ”imageReference”: {
 ”publisher”: “[variables(‘publisher’)]”,
 ”offer”: “[variables(‘offer’)]”,
 ”sku”: “[variables(‘sku’)]”,
 ”version”: “latest”
 },
 ”osDisk”: {
 ”createOption”: “FromImage”,
 ”name”: “[variables(‘diskname’)]”,
 ”managedDisk”: {
 ”storageAccountType”: “[variables(‘storageAccountType’)]”
 }
  },
 ”dataDisks”: [
 {
 ”lun”: 0,
 ”name”: “[variables(‘datadiskname’)]”,

 ”createOption”: “Empty”,
 ”managedDisk”: {
  ”storageAccountType”: “[variables(‘storageAccountType’)]”
  },
  ”diskSizeGB”: 128

  }
 ]
},
 ”networkProfile”: {
 ”networkInterfaces”: [
 {
 ”id”: “[resourceId(‘Microsoft.Network/networkInterfaces’,variables(‘nicName’))]”
 }
 ]
},
 ”diagnosticsProfile”: {
 ”bootDiagnostics”: {
 ”enabled”: true,
 ”storageUri”: “[concat(‘https://’, variables(‘storageAccountName’), ‘.blob.core.windows.net’)]”
       }
     }
   }
  }
 ]

}

2.Windows SQL Serverをテンプレートを使ってデプロイする

テンプレート機能にARMテンプレートを登録します。以下の内容が表示されますので、名前と説明を入力しOKを表示します。

テンプレート画面が表示されますので、デフォルト表示されている内容を削除し、1)で作成したテンプレートをペーストしOKボタンをクリックします。 保存が完了したテンプレートを選択すると以下の画面が表示されますので、リソースグループ名を登録、使用条件に同意し、購入ボタンをクリックします。

デプロイが完了したら、リソースに移動して確認します。無事完成しているかと思います。

3.登録されているテンプレートをPower Shellから呼び出せない(2019年12月現在)

2019年12月時点では、テンプレート機能に登録したテンプレートを外部から呼び出すことはできないそうです。Azure Portalからのデプロイしかできないそうです。

Power Shell等からARMテンプレートを使ったデプロイを行うには、ローカルに保存したファイルやGitHubを指定してのデプロイとなるようです。