diff --git a/doc/network-manage-loadbalancer/CONTRIBUTING.md b/doc/network-manage-loadbalancer/CONTRIBUTING.md new file mode 100644 index 0000000..e2abe20 --- /dev/null +++ b/doc/network-manage-loadbalancer/CONTRIBUTING.md @@ -0,0 +1,11 @@ +# Contributing to Azure samples + +Thank you for your interest in contributing to Azure samples! + +## Ways to contribute + +You can contribute to [Azure samples](https://azure.microsoft.com/documentation/samples/) in a few different ways: + +- Submit feedback on [this sample page](https://azure.microsoft.com/documentation/samples/network-python-manage-loadbalancer/) whether it was helpful or not. +- Submit issues through [issue tracker](https://github.com/Azure-Samples/network-python-manage-loadbalancer/issues) on GitHub. We are actively monitoring the issues and improving our samples. +- If you wish to make code changes to samples, or contribute something new, please follow the [GitHub Forks / Pull requests model](https://help.github.com/articles/fork-a-repo/): Fork the sample repo, make the change and propose it back by submitting a pull request. \ No newline at end of file diff --git a/doc/network-manage-loadbalancer/LICENSE b/doc/network-manage-loadbalancer/LICENSE new file mode 100644 index 0000000..d8d98a8 --- /dev/null +++ b/doc/network-manage-loadbalancer/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015 Microsoft Corporation + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/doc/network-manage-loadbalancer/README.md b/doc/network-manage-loadbalancer/README.md new file mode 100644 index 0000000..d49b48d --- /dev/null +++ b/doc/network-manage-loadbalancer/README.md @@ -0,0 +1,102 @@ +--- +page_type: sample +languages: +- python +products: +- azure +description: "This sample shows how to manage a load balancer using the Azure Resource Manager APIs for Python." +urlFragment: network-python-manage-loadbalancer +--- + +# Getting Started with Azure Resource Manager for load balancers in Python + +This sample shows how to manage a load balancer using the Azure Resource Manager APIs for Python. + +You can use a load balancer to provide high availability for your workloads in Azure. An Azure load balancer is a Layer-4 (TCP, UDP) type load balancer that distributes incoming traffic among healthy service instances in cloud services or virtual machines defined in a load balancer set. + +For a detailed overview of Azure load balancers, see [Azure Load Balancer overview](https://azure.microsoft.com/documentation/articles/load-balancer-overview/). + +![alt tag](./lb.JPG) + +This sample deploys an internet-facing load balancer. It then creates and deploys two Azure virtual machines behind the load balancer. For a detailed overview of internet-facing load balancers, see [Internet-facing load balancer overview](https://azure.microsoft.com/documentation/articles/load-balancer-internet-overview/). + +To deploy an internet-facing load balancer, you'll need to create and configure the following objects. + +- Front end IP configuration - contains public IP addresses for incoming network traffic. +- Back end address pool - contains network interfaces (NICs) for the virtual machines to receive network traffic from the load balancer. +- Load balancing rules - contains rules mapping a public port on the load balancer to port in the back end address pool. +- Inbound NAT rules - contains rules mapping a public port on the load balancer to a port for a specific virtual machine in the back end address pool. +- Probes - contains health probes used to check availability of virtual machines instances in the back end address pool. + +You can get more information about load balancer components with Azure resource manager at [Azure Resource Manager support for Load Balancer](https://azure.microsoft.com/documentation/articles/load-balancer-arm/). + +## Tasks performed in this sample + +The sample performs the following tasks to create the load balancer and the load-balanced virtual machines: + +1. Create a resource group +4. Create a public IP +5. Build the load balancer payload + 1. Build a front-end IP pool + 2. Build a back-end address pool + 3. Build a health probe + 4. Build a load balancer rule + 5. Build inbound NAT rule 1 + 6. Build inbound NAT rule 2 +6. Create the load balancer with the above payload +2. Create a virtual network (vnet) +3. Create a subnet +7. Create NIC 1 +8. Create NIC 2 +9. Find an Ubutnu VM image +10. Create an availability set +11. Create the first VM: Web1 +12. Create the second VM: Web2 +13. Delete the resource group and the resources created in the previous steps + +## Run this sample + +1. If you don't already have a Microsoft Azure subscription, you can register for a [free trial account](http://go.microsoft.com/fwlink/?LinkId=330212). + +1. Install [Python](https://www.python.org/downloads/) if you haven't already. + +2. We recommend using a [virtual environment](https://docs.python.org/3/tutorial/venv.html) to run this example, but it's not mandatory. You can initialize a virtual environment this way: + + pip install virtualenv + virtualenv mytestenv + cd mytestenv + source bin/activate + +3. Clone the sample repository. + + git clone https://github.com/Azure-Samples/network-python-manage-loadbalancer.git + +4. Install the dependencies using pip. + + cd network-python-manage-loadbalancer + pip install -r requirements.txt + +5. Create an Azure service principal, using +[Azure CLI](http://azure.microsoft.com/documentation/articles/resource-group-authenticate-service-principal-cli/), +[PowerShell](http://azure.microsoft.com/documentation/articles/resource-group-authenticate-service-principal/) +or [Azure Portal](http://azure.microsoft.com/documentation/articles/resource-group-create-service-principal-portal/). + +6. Export these environment variables into your current shell. + + export AZURE_TENANT_ID={your tenant ID} + export AZURE_CLIENT_ID={your client ID} + export AZURE_CLIENT_SECRET={your client secret} + export AZURE_SUBSCRIPTION_ID={your subscription ID} + +7. Run the sample for public load balancer. + + python example_public_load_balancer.py + Or + + Run the sample for internal load balancer. + + python example_internal_load_balancer.py + +## More information + +- [Azure SDK for Python](http://github.com/Azure/azure-sdk-for-python) diff --git a/doc/network-manage-loadbalancer/example.py b/doc/network-manage-loadbalancer/example.py new file mode 100644 index 0000000..fe28d3f --- /dev/null +++ b/doc/network-manage-loadbalancer/example.py @@ -0,0 +1,426 @@ +import os +from azure.common.credentials import ServicePrincipalCredentials +from azure.mgmt.resource import ResourceManagementClient +from azure.mgmt.storage import StorageManagementClient +from azure.mgmt.network import NetworkManagementClient +from azure.mgmt.compute import ComputeManagementClient +from haikunator import Haikunator + +haikunator = Haikunator() + +# Azure Datacenter +LOCATION = 'westus' + +# Resource Group +GROUP_NAME = 'azure-sample-group-loadbalancer' + +# Network +VNET_NAME = 'azure-sample-vnet' +SUBNET_NAME = 'azure-sample-subnet' +DOMAIN_LABEL_NAME = 'testdns'+haikunator.haikunate() +PUBLIC_IP_NAME = 'azure-sample-publicip' + +# Load balancer +LB_NAME = 'azure-sample-loadbalancer' +FIP_NAME = 'azure-sample-frontendipname' +ADDRESS_POOL_NAME = 'azure-sample-addr-pool' +PROBE_NAME = 'azure-sample-probe' +LB_RULE_NAME = 'azure-sample-lb-rule' + +NETRULE_NAME_1 = 'azure-sample-netrule1' +NETRULE_NAME_2 = 'azure-sample-netrule2' + +FRONTEND_PORT_1 = 21 +FRONTEND_PORT_2 = 23 +BACKEND_PORT = 22 + +# VM +AVAILABILITY_SET_NAME = 'azure-sample-availabilityset' +OS_DISK_NAME = 'azure-sample-osdisk' +STORAGE_ACCOUNT_NAME = haikunator.haikunate(delimiter='') + +IP_CONFIG_NAME = 'azure-sample-ip-config' +VMS_INFO = { + 1: { + 'name': 'Web1', + 'nic_name': 'azure-sample-nic1', + 'username': 'notadmin1', + 'password': 'Pa$$w0rd91' + }, + 2: { + 'name': 'Web2', + 'nic_name': 'azure-sample-nic2', + 'username': 'notadmin2', + 'password': 'Pa$$w0rd92' + } +} + +# Ubuntu config +PUBLISHER = 'Canonical' +OFFER = 'UbuntuServer' +SKU = '15.10' +VERSION = '15.10.201603150' + +# Windows config +#PUBLISHER = 'microsoftwindowsserver' +#OFFER = 'windowsserver' +#SKU = '2012-r2-datacenter' + +# Manage resources and resource groups - create, update and delete a resource group, +# deploy a solution into a resource group, export an ARM template. Create, read, update +# and delete a resource +# +# This script expects that the following environment vars are set: +# +# AZURE_TENANT_ID: with your Azure Active Directory tenant id or domain +# AZURE_CLIENT_ID: with your Azure Active Directory Application Client ID +# AZURE_CLIENT_SECRET: with your Azure Active Directory Application Secret +# AZURE_SUBSCRIPTION_ID: with your Azure Subscription Id +# + + +def run_example(): + """Resource Group management example.""" + # + # Create all clients with an Application (service principal) token provider + # + subscription_id = os.environ.get( + 'AZURE_SUBSCRIPTION_ID', + '11111111-1111-1111-1111-111111111111') # your Azure Subscription Id + credentials = ServicePrincipalCredentials( + client_id=os.environ['AZURE_CLIENT_ID'], + secret=os.environ['AZURE_CLIENT_SECRET'], + tenant=os.environ['AZURE_TENANT_ID'] + ) + resource_client = ResourceManagementClient(credentials, subscription_id) + compute_client = ComputeManagementClient(credentials, subscription_id) + storage_client = StorageManagementClient(credentials, subscription_id) + network_client = NetworkManagementClient(credentials, subscription_id) + + # Create Resource group + print('Create Resource Group') + resource_client.resource_groups.create_or_update( + GROUP_NAME, {'location': LOCATION}) + + # Create PublicIP + print('Create Public IP') + public_ip_parameters = { + 'location': LOCATION, + 'public_ip_allocation_method': 'static', + 'dns_settings': { + 'domain_name_label': DOMAIN_LABEL_NAME + }, + 'idle_timeout_in_minutes': 4 + } + async_publicip_creation = network_client.public_ip_addresses.create_or_update( + GROUP_NAME, + PUBLIC_IP_NAME, + public_ip_parameters + ) + public_ip_info = async_publicip_creation.result() + + # Building a FrontEndIpPool + print('Create FrontEndIpPool configuration') + frontend_ip_configurations = [{ + 'name': FIP_NAME, + 'private_ip_allocation_method': 'Dynamic', + 'public_ip_address': { + 'id': public_ip_info.id + } + }] + + # Building a BackEnd address pool + print('Create BackEndAddressPool configuration') + backend_address_pools = [{ + 'name': ADDRESS_POOL_NAME + }] + + # Building a HealthProbe + print('Create HealthProbe configuration') + probes = [{ + 'name': PROBE_NAME, + 'protocol': 'Http', + 'port': 80, + 'interval_in_seconds': 15, + 'number_of_probes': 4, + 'request_path': 'healthprobe.aspx' + }] + + # Building a LoadBalancer rule + print('Create LoadBalancerRule configuration') + load_balancing_rules = [{ + 'name': LB_RULE_NAME, + 'protocol': 'tcp', + 'frontend_port': 80, + 'backend_port': 80, + 'idle_timeout_in_minutes': 4, + 'enable_floating_ip': False, + 'load_distribution': 'Default', + 'frontend_ip_configuration': { + 'id': construct_fip_id(subscription_id) + }, + 'backend_address_pool': { + 'id': construct_bap_id(subscription_id) + }, + 'probe': { + 'id': construct_probe_id(subscription_id) + } + }] + + # Building InboundNATRule1 + print('Create InboundNATRule1 configuration') + inbound_nat_rules = [{ + 'name': NETRULE_NAME_1, + 'protocol': 'tcp', + 'frontend_port': FRONTEND_PORT_1, + 'backend_port': BACKEND_PORT, + 'enable_floating_ip': False, + 'idle_timeout_in_minutes': 4, + 'frontend_ip_configuration': { + 'id': construct_fip_id(subscription_id) + } + }] + + # Building InboundNATRule2 + print('Create InboundNATRule2 configuration') + inbound_nat_rules.append({ + 'name': NETRULE_NAME_2, + 'protocol': 'tcp', + 'frontend_port': FRONTEND_PORT_2, + 'backend_port': BACKEND_PORT, + 'enable_floating_ip': False, + 'idle_timeout_in_minutes': 4, + 'frontend_ip_configuration': { + 'id': construct_fip_id(subscription_id) + } + }) + + # Creating Load Balancer + print('Creating Load Balancer') + lb_async_creation = network_client.load_balancers.create_or_update( + GROUP_NAME, + LB_NAME, + { + 'location': LOCATION, + 'frontend_ip_configurations': frontend_ip_configurations, + 'backend_address_pools': backend_address_pools, + 'probes': probes, + 'load_balancing_rules': load_balancing_rules, + 'inbound_nat_rules': inbound_nat_rules + } + ) + lb_info = lb_async_creation.result() + + ############################################################## + # From here, we create the VM and link the LB inside the NIC # + ############################################################## + + # Create VNet + print('Create Vnet') + async_vnet_creation = network_client.virtual_networks.create_or_update( + GROUP_NAME, + VNET_NAME, + { + 'location': LOCATION, + 'address_space': { + 'address_prefixes': ['10.0.0.0/16'] + } + } + ) + async_vnet_creation.wait() + + # Create Subnet + async_subnet_creation = network_client.subnets.create_or_update( + GROUP_NAME, + VNET_NAME, + SUBNET_NAME, + {'address_prefix': '10.0.0.0/24'} + ) + subnet_info = async_subnet_creation.result() + + # Creating NIC + print('Creating NetworkInterface 1') + + back_end_address_pool_id = lb_info.backend_address_pools[0].id + + inbound_nat_rule_1_id = lb_info.inbound_nat_rules[0].id + async_nic1_creation = network_client.network_interfaces.create_or_update( + GROUP_NAME, + VMS_INFO[1]['nic_name'], + create_nic_parameters( + subnet_info.id, back_end_address_pool_id, inbound_nat_rule_1_id) + ) + + inbound_nat_rule_2_id = lb_info.inbound_nat_rules[1].id + print('Creating NetworkInterface 2') + async_nic2_creation = network_client.network_interfaces.create_or_update( + GROUP_NAME, + VMS_INFO[2]['nic_name'], + create_nic_parameters( + subnet_info.id, back_end_address_pool_id, inbound_nat_rule_2_id) + ) + + nic1_info = async_nic1_creation.result() + nic2_info = async_nic2_creation.result() + + # Create availability set + print('Create availability set') + availability_set_info = compute_client.availability_sets.create_or_update( + GROUP_NAME, + AVAILABILITY_SET_NAME, + {'location': LOCATION} + ) + + # Create a storage account + print('Create a storage account') + storage_async_operation = storage_client.storage_accounts.create( + GROUP_NAME, + STORAGE_ACCOUNT_NAME, + { + 'sku': {'name': 'standard_lrs'}, + 'kind': 'storage', + 'location': LOCATION + } + ) + storage_async_operation.wait() + + # Create VMs + print('Creating Virtual Machine 1') + vm_parameters1 = create_vm_parameters( + nic1_info.id, availability_set_info.id, VMS_INFO[1]) + async_vm1_creation = compute_client.virtual_machines.create_or_update( + GROUP_NAME, VMS_INFO[1]['name'], vm_parameters1) + async_vm1_creation.wait() + + print('Creating Virtual Machine 2') + vm_parameters2 = create_vm_parameters( + nic2_info.id, availability_set_info.id, VMS_INFO[2]) + async_vm2_creation = compute_client.virtual_machines.create_or_update( + GROUP_NAME, VMS_INFO[2]['name'], vm_parameters2) + async_vm2_creation.wait() + + provide_vm_login_info_to_user( + 1, public_ip_info, FRONTEND_PORT_1, VMS_INFO[1]) + provide_vm_login_info_to_user( + 2, public_ip_info, FRONTEND_PORT_2, VMS_INFO[2]) + + input("Press enter to delete this Resource Group.") + + # Delete Resource group and everything in it + print('Delete Resource Group') + delete_async_operation = resource_client.resource_groups.delete(GROUP_NAME) + delete_async_operation.wait() + print("\nDeleted: {}".format(GROUP_NAME)) + + +def construct_fip_id(subscription_id): + """Build the future FrontEndId based on components name. + """ + return ('/subscriptions/{}' + '/resourceGroups/{}' + '/providers/Microsoft.Network' + '/loadBalancers/{}' + '/frontendIPConfigurations/{}').format( + subscription_id, GROUP_NAME, LB_NAME, FIP_NAME + ) + + +def construct_bap_id(subscription_id): + """Build the future BackEndId based on components name. + """ + return ('/subscriptions/{}' + '/resourceGroups/{}' + '/providers/Microsoft.Network' + '/loadBalancers/{}' + '/backendAddressPools/{}').format( + subscription_id, GROUP_NAME, LB_NAME, ADDRESS_POOL_NAME + ) + + +def construct_probe_id(subscription_id): + """Build the future ProbeId based on components name. + """ + return ('/subscriptions/{}' + '/resourceGroups/{}' + '/providers/Microsoft.Network' + '/loadBalancers/{}' + '/probes/{}').format( + subscription_id, GROUP_NAME, LB_NAME, PROBE_NAME + ) + + +def provide_vm_login_info_to_user(num, public_ip_info, frontend_port, vm_info): + """Print on the console the connection information for a given VM. + """ + print('\n\nLogin information for the {} VM: {}'.format( + num, vm_info['name'])) + print('-------------------------------------------') + print('ssh to ip:port - {}:{}'.format(public_ip_info.ip_address, frontend_port)) + print('username - {}'.format(vm_info['username'])) + print('password - {}'.format(vm_info['password'])) + + +def create_nic_parameters(subnet_id, address_pool_id, natrule_id): + """Create the NIC parameters structure. + """ + return { + 'location': LOCATION, + 'ip_configurations': [{ + 'name': IP_CONFIG_NAME, + 'subnet': { + 'id': subnet_id + }, + 'load_balancer_backend_address_pools': [{ + 'id': address_pool_id + }], + 'load_balancer_inbound_nat_rules': [{ + 'id': natrule_id + }] + }] + } + + +def create_vm_parameters(nic_id, availset_id, vm_info): + """Create the VM parameters structure. + """ + return { + 'location': LOCATION, + 'os_profile': { + 'computer_name': vm_info['name'], + 'admin_username': vm_info['username'], + 'admin_password': vm_info['password'] + }, + 'hardware_profile': { + 'vm_size': 'Standard_DS1' + }, + 'storage_profile': { + 'image_reference': { + 'publisher': PUBLISHER, + 'offer': OFFER, + 'sku': SKU, + 'version': VERSION + }, + 'os_disk': { + 'name': OS_DISK_NAME, + 'caching': 'None', + 'create_option': 'fromImage', + 'vhd': { + 'uri': 'https://{}.blob.core.windows.net/vhds/{}.vhd'.format( + STORAGE_ACCOUNT_NAME, vm_info['name']) + } + }, + }, + 'network_profile': { + 'network_interfaces': [{ + 'id': nic_id, + 'primary': True + }] + }, + 'availability_set': { + 'id': availset_id + } + } + + +if __name__ == "__main__": + run_example() diff --git a/doc/network-manage-loadbalancer/example_internal_load_balancer.py b/doc/network-manage-loadbalancer/example_internal_load_balancer.py new file mode 100644 index 0000000..064174a --- /dev/null +++ b/doc/network-manage-loadbalancer/example_internal_load_balancer.py @@ -0,0 +1,453 @@ +import os + +from azure.identity import DefaultAzureCredential +from azure.mgmt.resource import ResourceManagementClient +from azure.mgmt.network import NetworkManagementClient +from azure.mgmt.network import models as network_models +from azure.mgmt.compute import ComputeManagementClient + +# Azure Datacenter +LOCATION = 'eastus' +SKU = 'Standard' +# Resource Group +GROUP_NAME = 'myInternalLoadBalancer1' + +# Network +VNET_NAME = 'myVNet' +ADDRESS_PREFIXES = '10.1.0.0/16' +SUBNET_NAME = 'myBackendSubnet' +SUBNET_PREFIXES = '10.1.0.0/24' + +# Nic ip-config +NIC_IP_CONFIG_NAME = 'ipconfig1' + +# Public IP address for the bastion host +BASTION_PUBLIC_IP_NAME = 'myBastionIP' + +# Bastion subnet +IP_CONFIG_NAME = 'myBastionIPConfig' +BASTION_SUBNET_NAME = 'AzureBastionSubnet' +BASTION_SUBNET_PREFIXES = '10.1.1.0/24' + +# Bastion host +BASTION_NAME = 'myBastionHost' + +# Network security group +NSG_NAME = 'myNSG' + +# Network Security Group Rule +NSG_RULE_NAME = 'myNSGRuleHTTP' + +# Network interfaces for the virtual machines +NIC_NAMES = ['myNicVM1', 'myNicVM2', 'myNicVM3'] + +# Virtual machine +VM_NAMES = ['myVM1', 'myVM2', 'myVM3'] +# VN_IMAGE = 'win2019datacenter' +VM_ADMIN_USERNAME = 'azureuser' +VM_ADMIN_PASSEORD = 'P@ssw0rd123' + +# Public IP address - Standard +PUBLIC_IP_NAME = 'myPublicIP' + +# Public Load balancer +LB_NAME = 'myLoadBalancer' +FIP_NAME = 'myFrontEnd' +BP_NAME = 'myBackEndPool' + +# Health probe +LB_PROBE_NAME = 'myHealthProbe' +LB_PROTOCOL = 'tcp' +LB_PORT = 80 + +# Load balancer rule +LB_RELE_NAME = 'myHTTPRule' + +# NIC Test +NIC_TEST_NAME = 'myNicTestVM' + +# VM Test +VM_TEST_NAME = 'myTestVM' +################################# + +# Single IP for the outbound connectivity +PUBLIC_IP_OB_NAME = 'myPublicIPOutbound' + +# Public IP prefix for the outbound connectivity +PUBLIC_IP_PREDIX_OB_NAME = 'myPublicIPPrefixOutbound' +PUBLIC_IP_PREDIX_OB_LENGTH = 28 + +# Outbound frontend IP configuration +FIP_OB_NAME = 'myFrontEndOutbound' + +# Outbound pool +OB_POOL_NAME = 'myBackendPoolOutbound' + +# Oubtbound rule +OB_RULE = 'myOutboundRule' + +# Manage resources and resource groups - create, update and delete a resource group, +# deploy a solution into a resource group, export an ARM template. Create, read, update +# and delete a resource +# +# This script expects that the following environment vars are set: +# +# AZURE_TENANT_ID: with your Azure Active Directory tenant id or domain +# AZURE_CLIENT_ID: with your Azure Active Directory Application Client ID +# AZURE_CLIENT_SECRET: with your Azure Active Directory Application Secret +# AZURE_SUBSCRIPTION_ID: with your Azure Subscription Id + +def run_example(): + import time + start_time = time.time() + """Resource Group management example.""" + # + # Create all clients with an Application (service principal) token provider + # + subscription_id = os.environ.get( + 'AZURE_SUBSCRIPTION_ID', + '11111111-1111-1111-1111-111111111111') # your Azure Subscription Id + + resource_client = ResourceManagementClient( + credential=DefaultAzureCredential(), + subscription_id=subscription_id + ) + network_client = NetworkManagementClient( + credential=DefaultAzureCredential(), + subscription_id=subscription_id + ) + compute_client = ComputeManagementClient( + credential=DefaultAzureCredential(), + subscription_id=subscription_id + ) + + # Create Resource group + rg = resource_client.resource_groups.create_or_update( + GROUP_NAME, {'location': LOCATION}) + print('Create Resource Group:\n{}'.format(rg)) + + # Create VNet + network = network_client.virtual_networks.begin_create_or_update( + GROUP_NAME, + VNET_NAME, + network_models.VirtualNetwork( + location=LOCATION, + address_space=network_models.AddressSpace( + address_prefixes=[ADDRESS_PREFIXES] + ), + subnets=[network_models.Subnet( + name=SUBNET_NAME, + address_prefix=SUBNET_PREFIXES + ), ] + ) + ).result() + print("Create Vnet:\n{}".format(network)) + + # Create PublicIP for the Bastion Host + bastion_public_ip = network_client.public_ip_addresses.begin_create_or_update( + GROUP_NAME, + BASTION_PUBLIC_IP_NAME, + network_models.PublicIPAddress( + location=LOCATION, + public_ip_allocation_method="Static", + sku=network_models.PublicIPPrefixSku(name="Standard") + ) + ).result() + print("Create Public IP for the bastion host:\n{}".format(bastion_public_ip)) + + # Create Bastion Subnet + bastion_subnet = network_client.subnets.begin_create_or_update( + GROUP_NAME, + VNET_NAME, + BASTION_SUBNET_NAME, + {'address_prefix': BASTION_SUBNET_PREFIXES} + ).result() + print("Create a bastion subnet:\n{}".format(bastion_subnet)) + + # Create Bastion Host + ip_configuration = network_models.BastionHostIPConfiguration( + name=NIC_IP_CONFIG_NAME, + subnet=network_models.SubResource(id=bastion_subnet.id), + public_ip_address=network_models.SubResource(id=bastion_public_ip.id) + ) + bastion_parameters = network_models.BastionHost( + location=LOCATION, + ip_configurations=[ip_configuration] + ) + + bastion_host = network_client.bastion_hosts.begin_create_or_update( + GROUP_NAME, + BASTION_NAME, + parameters=bastion_parameters + ).result() + print("Create a bastion host:\n{}".format(bastion_host)) + + # Create Network Security Group + nsg_parameters = network_models.NetworkSecurityGroup(location=LOCATION) + network_security_group = network_client.network_security_groups.begin_create_or_update( + GROUP_NAME, + NSG_NAME, + parameters=nsg_parameters + ).result() + print("Create Network Security Group:\n{}".format(network_security_group)) + + # Create Network Security Group Rule + nsg_rule_parameters = network_models.SecurityRule( + protocol='*', + direction='inbound', + source_address_prefix='*', + source_port_range='*', + destination_address_prefix='*', + destination_port_range=80, + access='allow', + priority=200 + ) + nsg_rule = network_client.security_rules.begin_create_or_update( + GROUP_NAME, + NSG_NAME, + NSG_RULE_NAME, + nsg_rule_parameters + ).result() + print("Create Network Security Group Rule:\n{}".format(nsg_rule)) + + # Create Backend Servers - Standard + # Create Network Interfaces for the VMs + network_interface_parameters = network_models.NetworkInterface( + location=LOCATION, + enable_accelerated_networking=True, + ip_configurations=[network_models.NetworkInterfaceIPConfiguration( + name=IP_CONFIG_NAME, + subnet=network_models.Subnet(id=network.subnets[0].id) + ), + ], + network_security_group=network_models.NetworkSecurityGroup(id=network_security_group.id) + ) + network_interfaces = [] + for nic_name in NIC_NAMES: + network_interface = network_client.network_interfaces.begin_create_or_update( + GROUP_NAME, + nic_name, + network_interface_parameters + ).result() + network_interfaces.append(network_interface) + print("Create Network Interface named {}:\n{}".format(nic_name, network_interface)) + + ############################################################## + # From here, we create the VM and link the LB inside the NIC # + ############################################################## + + # Create VMs + vms = [] + for i in range(3): + vm = compute_client.virtual_machines.begin_create_or_update( + GROUP_NAME, + VM_NAMES[i], + { + "location": LOCATION, + "hardware_profile": { + "vm_size": "Standard_D2_v2" + }, + "storage_profile": { + "image_reference": { + "sku": "2019-Datacenter", + "publisher": "MicrosoftWindowsServer", + "version": "latest", + "offer": "WindowsServer" + }, + "os_disk": { + "caching": "ReadWrite", + "managed_disk": { + "storage_account_type": "Standard_LRS" + }, + "name": "myVMosdisk" + str(i + 1), + "create_option": "FromImage" + }, + "data_disks": [ + { + "disk_size_gb": "1023", + "create_option": "Empty", + "lun": "0" + } + ] + }, + "os_profile": { + "admin_username": VM_ADMIN_USERNAME, + "computer_name": "myVM", + "admin_password": VM_ADMIN_PASSEORD, + "windows_configuration": { + "enable_automatic_updates": True # need automatic update for reimage + } + }, + "network_profile": { + "network_interfaces": [ + { + "id": network_interfaces[i].id, + "properties": { + "primary": True + } + } + ] + } + } + ).result() + vms.append(vm) + print('Create VM{} :\n{}'.format(str(i + 1), vm)) + + # Create Load Balancer + lb_fip_subnets = [network_subnet for network_subnet in network.subnets if network_subnet.name == SUBNET_NAME] + load_balancer_parameters = network_models.LoadBalancer( + location=LOCATION, + sku=network_models.Sku(name=SKU), + frontend_ip_configurations=[ + network_models.FrontendIPConfiguration( + name=FIP_NAME, + subnet=lb_fip_subnets[0] + ) + ], + backend_address_pools=[ + network_models.BackendAddressPool( + name=BP_NAME + ) + ] + ) + + load_balancer = network_client.load_balancers.begin_create_or_update( + GROUP_NAME, + LB_NAME, + load_balancer_parameters + ).result() + print("Create Load Balancer:\n{}".format(load_balancer)) + + # Create Health Probe + load_balancer_parameters.probes = [ + network_models.Probe( + protocol=LB_PROTOCOL, + port=LB_PORT, + name=LB_PROBE_NAME + ) + ] + lb_probe = network_client.load_balancers.begin_create_or_update( + GROUP_NAME, + LB_NAME, + load_balancer_parameters + ).result().probes + print("Create Health Probe: \n{}".format(eval(str(lb_probe[0])))) + + # Create Load Balancer Rule + load_balancer_parameters.load_balancing_rules = [ + network_models.LoadBalancingRule( + name=LB_RELE_NAME, + protocol='tcp', + frontend_port=80, + backend_port=80, + frontend_ip_configuration=network_models.SubResource(id=load_balancer.frontend_ip_configurations[0].id), + backend_address_pool=network_models.SubResource(id=load_balancer.backend_address_pools[0].id), + probe=network_models.SubResource(id=lb_probe[0].id), + idle_timeout_in_minutes=15, + enable_floating_ip=True + ) + ] + lb_rule = network_client.load_balancers.begin_create_or_update( + GROUP_NAME, + LB_NAME, + load_balancer_parameters + ).result().load_balancing_rules + print("Create Load Balancer Rule: \n{}".format(lb_rule[0])) + + # Add VMs to Load Balancer Backend Pool + for i in range(3): + for nic_ipconf in network_interfaces[i].ip_configurations: + if nic_ipconf.name == NIC_IP_CONFIG_NAME: + nic_ipconf.load_balancer_backend_address_pools = [load_balancer.backend_address_pools[0], + ] + add_vm_to_lb_bp = network_client.network_interfaces.begin_create_or_update( + GROUP_NAME, + NIC_NAMES[i], + network_interfaces[i] + ).result().ip_configurations + print("Add {} to Load Balancer Backend Pool: \n{}".format(NIC_NAMES[i], add_vm_to_lb_bp)) + + # Test Load Balancer + # Create NIC for VM to test + nic_test_parameters = network_models.NetworkInterface( + location=LOCATION, + # enable_accelerated_networking=True, + ip_configurations=[network_models.NetworkInterfaceIPConfiguration( + name=NIC_IP_CONFIG_NAME, + subnet=network_models.Subnet(id=network.subnets[0].id) + ), + ], + network_security_group=network_models.NetworkSecurityGroup(id=network_security_group.id) + ) + nic_test = network_client.network_interfaces.begin_create_or_update( + GROUP_NAME, + NIC_TEST_NAME, + nic_test_parameters + ).result() + print("Create Network Interface:\n{}".format(nic_test)) + + # Create VM for test + vm_test_parameters = { + "location": LOCATION, + "hardware_profile": { + "vm_size": "Standard_D2_v2" + }, + "storage_profile": { + "image_reference": { + "sku": "2019-Datacenter", + "publisher": "MicrosoftWindowsServer", + "version": "latest", + "offer": "WindowsServer" + }, + "os_disk": { + "caching": "ReadWrite", + "managed_disk": { + "storage_account_type": "Standard_LRS" + }, + "name": "myVMosdisk", + "create_option": "FromImage" + }, + "data_disks": [ + { + "disk_size_gb": "1023", + "create_option": "Empty", + "lun": "0" + } + ] + }, + "os_profile": { + "admin_username": VM_ADMIN_USERNAME, + "computer_name": "myVM", + "admin_password": VM_ADMIN_PASSEORD, + "windows_configuration": { + "enable_automatic_updates": True # need automatic update for reimage + } + }, + "network_profile": { + "network_interfaces": [ + { + "id": nic_test.id, + "properties": { + "primary": True + } + } + ] + } + } + vm_test = compute_client.virtual_machines.begin_create_or_update( + GROUP_NAME, + VM_TEST_NAME, + vm_test_parameters + ).result() + print('Create VM for test:\n{}'.format(vm_test)) + print("Running time: {}".format(time.time() - start_time)) + + # Delete Resource group and everything in it + input("Press enter to delete this Resource Group.") + print('Delete Resource Group') + delete_group = resource_client.resource_groups.begin_delete(GROUP_NAME) + print("\nDeleted: {}".format(GROUP_NAME)) + + +if __name__ == "__main__": + run_example() diff --git a/doc/network-manage-loadbalancer/example_public_load_balancer.py b/doc/network-manage-loadbalancer/example_public_load_balancer.py new file mode 100644 index 0000000..7472717 --- /dev/null +++ b/doc/network-manage-loadbalancer/example_public_load_balancer.py @@ -0,0 +1,470 @@ +import os + +from azure.identity import DefaultAzureCredential +from azure.mgmt.resource import ResourceManagementClient +from azure.mgmt.network import NetworkManagementClient +from azure.mgmt.network import models as network_models +from azure.mgmt.compute import ComputeManagementClient + +# Azure Datacenter +LOCATION = 'eastus' +SKU = 'Standard' +# Resource Group +GROUP_NAME = 'myPublicLoadBalancer1' + +# Network +VNET_NAME = 'myVNet' +ADDRESS_PREFIXES = '10.1.0.0/16' +SUBNET_NAME = 'myBackendSubnet' +SUBNET_PREFIXES = '10.1.0.0/24' + +# Nic ip-config +NIC_IP_CONFIG_NAME = 'ipconfig1' + +# Public IP address for the bastion host +BASTION_PUBLIC_IP_NAME = 'myBastionIP' + +# Bastion subnet +IP_CONFIG_NAME = 'myBastionIPConfig' +BASTION_SUBNET_NAME = 'AzureBastionSubnet' +BASTION_SUBNET_PREFIXES = '10.1.1.0/24' + +# Bastion host +BASTION_NAME = 'myBastionHost' + +# Network security group +NSG_NAME = 'myNSG' + +# Network Security Group Rule +NSG_RULE_NAME = 'myNSGRuleHTTP' + +# Network interfaces for the virtual machines +NIC_NAMES = ['myNicVM1', 'myNicVM2', 'myNicVM3'] + +# Virtual machine +VM_NAMES = ['myVM1', 'myVM2', 'myVM3'] +# VN_IMAGE = 'win2019datacenter' +VM_ADMIN_USERNAME = 'azureuser' +VM_ADMIN_PASSEORD = 'P@ssw0rd123' + +# Public IP address - Standard +PUBLIC_IP_NAME = 'myPublicIP' + +# Public Load balancer +LB_NAME = 'myLoadBalancer' +FIP_NAME = 'myFrontEnd' +BP_NAME = 'myBackEndPool' + +# Health probe +LB_PROBE_NAME = 'myHealthProbe' +LB_PROTOCOL = 'tcp' +LB_PORT = 80 + +# Load balancer rule +LB_RELE_NAME = 'myHTTPRule' + +# Single IP for the outbound connectivity +PUBLIC_IP_OB_NAME = 'myPublicIPOutbound' + +# Public IP prefix for the outbound connectivity +PUBLIC_IP_PREDIX_OB_NAME = 'myPublicIPPrefixOutbound' +PUBLIC_IP_PREDIX_OB_LENGTH = 28 + +# Outbound frontend IP configuration +FIP_OB_NAME = 'myFrontEndOutbound' + +# Outbound pool +OB_POOL_NAME = 'myBackendPoolOutbound' + +# Oubtbound rule +OB_RULE = 'myOutboundRule' + +# Manage resources and resource groups - create, update and delete a resource group, +# deploy a solution into a resource group, export an ARM template. Create, read, update +# and delete a resource +# +# This script expects that the following environment vars are set: +# +# AZURE_TENANT_ID: with your Azure Active Directory tenant id or domain +# AZURE_CLIENT_ID: with your Azure Active Directory Application Client ID +# AZURE_CLIENT_SECRET: with your Azure Active Directory Application Secret +# AZURE_SUBSCRIPTION_ID: with your Azure Subscription Id + +def run_example(): + import time + start_time = time.time() + """Resource Group management example.""" + # + # Create all clients with an Application (service principal) token provider + # + subscription_id = os.environ.get( + 'AZURE_SUBSCRIPTION_ID', + '11111111-1111-1111-1111-111111111111') # your Azure Subscription Id + + resource_client = ResourceManagementClient( + credential=DefaultAzureCredential(), + subscription_id=subscription_id + ) + network_client = NetworkManagementClient( + credential=DefaultAzureCredential(), + subscription_id=subscription_id + ) + compute_client = ComputeManagementClient( + credential=DefaultAzureCredential(), + subscription_id=subscription_id + ) + + # Create Resource group + rg = resource_client.resource_groups.create_or_update( + GROUP_NAME, {'location': LOCATION}) + print('Create Resource Group:\n{}'.format(rg)) + + # Create VNet + network = network_client.virtual_networks.begin_create_or_update( + GROUP_NAME, + VNET_NAME, + network_models.VirtualNetwork( + location=LOCATION, + address_space=network_models.AddressSpace( + address_prefixes=[ADDRESS_PREFIXES] + ), + subnets=[network_models.Subnet( + name=SUBNET_NAME, + address_prefix=SUBNET_PREFIXES + ), ] + ) + ).result() + print("Create Vnet:\n{}".format(network)) + + # Create PublicIP for the Bastion Host + bastion_public_ip = network_client.public_ip_addresses.begin_create_or_update( + GROUP_NAME, + BASTION_PUBLIC_IP_NAME, + network_models.PublicIPAddress( + location=LOCATION, + public_ip_allocation_method="Static", + sku=network_models.PublicIPPrefixSku(name="Standard") + ) + ).result() + print("Create Public IP for the bastion host:\n{}".format(bastion_public_ip)) + + # Create Bastion Subnet + bastion_subnet = network_client.subnets.begin_create_or_update( + GROUP_NAME, + VNET_NAME, + BASTION_SUBNET_NAME, + {'address_prefix': BASTION_SUBNET_PREFIXES} + ).result() + print("Create a bastion subnet:\n{}".format(bastion_subnet)) + + # Create Bastion Host + ip_configuration = network_models.BastionHostIPConfiguration( + name=NIC_IP_CONFIG_NAME, + subnet=network_models.SubResource(id=bastion_subnet.id), + public_ip_address=network_models.SubResource(id=bastion_public_ip.id) + ) + bastion_parameters = network_models.BastionHost( + location=LOCATION, + ip_configurations=[ip_configuration] + ) + + bastion_host = network_client.bastion_hosts.begin_create_or_update( + GROUP_NAME, + BASTION_NAME, + parameters=bastion_parameters + ).result() + print("Create a bastion host:\n{}".format(bastion_host)) + + # Create Network Security Group + nsg_parameters = network_models.NetworkSecurityGroup(location=LOCATION) + network_security_group = network_client.network_security_groups.begin_create_or_update( + GROUP_NAME, + NSG_NAME, + parameters=nsg_parameters + ).result() + print("Create Network Security Group:\n{}".format(network_security_group)) + + # Create Network Security Group Rule + nsg_rule_parameters = network_models.SecurityRule( + protocol='*', + direction='inbound', + source_address_prefix='*', + source_port_range='*', + destination_address_prefix='*', + destination_port_range=80, + access='allow', + priority=200 + ) + nsg_rule = network_client.security_rules.begin_create_or_update( + GROUP_NAME, + NSG_NAME, + NSG_RULE_NAME, + nsg_rule_parameters + ).result() + print("Create Network Security Group Rule:\n{}".format(nsg_rule)) + + # Create Backend Servers - Standard + # Create Network Interfaces for the VMs + network_interface_parameters = network_models.NetworkInterface( + location=LOCATION, + enable_accelerated_networking=True, + ip_configurations=[network_models.NetworkInterfaceIPConfiguration( + name=NIC_IP_CONFIG_NAME, + subnet=network_models.Subnet(id=network.subnets[0].id) + ), + ], + network_security_group=network_models.NetworkSecurityGroup(id=network_security_group.id) + ) + network_interfaces = [] + for nic_name in NIC_NAMES: + network_interface = network_client.network_interfaces.begin_create_or_update( + GROUP_NAME, + nic_name, + network_interface_parameters + ).result() + network_interfaces.append(network_interface) + print("Create Network Interface named {}:\n{}".format(nic_name, network_interface)) + + ############################################################## + # From here, we create the VM and link the LB inside the NIC # + ############################################################## + + # Create VMs + vms = [] + for i in range(3): + vm = compute_client.virtual_machines.begin_create_or_update( + GROUP_NAME, + VM_NAMES[i], + { + "location": LOCATION, + "hardware_profile": { + "vm_size": "Standard_D2_v2" + }, + "storage_profile": { + "image_reference": { + "sku": "2019-Datacenter", + "publisher": "MicrosoftWindowsServer", + "version": "latest", + "offer": "WindowsServer" + }, + "os_disk": { + "caching": "ReadWrite", + "managed_disk": { + "storage_account_type": "Standard_LRS" + }, + "name": "myVMosdisk"+str(i+1), + "create_option": "FromImage" + }, + "data_disks": [ + { + "disk_size_gb": "1023", + "create_option": "Empty", + "lun": "0" + } + ] + }, + "os_profile": { + "admin_username": VM_ADMIN_USERNAME, + "computer_name": "myVM", + "admin_password": VM_ADMIN_PASSEORD, + "windows_configuration": { + "enable_automatic_updates": True # need automatic update for reimage + } + }, + "network_profile": { + "network_interfaces": [ + { + "id": network_interfaces[i].id, + "properties": { + "primary": True + } + } + ] + } + } + ).result() + vms.append(vm) + print('Create VM{} :\n{}'.format(str(i+1), vm)) + + # Create PublicIP for the Load Balancer + public_ip = network_client.public_ip_addresses.begin_create_or_update( + GROUP_NAME, + PUBLIC_IP_NAME, + network_models.PublicIPAddress( + location=LOCATION, + public_ip_allocation_method="Static", + sku=network_models.PublicIPPrefixSku(name="Standard") + ) + ).result() + print("Create PublicIP for the Load Balancer:\n{}".format(public_ip)) + + # Create Load Balancer + load_balancer_parameters = network_models.LoadBalancer( + location=LOCATION, + sku=network_models.Sku(name=SKU), + frontend_ip_configurations=[ + network_models.FrontendIPConfiguration( + name=FIP_NAME, + public_ip_address=network_models.PublicIPAddress( + id=public_ip.id + ) + ) + ], + backend_address_pools=[ + network_models.BackendAddressPool( + name=BP_NAME + ) + ] + ) + + load_balancer = network_client.load_balancers.begin_create_or_update( + GROUP_NAME, + LB_NAME, + load_balancer_parameters + ).result() + print("Create Load Balancer:\n{}".format(load_balancer)) + + # Create Health Probe + load_balancer_parameters.probes = [ + network_models.Probe( + protocol=LB_PROTOCOL, + port=LB_PORT, + name=LB_PROBE_NAME + ) + ] + lb_probe = network_client.load_balancers.begin_create_or_update( + GROUP_NAME, + LB_NAME, + load_balancer_parameters + ).result().probes + print("Create Health Probe: \n{}".format(eval(str(lb_probe[0])))) + + # Create Load Balancer Rule + load_balancer_parameters.load_balancing_rules = [ + network_models.LoadBalancingRule( + name=LB_RELE_NAME, + protocol='tcp', + frontend_port=80, + backend_port=80, + frontend_ip_configuration=network_models.SubResource(id=load_balancer.frontend_ip_configurations[0].id), + backend_address_pool=network_models.SubResource(id=load_balancer.backend_address_pools[0].id), + probe=network_models.SubResource(id=lb_probe[0].id), + disable_outbound_snat=True, + idle_timeout_in_minutes=15, + enable_floating_ip=True + ) + ] + lb_rule = network_client.load_balancers.begin_create_or_update( + GROUP_NAME, + LB_NAME, + load_balancer_parameters + ).result().load_balancing_rules + print("Create Load Balancer Rule: \n{}".format(lb_rule[0])) + + # Add VMs to Load Balancer Backend Pool + for i in range(3): + for nic_ipconf in network_interfaces[i].ip_configurations: + if nic_ipconf.name == NIC_IP_CONFIG_NAME: + nic_ipconf.load_balancer_backend_address_pools = [load_balancer.backend_address_pools[0], + ] + add_vm_to_lb_bp = network_client.network_interfaces.begin_create_or_update( + GROUP_NAME, + NIC_NAMES[i], + network_interfaces[i] + ).result().ip_configurations + print("Add {} to Load Balancer Backend Pool: \n{}".format(NIC_NAMES[i], add_vm_to_lb_bp)) + + # Create Public IP for the Outbound Connectivity + outbound_rule_ip = network_client.public_ip_addresses.begin_create_or_update( + GROUP_NAME, + PUBLIC_IP_OB_NAME, + network_models.PublicIPAddress( + location=LOCATION, + public_ip_allocation_method="Static", + sku=network_models.PublicIPPrefixSku(name="Standard") + ) + ).result() + print("Create Public IP for the Outbound Connectivity:\n{}".format(outbound_rule_ip)) + + # Create Frontend IP Configuration + load_balancer_parameters.frontend_ip_configurations.append( + network_models.FrontendIPConfiguration( + name=FIP_OB_NAME, + public_ip_address=outbound_rule_ip + ) + ) + lb_fip_config = network_client.load_balancers.begin_create_or_update( + GROUP_NAME, + LB_NAME, + load_balancer_parameters + ).result().frontend_ip_configurations + print("Create Frontend IP Configuration:\n{}".format(lb_fip_config[-1])) + + # Create Outbound Pool + load_balancer_parameters.backend_address_pools.append( + network_models.BackendAddressPool( + name=OB_POOL_NAME, + ) + ) + lb_ob_pool = network_client.load_balancers.begin_create_or_update( + GROUP_NAME, + LB_NAME, + load_balancer_parameters + ).result().backend_address_pools + print("Create Outbound Pool:\n{}".format(lb_ob_pool[-1])) + + # Create Outbound Rule for the Outbound Backend Pool + load_balancer_parameters.outbound_rules = [ + network_models.OutboundRule( + name=OB_RULE, + frontend_ip_configurations=[network_models.SubResource(id=lb_fip_config[-1].id)], + protocol='All', + idle_timeout_in_minutes=15, + allocated_outbound_ports=10000, + backend_address_pool=network_models.SubResource(id=lb_ob_pool[-1].id) + ) + ] + lb_ob_rule = network_client.load_balancers.begin_create_or_update( + GROUP_NAME, + LB_NAME, + load_balancer_parameters + ).result().outbound_rules + print("Create Outbound Rule for the Outbound Backend Pool:\n{}".format(lb_ob_rule[-1])) + + # Add VMs to the Outbound Pool + ob_pool_info = network_client.load_balancer_backend_address_pools.get( + GROUP_NAME, + LB_NAME, + OB_POOL_NAME + ) + for i in range(3): + vmnic_info = network_client.network_interfaces.get( + GROUP_NAME, NIC_NAMES[i] + ) + for ip_conf in vmnic_info.ip_configurations: + if ip_conf.name == NIC_IP_CONFIG_NAME: + ip_conf.load_balancer_backend_address_pools.append(ob_pool_info) + + add_vm_to_lb_op = network_client.network_interfaces.begin_create_or_update( + GROUP_NAME, + NIC_NAMES[i], + vmnic_info + ).result().ip_configurations + print("Add {} to Load Balancer Outbound Pool: \n{}".format(NIC_NAMES[i], add_vm_to_lb_op)) + + # Get the Public IP Address of the Load Balancer + network_public_ip_info = network_client.public_ip_addresses.get( + GROUP_NAME, PUBLIC_IP_NAME + ) + print("Public IP Address:\n{}".format(network_public_ip_info.ip_address)) + print("Running time: {}".format(time.time()-start_time)) + + # Delete Resource group and everything in it + input("Press enter to delete this Resource Group.") + print('Delete Resource Group') + delete_group = resource_client.resource_groups.begin_delete(GROUP_NAME) + print("\nDeleted: {}".format(GROUP_NAME)) + + +if __name__ == "__main__": + run_example() diff --git a/doc/network-manage-loadbalancer/lb.JPG b/doc/network-manage-loadbalancer/lb.JPG new file mode 100644 index 0000000..70ff2d3 Binary files /dev/null and b/doc/network-manage-loadbalancer/lb.JPG differ diff --git a/doc/network-manage-loadbalancer/requirements.txt b/doc/network-manage-loadbalancer/requirements.txt new file mode 100644 index 0000000..c501f74 --- /dev/null +++ b/doc/network-manage-loadbalancer/requirements.txt @@ -0,0 +1,4 @@ +azure-identity +azure-mgmt-resource==18.0.0 +azure-mgmt-network==19.0.0 +azure-mgmt-compute==22.0.0 \ No newline at end of file