I noticed the Microsoft documentation related to the following function is a little bit vague.
reference(resourceName or resourceIdentifier, [apiVersion], [‘Full’])
The second issue is see a lot of people having is how do you reference a resource already created in ARM and get some of that objects properties e.g. FQDN on a public IP already created etc.
The clue to solve this issue, so that ARM Template B can reference a resource created in ARM Template A can be found here:
By using the reference function, you implicitly declare that one resource depends on another resource if the referenced resource is provisioned within same template and you refer to the resource by its name (not resource ID). You don’t need to also use the dependsOn property. The function isn’t evaluated until the referenced resource has completed deployment.
Or use linked templates (Linked templates is a huge rework and you need to host the files on the net). Lets see if we can do it via resourceId.
Therefore if we do reference a resource by resourceId, we will remove the implicit “depends on”, allowing ARM Template B to use a resource created in a totally different ARM template.
A great example might be the FQDN on an IP Address.
Imagine ARM Template A creates the IP Address
"resourceType": "Service Fabric",
Now Imagine we need to get the FQDN of the IP Address in a ARM Template B
What we going to do is try this:
reference(resourceIdentifier, [apiVersion]) ->
reference(resourceId(), [apiVersion]) ->
Here is an example where ARM template B references a resource in A and gets a property.
"managementEndpoint": "[concat('https://',reference(resourceId('Microsoft.Network/publicIPAddresses/',variables('AppPublicIPName')), variables('publicIPApiVersion')).dnsSettings.fqdn,':',variables('nodeTypePrimaryServiceFabricHttpPort'))]",
The important thing here is to ensure you always include the API Version. This pattern is a very powerful way to create smaller and more modular ARM templates.
Note: In the above pattern, you do not need to define DependsOn in ARM Template B, as we are explicitly defining a reference to an existing resource. ARM Template B is not responsible for creating a public IP. If you need it, you run ARM Template A.
So if you need a reference to existing resources use the above. If you need a reference to resources created in the SAME ARM template use: