farmer icon indicating copy to clipboard operation
farmer copied to clipboard

Suggestion: Expansion of context passed to `BuildResources`

Open TheRSP opened this issue 2 years ago • 4 comments

Currently every IBuilder defines a BuildResources method which takes in a single argument which is the location. I propose that this be expanded to a context object which could include the location and other bits of information. In particular I am interested in getting the name of the surrounding resourceGroup.

Example implementation is shown here. This would require a small change to every builder which currently exists but allows future expansions of this context without requiring changes to every builder.

+type rec BuilderContext = 
+  { Location : Location // Target location to store deployment data
+    ResourceGroup : string // The name of the resource group being deployed to 
+    ParentContext : BuilderContext option } // The BuilderContext for the parent deployment where this is in a nested deployment

 type IBuilder =
-    abstract member BuildResources : Location -> IArmResource list
+    abstract member BuildResources : BuildContext -> IArmResource list
     abstract member ResourceId : ResourceId

 type ExistingBuilder
   interface IBuilder with
-    this.BuildResources location =
+    this.BuildResources context =
+      let location = context.Location
       // ... existing BuildResources code

In future, it may be desirable to add deployment scope or other properties into this context.

Why do I want this?

I'm working on a fix for #846 and have found I need to know the name of the resource group so that I can reference resources being deployed from a nested resource group. While I can get around it this time, this will be at least the second time that having the resourceGroup name available would be useful.

TheRSP avatar Dec 14 '21 15:12 TheRSP

Further to this, it would seem sensible to also expand the context given to IPostDeploy.Run - it would be useful to have access to the outputs of the ARM deployment in this method which would allow for access to calculated properties like the id of newly-created resources.

TheRSP avatar Dec 22 '21 10:12 TheRSP

To make this a non-breaking change, a new interface IAdvancedBuilder could be introduced which would take the new context object. In this situation, an instance of IBuilder could easily be converted to an IAdvancedBuilder:

type IBuilder with
  member this.ToAdvancedBuilder() =
    { new IAdvancedBuilder with
        member _.BuildResources context = this.BuildResources context.Location }

TheRSP avatar Dec 22 '21 10:12 TheRSP

@ninjarobot @isaacabraham What do you think about this idea? Benefits:

  • We can get rid of the ARM expressions used to name resourceGroups in webApp hostnameBindings/certificates
  • We can give better naming for nested deployments (currently, if using Farmer heavily, investigating failed deployments can be hard because the deployment names are reused too frequently)

TheRSP avatar Jan 27 '22 10:01 TheRSP

@isaacabraham @ninjarobot Any comments? If you're happy with the proposal I can work on a PR to implement this but I don't want to start unless you agree with the concept.

TheRSP avatar Mar 03 '22 15:03 TheRSP