Open Adunaphel opened 4 years ago
I think you are getting that error because of a spelling issue. In the variable I see pupbipv4
, but the resource symbolic name is pubipv4
.
That being said, I'm not exactly sure what you are trying to accomplish. Can you elaborate a bit more and also show a JSON equivalent of what you do in ARM Templates?
Referencing a resource like this in a variable is actually not allowed in the json. We should block this in bicep.
@Adunaphel - here's an example of referencing a publicIp in a nic, which I think shows something similar to what you're looking for:
Indeed you are right, I only now notice the typo.
To answer your question, the thing I want to achieve here is to be able to dynamically set the NIC configuration depending on whether the VM in question needs only ipv4 or dual stack ipv4 and ipv6 networking (leaving out a lot of properties for brevity):
"variables": {
"publicIpAddressId": {
"id": "[resourceId( 'Microsoft.Network/publicIPAddresses', variables( 'publicIpAddressName' ) )]"
},
"publicIpv6AddressId": {
"id": "[resourceId( 'Microsoft.Network/publicIPAddresses', concat( variables( 'publicIpAddressName' ), 'v6' ) )]"
},
"ipv4NicConfig": {
"name": "[parameters( 'virtualMachine' ).network.privateIpConfigurationName]",
"properties": {
"privateIPAddressVersion": "IPv4",
"subnet": {
"id": "[resourceId( 'Microsoft.Network/virtualNetworks/subnets', parameters( 'virtualMachine' ).network.virtualNetworkName, parameters( 'virtualMachine' ).network.subnetName )]"
},
"publicIpAddress": "[if( parameters( 'virtualMachine' ).network.needsPublicIp, variables( 'publicIpAddressId' ), json( 'null' ) )]",
"primary": true,
}
},
"ipv6NicConfig": {
"name": "[parameters( 'virtualMachine' ).network.privateIpv6ConfigurationName]",
"properties": {
"privateIPAddressVersion": "IPv6",
"subnet": {
"id": "[resourceId( 'Microsoft.Network/virtualNetworks/subnets', parameters( 'virtualMachine' ).network.virtualNetworkName, parameters( 'virtualMachine' ).network.subnetName )]"
},
"publicIpAddress": "[if( parameters( 'virtualMachine' ).network.needsPublicIpv6, variables( 'publicIpv6AddressId' ), json( 'null' ) )]",
}
},
"nicConfig": {
"singleStack": [
"[variables( 'ipv4NicConfig' )]"
],
"dualStack": [
"[variables( 'ipv4NicConfig' )]",
"[variables( 'ipv6NicConfig' )]"
]
}
}
"resources": [
{
"condition": "[parameters( 'virtualMachine' ).network.needsPublicIp]",
"name": "[variables( 'publicIpAddressName' )]",
(....)
},
{
"condition": "[parameters( 'virtualMachine' ).network.needsPublicIpv6]",
"name": "[concat( variables( 'publicIpAddressName' ), 'v6' )]",
(....)
},
{
"dependsOn": [
"[resourceId( 'Microsoft.Network/publicIPAddresses', variables( 'publicIpAddressName' ) )]",
"[resourceId( 'Microsoft.Network/publicIPAddresses', concat( variables( 'publicIpAddressName' ), 'v6' ) )]"
],
"name": "[variables( 'networkInterfaceName' )]",
"type": "Microsoft.Network/networkInterfaces",
"apiVersion": "[variables( 'apiVersions' ).networkInterfaces]",
"location": "[resourceGroup().location]",
"tags": "[union( parameters( 'virtualMachine' ).tags, parameters( 'tags' ) )]",
"properties": {
"ipConfigurations": "[if( parameters( 'virtualMachine' ).network.needsPublicIpv6, variables( 'nicConfig' ).dualStack, variables( 'nicConfig' ).singleStack )]",
"enableAcceleratedNetworking": "[parameters( 'virtualMachine' ).network.enableAcceleratedNetworking]"
}
}
After fixing my typo and building the template, there is still an issue here, because referencing the resources results in a reference() call in the variables, which is not allowed, instead of just a resourceId call to get the resource's ID:
param virtualMachine object
param tags object
var zones = virtualMachine.zone > 0 ? createArray(virtualMachine.zone) : []
var publicIpDnsSettings = {
domainNameLabel: virtualMachine.network.publicIpDnsName
}
var ipv4nicConfig = {
name: virtualMachine.network.privateIpConfigurationName
properties: {
privateIPAllocationMethod: (empty(virtualMachine.network.privateIpAddress)) ? 'Dynamic': 'Static'
privateIPAddress: (empty(virtualMachine.network.privateIPAddress)) ? null : virtualMachine.network.privateIpAddress
privateIPAddressVersion: 'IPv4'
subnet: resourceId(virtualMachine.network.virtualNetworkResourceGroup, 'Microsoft.Network/subnets', virtualMachine.network.virtualNetworkName, virtualMachine.network.subnetName)
publicIpAddress: (virtualMachine.network.needsPublicIp) ? pubipv4 : null
}
}
var ipv6nicConfig = {
name: virtualMachine.network.privateIpv6ConfigurationName
properties: {
privateIPAllocationMethod: (empty(virtualMachine.network.privateIpAddress)) ? 'Dynamic': 'Static'
privateIPAddress: (empty(virtualMachine.network.privateIPAddress)) ? null : virtualMachine.network.privateIpv6Address
privateIPAddressVersion: 'IPv6'
subnet: resourceId(virtualMachine.network.virtualNetworkResourceGroup, 'Microsoft.Network/subnets', virtualMachine.network.virtualNetworkName, virtualMachine.network.subnetName)
publicIpAddress: (virtualMachine.network.needsPublicIpv6) ? pubipv6 : null
}
}
var nicConfig = {
singleStack: [
ipv4nicConfig
]
dualStack: [
ipv4nicConfig
ipv6nicConfig
]
}
resource pubipv4 'Microsoft.Network/publicIpAddresses@2020-05-01' = {
name: '${virtualMachine.name}-pip'
location: resourceGroup().location
//zones: virtualMachine.network.enabledPublicIpZone ? zones : null
tags: union(tags, virtualMachine.tags)
sku: {
name: 'Standard'
}
properties: {
publicIpAllocationMethod: virtualMachine.network.publicIpAllocationMethod
publicIpAddressVersion: 'IPv4'
idleTimeoutInMinutes: virtualMachine.network.publicIpIdleTimeoutInMinutes
dnsSettings: (empty(virtualMachine.network.publicIpDnsName)) ? null : publicIpDnsSettings
publicIpPrefix: {
id: resourceId(virtualMachine.network.publicIpPrefix.resourceGroup, 'Microsoft.Network/publicIPPrefixes', virtualMachine.network.publicIpPrefix.name)
}
}
}
resource pubipv6 'Microsoft.Network/publicIpAddresses@2020-05-01' = {
name: '${virtualMachine.name}-pipv6'
location: resourceGroup().location
//zones: virtualMachine.network.enabledPublicIpZone ? zones : null
tags: union(tags, virtualMachine.tags)
sku: {
name: 'Standard'
}
properties: {
publicIpAllocationMethod: virtualMachine.network.publicIpv6AllocationMethod
publicIpAddressVersion: 'IPv6'
idleTimeoutInMinutes: virtualMachine.network.publicIpv6IdleTimeoutInMinutes
dnsSettings: (empty(virtualMachine.network.publicIpv6DnsName)) ? null : publicIpDnsSettings
publicIpPrefix: {
id: resourceId(virtualMachine.network.publicIpv6Prefix.resourceGroup, 'Microsoft.Network/publicIPPrefixes', virtualMachine.network.publicIpv6Prefix.name)
}
}
}
resource vmnic 'Microsoft.Network/networkInterfaces@2020-05-01' = {
name: (empty(virtualMachine.networkInterfaceName)) ? '${virtualMachine.name}-nic' : '${virtualMachine.networkInterfaceName}'
location: resourceGroup().location
tags: union(tags, virtualMachine.tags)
properties: {
ipConfigurations: (virtualMachine.network.needsPublicIpv6) ? nicConfig.dualStack : nicConfig.singleStack
enableAcceleratedNetworking: virtualMachine.network.enableAcceleratedNetworking
}
}
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"virtualMachine": {
"type": "object"
},
"tags": {
"type": "object"
}
},
"functions": [],
"variables": {
"publicIpDnsSettings": {
"domainNameLabel": "[parameters('virtualMachine').network.publicIpDnsName]"
},
"ipv4nicConfig": {
"name": "[parameters('virtualMachine').network.privateIpConfigurationName]",
"properties": {
"privateIPAllocationMethod": "[if(empty(parameters('virtualMachine').network.privateIpAddress), 'Dynamic', 'Static')]",
"privateIPAddress": "[if(empty(parameters('virtualMachine').network.privateIPAddress), json('null'), parameters('virtualMachine').network.privateIpAddress)]",
"privateIPAddressVersion": "IPv4",
"subnet": "[resourceId(parameters('virtualMachine').network.virtualNetworkResourceGroup, 'Microsoft.Network/subnets', parameters('virtualMachine').network.virtualNetworkName, parameters('virtualMachine').network.subnetName)]",
"publicIpAddress": "[if(parameters('virtualMachine').network.needsPublicIp, reference(resourceId('Microsoft.Network/publicIpAddresses', format('{0}-pip', parameters('virtualMachine').name)), '2020-05-01', 'full'), json('null'))]"
}
},
"ipv6nicConfig": {
"name": "[parameters('virtualMachine').network.privateIpv6ConfigurationName]",
"properties": {
"privateIPAllocationMethod": "[if(empty(parameters('virtualMachine').network.privateIpAddress), 'Dynamic', 'Static')]",
"privateIPAddress": "[if(empty(parameters('virtualMachine').network.privateIPAddress), json('null'), parameters('virtualMachine').network.privateIpv6Address)]",
"privateIPAddressVersion": "IPv6",
"subnet": "[resourceId(parameters('virtualMachine').network.virtualNetworkResourceGroup, 'Microsoft.Network/subnets', parameters('virtualMachine').network.virtualNetworkName, parameters('virtualMachine').network.subnetName)]",
"publicIpAddress": "[if(parameters('virtualMachine').network.needsPublicIpv6, reference(resourceId('Microsoft.Network/publicIpAddresses', format('{0}-pipv6', parameters('virtualMachine').name)), '2020-05-01', 'full'), json('null'))]"
}
},
"nicConfig": {
"singleStack": [
"[variables('ipv4nicConfig')]"
],
"dualStack": [
"[variables('ipv4nicConfig')]",
"[variables('ipv6nicConfig')]"
]
}
},
"resources": [
{
"type": "Microsoft.Network/publicIpAddresses",
"apiVersion": "2020-05-01",
"name": "[format('{0}-pip', parameters('virtualMachine').name)]",
"location": "[resourceGroup().location]",
"tags": "[union(parameters('tags'), parameters('virtualMachine').tags)]",
"sku": {
"name": "Standard"
},
"properties": {
"publicIpAllocationMethod": "[parameters('virtualMachine').network.publicIpAllocationMethod]",
"publicIpAddressVersion": "IPv4",
"idleTimeoutInMinutes": "[parameters('virtualMachine').network.publicIpIdleTimeoutInMinutes]",
"dnsSettings": "[if(empty(parameters('virtualMachine').network.publicIpDnsName), json('null'), variables('publicIpDnsSettings'))]",
"publicIpPrefix": {
"id": "[resourceId(parameters('virtualMachine').network.publicIpPrefix.resourceGroup, 'Microsoft.Network/publicIPPrefixes', parameters('virtualMachine').network.publicIpPrefix.name)]"
}
}
},
{
"type": "Microsoft.Network/publicIpAddresses",
"apiVersion": "2020-05-01",
"name": "[format('{0}-pipv6', parameters('virtualMachine').name)]",
"location": "[resourceGroup().location]",
"tags": "[union(parameters('tags'), parameters('virtualMachine').tags)]",
"sku": {
"name": "Standard"
},
"properties": {
"publicIpAllocationMethod": "[parameters('virtualMachine').network.publicIpv6AllocationMethod]",
"publicIpAddressVersion": "IPv6",
"idleTimeoutInMinutes": "[parameters('virtualMachine').network.publicIpv6IdleTimeoutInMinutes]",
"dnsSettings": "[if(empty(parameters('virtualMachine').network.publicIpv6DnsName), json('null'), variables('publicIpDnsSettings'))]",
"publicIpPrefix": {
"id": "[resourceId(parameters('virtualMachine').network.publicIpv6Prefix.resourceGroup, 'Microsoft.Network/publicIPPrefixes', parameters('virtualMachine').network.publicIpv6Prefix.name)]"
}
}
},
{
"type": "Microsoft.Network/networkInterfaces",
"apiVersion": "2020-05-01",
"name": "[if(empty(parameters('virtualMachine').networkInterfaceName), format('{0}-nic', parameters('virtualMachine').name), format('{0}', parameters('virtualMachine').networkInterfaceName))]",
"location": "[resourceGroup().location]",
"tags": "[union(parameters('tags'), parameters('virtualMachine').tags)]",
"properties": {
"ipConfigurations": "[if(parameters('virtualMachine').network.needsPublicIpv6, variables('nicConfig').dualStack, variables('nicConfig').singleStack)]",
"enableAcceleratedNetworking": "[parameters('virtualMachine').network.enableAcceleratedNetworking]"
},
"dependsOn": [
"[resourceId('Microsoft.Network/publicIpAddresses', format('{0}-pip', parameters('virtualMachine').name))]",
"[resourceId('Microsoft.Network/publicIpAddresses', format('{0}-pipv6', parameters('virtualMachine').name))]"
]
}
],
"outputs": {}
}
Gotcha - so this is an ARM template limitation. Ideally we fix this there, but optionally we can "handle it" in bicep by removing the variable in the generated JSON and "hardcoding" the values where you would have otherwise used the variable.
This is still an issue - minimal repro here.
We correctly inline variables for a reference to myRes.properties
, but not a reference to myRes
itself.
I have the following code snippet:
And the message I get is "The name 'pubipv4' does not exist in the current context." For a lot of our templates, we build properties sections in variables because it allows us to be far more flexible (in this case creating a single stack ipv4 nic or a dual stack ipv4/ipv6 nic depending on config) so being able to access the shorthand resources would be really helpful