この記事では、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 の組み込みロールに関するページを参照してください。
デプロイのスコープ
リソース グループ、サブスクリプション、管理グループ、またはテナントをデプロイのターゲットにすることができます。 デプロイのスコープに応じて、さまざまな方法を使用します。
リソース グループにデプロイするには、ResourceManagementClient.deployments.begin_create_or_updateを使用します。
サブスクリプションにデプロイするには、ResourceManagementClient.deployments.begin_create_or_update_at_subscription_scopeを使用します。
サブスクリプション レベルのデプロイの詳細については、「サブスクリプション レベルでのリソース グループとリソースの作成」を参照してください。
管理グループをデプロイするには、ResourceManagementClient.deployments.begin_create_or_update_at_management_group_scope を使用します。
管理グループ レベルのデプロイの詳細については、「 管理グループ レベルでのリソースの作成」を参照してください。
テナントをデプロイするには、ResourceManagementClient.deployments.begin_create_or_update_at_tenant_scope を使用します。
テナント レベルのデプロイの詳細については、「テナント レベルでのリソースの作成」を参照してください。
各スコープに対して、テンプレートをデプロイするユーザーにはリソースを作成するためのアクセス許可が必要です。
デプロイ名
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 はテンプレートのエラーも検証します。
次のステップ
- エラーが発生したときに正常なデプロイにロールバックするには、「デプロイが成功した場合 のエラー時のロールバック」を参照してください。
- リソース グループに存在するが、テンプレートで定義されていないリソースを処理する方法を指定するには、 Azure Resource Manager のデプロイ モードに関するページを参照してください。
- テンプレートでパラメーターを定義する方法については、「ARM テンプレート の構造と構文について」を参照してください。
- SAS トークンを必要とするテンプレートをデプロイする方法については、「SAS トークンを使用してプライベート ARM テンプレートをデプロイする」を参照してください。