ARM resources can depend on one another, and Farmer caters for this as well. Dependencies guarantee that when resources are created, Azure will provision them in the correct order so that e.g. a storage account is created before Azure tries to grab the storage account key / connection string for your web app setting.
Much of this work is done for you:
In the sample below, the web app { }
will automatically realise that it needs to depend on Storage Account based on the “owner” of Key
expression that is supplied.
let myStorage = storageAccount {
name "sampleaccount"
}
let myApp = webApp {
name "myapp"
setting "storage_key" myStorage.Key
}
Normally, Farmer will do everything you need. However, there are some times when you may need to explicitly set a dependency:
Setting a dependency requires you to call the depends_on
keyword on the target resource, providing a handle to the dependent resource.
let myStorage1 = storageAccount {
name "sampleaccountFirst"
}
let myApp = webApp {
name "myapp"
depends_on myStorage1
}
Here, we set up an explicit dependency on myApp
for myStorage
.
You can also supply multiple dependencies at once as a list; this is useful if you are programmatically creating multiple resources.
// Create five storage accounts
let storageAccounts : IBuilder list = [
for letter in [ 'a' .. 'e' ] do
storageAccount {
name $"mystorage{letter}"
}
]
let myApp = webApp {
name "myapp"
depends_on storageAccounts // add them all to the web app as dependencies
}
Notice the extra type hint, : IBuilder list
. This is required because F# does not, by default, allow you to implicitly treat a list of values as a supertype. In this case, a StorageAccountConfig list
is not considered implicitly convertable to : IBuilder list
(which is an interface that StorageAccountConfig
implements). Therefore, we have to do it ourselves using the extra type declaration.
You can also use the :>
(safe upcast) operator when declaring the StorageAccount:
let storageAccounts = [ // inferred as IBuilder list
for letter in [ 'a' .. 'e' ] do
storageAccount {
name $"mystorage%c" letter)
} :> IBuilder
]
We’re looking at improving this situation in the future using F#‘s “flexible types” feature.
All builders that support dependencies support a number of depends_on
overloads: