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

使用Azure Python SDK v2.0.0rc6克隆运行中VM至其他资源组遇问题求助

解决Azure Python SDK v2.0.0rc6克隆VM到其他资源组的问题

看了你的代码,发现几个关键问题导致创建VM时抛出异常,我来帮你梳理下正确的步骤和修正方案:

核心问题分析

  1. StorageProfile参数冲突:你在创建VM时同时指定了os_disk(attach模式)和image_reference,这两个参数是互斥的——用现有磁盘attach的话不需要镜像引用,反之亦然,这会直接触发Azure API报错。
  2. 直接引用源磁盘的错误:你直接用了原资源组里的managed_disk.id来attach,但源磁盘正被原VM占用,而且目标资源组大概率没有访问原磁盘的权限。正确的做法是先从快照生成目标资源组的新托管磁盘,再用新磁盘创建VM。
  3. 未等待异步操作完成:创建快照是异步操作,你需要等待快照完全就绪后再进行后续步骤,否则会用到未完成的快照导致失败。

修正后的完整流程代码

1. 获取源VM和OS磁盘信息

# 获取源VM对象
source_vm = self.compute_client.virtual_machines.get(
    resource_group_name=source_rg_name,
    vm_name=virtual_machine
)
os_disk_name = source_vm.storage_profile.os_disk.name
# 获取源OS托管磁盘
managed_disk = self.compute_client.disks.get(
    resource_group_name=source_rg_name,
    disk_name=os_disk_name
)

2. 创建OS磁盘快照并等待完成

snapshot_name = f"SNAPSHOT-{os_disk_name}"
# 发起快照创建请求
snapshot_poller = self.compute_client.snapshots.create_or_update(
    resource_group_name=source_rg_name,
    snapshot_name=snapshot_name,
    parameters={
        'location': managed_disk.location,
        'creation_data': {
            'create_option': 'Copy',
            'source_uri': managed_disk.id
        }
    }
)
# 必须等待快照创建完成,否则后续基于快照创建磁盘会失败
snapshot = snapshot_poller.result()

3. 在目标资源组基于快照创建新的托管磁盘

target_os_disk_name = f"OS-DISK-{virtual_machine}"
# 发起目标磁盘创建请求
disk_poller = self.compute_client.disks.create_or_update(
    resource_group_name=self.config.cybric_resource_group_name,
    disk_name=target_os_disk_name,
    parameters={
        'location': managed_disk.location,
        'creation_data': {
            'create_option': 'Copy',
            'source_uri': snapshot.id
        },
        'sku': {
            'name': managed_disk.sku.name  # 保持和源磁盘相同的存储SKU
        }
    }
)
target_os_disk = disk_poller.result()

4. 创建目标VM(修正StorageProfile)

# 准备网络配置(确保目标资源组的NIC已提前创建好)
network_profile = azure.mgmt.compute.models.NetworkProfile(
    network_interfaces=[
        azure.mgmt.compute.models.NetworkInterfaceReference(
            id=nic_obj['id'], primary=True
        )
    ]
)

# 构建StorageProfile:只指定OS磁盘,移除冲突的image_reference
storage_profile = azure.mgmt.compute.models.StorageProfile(
    os_disk=azure.mgmt.compute.models.OSDisk(
        caching=source_vm.storage_profile.os_disk.caching,  # 复用源VM的缓存设置
        create_option=azure.mgmt.compute.models.DiskCreateOptionTypes.attach,
        name=target_os_disk_name,
        managed_disk=azure.mgmt.compute.models.ManagedDiskParameters(
            id=target_os_disk.id
        )
    )
)

# (可选)添加数据磁盘:流程和OS磁盘一致,先快照再创建目标磁盘
data_disks = []
for idx, data_disk in enumerate(source_vm.storage_profile.data_disks):
    # 省略创建数据磁盘快照、目标磁盘的代码(参考OS磁盘流程)
    # 假设已创建好target_data_disk:
    data_disks.append(azure.mgmt.compute.models.DataDisk(
        lun=idx,
        create_option=azure.mgmt.compute.models.DiskCreateOptionTypes.attach,
        managed_disk=azure.mgmt.compute.models.ManagedDiskParameters(
            id=target_data_disk.id
        ),
        caching=data_disk.caching,
        name=target_data_disk.name
    ))
storage_profile.data_disks = data_disks

# 发起VM创建请求
vm_poller = self.compute_client.virtual_machines.create_or_update(
    resource_group_name=self.config.cybric_resource_group_name,
    vm_name=virtual_machine,
    parameters=azure.mgmt.compute.models.VirtualMachine(
        location=source_vm.location,
        os_profile=source_vm.os_profile,
        hardware_profile=source_vm.hardware_profile,
        network_profile=network_profile,
        storage_profile=storage_profile
    )
)
# 等待VM创建完成
target_vm = vm_poller.result()

额外注意事项

  • 权限配置:确保你的服务主体或用户账号拥有原资源组的磁盘读取、快照创建权限,以及目标资源组的磁盘创建、VM创建权限。
  • SKU一致性:创建目标磁盘时尽量保持和源磁盘相同的存储SKU(如Standard_LRS、Premium_LRS),避免性能或兼容性问题。
  • 异步操作等待:所有create_or_update返回的poller都需要调用result()等待操作完成,否则后续步骤会引用未就绪的资源。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 04:01:06