Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support type aware names across Variables Outputs Parameters Resources #1389

Closed
kilasuit opened this issue Jan 26, 2021 · 3 comments
Closed
Labels
question Further information is requested

Comments

@kilasuit
Copy link

kilasuit commented Jan 26, 2021

Is your feature request related to a problem? Please describe.
One of the issues right now that is an issue that you cannot have a variable, outputs, parameter, resources to have the same name

Describe the solution you'd like
Ideally in bicep we should allow the following

param common string

var common = param.common

resource common 'Microsoft.Resources/resourceGroups@2019-05-01' = {
  name: var.common
  location: location
}

output commonResource string = resource.common.name
output commonVariable string = var.common.name
output commonParameter string = param.common.name

this should build a working arm template something like the below (though ideally would negate the need for the type prefix)

{
    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "param_common": {
            "type": "string",
            "metadata": {
                "description": "Resource Group Name"
            }
        }
    },
    "variables": {
        "var_common": "[parameters('param_common')]""
    },
    "resources": [
        {
            "name": "resource_common",
            "type": "Microsoft.Resources/resourceGroups",
            "apiVersion": "2019-10-01",
            "location": "eastus",
            "dependsOn": [
            ],
            "tags": {
            }
        }
    ],
    "outputs": {
        "CommonResource": {
            "type": "string",
            "value": "[reference('resource_common').outputs.name]"
        },
        "CommonVariable": {
            "type": "string",
            "value": "[variables('var_common')]"
        },
        "CommonParameter": {
            "type": "string",
            "value": "[parameters('param_common')]"
        }
    }
}

or better yet just the below

{
    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "common": {
            "type": "string",
            "metadata": {
                "description": "Resource Group Name"
            }
        }
    },
    "variables": {
        "common": "[parameters('common')]"
    },
    "resources": [
        {
            "name": "[variables('common')]",
            "type": "Microsoft.Resources/resourceGroups",
            "apiVersion": "2019-10-01",
            "location": "eastus",
            "dependsOn": [
            ],
            "tags": {
            }
        }
    ],
    "outputs": {
        "CommonResource": {
            "type": "string",
            "value": "[reference(variables('common')).outputs.name]"
        },
        "CommonVariable": {
            "type": "string",
            "value": "[variables('common')]"
        },
        "CommonParameter": {
            "type": "string",
            "value": "[parameters('common')]"
        }
    }
}

This would help in flexibility in more advanced needs and should be an opt-in type experience for those that wish to use it (i.e. bicep conversion should automagically handle this for you whether or not you choose to use var.common/param.common/resource.common)

As a side issue it would be great if in ARM you could also similarly replace code like this "[reference('resource_common').outputs.name]" which works without needing to fully provide a resource type (by smart implicit referencing) with "[resource('common').name]"

@kilasuit kilasuit added the enhancement New feature or request label Jan 26, 2021
@ghost ghost added the Needs: Triage 🔍 label Jan 26, 2021
@alex-frankel
Copy link
Collaborator

We made a conscious decision not to allow this - reason being is you tradeoff terseness/readability to allow for this flexibility. Meaning you end up seeing param.*, var.* everywhere, which we'd like to avoid. We recognize this is less flexible than what is currently possible in ARM, but we think this tradeoff is worth it.

Can you provide some examples where this is causing issues for you today? It's possible there are cases that we haven't considered (like with outputs, which has led to some planned changes)

@alex-frankel alex-frankel added question Further information is requested and removed Needs: Triage 🔍 enhancement New feature or request labels Jan 27, 2021
@alex-frankel
Copy link
Collaborator

Closing for now, but feel free to re-open if there are scenarios for this that you'd like to share

@kilasuit
Copy link
Author

Sorry for the delay, I've come back to this 3 times and some machine reboots in between had lost my comments.

I don't disagree that if it was enforced as a default part of the language you could easily make it less readable to some using the language & would most likely add some additional developer friction of this is too ARM-like but I'm not asking for it to be a mandatory part of the language, but I very much do think that it should be available as an optional part of the language. By doing so you'd allow the author the flexibility to decide either to use it or not, & either way it already kind of ends up in the ARM that bicep build spits out the otherside so would for some aid in the transition to bicep from ARM & vice versa.

However for the flipside it can make it more easily readable for a number of your intended audience, because seeing param.myparam, var.myvar allows you to understand exactly what context you are reading at that exact moment, especially in larger templates & would also allow you to make use of same named variables and parameters if you chose to do so. I use them on occasions where I need to get state across differing boundaries and return an updated object that I've passed through as part of another lower level template deployment a number of times.

If you were to add this to the language with additional editor tooling to easily switch on / off the use of param.myparam, var.myvar etc everywhere, whilst making sure that bicep build doesn't really care if they are used or not, whilst also adding a parameter to bicep decompile for it to spit out bicep from ARM with/without I believe will help aid in making bicep a more accessible & accepted language overall, especially as we should be expecting a much wider set of users of bicep in the years to come, than perhaps there was with ARM.

I personally find that when speed reading an ARM template that I understand it much quicker because of some of its verboseness especially for [paramaters('myparam')], [variables('myvar')] as I can very quickly know where to go and look (and can even have it side by side in my editor) and that this was greatly improved yet again when the editor tooling in vscode also shipped language syntax aware colourisation, which I am sure will come in later stages of support of bicep editor tooling too.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants