示例:使用 Azure 库创建虚拟机

本文介绍如何使用 Python 脚本中的 Azure SDK 管理库创建包含 Linux 虚拟机的资源组。

本文中的所有命令在 Linux/macOS bash 和 Windows 命令行界面中的工作方式相同,除非另有说明。

本文后面列出了 等效的 Azure CLI 命令 。 如果想要使用 Azure 门户,请参阅 “创建 Linux VM ”和 “创建 Windows VM”。

注释

通过代码创建虚拟机是一个多步骤过程,涉及预配虚拟机所需的许多其他资源。 如果只是从命令行运行此类代码,则使用 az vm create 命令会更加容易,该命令会自动为选择省略的任何设置预配这些辅助资源。 唯一必需的参数是资源组、VM 名称、映像名称和登录凭据。 有关详细信息,请参阅 使用 Azure CLI 快速创建虚拟机

1:设置本地开发环境

如果尚未安装,请设置可以运行此代码的环境。 下面是一些选项:

  • 使用 venv 或所选工具配置 Python 虚拟环境。 若要开始使用虚拟环境,请务必激活它。 若要安装 python,请参阅 “安装 Python”。

    #!/bin/bash
    # Create a virtual environment
    python -m venv .venv
    # Activate the virtual environment
    source .venv/Scripts/activate # only required for Windows (Git Bash)
    
  • 使用 conda 环境。 若要安装 Conda,请参阅 “安装 Miniconda”。

  • Visual Studio CodeGitHub Codespaces中使用 开发容器

2:安装所需的 Azure 库包

创建列出此示例中使用的管理库 的requirements.txt 文件:

azure-mgmt-resource
azure-mgmt-compute
azure-mgmt-network
azure-identity

然后,在激活虚拟环境的终端或命令提示符下,安装 requirements.txt中列出的管理库:

pip install -r requirements.txt

3:编写代码以创建虚拟机

使用以下代码创建名为 provision_vm.py 的 Python 文件。 注释说明了详细信息:

# Import the needed credential and management objects from the libraries.
import os

from azure.identity import DefaultAzureCredential
from azure.mgmt.compute import ComputeManagementClient
from azure.mgmt.network import NetworkManagementClient
from azure.mgmt.resource import ResourceManagementClient

print(
    "Provisioning a virtual machine...some operations might take a \
minute or two."
)

# Acquire a credential object.
credential = DefaultAzureCredential()

# Retrieve subscription ID from environment variable.
subscription_id = os.environ["AZURE_SUBSCRIPTION_ID"]


# Step 1: Provision a resource group

# Obtain the management object for resources.
resource_client = ResourceManagementClient(credential, subscription_id)

# Constants we need in multiple places: the resource group name and
# the region in which we provision resources. You can change these
# values however you want.
RESOURCE_GROUP_NAME = "PythonAzureExample-VM-rg"
LOCATION = "westus2"

# Provision the resource group.
rg_result = resource_client.resource_groups.create_or_update(
    RESOURCE_GROUP_NAME, {"___location": LOCATION}
)

print(
    f"Provisioned resource group {rg_result.name} in the \
{rg_result.___location} region"
)

# For details on the previous code, see Example: Provision a resource
# group at https://learn.microsoft.com/azure/developer/python/
# azure-sdk-example-resource-group

# Step 2: provision a virtual network

# A virtual machine requires a network interface client (NIC). A NIC
# requires a virtual network and subnet along with an IP address.
# Therefore we must provision these downstream components first, then
# provision the NIC, after which we can provision the VM.

# Network and IP address names
VNET_NAME = "python-example-vnet"
SUBNET_NAME = "python-example-subnet"
IP_NAME = "python-example-ip"
IP_CONFIG_NAME = "python-example-ip-config"
NIC_NAME = "python-example-nic"

# Obtain the management object for networks
network_client = NetworkManagementClient(credential, subscription_id)

# Provision the virtual network and wait for completion
poller = network_client.virtual_networks.begin_create_or_update(
    RESOURCE_GROUP_NAME,
    VNET_NAME,
    {
        "___location": LOCATION,
        "address_space": {"address_prefixes": ["10.0.0.0/16"]},
    },
)

vnet_result = poller.result()

print(
    f"Provisioned virtual network {vnet_result.name} with address \
prefixes {vnet_result.address_space.address_prefixes}"
)

# Step 3: Provision the subnet and wait for completion
poller = network_client.subnets.begin_create_or_update(
    RESOURCE_GROUP_NAME,
    VNET_NAME,
    SUBNET_NAME,
    {"address_prefix": "10.0.0.0/24"},
)
subnet_result = poller.result()

print(
    f"Provisioned virtual subnet {subnet_result.name} with address \
prefix {subnet_result.address_prefix}"
)

# Step 4: Provision an IP address and wait for completion
poller = network_client.public_ip_addresses.begin_create_or_update(
    RESOURCE_GROUP_NAME,
    IP_NAME,
    {
        "___location": LOCATION,
        "sku": {"name": "Standard"},
        "public_ip_allocation_method": "Static",
        "public_ip_address_version": "IPV4",
    },
)

ip_address_result = poller.result()

print(
    f"Provisioned public IP address {ip_address_result.name} \
with address {ip_address_result.ip_address}"
)

# Step 5: Provision the network interface client
poller = network_client.network_interfaces.begin_create_or_update(
    RESOURCE_GROUP_NAME,
    NIC_NAME,
    {
        "___location": LOCATION,
        "ip_configurations": [
            {
                "name": IP_CONFIG_NAME,
                "subnet": {"id": subnet_result.id},
                "public_ip_address": {"id": ip_address_result.id},
            }
        ],
    },
)

nic_result = poller.result()

print(f"Provisioned network interface client {nic_result.name}")

# Step 6: Provision the virtual machine

# Obtain the management object for virtual machines
compute_client = ComputeManagementClient(credential, subscription_id)

VM_NAME = "ExampleVM"
USERNAME = "azureuser"
PASSWORD = "ChangePa$$w0rd24"

print(
    f"Provisioning virtual machine {VM_NAME}; this operation might \
take a few minutes."
)

# Provision the VM specifying only minimal arguments, which defaults
# to an Ubuntu 18.04 VM on a Standard DS1 v2 plan with a public IP address
# and a default virtual network/subnet.

poller = compute_client.virtual_machines.begin_create_or_update(
    RESOURCE_GROUP_NAME,
    VM_NAME,
    {
        "___location": LOCATION,
        "storage_profile": {
            "image_reference": {
                "publisher": "Canonical",
                "offer": "UbuntuServer",
                "sku": "16.04.0-LTS",
                "version": "latest",
            }
        },
        "hardware_profile": {"vm_size": "Standard_DS1_v2"},
        "os_profile": {
            "computer_name": VM_NAME,
            "admin_username": USERNAME,
            "admin_password": PASSWORD,
        },
        "network_profile": {
            "network_interfaces": [
                {
                    "id": nic_result.id,
                }
            ]
        },
    },
)

vm_result = poller.result()

print(f"Provisioned virtual machine {vm_result.name}")

代码中的身份验证

本文稍后会使用 Azure CLI 登录到 Azure,以运行示例代码。 如果帐户有权在 Azure 订阅中创建资源组和网络和计算资源,代码将成功运行。

若要在生产脚本中使用此类代码,可以将环境变量设置为使用基于服务主体的方法进行身份验证。 若要了解详细信息,请参阅 如何使用 Azure 服务对 Python 应用进行身份验证。 需要确保服务主体有足够的权限在订阅中创建资源组和网络和计算资源,方法是在 Azure 中为其分配适当的角色;例如,订阅上的 参与者 角色。

4.运行脚本

  1. 如果尚未登录,请使用 Azure CLI 登录到 Azure:

    az login
    
  2. AZURE_SUBSCRIPTION_ID 环境变量设置为订阅 ID。 (可以运行 az account show 命令并从输出中的属性获取订阅 ID id ):

    set AZURE_SUBSCRIPTION_ID=00000000-0000-0000-0000-000000000000
    
  3. 运行以下脚本:

    python provision_vm.py
    

预配过程需要几分钟才能完成。

5.验证资源

打开 Azure 门户,导航到“PythonAzureExample-VM-rg”资源组,并记下虚拟机、虚拟磁盘、网络安全组、公共 IP 地址、网络接口和虚拟网络。

显示虚拟机和相关资源的新资源组的 Azure 门户页

还可以使用 Azure CLI 通过 az vm list 命令验证 VM 是否存在:

az vm list --resource-group PythonAzureExample-VM-rg

等效的 Azure CLI 命令

rem Provision the resource group

az group create -n PythonAzureExample-VM-rg -l westus2

rem Provision a virtual network and subnet

az network vnet create -g PythonAzureExample-VM-rg -n python-example-vnet ^
    --address-prefix 10.0.0.0/16 --subnet-name python-example-subnet ^
    --subnet-prefix 10.0.0.0/24

rem Provision a public IP address

az network public-ip create -g PythonAzureExample-VM-rg -n python-example-ip ^
    --allocation-method Dynamic --version IPv4

rem Provision a network interface client

az network nic create -g PythonAzureExample-VM-rg --vnet-name python-example-vnet ^
    --subnet python-example-subnet -n python-example-nic ^
    --public-ip-address python-example-ip

rem Provision the virtual machine

az vm create -g PythonAzureExample-VM-rg -n ExampleVM -l "westus2" ^
    --nics python-example-nic --image UbuntuLTS --public-ip-sku Standard ^
    --admin-username azureuser --admin-password ChangePa$$w0rd24

如果收到有关容量限制错误提示,可以尝试其他大小或区域。 有关详细信息,请参阅解决有关 SKU 不可用的错误

6:清理资源

如果要继续使用本文中创建的虚拟机和网络,请保留资源。 否则,请运行 az group delete 命令以删除资源组。

资源组不会在订阅中产生任何持续费用,但组中包含的资源(如虚拟机)可能会继续产生费用。 清理不经常使用的组是一种很好的做法。 --no-wait 参数允许命令立即返回,而不是等待作完成。

az group delete -n PythonAzureExample-VM-rg --no-wait

还可以使用 ResourceManagementClient.resource_groups.begin_delete 方法从代码中删除资源组。 示例中的代码 :创建资源组 演示用法。

另请参阅

以下资源包含使用 Python 创建虚拟机的更全面的示例:

  • Azure 虚拟机管理示例 - Python (GitHub)。 此示例演示了更多管理作,例如启动和重启 VM、停止和删除 VM、增加磁盘大小和管理数据磁盘。