0

I have a requirement to update/set public IP address of VMScaleset instances from a given IpPublicPrefix(for customer to whitelist these IPs). I've tried creating VMScaleset with two instances (with a Virtual Network, SubNet, Network Interface) and PublicIpPrefix but the code suggested from Azure doc is not working at all. https://learn.microsoft.com/en-us/powershell/module/azurerm.network/set-azurermnetworkinterface?view=azurermps-6.13.0

First issue: below code does not return the Network Interface I created above. Is this bug in Azure API? Get-AzureRmNetworkInterface -ResourceGroupName "ResourceGroup1" -Name "NetworkInterface1" It only returns list of Network Interfaces which were created for VM(created not from VMSS), it does not include Network Interface which were created during VMSS creation.

Second Issue: Per some comments here and there, NetworkInterface for VMSS will not display in Azure Portal (search for Network Interfaces) nor AzureRM API then how do we suppose to know and update NIC for a VMSS or its instances?

I have been using AzureRm module 6.13.1

kaish
  • 1
  • 1

1 Answers1

0

For the first issue, the public IP of the scale set instances is not a separate resource in the Azure portal, we can not use Get-AzureRmNetworkInterface to get the network interface information.

For the second issue, you can create a scale set with public IP per virtual machine by ARM template. You can add a publicIpAddressConfiguration JSON property to the scale set ipConfigurations section.

Note that IpPublicPrefix requires a standard SKU load balancer and public IP address. Here is a working sample.

{
    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "vmSku": {
            "type": "string",
            "defaultValue": "Standard_A1_v2",
            "metadata": {
                "description": "Size of VMs in the VM Scale Set."
            }
        },
        "windowsOSVersion": {
            "type": "string",
            "defaultValue": "2019-Datacenter",
            "allowedValues": [
                "2008-R2-SP1",
                "2012-Datacenter",
                "2012-R2-Datacenter",
                "2016-Datacenter",
                "2019-Datacenter"
            ],
            "metadata": {
                "description": "The Windows version for the VM. This will pick a fully patched image of this given Windows version. Allowed values: 2008-R2-SP1, 2012-Datacenter, 2012-R2-Datacenter & 2016-Datacenter, 2019-Datacenter."
            }
        },
        "vmssName": {
            "type": "string",
            "minLength": 3,
            "maxLength": 61,
            "metadata": {
                "description": "String used as a base for naming resources. Must be 3-61 characters in length and globally unique across Azure. A hash is prepended to this string for some resources, and resource-specific information is appended."
            }
        },
        "instanceCount": {
            "type": "int",
            "defaultValue": 3,
            "minValue": 1,
            "maxValue": 100,
            "metadata": {
                "description": "Number of VM instances (100 or less)."
            }
        },
        "singlePlacementGroup": {
            "type": "bool",
            "defaultValue": true,
            "metadata": {
                "description": "When true this limits the scale set to a single placement group, of max size 100 virtual machines. NOTE: If singlePlacementGroup is true, it may be modified to false. However, if singlePlacementGroup is false, it may not be modified to true."
            }
        },
        "adminUsername": {
            "type": "string",
            "defaultValue": "vmssadmin",
            "metadata": {
                "description": "Admin username on all VMs."
            }
        },
        "adminPassword": {
            "type": "securestring",
            "metadata": {
                "description": "Admin password on all VMs."
            }
        },
        
        "location": {
            "type": "string",
            "defaultValue": "[resourceGroup().location]",
            "metadata": {
                "description": "Location for all resources."
            }
        },
        "platformFaultDomainCount": {
            "type": "int",
            "defaultValue": 1,
            "metadata": {
                "description": "Fault Domain count for each placement group."
            }
        },
        "publicIPPrefixes_pubprefix_name": {
            "defaultValue": "vmsspublicprefix",
            "type": "string"
        }
    },
    "variables": {
        "namingInfix": "[toLower(substring(concat(parameters('vmssName'), uniqueString(resourceGroup().id)), 0, 9))]",
        "longNamingInfix": "[toLower(parameters('vmssName'))]",
        "addressPrefix": "10.0.0.0/16",
        "subnetPrefix": "10.0.0.0/24",
        "virtualNetworkName": "[concat(variables('namingInfix'), 'vnet')]",
        "publicIPAddressName": "[concat(variables('namingInfix'), 'pip')]",
        "subnetName": "[concat(variables('namingInfix'), 'subnet')]",
        "loadBalancerName": "[concat(variables('namingInfix'), 'lb')]",
        "publicIPAddressID": "[resourceId('Microsoft.Network/publicIPAddresses',variables('publicIPAddressName'))]",
        "lbProbeID": "[resourceId('Microsoft.Network/loadBalancers/probes',variables('loadBalancerName'), 'tcpProbe')]",
        "natPoolName": "[concat(variables('namingInfix'), 'natpool')]",
        "bePoolName": "[concat(variables('namingInfix'), 'bepool')]",
        "lbPoolID": "[resourceId('Microsoft.Network/loadBalancers/backendAddressPools',variables('loadBalancerName'),variables('bePoolName'))]",
        "natStartPort": 50000,
        "natEndPort": 50119,
        "natBackendPort": 3389,
        "nicName": "[concat(variables('namingInfix'), 'nic')]",
        "ipConfigName": "[concat(variables('namingInfix'), 'ipconfig')]",
        "frontEndIPConfigID": "[resourceId('Microsoft.Network/loadBalancers/frontendIPConfigurations',variables('loadBalancerName'),'loadBalancerFrontEnd')]",
        "osType": {
            "publisher": "MicrosoftWindowsServer",
            "offer": "WindowsServer",
            "sku": "[parameters('windowsOSVersion')]",
            "version": "latest"
        },
        "imageReference": "[variables('osType')]"

    },
    "resources": [
        {
            "type": "Microsoft.Network/loadBalancers",
            "apiVersion": "2020-06-01",
            "name": "[variables('loadBalancerName')]",
            "location": "[parameters('location')]",
            "dependsOn": [
                "[resourceId('Microsoft.Network/publicIPAddresses', variables('publicIPAddressName'))]"
            ],
            "sku": {
                   "name": "Standard"
                  },
            "properties": {
                "frontendIPConfigurations": [
                    {
                        "name": "LoadBalancerFrontEnd",
                        "properties": {
                            "publicIPAddress": {
                                "id": "[variables('publicIPAddressID')]",
                                "name": "Standard"
                            }
                        }
                    }
                ],
                "backendAddressPools": [
                    {
                        "name": "[variables('bePoolName')]"
                    }
                ],
                "inboundNatPools": [
                    {
                        "name": "[variables('natPoolName')]",
                        "properties": {
                            "frontendIPConfiguration": {
                                "id": "[variables('frontEndIPConfigID')]"
                            },
                            "protocol": "Tcp",
                            "frontendPortRangeStart": "[variables('natStartPort')]",
                            "frontendPortRangeEnd": "[variables('natEndPort')]",
                            "backendPort": "[variables('natBackendPort')]"
                        }
                    }
                ],
                "loadBalancingRules": [
                    {
                        "name": "LBRule",
                        "properties": {
                            "frontendIPConfiguration": {
                                "id": "[variables('frontEndIPConfigID')]"
                            },
                            "backendAddressPool": {
                                "id": "[variables('lbPoolID')]"
                            },
                            "protocol": "Tcp",
                            "frontendPort": 80,
                            "backendPort": 80,
                            "enableFloatingIP": false,
                            "idleTimeoutInMinutes": 5,
                            "probe": {
                                "id": "[variables('lbProbeID')]"
                            }
                        }
                    }
                ],
                "probes": [
                    {
                        "name": "tcpProbe",
                        "properties": {
                            "protocol": "Tcp",
                            "port": 80,
                            "intervalInSeconds": 5,
                            "numberOfProbes": 2
                        }
                    }
                ]
            }
        },

        {
            "type": "Microsoft.Network/publicIPPrefixes",
            "apiVersion": "2020-11-01",
            "name": "[parameters('publicIPPrefixes_pubprefix_name')]",
            "location": "[parameters('location')]",
            "sku": {
                "name": "Standard",
                "tier": "Regional"
            },
            "properties": {
                "prefixLength": 28,
                "publicIPAddressVersion": "IPv4",
                "ipTags": []
            }
        },
        {
            "type": "Microsoft.Compute/virtualMachineScaleSets",
            "apiVersion": "2020-06-01",
            "name": "[variables('namingInfix')]",
            "location": "[parameters('location')]",
            "sku": {
                "name": "[parameters('vmSku')]",
                "tier": "Standard",
                "capacity": "[parameters('instanceCount')]"
            },
            "dependsOn": [
                "[resourceId('Microsoft.Network/loadBalancers', variables('loadBalancerName'))]",
                "[resourceId('Microsoft.Network/virtualNetworks', variables('virtualNetworkName'))]",
                "[resourceId('Microsoft.Network/publicIPPrefixes',parameters('publicIPPrefixes_pubprefix_name'))]"
            ],
            "properties": {
                "overprovision": true,
                "upgradePolicy": {
                    "mode": "Automatic"
                },
                "singlePlacementGroup": "[parameters('singlePlacementGroup')]",
                "platformFaultDomainCount": "[parameters('platformFaultDomainCount')]",
                "virtualMachineProfile": {
                    "storageProfile": {
                        "osDisk": {
                            "caching": "ReadWrite",
                            "createOption": "FromImage"
                        },
                        "imageReference": "[variables('imageReference')]"
                    },
                    "osProfile": {
                        "computerNamePrefix": "[variables('namingInfix')]",
                        "adminUsername": "[parameters('adminUsername')]",
                        "adminPassword": "[parameters('adminPassword')]"
                    },
                    "networkProfile": {
                        "networkInterfaceConfigurations": [
                            {
                                "name": "[variables('nicName')]",
                                "properties": {
                                    "primary": true,
                                    "ipConfigurations": [
                                        {
                                            "name": "[variables('ipConfigName')]",
                                            "properties": {
                                                "subnet": {
                                                    "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('virtualNetworkName'), variables('subnetName'))]"
                                                },
                                                "loadBalancerBackendAddressPools": [
                                                    {
                                                        "id": "[variables('lbPoolID')]"
                                                    }
                                                ],
                                                "loadBalancerInboundNatPools": [
                                                    {
                                                        "id": "[resourceId('Microsoft.Network/loadBalancers/inboundNatPools', variables('loadBalancerName'),  variables('natPoolName'))]"
                                                    }
                                                ],

                                                    "publicipaddressconfiguration": {
                                                        "name": "pub1",
                                                        "properties": {
                                                            "idleTimeoutInMinutes": 15,
                                                        "publicIPAddressVersion": "IPv4",
                                                        "publicIPPrefix":{
                                                            "id": "[resourceId('Microsoft.Network/publicIPPrefixes',parameters('publicIPPrefixes_pubprefix_name'))]"
                                                        }
                                                        }
                                                                    
                                                    }

                                            }


                                        }
                                    ]
                                }
                            }
                        ]
                    }

                }
            }
        },
        {
            "type": "Microsoft.Network/publicIPAddresses",
            "apiVersion": "2020-06-01",
            "name": "[variables('publicIPAddressName')]",
            "location": "[parameters('location')]",
              "sku": {
                    "name": "Standard"      
                },
            "properties": {
                "publicIPAllocationMethod": "Static",
                "dnsSettings": {
                    "domainNameLabel": "[variables('longNamingInfix')]"
                }
            }
        },
        {
            "type": "Microsoft.Network/virtualNetworks",
            "apiVersion": "2020-06-01",
            "name": "[variables('virtualNetworkName')]",
            "location": "[parameters('location')]",
            "properties": {
                "addressSpace": {
                    "addressPrefixes": [
                        "[variables('addressPrefix')]"
                    ]
                },
                "subnets": [
                    {
                        "name": "[variables('subnetName')]",
                        "properties": {
                            "addressPrefix": "[variables('subnetPrefix')]"
                        }
                    }
                ]
            }
        },
        {
            "type": "Microsoft.Insights/autoscaleSettings",
            "apiVersion": "2015-04-01",
            "name": "autoscalehost",
            "location": "[parameters('location')]",
            "dependsOn": [
                "[resourceId('Microsoft.Compute/virtualMachineScaleSets/', variables('namingInfix'))]"
            ],
            "properties": {
                "name": "autoscalehost",
                "targetResourceUri": "[resourceId('Microsoft.Compute/virtualMachineScaleSets', variables('namingInfix'))]",
                "enabled": true,
                "profiles": [
                    {
                        "name": "Profile1",
                        "capacity": {
                            "minimum": "1",
                            "maximum": "10",
                            "default": "1"
                        },
                        "rules": [
                            {
                                "metricTrigger": {
                                    "metricName": "Percentage CPU",
                                    "metricResourceUri": "[resourceId('Microsoft.Compute/virtualMachineScaleSets', variables('namingInfix'))]",
                                    "timeGrain": "PT1M",
                                    "statistic": "Average",
                                    "timeWindow": "PT5M",
                                    "timeAggregation": "Average",
                                    "operator": "GreaterThan",
                                    "threshold": 50
                                },
                                "scaleAction": {
                                    "direction": "Increase",
                                    "type": "ChangeCount",
                                    "value": "1",
                                    "cooldown": "PT5M"
                                }
                            },
                            {
                                "metricTrigger": {
                                    "metricName": "Percentage CPU",
                                    "metricResourceUri": "[resourceId('Microsoft.Compute/virtualMachineScaleSets', variables('namingInfix'))]",
                                    "timeGrain": "PT1M",
                                    "statistic": "Average",
                                    "timeWindow": "PT5M",
                                    "timeAggregation": "Average",
                                    "operator": "LessThan",
                                    "threshold": 30
                                },
                                "scaleAction": {
                                    "direction": "Decrease",
                                    "type": "ChangeCount",
                                    "value": "1",
                                    "cooldown": "PT5M"
                                }
                            }
                        ]
                    }
                ]
            }
        }
    ]

}

Also, you can get the specified public IP address of an instance in a virtual machine scale set with the REST API.

GET https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachineScaleSets/{virtualMachineScaleSetName}/virtualMachines/{virtualmachineIndex}/networkInterfaces/{networkInterfaceName}/ipconfigurations/{ipConfigurationName}/publicipaddresses/{publicIpAddressName}?api-version=2018-10-01
Nancy
  • 26,865
  • 3
  • 18
  • 34
  • If my answer is helpful for you, you could accept it as an answer( click on the checkmark beside the answer to toggle it from greyed out to fill in.). read https://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work This can be beneficial to other community members. – Nancy May 25 '21 at 07:45
  • Thanks Nancy, however, I tried something different. Create Network Interface separately and add it to Virtual Network. While creating Virtual Network, it uses older template from 2015 which is why Network Interface is not accessible from Azure powershell cmdlet. Creating Network Interface separately uses 2018 template and this is accessible using Get-AzureRmNetworkInterface cmdlet. – kaish May 26 '21 at 17:20
  • The second part is even though if I set publicIPPrefix at the VMSS, any VM instance out of it will get the new public IP after the reboot and keep changing on every reboot. This is not what I am looking for. Once each VM instance gets the new public IP, it should not change throughout its lifecycle(unless publicIPPrefix of VMSS is changed) – kaish May 26 '21 at 17:25
  • That's not true. When I created the VMSS as my above template, even I restarted vmss instance or restarted the whole vmss at one go, the public IP address of each instance did not change. – Nancy May 27 '21 at 02:05
  • Have you tried the above template? Does it solve your question? – Nancy May 28 '21 at 06:58
  • my scenario is to access the VMSS and its Virtual Network, Network Interface which are already created using Terraform script(unsure about the template version), and update scale set instances' public IP to be from the publicIpPrefix. Also, there is no Load balancer in the scene, trying to mimic the way it is done in AWS where ASG creates instances and instance public IP is updated from pre-created EIP list. – kaish May 28 '21 at 17:08
  • load balance is not necessary here,you can remove that section in arm template. You also can deploy arm template with terraform. – Nancy May 28 '21 at 22:37