如何用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
相关产品推荐
相关产品推荐

