次の方法で共有


ARM テンプレートと Python を使用してリソースをデプロイする

この記事では、Azure Resource Manager テンプレート (ARM テンプレート) で Python を使用してリソースを Azure にデプロイする方法について説明します。 Azure ソリューションのデプロイと管理の概念に慣れていない場合は、 テンプレートのデプロイの概要を参照してください。

[前提条件]

  • デプロイするテンプレート。 デプロイするテンプレートがない場合は、Azure クイック スタート テンプレート リポジトリからサンプル テンプレートを保存します。

  • Python 3.8 以降がインストールされています。 最新のものをインストールするには、Python.org を参照してください。

  • 仮想環境にインストールされている Python 用の次の Azure ライブラリ パッケージ。 いずれかのパッケージをインストールするには、 pip install {package-name}

    • azure-identity (アズール・アイデンティティ)
    • azure-mgmt-resource

    これらのパッケージの古いバージョンが既に仮想環境にインストールされている場合は、pip install --upgrade {package-name}でそれらを更新する必要があるかもしれません。

  • この記事の例では、CLI ベースの認証 (AzureCliCredential) を使用します。 環境によっては、認証を行うために最初に az login を実行する必要がある場合があります。

必要なアクセス許可

Bicep ファイルまたは Azure Resource Manager (ARM) テンプレートをデプロイするには、デプロイするリソースに対する書き込みアクセス権と、 Microsoft.Resources/deployments リソースの種類に対するすべての操作へのアクセス権が必要です。 たとえば、仮想マシンをデプロイするには、Microsoft.Compute/virtualMachines/write および Microsoft.Resources/deployments/* アクセス許可が必要です。 What-If 操作のアクセス許可要件も同じです。

Azure CLI バージョン 2.76.0 以降 と Azure PowerShell バージョン 13.4.0 以降 では、このプロセス中に ARM が Bicep テンプレートを徹底的に検証する方法を決定する ValidationLevel スイッチが導入されています。 詳細については、「What-if コマンド」を参照してください。

ロールとアクセス許可の一覧については、Azure の組み込みロールに関するページを参照してください。

デプロイのスコープ

リソース グループ、サブスクリプション、管理グループ、またはテナントをデプロイのターゲットにすることができます。 デプロイのスコープに応じて、さまざまな方法を使用します。

各スコープに対して、テンプレートをデプロイするユーザーにはリソースを作成するためのアクセス許可が必要です。

デプロイ名

ARM テンプレートをデプロイするときに、デプロイに名前を付けることができます。 この名前は、デプロイ履歴からデプロイを取得するのに役立ちます。 デプロイの名前を指定しない場合は、テンプレート ファイルの名前が使用されます。 たとえば、azuredeploy.json という名前のテンプレートをデプロイするときにデプロイ名を指定しなかった場合、デプロイの名前は azuredeploy になります。

デプロイを実行するたびに、リソース グループのデプロイ履歴にデプロイ名のエントリが追加されます。 別のデプロイを実行するときに同じ名前を付けると、現在のデプロイによって前のエントリが置き換えられます。 デプロイ履歴に一意のエントリを保持する場合は、デプロイごとに一意の名前を付けます。

一意の名前を作成するために、ランダムな数値を割り当てることができます。

import random

suffix = random.randint(1, 1000)
deployment_name = f"ExampleDeployment{suffix}"

または、日付の値を追加します。

from datetime import datetime

today = datetime.now().strftime("%m-%d-%Y")
deployment_name = f"ExampleDeployment{today}"

同じリソース グループに対して同じ名前のデプロイを同時に実行した場合は、最後のデプロイのみが完了します。 完了していない同じ名前のデプロイは、最後のデプロイによって置き換えられます。 たとえば、newStorage という名前のストレージ アカウントをデプロイする storage1 という名前のデプロイを実行し、newStorage という名前のストレージ アカウントをデプロイする storage2 という名前の別のデプロイを同時に実行した場合は、1 つのストレージ アカウントのみがデプロイされます。 結果のストレージ アカウントの名前は storage2 になります。

ただし、newStorage という名前のストレージ アカウントをデプロイする storage1 という名前のデプロイを実行し、その完了直後に、newStorage という名前のストレージ アカウントをデプロイする storage2 という名前の別のデプロイを実行した場合は、ストレージ アカウントが 2 つになります。 1 つは storage1 という名前に、もう 1 つは storage2 という名前になります。 ただし、デプロイ履歴にはエントリが 1 つだけ存在します。

デプロイごとに一意の名前を指定すると、競合なしでそれらを同時に実行できます。 newStorage1 という名前のストレージ アカウントをデプロイする storage1 という名前のデプロイを実行し、newStorage2 という名前のストレージ アカウントをデプロイする storage2 という名前の別のデプロイを同時に実行した場合は、2 つのストレージ アカウントがデプロイされ、デプロイ履歴には 2 つのエントリが存在します。

同時デプロイによる競合を回避し、デプロイ履歴に一意のエントリが確実に存在するようにするには、各デプロイに一意の名前を付けます。

ローカル テンプレートのデプロイ

ローカル コンピューターからのテンプレートまたは外部に格納されているものをデプロイできます。 このセクションでは、ローカル テンプレートのデプロイについて説明します。

存在しないリソース グループにデプロイする場合は、リソース グループを作成します。 リソース グループ名には、英数字、ピリオド、アンダースコア、ハイフン、かっこのみを含めることができます。 最大長は 90 文字です。 名前の末尾をピリオドにすることはできません。

import os
from azure.identity import AzureCliCredential
from azure.mgmt.resource import ResourceManagementClient

credential = AzureCliCredential()
subscription_id = os.environ["AZURE_SUBSCRIPTION_ID"]

resource_client = ResourceManagementClient(credential, subscription_id)

rg_result = resource_client.resource_groups.create_or_update(
    "exampleGroup",
    {
        "location": "Central US"
    }
)

print(f"Provisioned resource group with ID: {rg_result.id}")

ARM テンプレートをデプロイするには、ResourceManagementClient.deployments.begin_create_or_update を使用します。 次の例では、storage.json という名前のローカル テンプレートが必要です。

import os
import json
from azure.identity import AzureCliCredential
from azure.mgmt.resource import ResourceManagementClient
from azure.mgmt.resource.resources.models import DeploymentMode

credential = AzureCliCredential()
subscription_id = os.environ["AZURE_SUBSCRIPTION_ID"]

resource_client = ResourceManagementClient(credential, subscription_id)

with open("storage.json", "r") as template_file:
    template_body = json.load(template_file)

rg_deployment_result = resource_client.deployments.begin_create_or_update(
    "exampleGroup",
    "exampleDeployment",
    {
        "properties": {
            "template": template_body,
            "parameters": {
                "storagePrefix": {
                    "value": "demostore"
                },
            },
            "mode": DeploymentMode.incremental
        }
    }
)

デプロイが完了するまでに数分かかる場合があります。

リモート テンプレートのデプロイ

ARM テンプレートをローカル コンピューターに格納する代わりに、外部の場所に格納することもできます。 ソース管理リポジトリ (GitHub など) にテンプレートを格納できます。 または、組織内の共有アクセス用の Azure ストレージ アカウントに格納することができます。

存在しないリソース グループにデプロイする場合は、リソース グループを作成します。 リソース グループ名には、英数字、ピリオド、アンダースコア、ハイフン、かっこのみを含めることができます。 最大長は 90 文字です。 名前の末尾をピリオドにすることはできません。

import os
from azure.identity import AzureCliCredential
from azure.mgmt.resource import ResourceManagementClient

credential = AzureCliCredential()
subscription_id = os.environ["AZURE_SUBSCRIPTION_ID"]

resource_client = ResourceManagementClient(credential, subscription_id)

rg_result = resource_client.resource_groups.create_or_update(
    "exampleGroup",
    {
        "location": "Central US"
    }
)

print(f"Provisioned resource group with ID: {rg_result.id}")

ARM テンプレートをデプロイするには、ResourceManagementClient.deployments.begin_create_or_update を使用します。 次の例では、リモート テンプレートをデプロイします。 このテンプレートでは、ストレージ アカウントが作成されます。

import os
from azure.identity import AzureCliCredential
from azure.mgmt.resource import ResourceManagementClient
from azure.mgmt.resource.resources.models import DeploymentMode

credential = AzureCliCredential()
subscription_id = os.environ["AZURE_SUBSCRIPTION_ID"]

resource_client = ResourceManagementClient(credential, subscription_id)

resource_group_name = "exampleGroup"
location = "westus"
template_uri = "https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/quickstarts/microsoft.storage/storage-account-create/azuredeploy.json"

rg_deployment_result = resource_client.deployments.begin_create_or_update(
    resource_group_name,
    "exampleDeployment",
    {
        "properties": {
            "templateLink": {
                "uri": template_uri
            },
            "parameters": {
                "location": {
                    "value": location
                }
            },
            "mode": DeploymentMode.incremental
        }
    }
)

前の例では、テンプレートにはパブリックにアクセスできる URI が必要になります。テンプレートに機密データを含めてはいけないため、この方法は多くの場合に利用できます。 機密データ (管理者パスワードなど) を指定する必要がある場合は、セキュリティで保護されたパラメーターとしてその値を渡します。 匿名アクセスを許可しないストレージ アカウントにテンプレートを保持する場合は、SAS トークンを指定する必要があります。

import os
from azure.identity import AzureCliCredential
from azure.mgmt.resource import ResourceManagementClient
from azure.mgmt.resource.resources.models import DeploymentMode

credential = AzureCliCredential()
subscription_id = os.environ["AZURE_SUBSCRIPTION_ID"]
sas_token = os.environ["SAS_TOKEN"]

resource_client = ResourceManagementClient(credential, subscription_id)

resource_group_name = "exampleGroup"
location = "westus"
template_uri = f"https://stage20230425.blob.core.windows.net/templates/storage.json?{sas_token}"

rg_deployment_result = resource_client.deployments.begin_create_or_update(
    resource_group_name,
    "exampleDeployment",
    {
        "properties": {
            "templateLink": {
                "uri": template_uri
            },
            "parameters": {
                "location": {
                    "value": location
                }
            },
            "mode": DeploymentMode.incremental
        }
    }
)

詳細については、「 リンクされたテンプレートの相対パスを使用する」を参照してください。

テンプレート スペックのデプロイ

ローカル テンプレートまたはリモート テンプレートをデプロイする代わりに、 テンプレート スペックを作成できます。テンプレート スペックは、ARM テンプレートを含む Azure サブスクリプション内のリソースです。 これにより、テンプレートを組織内のユーザーと安全に共有することが容易になります。 テンプレート スペックへのアクセス権を付与するには、Azure ロールベースのアクセス制御 (Azure RBAC) を使用します。

次の例では、テンプレート スペックの作成とデプロイの方法を示します。

まず、ARM テンプレートを指定して、テンプレート スペックを作成します。

import os
import json
from azure.identity import AzureCliCredential
from azure.mgmt.resource.templatespecs import TemplateSpecsClient
from azure.mgmt.resource.templatespecs.models import TemplateSpecVersion, TemplateSpec

credential = AzureCliCredential()
subscription_id = os.environ["AZURE_SUBSCRIPTION_ID"]

template_specs_client = TemplateSpecsClient(credential, subscription_id)

template_spec = TemplateSpec(
    location="westus2",
    description="Storage Spec"
)

template_specs_client.template_specs.create_or_update(
    "templateSpecsRG",
    "storageSpec",
    template_spec
)

with open("storage.json", "r") as template_file:
    template_body = json.load(template_file)

version = TemplateSpecVersion(
    location="westus2",
    description="Storage Spec",
    main_template=template_body
)

template_spec_result = template_specs_client.template_spec_versions.create_or_update(
     "templateSpecsRG",
    "storageSpec",
    "1.0.0",
    version
)

print(f"Provisioned template spec with ID: {template_spec_result.id}")

次に、テンプレート スペックの ID を取得して、デプロイします。

import os
from azure.identity import AzureCliCredential
from azure.mgmt.resource import ResourceManagementClient
from azure.mgmt.resource.resources.models import DeploymentMode
from azure.mgmt.resource.templatespecs import TemplateSpecsClient

credential = AzureCliCredential()
subscription_id = os.environ["AZURE_SUBSCRIPTION_ID"]

resource_client = ResourceManagementClient(credential, subscription_id)
template_specs_client = TemplateSpecsClient(credential, subscription_id)

template_spec = template_specs_client.template_spec_versions.get(
    "templateSpecsRg",
    "storageSpec",
    "1.0.0"
)

rg_deployment_result = resource_client.deployments.begin_create_or_update(
    "exampleGroup",
    "exampleDeployment",
    {
        "properties": {
            "template_link": {
                "id": template_spec.id
            },
            "mode": DeploymentMode.incremental
        }
    }
)

詳細については、 Azure Resource Manager テンプレートの仕様に関するページを参照してください。

変更のプレビュー

テンプレートをデプロイする前に、テンプレートが環境に与える変更をプレビューすることができます。 what-if 操作を使用して、テンプレートが期待する変更を行うことを確認します。 また、what-if はテンプレートのエラーも検証します。

次のステップ