Azure VM metadata missing / emtpy publicIpAddress - azure

On an Azure VM when querying for metadata, the publicIpAddress has no value even though the machine as a public IP.
curl -H Metadata:true "http://169.254.169.254/metadata/instance?api-version=2019-11-01"
returns an empty string for publicIpAddress
{
"compute": {
// ... Omitted for brevity
},
"network": {
"interface": [
{
"ipv4": {
"ipAddress": [
{
"privateIpAddress": "10.3.0.4",
"publicIpAddress": ""
}
],
// ... Rest has been omitted for brevity
Does anyone know why? I checked https://learn.microsoft.com/en-us/azure/virtual-machines/windows/instance-metadata-service, but couldn't find any reason for the public IP address not to show up

I believe your public IP address is Standard SKU instead of Basic SKU, which does not support instance metadata service.
From MSDN:
Only Public IP addresses with basic SKU are available when using instance metadata service IMDS. Standard SKU is not supported.
This GitHub Issue also has more information.
I've also tested this with both basic and standard SKU public IP addresses, and standard SKU will give you "publicIpAddress":"" when querying the instance metadata instance API.
Solution
To be able to use the instance metadata service, you need to use a Basic SKU public IP address. You cannot change the SKU once a public IP address is created, as highlighted in MSDN.
Instead, you could first disassociate your Standard SKU public IP address instance from your virtual machine network interface, create a new public IP address with Basic SKU, then associate this public IP address with your virtual machine network interface. This is required since a network interface can only have one public IP address associated to it.
Checking Public IP Address SKU
You can run Get-AzPublicIpAddress from Azure PowerShell command to check your public address SKU:
(Get-AzPublicIpAddress -Name "PUBLIC-IP-NAME" -ResourceGroupName "RESOURCE-GROUP").Sku.Name
Or using az network public-ip show from Azure CLI if you prefer:
az network public-ip show -n "PUBLIC-IP-NAME" -g "RESOURCE-GROUP" --query "sku.name"
Or just check via Azure portal by navigating to your public IP address instance.

Related

Azure: How do I associate the private DNS zone with virtual networks across the subscriptions?

I have 2 virtual networks in 2 different subscriptions as below:
VNET1 : 192.168.0.0/24 in subscription#1 (HUB)
VNET2 : 192.168.1.0/24 in subscription#2 (SPOKE)
I've created the peering and I am able to ping from both sides properly.
Now, I have created the Private Zone in subscription#1 (HUB) as shown below
resource "azurerm_private_dns_zone" "keyvalutzone" {
name = "privatelink.vaultcore.azure.net"
resource_group_name = azurerm_resource_group.ipz12-dat-np-connection-rg.name
depends_on = [
azurerm_resource_group.ipz12-dat-np-connection-rg
]
}
and it is Linked with VNET as shown below
resource "azurerm_private_dns_zone_virtual_network_link" "network_link_hub_vnet_keyvalut" {
name = "vnet_link_hub_keyvalut"
resource_group_name = azurerm_resource_group.ipz12-dat-np-connection-rg.name
private_dns_zone_name = azurerm_private_dns_zone.keyvalutzone.name
virtual_network_id = azurerm_virtual_network.hub_vnet.id
depends_on = [
azurerm_private_dns_zone.keyvalutzone,
azurerm_virtual_network.hub_vnet
]
}
Question: Do I need to associate this private DNS zone with all virtual networks including VNET2 in subscription#2 (SPOKE) so that private endpoints can be resolved in VNET2? If so, how do I associate this private DNS zone with VNET2?
Note: I have a Private DNS Resolver in subscription#1 (HUB) as it's inbound endpoint address is used as a custom DNS in VNET1 in subscription#1 (HUB)
resource "azurerm_private_dns_resolver" "hub_private_dns_resolver" {
name = "hub_private_dns_resolver"
resource_group_name = azurerm_resource_group.ipz12-dat-np-connection-rg.name
location = azurerm_resource_group.ipz12-dat-np-connection-rg.location
virtual_network_id = azurerm_virtual_network.hub_vnet.id
}
resource "azurerm_private_dns_resolver_inbound_endpoint" "hub_private_dns_resolver_ie" {
name = "hub_private_dns_resolver_ie"
private_dns_resolver_id = azurerm_private_dns_resolver.hub_private_dns_resolver.id
location = azurerm_private_dns_resolver.hub_private_dns_resolver.location
ip_configurations {
private_ip_allocation_method = "Dynamic"
subnet_id = azurerm_subnet.dns_resolver_inbound_subnet.id
}
}
I tried to reproduce the same in my environment and got the results like below:
You can use virtual network that belong to different subscription with private dns zone make sure you have write operation permission on the virtual networks and the private DNS zone like Network Contributor and Private DNS zone Contributor roles
If you are using private endpoint in a hub-and-spoke model from a different subscription or same subscription It is recommended to link the same private DNS zones to all spokes and hub virtual networks that contain clients that need DNS resolution from the zones.
You can link a private DNS zone with N no of virtual network. It is also possible to connect a private zone to a virtual network that is a part of a different subscription.
Make sure to Enable auto registration whenever a new virtual machine is created automatically registered with this private dns zone.
Then I have created virtual machine it registered automatically and try to add record like below:
Now try to test private dns zone and configure the firewall on both virtual machines to allow inbound ICMP packets in RDP powershell like below:
New-NetFirewallRule –DisplayName "Allow ICMPv4-In" –Protocol ICMPv4
Now from this machine vm2(infra002) I am able to ping vm1 using the automatically registered host name like below:
Reference:
Azure Private Endpoint DNS configuration | Microsoft

Powershell Resolve-DnsName not working when Private Endpoint enabled

I have an Azure storage account with public IP address and can resolve this name using both nslookup and Resolve-DnsName. Output below, truncated for brevity.
C:>nslookup stgweb.blob.core.windows.net
Name: blob.syd25prdstr01a.store.core.windows.net
Address: 20.60.72.36
Aliases: stgweb.blob.core.windows.net
Resolve-DnsName -Name stgweb.blob.core.windows.net
Name : blob.syd25prdstr01a.store.core.windows.net
QueryType : A
TTL : 60
Section : Answer
IP4Address : 20.60.72.36
When I create a private endpoint the private IP address resolves correctly from an Azure VM in both nslookup and Resolve-DnsName. But I can no longer resolve the public name from outside of Azure using Resolve-DnsName, but can using NSlookup.
C:>nslookup stgweb.blob.core.windows.net
Name: blob.syd25prdstr01a.store.core.windows.net
Address: 20.60.72.36
Aliases: stgweb.blob.core.windows.net
stgweb.privatelink.blob.core.windows.net
PS>Resolve-DnsName -Name stgweb.blob.core.windows.net
Resolve-DnsName: stgweb.blob.core.windows.net : DNS name does not exist.
But Resolve-DnsName will resolve the blob.syd25prdstr01a.store.core.windows.net name
PS>Resolve-DnsName -Name blob.syd25prdstr01a.store.core.windows.net
blob.syd25prdstr01a.store.core.windows.net A 60 Answer 20.60.72.36
Why is this, is there a way to get Resolve-DnsName to work correctly like NSlookup? Its not just storage accounts its anything with a private endpoint that fails.
• When you enable the private endpoint for a storage account, a private DNS zone is created with the name of ‘privatelink.blob.core.windows.net’ in which an ‘A’ host record is created for the storage account with a private IP address assigned as shown below: -
This is created along with a private NIC configuration as below wherein it is implied or deployed that the private DNS integration for the NIC created is associated with the storage account as well as with the private link created for it due to which when you are trying to resolve the FQDN of the storage account, i.e., ‘kartikbstor.blob.core.windows.net’, it will not be accessible since it is privately associated with the IP address in the virtual network associated. Therefore, only when you try to ‘nslookup’ for the ‘CNAME’ record created by you, i.e., ‘blob.syd25prdstr01a.store.core.windows.net’ after creating private endpoint, it is not accessible since the private link DNS configuration takes into effect after private endpoint creation.
• As the ‘nslookup’ from inside the Azure VM searches for the DNS entries in the respective virtual network’s private DNS zone only due to which the DNS ‘A’ record related to the private link are relayed back and the DNS resolution regarding it takes place. Similarly, when you hit the ‘Resolve-DNS’ command after creation of the private endpoint, this command tries to search for the ‘CNAME’ record, i.e., ‘blob.syd25prdstr01a.store.core.windows.net’ in the private DNS zone which is found but the public DNS name is not accessible any longer since its FQDN is no longer available in the private DNS zone created due to private link creation.
Therefore, when you create the private endpoint for a storage account, the public DNS entries are not accessible from inside the virtual network’s resources, i.e., Azure VM and instead are accessible from the public internet*.
For more detailed information, kindly refer to the below link: -
https://learn.microsoft.com/en-us/powershell/module/dnsclient/resolve-dnsname?view=windowsserver2022-ps

How to Retrieve Public IP Address and Private IP Address of an Azure VM with Azure Java SDK

I am working on a Java project that needs to retrieve a VM's public ip and private ip with Azure Java SDK.
I find two potentially useful classes com.microsoft.azure.management.compute.VirtualMachine
and
com.azure.resourcemanager.compute.fluent.models.VirtualMachineInner
After hours of investigation, I cannot figure out how.
The VirtualMachine class only has a function to get primary public ip. Neither of them has a function to get private ip.
Did I missing anything from the two classes?
Is there a way to list all details of VMs under a subscription with Java SDK like what we get with az vm list -d --subscription $Subscription_Id in Azure CLI?
Thanks in advance
Call (the azure object is initialized via guide https://aka.ms/azsdk/java/mgmt)
var vms = azure.virtualMachines().list();
Then for each of them, call
vm.getPrimaryNetworkInterface().primaryPrivateIP();
for private IP.
vm.getPrimaryPublicIPAddress();
for object of public IP, it could be null. If not null, then use ipAddress().
It is more complicated as either private IP or public IP is not within the VirtualMachine object, but in NetworkInterface object (or further PublicIpAddress object) and need to be done via additional REST API.

Finding out the public IP of a VMSS instance from within that instance (per-instance public IP VMSS)

I’ve created a VMSS in Azure with per-instance public IPs described here: https://learn.microsoft.com/en-us/azure/virtual-machine-scale-sets/virtual-machine-scale-sets-networking#creating-a-scale-set-with-public-ip-per-virtual-machine. I need a per-instance IP public IP configuration so that every individual instance is independently available from the outside.
Since there is apparently no way to specify a sku for such IPs (full format is here: https://learn.microsoft.com/en-us/azure/templates/microsoft.compute/virtualmachinescalesets#virtualmachinescalesetpublicipaddressconfigurationproperties-object), all IPs are always Standard. I can query public IPs as they are being created by VMSS, they are indeed Standard.
Metadata service (that I planned to use to get the IP from within the instance) only returns Basic public IPs (as stated here: https://learn.microsoft.com/en-us/azure/virtual-network/public-ip-addresses#standard).
How do I get the instance’s public IP from within the instance short of pinging a random 3rd party web site that returns the caller’s IP or talking to ARM from the instance?
After my validation, you can get the instance’s public IP from within the instance refer to this sample. This also works to get the basic public IP from Azure VM.
Invoke-RestMethod -Headers #{"Metadata"="true"} -Method GET -Uri "http://169.254.169.254/metadata/instance/network/interface/0/ipv4/ipAddress/0/publicIpAddress?api-version=2017-08-01&format=text" | ConvertTo-Json
I create the VMSS with public IP in ARM template like this:
"publicIPAddressconfiguration": {
"name": "publicip",
"properties": {
"idleTimeoutInMinutes": 10,
"dnsSettings": {
"domainNameLabel": "[parameters('vmssName')]"
}
}
}

How to get DNS Name in azure Virtual Machines - List All api?

I want to get the DNS Name in azure Virtual Machines - List All api in nodejs.
Please help me.
I checked this url Virtual Machines - List All
But DNS Name not availble in the response.
If you want to get the FQDN for Azure VMs in the Azure portal. When you create a virtual machine (VM) in the Azure portal, a public IP resource for the virtual machine is automatically created. The FQDN actually is attached to the public IP resource for external accessing. So you will look for the public IP for the DNS name.
You can look up the API Public IP Addresses - List All
"dnsSettings": {
"domainNameLabel": "testlbl",
"fqdn": "testlbl.westus.cloudapp.azure.com"
},

Resources