You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python复刻AZ CLI逻辑创建无公网IP的通用化镜像Azure VM

完全可以通过Python实现,我们使用Azure官方Python SDK即可完成和你给出的AZ CLI完全一致的效果,不需要额外创建资源组、VNet、子网等已有资源。

前置依赖

先安装需要的SDK包:

pip install azure-mgmt-compute azure-mgmt-network azure-identity azure-mgmt-msi

核心实现逻辑

关键点说明

  • 复用已有VNet/子网:直接查询获取现有子网的资源ID,创建网卡时直接绑定该ID即可,不需要新建网络资源
  • 不分配公网IP:创建网卡时不关联任何公网IP资源即可,对应AZ CLI的--public-ip-address ""参数效果
  • 其余参数和你使用的AZ CLI参数一一对应,包括共享镜像库镜像、托管身份、SSH认证配置等

完整示例代码

from azure.identity import DefaultAzureCredential
from azure.mgmt.compute import ComputeManagementClient
from azure.mgmt.network import NetworkManagementClient
from azure.mgmt.msi import ManagedServiceIdentityClient
from azure.mgmt.compute.models import (
    VirtualMachine,
    HardwareProfile,
    StorageProfile,
    OSProfile,
    LinuxConfiguration,
    SshConfiguration,
    SshPublicKey,
    NetworkInterfaceReference,
    VirtualMachineIdentity,
    UserAssignedIdentitiesValue
)

# -------------------------- 替换为你自己的参数 --------------------------
SUBSCRIPTION_ID = "你的Azure订阅ID"
RG = "镜像所在资源组名"
RG2 = "VM所在资源组名"
SIG = "共享镜像库名称"
SIG_IMAGE_DEFINITION = "镜像定义名称"
VERSION = "镜像版本号"
VM_NAME = "虚拟机名称"
SIZE = "虚拟机规格,比如Standard_D2s_v3"
IDENTITY_NAME = "用户托管身份名称"
SSH_KEY_PATH = "本地SSH公钥路径,比如~/.ssh/id_rsa.pub"
ADMIN_USERNAME = "admin"
EXISTING_VNET_NAME = "已有VNet的名称"
EXISTING_SUBNET_NAME = "已有子网的名称"
# -----------------------------------------------------------------------

# 初始化认证和客户端
credential = DefaultAzureCredential()
compute_client = ComputeManagementClient(credential, SUBSCRIPTION_ID)
network_client = NetworkManagementClient(credential, SUBSCRIPTION_ID)
msi_client = ManagedServiceIdentityClient(credential, SUBSCRIPTION_ID)

# 1. 获取共享镜像版本ID(对应CLI中az sig image-version show部分)
image_version = compute_client.gallery_image_versions.get(
    resource_group_name=RG,
    gallery_name=SIG,
    gallery_image_name=SIG_IMAGE_DEFINITION,
    gallery_image_version_name=VERSION
)
image_id = image_version.id

# 2. 获取用户托管身份ID(对应CLI中az identity show部分)
identity = msi_client.user_assigned_identities.get(
    resource_group_name=RG2,
    resource_name=IDENTITY_NAME
)
identity_id = identity.id

# 3. 获取已有子网ID(复用现有网络资源,不需要新建VNet/子网)
subnet = network_client.subnets.get(
    resource_group_name=RG2,
    virtual_network_name=EXISTING_VNET_NAME,
    subnet_name=EXISTING_SUBNET_NAME
)
subnet_id = subnet.id

# 4. 创建网卡,不绑定公网IP(实现无公网IP效果)
nic_name = f"{VM_NAME}-nic"
nic_params = {
    "location": image_version.location,
    "ip_configurations": [{
        "name": f"{nic_name}-ipconfig",
        "subnet": {"id": subnet_id}
        # 不配置public_ip_address参数,即不分配公网IP
    }]
}
nic_poller = network_client.network_interfaces.begin_create_or_update(
    resource_group_name=RG2,
    network_interface_name=nic_name,
    parameters=nic_params
)
nic = nic_poller.result()
nic_id = nic.id

# 5. 读取SSH公钥内容
with open(SSH_KEY_PATH, "r") as f:
    ssh_key_data = f.read().strip()

# 6. 创建虚拟机
vm_params = VirtualMachine(
    location=image_version.location,
    hardware_profile=HardwareProfile(vm_size=SIZE),
    storage_profile=StorageProfile(
        image_reference={"id": image_id}
    ),
    os_profile=OSProfile(
        computer_name=VM_NAME,
        admin_username=ADMIN_USERNAME,
        linux_configuration=LinuxConfiguration(
            disable_password_authentication=True,
            ssh=SshConfiguration(
                public_keys=[
                    SshPublicKey(
                        path=f"/home/{ADMIN_USERNAME}/.ssh/authorized_keys",
                        key_data=ssh_key_data
                    )
                ]
            )
        )
    ),
    network_profile={
        "network_interfaces": [
            NetworkInterfaceReference(id=nic_id, primary=True)
        ]
    },
    identity=VirtualMachineIdentity(
        type="UserAssigned",
        user_assigned_identities={
            identity_id: UserAssignedIdentitiesValue()
        }
    )
)

vm_poller = compute_client.virtual_machines.begin_create_or_update(
    resource_group_name=RG2,
    vm_name=VM_NAME,
    parameters=vm_params
)
vm = vm_poller.result()
print(f"虚拟机创建成功,资源ID:{vm.id}")

上述代码执行逻辑和你提供的AZ CLI完全一致,所有依赖的资源(资源组、VNet、子网、共享镜像、托管身份)均使用已有的资源,不会额外创建不需要的网络资源,且创建的虚拟机无公网IP。

内容的提问来源于stack exchange,提问作者archcutbank

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 06:06:02