ARM Template の Deploy

  • VNet
  • AzureResourceManager
  • ARM に軍配

    Terraform の Azure Provider が追いついていない

    普段、AWS でインフラを管理する際には Terraform を使っていますので、Azure でも同様に Terraform を使おうとしておりましたが、どうも Terraform の Azure Provider が追いついていないようでした。

    SQL Database のプライベートエンドポイントの設定や、VirtualMachine の自動バックアップの設定に関するオプションが Terraform の Azure Provider に存在しません。(2021年1月11日時点)

    AWS や GCP 等の異なるクラウド環境に対して通用する Terraform は便利ですが、Azure にだけ限定してインフラコード管理するならば、ARM に軍配が上がります。

    そこで、ARM Template でのインフラ構築方法を1から学ぶに当たり、記事を書いていこうと思います。

    ARM を試してみる

    準備 Install PowerShell for Mac

    Mac に PowerShell をインストールします。

    macpro:~ atsushi$ brew install openssl macpro:~ atsushi$ brew install curl macpro:~ atsushi$ brew install --cask powershell

    Azure に Login

    PowerShell でのログインコマンドは以下です。

    macpro:~ atsushi$ pwsh PowerShell 7.1.0 Copyright (c) Microsoft Corporation. https://aka.ms/powershell Type 'help' to get help. PS /Users/atsushi> Connect-AzAccount

    ログインができたら、後続の作業のために Resource Group を作成しておきます。

    PS /Users/atsushi> New-AzResourceGroup -Name sample-rg01 -Location "East US" ResourceGroupName : sample-rg01 Location : eastus ProvisioningState : Succeeded Tags : ResourceId : /subscriptions/00000000/resourceGroups/sample-rg01

    ここまでで準備は完了です。

    テンプレートを用意

    サンプルテンプレートを用意しました。ストレージアカウントを作成するだけのテンプレートです。

    {
        "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
        "contentVersion": "1.0.0.0",
        "parameters": {
          "storageAccountType": {
            "type": "string",
            "defaultValue": "Standard_LRS",
            "allowedValues": [
              "Standard_LRS",
              "Standard_GRS",
              "Standard_ZRS",
              "Premium_LRS"
            ]
          }
        },
        "resources": [
          {
            "type": "Microsoft.Storage/storageAccounts",
            "apiVersion": "2019-06-01",
            "name": "[concat('store', uniquestring(resourceGroup().id))]",
            "location": "[resourceGroup().location]",
            "kind": "StorageV2",
            "sku": {
              "name": "[parameters('storageAccountType')]"
            }
          }
        ]
    }

    ARM Template の Deploy

    デプロイ

    さあ、デプロイしてみましょう。

    PS /Users/atsushi> New-AzResourceGroupDeployment ` -Name ExampleDeployment ` -ResourceGroupName atsushi.koizumi.data ` -TemplateFile /Users/atsushi/github/arm_test01/sample.json DeploymentName : ExampleDeployment ResourceGroupName : sample-rg01 ProvisioningState : Succeeded Timestamp : 1/11/2021 7:54:31 AM Mode : Incremental TemplateLink : Parameters : Name Type Value ==================== ========================= ========== storageAccountType String Standard_LRS Outputs : DeploymentDebugLogLevel :

    実行結果を確認

    ちゃんとストレージアカウントが作成されているか、PowerShell で確認してみましょう。

    PS /Users/atsushi> Get-AzStorageAccount -ResourceGroupName sample-rg01 | ` Select-Object ResourceGroupName,StorageAccountName,CreationTime,ProvisioningState ResourceGroupName StorageAccountName CreationTime ProvisioningState ----------------- ------------------ ------------ ----------------- sample-rg01 storejkg664ibl7mf2 1/11/2021 7:54:07 AM Succeeded

    うまく作成できているようです。

    ARM デプロイ履歴

    デプロイ履歴確認方法

    以下のコマンドで ARM のデプロイ履歴は確認できます。

    PS /Users/atsushi> Get-AzResourceGroupDeployment -ResourceGroupName sample-rg01 DeploymentName : ExampleDeployment ResourceGroupName : sample-rg01 ProvisioningState : Succeeded Timestamp : 1/11/2021 7:54:31 AM Mode : Incremental TemplateLink : Parameters : Name Type Value ==================== ========================= ========== storageAccountType String Standard_LRS Outputs : DeploymentDebugLogLevel :

    実験:再デプロイした結果を見てみる

    PS /Users/atsushi> New-AzResourceGroupDeployment ` -Name ExampleDeployment ` -ResourceGroupName atsushi.koizumi.data ` -TemplateFile /Users/atsushi/github/arm_test01/sample.json DeploymentName : ExampleDeployment ResourceGroupName : sample-rg01 ProvisioningState : Succeeded Timestamp : 1/11/2021 10:39:24 AM Mode : Incremental TemplateLink : Parameters : Name Type Value ==================== ========================= ========== storageAccountType String Standard_LRS Outputs : DeploymentDebugLogLevel : PS /Users/atsushi> Get-AzStorageAccount -ResourceGroupName sample-rg01 | ` Select-Object ResourceGroupName,StorageAccountName,CreationTime,ProvisioningState ResourceGroupName StorageAccountName CreationTime ProvisioningState ----------------- ------------------ ------------ ----------------- sample-rg01 storejkg664ibl7mf2 1/11/2021 7:54:07 AM Succeeded PS /Users/atsushi> Get-AzResourceGroupDeployment -ResourceGroupName sample-rg01 DeploymentName : ExampleDeployment ResourceGroupName : sample-rg01 ProvisioningState : Succeeded Timestamp : 1/11/2021 10:39:24 AM Mode : Incremental TemplateLink : Parameters : Name Type Value ==================== ========================= ========== storageAccountType String Standard_LRS Outputs : DeploymentDebugLogLevel :

    分かったこと

    デプロイ履歴と、リソースのステータスから判明したことは、以下の2点です。

    • 全く同じリソースをデプロイしても、再作成とはならずにリソースの状態は変化しない。
    • デプロイ履歴は更新されるが、"DeploymentName" が全く同じだと上書きされてしまう。

    ARM にも記載されていますが、デプロイ名を一意にしておかないと過去のデプロイ履歴が追えなくなってしまいます。

    回避策として、デプロイ時の標準出力をログファイルに保存しておくという方法もありますが、ログファイル管理の手間が増えてしまいます。それよりも、履歴の数に制限がなければ、デプロイ名を一意にすることで履歴を残した方が管理しやすそうですね。

    デプロイ名を変えてデプロイしたら履歴が増えた

    試しに "DeploymentName" を変えて再度、デプロイを試みてみましょう。デプロイ履歴はどうなるでしょうか。

    PS /Users/atsushi/> Get-AzResourceGroupDeployment -ResourceGroupName sample-rg01 DeploymentName : ExampleDeployment-2 ResourceGroupName : sample-rg01 ProvisioningState : Succeeded Timestamp : 1/11/2021 10:49:38 AM Mode : Incremental TemplateLink : Parameters : Name Type Value ==================== ========================= ========== storageAccountType String Standard_LRS Outputs : DeploymentDebugLogLevel : DeploymentName : ExampleDeployment ResourceGroupName : sample-rg01 ProvisioningState : Succeeded Timestamp : 1/11/2021 10:39:24 AM Mode : Incremental TemplateLink : Parameters : Name Type Value ==================== ========================= ========== storageAccountType String Standard_LRS Outputs : DeploymentDebugLogLevel :

    デプロイ履歴が増えましたね。こちらに詳細が記載れています。デプロイ履歴は "800件" が上限のようですね。

    800件ということは、やはり定期的にデプロイ履歴を別の場所に保管しておく必要がありそうです。

    デプロイ履歴の詳細

    デプロイ履歴の詳細も確認することができます。

    PS C:\Users\atsus> Get-AzResourceGroupDeploymentOperation -ResourceGroupName sample-rg01 -DeploymentName ExampleDeployment-2 Id : /subscriptions/00000000-0000/resourceGroups/sample-rg01/providers/Microsoft.Resources/deployments/ExampleDeployment-2/operations/153BEF26EA4F6283 OperationId : 153BEF26EA4F6283 ProvisioningState : Succeeded StatusCode : OK StatusMessage : TargetResource : /subscriptions/00000000-0000/resourceGroups/sample-rg01/providers/Microsoft.Storage/storageAccounts/storejkg664ibl7mf2 Id : /subscriptions/00000000-0000/resourceGroups/sample-rg01/providers/Microsoft.Resources/deployments/ExampleDeployment-2/operations/08585912447165640736 OperationId : 08585912447165640736 ProvisioningState : Succeeded StatusCode : OK StatusMessage : TargetResource :

    デプロイ前の確認

    デプロイ実行前に、「もし実行したらどうなるのか!?」の確認もできます。

    PS C:\Users\atsus> Get-AzResourceGroupDeploymentWhatIfResult ` -ResourceGroupName sample-rg01 -TemplateFile sample.json Note: The result may contain false positive predictions (noise). You can help us improve the accuracy of the result by opening an issue here: https://aka.ms/WhatIfIssues. Resource and property changes are indicated with this symbol: = NoChange The deployment will update the following scope: Scope: /subscriptions/00000000-0000/resourceGroups/sample-rg01 = Microsoft.Storage/storageAccounts/storejkg664ibl7mf2 [2019-06-01] Resource changes: 1 no change.

    下記のコマンドでも可能です。操作ミスを防ぐために上記のコマンドを使う方が良い気がします。

    PS C:\Users\atsus> New-AzResourceGroupDeployment ` -Whatif ` -Name ExampleDeployment-3 ` -ResourceGroupName sample-rg01 ` -TemplateFile /Users/atsushi/github/arm_test01/sample.json

    結果は同じになります。

    と、まあ、コツをつかんだら使いやすそうですね。これから、どんどん使っていきたいと思います。

    ARM で作成したリソースを削除したい

    Remove-AzResourceGroupDeployment

    それでは、Remove-Az コマンドでデプロイ履歴を消してみます。

    PS C:\Users\atsus> Remove-AzResourceGroupDeployment ` -Name ExampleDeployment ` -ResourceGroupName sample-rg01 True

    結果は True でした。ストレージアカウントが削除されているか、PowerShell で確認してみます。

    PS /Users/atsushi> Get-AzStorageAccount -ResourceGroupName sample-rg01 | ` Select-Object ResourceGroupName,StorageAccountName,CreationTime,ProvisioningState ResourceGroupName StorageAccountName CreationTime ProvisioningState ----------------- ------------------ ------------ ----------------- sample-rg01 storejkg664ibl7mf2 1/11/2021 7:54:07 AM Succeeded

    あれ?消えていない。。。

    デプロイ履歴を徹底的に消す

    もう一度、デプロイ履歴を確認してみます。

    PS /Users/atsushi> Get-AzResourceGroupDeployment -ResourceGroupName sample-rg01 | ` Select-Object DeploymentName,Timestamp DeploymentName Timestamp -------------- --------- ExampleDeployment-2 1/11/2021 10:49:38 AM

    まだ、デプロイ履歴が残っていましたね。この残っているデプロイ履歴も消します。

    PS C:\Users\atsus> Remove-AzResourceGroupDeployment ` -Name ExampleDeployment-2 ` -ResourceGroupName sample-rg01 True
    PS /Users/atsushi> Get-AzStorageAccount -ResourceGroupName sample-rg01 | ` Select-Object ResourceGroupName,StorageAccountName,CreationTime,ProvisioningState ResourceGroupName StorageAccountName CreationTime ProvisioningState ----------------- ------------------ ------------ ----------------- sample-rg01 storejkg664ibl7mf2 1/11/2021 7:54:07 AM Succeeded

    まだ消えていない。。。

    完全モードと増分モード

    実は、デプロイ履歴を消してもリソースが消えないのは仕様でございました。

    デプロイ履歴を消してもリソースは消えない

    ARM Template の実行にあたり2種類のモードが存在します。

    完全モード(Complete mode)

    テンプレートファイルと実態が完全に一致させるモードです。テンプレートにないリソースは削除されます。Terraform と同じですね。

    増分モード(Incremental mode)

    こちらはテンプレートにないリソースは削除されません。テンプレート管理外のリソースも存在することができます。

    詳細は Azrure の公式ページの解説を参照ください。

    最後に

    Azure Resource Manager template specs なるものがプレビューリリースされています。これは ARM 用の GitHub みたいなものでバージョン管理ができるのだとか。

    なかなか便利そうですね~。時間があるときに、これも触ってみたいなと思います。

  • VNet
  • AzureResourceManager