I had a same problem with my private VM in Azure. I ask ChatGPT to write me a ps script which can scheduled run in Azure and update the nsg with my private home computer dynamic IP...
# UpdateNSGRule PowerShell script
param (
[Parameter(Mandatory=$true)]
[string]$dnsName, # The dynamic DNS name to resolve
[Parameter(Mandatory=$true)]
[string]$resourceGroupName, # Azure resource group containing the NSG
[Parameter(Mandatory=$true)]
[string]$nsgName, # Name of the Network Security Group
[Parameter(Mandatory=$true)]
[string]$ruleName, # Name of the NSG rule to update
[Parameter(Mandatory=$true)]
[string]$appId, # Azure AD Application (client) ID
[Parameter(Mandatory=$true)]
[string]$appSecret, # Azure AD Application secret
[Parameter(Mandatory=$true)]
[string]$tenantId # Azure AD tenant ID
)
# Validate input parameters
if (-not $dnsName -or -not $resourceGroupName -or -not $nsgName -or -not $ruleName -or -not $appId -or -not $appSecret -or -not $tenantId) {
Write-Error "All parameters are required."
exit
}
function Update-AzureNSGRule {
try {
# Convert app secret to secure string for authentication
$secureAppSecret = ConvertTo-SecureString $appSecret -AsPlainText -Force
$psCredential = New-Object System.Management.Automation.PSCredential ($appId, $secureAppSecret)
# Authenticate to Azure with the service principal
Connect-AzAccount -ServicePrincipal -Credential $psCredential -Tenant $tenantId
Write-Host "Successfully authenticated to Azure."
} catch {
Write-Error "Failed to authenticate to Azure: $_"
return
}
try {
# Retrieve the current IP address for the provided DNS name
$ipAddress = (Resolve-DnsName $dnsName).IPAddress
if (-not $ipAddress) {
throw "DNS name resolution failed for $dnsName"
}
Write-Host "Resolved DNS IP Address: $ipAddress"
} catch {
Write-Error "DNS resolution error: $_"
return
}
try {
# Retrieve the Network Security Group (NSG) object
$nsg = Get-AzNetworkSecurityGroup -Name $nsgName -ResourceGroupName $resourceGroupName
if (-not $nsg) {
throw "NSG '$nsgName' not found in resource group '$resourceGroupName'."
}
Write-Host "Successfully retrieved NSG: '$nsgName'."
# Retrieve the specific rule from the NSG
$rule = $nsg.SecurityRules | Where-Object { $_.Name -eq $ruleName }
if (-not $rule) {
throw "Rule '$ruleName' not found in NSG '$nsgName'."
}
Write-Host "Successfully retrieved NSG rule: '$ruleName'."
# Log the current Source Address Prefix before updating
Write-Host "Current Source Address Prefix: $($rule.SourceAddressPrefix)"
# Update the rule with the new IP address
$rule.SourceAddressPrefix = ([System.String[]] @($ipAddress))
# Set-AzNetworkSecurityRuleConfig -Name $ruleName -NetworkSecurityGroup $nsg -SourceAddressPrefix $rule.SourceAddressPrefix
# Apply the updated rule to the NSG
$nsg | Set-AzNetworkSecurityGroup
Write-Host "NSG rule '$ruleName' updated successfully with new IP address: $ipAddress."
# Re-fetch the updated rule to confirm the change
# $updatedRule = $nsg.SecurityRules | Where-Object { $_.Name -eq $ruleName }
$updatedRule = (Get-AzNetworkSecurityGroup -ResourceGroupName $resourceGroupName -Name $nsgName).SecurityRules | Where-Object { $_.Name -eq $ruleName }
Write-Host "Updated Source Address Prefix: $($updatedRule.SourceAddressPrefix)"
Write-Host "ProvisioningState: $($updatedRule.ProvisioningState)"
Write-Host "Etag: $($updatedRule.Etag)"
} catch {
Write-Error "Failed to update NSG rule: $_"
}
}
# Execute the function to update the NSG rule
Update-AzureNSGRule