This step will get you up and running by incorporating something quickly and easily into the Farmer pipeline that emits a valid Azure Container Registry.
Technically this step is not necessary but it is the quickest way to get a working deployment from which you can iterate upon.
Start by looking at the sample azuredeploy.json file from the Azure Container Registry with Geo-replication Azure quickstart template and identifying the section of JSON that relates to the resource we want - in our case, the Microsoft.ContainerRegistry/registries
resource.
In VSCode, the use of
#r "nuget:..."
syntax can be enabled by going toSettings > F# > Fsi Extra Parameters
and adding--langversion:preview
to theFSharp.fsiExtraParameters
list (.NET 5 only). VS2019 and Rider already support this feature natively. If you are not using .NET 5, manually build Farmer and reference the dll manually - see thesamples
folder for examples.
// container-registry-prototype.fsx
#r "nuget: farmer"
open Farmer
// A function called "registries" that takes in a name, sku and boolean flag for whether to enable the admin user.
let registries name sku adminUserEnabled =
$"""{{
"name": "{name}",
"type": "Microsoft.ContainerRegistry/registries",
"apiVersion": "2019-05-01",
"location": "westeurope",
"tags": {{ }},
"sku": {{ "name": "{sku}" }},
"properties": {{ "adminUserEnabled": %b{adminUserEnabled} }}
}}"""
|> Resource.ofJson
let deployment = arm {
location Location.NorthEurope
add_resource (registries "my-registry" "Basic" true)
}
deployment
|> Writer.quickWrite "/test-output"
// or push out for real to Azure!
// deployment
// |> Deploy.execute "FarmerTest" Deploy.NoParameters
// |> printfn "%A"
Observe how we’ve pasted a minimal section of JSON and then tried to extract some of the candidates for parameterisation - in our case name
, sku
and adminUserEnabled
, and how we’ve used the Resource.ofJson
function to create an IArmResource
for us to quickly allow us “into” the Farmer pipeline.
Test out the JSON model you created and make sure it creates the resources in Azure you would expect. You can deploy with execute
or you can use whatIf
to see what the expected state would be.
For simple ARM resources, raw JSON may suffice, but normally you’ll want a little more control in order to programmatically choose whether to add / remove fields etc. during the export phase. The best way to do this is to replace the raw string export with an anonymous record:
let registries (name:string) (sku:string) (adminUserEnabled:bool) =
{| name = name
``type`` = "Microsoft.ContainerRegistry/registries"
apiVersion = "2019-05-01"
location = "westeurope"
tags = {| |}
sku = {| name = sku |}
properties = {| adminUserEnabled = adminUserEnabled |}
|}
|> Resource.ofObj
Notice how the structure is the same, but is now implemented directly in F#.