Azure Resource Manager set static IP using json template - azure-resource-manager

Using Azure Resource Manager Json template, can we set internal static IP without having to assign IP? My template creates a couple of Vms. When I set privateIPAllocationMethod to Static I get error that I have to set the IP also. Is it possible to assign IP dynamically and set it static?

Or are you looking for something you can do in ARM after you get an IP from Azure using dynamic the switch to static.
{
"name": "SetStaticIP",
"type": "Microsoft.Resources/deployments",
"apiVersion": "2015-01-01",
"dependsOn": [
"[concat(parameters('envPrefix'),parameters('vmName'),'nic')]",
"[concat(parameters('envPrefix'),parameters('vmName'))]",
"Microsoft.Insights.VMDiagnosticsSettings"
],
"properties": {
"mode": "Incremental",
"templateLink": {
"uri": "[concat(parameters('_artifactsLocation'), '/SetStaticIP.json', parameters('_artifactsLocationSasToken'))]",
"contentVersion": "1.0.0.0"
},
"parameters": {
"VirtualNetwork": {
"value": "[parameters('VirtualNetwork')]"
},
"VirtualNetworkId": {
"value": "[parameters('VirtualNetworkId')]" },
"nicName": {
"value": "[concat(parameters('envPrefix'),parameters('vmName'),'nic')]"
},
"ipAddress": {
"value": "[reference(concat(parameters('envPrefix'),parameters('vmName'),'nic')).ipConfigurations[0].properties.privateIPAddress]"
}
}
}
}

YES you can change dynamically assigned IP to static. Try this-
$nic=Get-AzureRmNetworkInterface -Name "TestNIC" -ResourceGroupName "TestRG"
$nic.IpConfigurations[0].PrivateIpAllocationMethod = "Static"
$nic.IpConfigurations[0].PrivateIpAddress = "x.x.x.x"
Set-AzureRmNetworkInterface -NetworkInterface $nic
You can refer to this article- https://azure.microsoft.com/en-us/documentation/articles/virtual-networks-static-private-ip-arm-ps/
Thanks.

Related

Put Azure Key Vault value in parameter array

I am trying to deploy a App service webapp via ARM template and need to put a secret from a key vault into an app setting (env variable).
I have always simply used an array of values from a parameters file to populate these app settings, but now I am struggling to get a keyvault value into that array. Something like shown below in an ARM parameter file.
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"someStringParam": {
"value": "stringLiteralValueHere"
},
"envVars": {
"value": [
{
"name": "envVarKeyName",
"value": "stringLiteralValueHere"
},
{
"name": "KVsecret1",
"value": ##KEY VAULT SECRET HERE##
}
]
}
}
}
I have tried using a reference to the keyvault for the value but that errors on deployment.
{
"name": "KVsecret1",
"reference": {
"keyVault": {
"id": "/subscriptions/<subscription_id>/resourceGroups/<resource_group>/providers/Microsoft.KeyVault/vaults/<vault_name>"
},
"secretName": "secret1"
}
}
I have also tried using a parameter inside of the parameter file, but that just used the literal string for the value.
"parameters": {
"KVsecret1": {
"reference": {
"keyVault": {
"id": "/subscriptions/<subscription_id>/resourceGroups/<resource_group>/providers/Microsoft.KeyVault/vaults/<vault_name>"
},
"secretName": "KVsecret1"
}
},
"envVars": {
"value": [
{
"name": "envVarKeyName",
"value": "stringLiteralValueHere"
},
{
"name": "KVsecret1",
"value": "[parameters('KVsecret1')]"
}
]
}
}
Is this possible??
EDIT: Adding some detail here.
I am also trying to shoe horn a reference to another resource to get put the app insights instrumentation key into an app setting. Below is what I would like to do, but the copy function needs to use the name of the property and that is dynamic in this case as it changes with the each member of the array from the parameter file.
{
"type": "Microsoft.Web/sites/config",
"apiVersion": "2022-03-01",
"name": "[concat(parameters('backEndwebAppName'),'/appsettings')]",
"kind": "string",
"properties": {
"APPINSIGHTS_INSTRUMENTATIONKEY": "[reference(concat('microsoft.insights/components/',parameters('appInsightsName')),'2020-02-02').InstrumentationKey]",
"secret1FromKeyvault": "[parameters('secret1FromKeyvault')]",
"copy": [
{
"name": "envVarsFromParams",
"count": "[length(parameters('backEndEnvVariables'))]",
"input": {
"name": "[parameters('backEndEnvVariables')[copyIndex('envVarsFromParams').name]]",
"value": "[parameters('backEndEnvVariables')[copyIndex('envVarsFromParams').value]]"
}
}
]
},
"dependsOn": [
"[resourceId('Microsoft.Web/sites', parameters('backEndwebAppName'))]"
]
},
This isn't possible today within the param file, but in your scenario (if it's as simple as your OP example) you can just union the two in your template. So in your parameter file, you have 2 params kvSecret (the reference) and envVars (all your other env vars) and then in the template use:
"variables": {
"keySecretObj": {
"name": "kvSecret",
"value": "[parameters('kvSecret')]"
},
"envVarsFinal": "[union(parameters(variables('kvSecretObj`), parameters(`envVars`))]"
That help?

Add new ip to existing CosmosDB account via ARM template

I halve arm template that is overwriting existing iprules of cosmosDb account, is it possible to modify arm template so it will only add new ip and not to clean already existing rules.
My template:
{
"type": "Microsoft.DocumentDB/databaseAccounts",
"apiVersion": "2021-10-15",
"name": "cosmosdbaccountname",
"location": "East US",
"properties": {
"ipRules": {
"ipAddressOrRange": "some ip"
}
}
}
If configuring IP Firewall to an already deployed Cosmos account, ensure the locations array matches what is currently deployed. You cannot simultaneously modify the locations array and other properties.
Below example shows how the ipRules property is exposed in API version 2020-04-01 or later:
{
"type": "Microsoft.DocumentDB/databaseAccounts",
"name": "[variables('accountName')]",
"apiVersion": "2020-04-01",
"location": "[parameters('location')]",
"kind": "GlobalDocumentDB",
"properties": {
"consistencyPolicy": "[variables('consistencyPolicy')[parameters('defaultConsistencyLevel')]]",
"locations": "[variables('locations')]",
"databaseAccountOfferType": "Standard",
"enableAutomaticFailover": "[parameters('automaticFailover')]",
"ipRules": [
{
"ipAddressOrRange": "40.76.54.131"
},
{
"ipAddressOrRange": "52.176.6.30"
},
{
"ipAddressOrRange": "52.169.50.45"
},
{
"ipAddressOrRange": "52.187.184.26"
}
]
}
}
Here's the same example for any API version prior to 2020-04-01:
{
"type": "Microsoft.DocumentDB/databaseAccounts",
"name": "[variables('accountName')]",
"apiVersion": "2019-08-01",
"location": "[parameters('location')]",
"kind": "GlobalDocumentDB",
"properties": {
"consistencyPolicy": "[variables('consistencyPolicy')[parameters('defaultConsistencyLevel')]]",
"locations": "[variables('locations')]",
"databaseAccountOfferType": "Standard",
"enableAutomaticFailover": "[parameters('automaticFailover')]",
"ipRangeFilter":"40.76.54.131,52.176.6.30,52.169.50.45,52.187.184.26"
}
}
Refer this configure IP to Cosmos account using ARM

Getting "parent resource not found" during ARM template deployment

I have private DNS zone zone.private which is already deployed in resource group and I'm trying to add A record to it with ARM template below which fails with Status Message: Can not perform requested operation on nested resource. Parent resource 'zone.private' not found. (Code:ParentResourceNotFound)
I'm supposed to be able to refer to refer to resources deployed in the same resource group to deploy nested resources but it fails for whatever reason. I have another zone called zone.domain.com deployed to the same resource group and deploying to that succeeds with no issues.
{
"type": "Microsoft.Network/dnsZones/A",
"apiVersion": "2018-05-01",
"name": "[concat('zone.private', '/', 'webexport-lb')]",
"properties": {
"TTL": 3600,
"ARecords": [
{
"ipv4Address": "1.1.1.1"
}
]
}
},
If you have a private DNS zone, you could use Microsoft.Network/privateDnsZones/A instead of Microsoft.Network/dnsZones/A.
So change it like this:
{
"type": "Microsoft.Network/privateDnsZones/A",
"apiVersion": "2018-09-01",
"name": "[concat('zone.private', '/', 'webexport-lb')]",
"properties": {
"ttl": 3600,
"aRecords": [
{
"ipv4Address": "1.1.1.1"
}
]
}
}

Passing Parameter Values to DSC Configuration from ARM Template

I have a simple DSC Config file that contains a credential and string input parameter. I want this DSC configuration deployed with a VM deployed in an ARM template but am missing the concept of how to pass these two parameters securely. How do I accomplish this?
I was receiving the same error but, after some shenanigans, it is working for me. The important part is the settings/Properties/SqlAgentCred/password reference to protectedSettings/Items/AgentPassword. Below is the properties node under my Powershell.DSC extension resource in my template.
"properties": {
"publisher": "Microsoft.Powershell",
"type": "DSC",
"typeHandlerVersion": "2.17",
"autoUpgradeMinorVersion": false,
"settings": {
"ModulesUrl": "https://blobstore.blob.core.windows.net/windows-powershell-dsc/DBServer.ps1.zip",
"ConfigurationFunction": "DBServer.ps1\\DBServer",
"Properties": {
"SqlAgentCred": {
"userName": "user#domain.com",
"password": "PrivateSettingsRef:AgentPassword"
}
},
"WmfVersion": "latest",
"Privacy": {
"DataCollection": "Disable"
}
},
"protectedSettings": {
"Items": {
"AgentPassword": "Pa$$word"
},
"DataBlobUri": ""
}
}
You will specify protected settings under protectedsettings section. Anything under ProtectedSettings are sent encrypted. Check https://blogs.msdn.microsoft.com/powershell/2016/02/26/arm-dsc-extension-settings/ for details.

Azure Resource Manager - Multiple VM NAT Rules

I am trying to create an ARM template that will provision multiple webservers with directly accessible ports. For instance I want a VM to have either port 9001 or 9002 open based on what the index of the VM is.
I am struggling to get the frontendPort parameter to accept a function. Here is the documentation that I have used.
Here is what the relevant portion of my template looks like:
"inboundNatRules": [
{
"copy": {
"name": "natCopy",
"count": "[parameters('numberOfVms')]"
},
"name": "[concat('directHttps-', copyIndex())]",
"properties": {
"frontendIPConfiguration": {
"id": "[concat(variables('lbID'),'/frontendIPConfigurations/LoadBalancerFrontEnd')]"
},
"frontendPort": "[add(9001, copyIndex())]",
"backendPort": 9001,
"enableFloatingIP": false,
"idleTimeoutInMinutes": 4,
"protocol": "Tcp",
"backendIPConfiguration": {
"id": "[resourceId('Microsoft.Network/networkInterfaces', concat(variables('vmNicName'), copyIndex()), 'ipconfig')]"
}
}
}
]
I was hoping that the this particular port would result in either "9001", or "9002".
"frontendPort": "[add(9001, copyIndex())]"
Instead, I see an error in Visual Studio's Intellisense, and when I try to deploy the solution.
Create template deployment 'deploymenttemplate-0107-1555'.
New-AzureRmResourceGroupDeployment : Resource Microsoft.Network/loadBalancers 'webserverLb'
failed with message 'Unable to process template language expressions for resource
'/subscriptions/some random guid/resourceGroups/webservers/providers/Microsoft.Network/loadBalancers/webserverLb'
at line '102' and column '10'. 'The template function 'copyIndex' is not expected at this location.
The function can only be used in a resource with copy specified.
Long story short, I'm simply trying to have the same number of NAT rules as I have VM's in the template, and dynamically assign the external port number.
Please let me know if I can provide any more information. Thank you.
Try:
[Concat(900,CopyIndex(1))]
which will offset the index (0 based) and give you the number you want.
This is the syntax that works for copying the NAT rules (I am adding an RDP rule on the standard back-end port):
"copy": [
{
"name": "inboundNatRules",
"count": "[parameters('numberOfWebInstances')]",
"input": {
"name": "[concat(parameters('lbNatRulePrefix'), copyindex('inboundNatRules'))]",
"properties": {
"frontendIPConfiguration": {
"id": "[variables('lbFrontEndIpId')]"
},
"frontendPort": "[add(50001, copyIndex('inboundNatRules'))]",
"backendPort": 3389,
"enableFloatingIP": false,
"idleTimeoutInMinutes": 4,
"protocol": "tcp"
}
}
}
],
And then to apply the rules to the NIC, you actually need to add some code on the NIC itself. The following is for both LB rules and NAT rules:
"loadBalancerBackendAddressPools": [
{
"id": "[concat(variables('lbID'), '/backendAddressPools/', parameters('lbPoolName'))]"
}
],
"loadBalancerInboundNatRules": [
{
"id": "[concat(variables('lbID'),'/inboundNatRules/' , parameters('lbNatRulePrefix'), copyindex())]"
}
]
#Your script is wrong it should you are writing copyindex() but you need to pass the name of rule it should work.
"inboundNatRules": [
{
"copy": {
"name": "natCopy",
"count": "[parameters('numberOfVms')]"
},
"name": "[concat('directHttps-', copyIndex(natCopy,1))]",
"properties": {
"frontendIPConfiguration": {
"id": "[concat(variables('lbID'),'/frontendIPConfigurations/LoadBalancerFrontEnd')]"
},
"frontendPort": "[add(9001, copyIndex(natCopy,1))]",
"backendPort": 9001,
"enableFloatingIP": false,
"idleTimeoutInMinutes": 4,
"protocol": "Tcp",
"backendIPConfiguration": {
"id": "[resourceId('Microsoft.Network/networkInterfaces', concat(variables('vmNicName'), copyIndex(natCopy,1)), 'ipconfig')]"
}
}
}
$LoadBalancer = Get-AzureRmLoadBalancer -ResourceGroupName $ResourceGroupName -Name $LoadBalancerName
$publicIP1 = Get-AzureRmPublicIpAddress -name $pipName -resourcegroupname $ResourceGroupName
$frontendIP1 = Get-AzureRmLoadBalancerFrontendIpConfig -LoadBalancer $LoadBalancer -Name $FrontendIpConfigName
$LoadBalancer | Add-AzureRmLoadBalancerInboundNatRuleConfig -Name "nat_rule_tcp_IP1_49157" -FrontendIpConfiguration $frontendIP1 -IdleTimeoutInMinutes 4 -Protocol TCP -FrontendPort 49157 -BackendPort 49157 | Set-AzureRmLoadBalancer

Resources