1

There is a document describing how to allocate a public IP per VM in VMSS: https://learn.microsoft.com/en-us/azure/virtual-machine-scale-sets/virtual-machine-scale-sets-networking#public-ipv4-per-virtual-machine

But it is not clear how to assign public static IP per VM. Is it possible?

ZakiMa
  • 5,637
  • 1
  • 24
  • 48

1 Answers1

2

Unfortunately, Azure does not provide control of the Public IP allocation method per instance in VMSS. You can see the all supported Properties of VirtualMachineScaleSetPublicIPAddressConfigurationProperties object in the latest ARM API version.

enter image description here

However, after my validation, when you restart the instance or VMSS scale-in or scale-out, the public IP address of existing instances is not changed. The public IP address of instances will be updated unless you stop the instance of VMSS.

Update

Currently, you can manage it with IpPublicPrefix. Note that IpPublicPrefix requires a standard SKU load balancer and public IP address. Here is a working sample. You can check the public IP address of the instances in VMSS with the REST API.

{
    "$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"
                                }
                            }
                        ]
                    }
                ]
            }
        }
    ]

}
Nancy
  • 26,865
  • 3
  • 18
  • 34
  • Thank you! So, it is possible for individual VMs in VMSS to be assigned static Public IP address. By some reason wasn't able to find it in documentation. Is it possible to specify multiple Public IP Prefix objects? What will happen when VMSS reaches capacity of Public IP Prefix? Will new VM allocations start to fail? – ZakiMa Nov 27 '20 at 10:11
  • We can not control the public ip allocated method. What do you mean static ip? Azure by default allow you to get a fixed public ip on the instance if you use arm template or cli to deploy vmss. If the vmss instance stop,the associated pip will remove. – Nancy Nov 27 '20 at 10:16
  • I need every VM to have a static (not dynamic) public IP address for outbound connectivity. So, my customers would be able to add these IP addresses/ranges to their firewall rules. It looks like that specifying IP Prefix will achieve this, correct? – ZakiMa Nov 27 '20 at 20:03
  • For applications that require large numbers of outbound connections or enterprise customers who require a single set of IPs to be used from a given virtual network, [Virtual Network NAT gateway](https://learn.microsoft.com/en-us/azure/virtual-network/nat-overview) is the recommended solution. Read [Using SNAT for outbound connections](https://learn.microsoft.com/en-us/azure/load-balancer/load-balancer-outbound-connections) – Nancy Nov 30 '20 at 07:13
  • My service is using Load Balancer right now. Let's focus on my question about how to migrate off it to public static IP per VM =) – ZakiMa Nov 30 '20 at 09:34
  • As far as I know, the short answer is It's not possible to set a static public IP for VMSS instances. But for your customer's requirement, you can use VNET NAT gateway for a fixed set of outbound IPs to whitelist it in the firewall. – Nancy Nov 30 '20 at 09:37
  • The fact that it is possible to specify a public IPPrefix means that it is possible to set a static IP for VMSS instances. Am I missing anything? I'm trying to understand whether it is possible to specify multiple IPPrefix objects to support scale requriement. – ZakiMa Nov 30 '20 at 10:26
  • @ZakiMa did you get an answer to this question? I have the same question.. – TheJoker Apr 20 '21 at 16:51
  • @ZakiMa I have updated the reply with IpPublicPrefix. – Nancy May 25 '21 at 07:51