Closed sydkar closed 1 year ago
This was mentioned on the comments in the community call, but just adding my two cents here.
The file name extension for the params file, in my opinion, should remain as .bicep.
Logic should be introduced to a .bicep file to reverse the param file logic of "using", for example "usedby" or similar.
Thus tying the two files together.
I know there was mention of introducing inherited or root structure param files, I presume the approach here would be parent and child, again the same logic of tying files together could be used.
My main point I guess is, I don't see the value in introducing a new file name extension as well as having to specify the file within the code itself.
A parameter file is a great idea. Thank you for working on it. I am just throwing out my two thoughts about it.
The parameters file is not a good location for using './main.bicep'
.
az deployment group create -g ExampleGroup --template-file main.bicep --parameters @dev.bicepparams
The word param
at the beginning of each parameter in the parameters file is unnecessary as everything in the parameters file will be the value of a parameter
paramString = 'foo'
paramNum = 1
paramObject = {
name: 'VNet1'
location: 'EastUS'
}
@wedoazure
We need to introduce a new extension for the parameter files so the language server knows how to validate the files. For example, when defining parameters in Bicep files, the syntax param paramName type
is used, but in parameter files, when you set the parameter value, you use param paramName = value
. Without a separate extension, we would be unable to determine which was valid for the context.
The direction of linking the files (pointing the parameters at the Bicep template) was something we discussed thoroughly, and we came to this decision because through our interviews, we recognized that it was more common to have multiple parameter files used for one Bicep file. In the future, with inherited parameter files, we hope to make parameters more reusable.
@musaugurlu
param
keyword because we intend to introduce variables in the future with the var
keyword, similar to those in Bicep files, and to keep the language consistent, we decided to keep the directive.@sydkar
I am unaware of how other tools deploy bicep templates, but using using
statement makes sense if there is any intention to deploy with parameters file only. Thank you for explaining it.
But I am curious about the use cases to pass variable values from the parameters file. If you pass values to both parameters and variables from the same file(or from outside of the template), what is the difference between parameters and variables? Other tools such as Terraform and Ansible pass variables from the command line or file because they don’t have parameters.
@musaugurlu The intent with variables is not to pass them between the Bicep template file and the parameters, it was meant to be used only in the parameter files to enable expressions and functions.
I agree with @musaugurlu regarding the exclusion of param
from each entry. This feels unnecessary as all entries should be parameter key-value pairs.
As a user of both Bicep and Terraform (and seeing the similarities between the two), it would make sense to keep the param file as simple as possible, similar to the Terraform tfvars
files.
As such, whilst I understand the thinking behind supporting vars and functions within the param file, I think this type of logic (beyond loading values from other file sources) should occur in the deployment template instead.
However, I can see the benefit of linking a param file to the associated bicep template with the using 'path/filename.bicep'
syntax. Terraform does this by virtue of the way modules are constructed. i.e. all files within a folder are evaluated as a single "deployment". As bicep works at the individual file level, having this (optional) reference makes it easier to have the bicep compiler and extensions work with minimal user input.
Thinking about file naming, rather than using a specific file name, it might work well to use .bicep
and then allow a bicep deployment to utilise the presence of the using 'path/filename.bicep'
entry to enable deployment using the parameter file only. i.e. bicep will automatically load the bicep template when a valid parameter file is selected for deployment.
Thinking about other use cases for the using 'path/filename.bicep'
syntax. It might also be useful to allow multiple param files to be chained together. This would be really useful for multi-environment deployment scenarios as it would allow a developer to specify a parameter file per environment containing values for that specific environment only, which points to a generic parameter file containing "safe defaults" for parameters, which then points to the deployment template.
Thinking about this in the context of a GitOps process, this would allow CODEOWNERS to be used to control who can make changes to parameters for each environment, and for the "safe defaults". If you can provide a way to flag a variable in the "safe defaults" as mandatory, you could then alter the merge behaviour to stop an environment owner overriding a safe default. The only difficulty I can see with this is how to enforce the correct order of dependencies.
For the proposed feature "I can use a VS Code action to generate a Bicep parameter file based off a Bicep template" it would be useful to automatically add all parameters with default values where present. If no default is specified, the type should be specified so the developer knows what is expected.
Great to see this on the backlog though, and thank you for continuing to make these great additions to bicep!
@krowlandson While we want to keep the parameter files as simple to author as possible, we want to enable users to use variables with the intent that it will help with string replacement in parameter values.
We have also looked into the extension and came to the conclusion that having a separate extension would be better as it would create a clear distinction for the language server to provide syntax validation. We are planning to eventually be able to automatically load the bicep template when the parameter file is deployed, as you described.
Your suggestion on chaining multiple parameter files together is something we are looking into and hoping to implement sometime in the future. We understand the want to be able to link multiple params files for a deployment and think it is an important capability to have.
Finally, to your point on the generated parameter file, I like your suggestions, and they align with the current behavior of ARM parameter generation, so we will be sure to keep these in mind!
Super excited to see this being worked on. Currently, parameters make my bicep files look TERRIBLE, taking up dozens up dozens of lines at the top of my files. Great start here! Do I understand this correct that I will be able to convert my bicep file to having a seperate file for my parameters? See here for the before https://github.com/Azure/azure-quickstart-templates/blob/master/application-workloads/azure-gamedev/gamedev-vm/main.bicep
After
using main.parameters.bicep
module gamedevvm './nestedtemplates/gamedev-vm.bicep' = {
name: 'gamingDevVM'
params: {
location: location
vmSize: vmSize
adminName: administratorLogin
adminPass: passwordAdministratorLogin
osType: osType
gameEngine: gameEngine
remoteAccessTechnology: remoteAccessTechnology
_artifactsLocation: _artifactsLocation
_artifactsLocationSasToken: _artifactsLocationSasToken
}
}
@description('Deployment Location')
param location string = resourceGroup().location
@description('The base URI where artifacts required by this template are located including a trailing \'/\'')
param _artifactsLocation string = deployment().properties.templateLink.uri
@description('The sasToken required to access _artifactsLocation.')
@secure()
param _artifactsLocationSasToken string = ''
@description('Select Game Engine Version')
@allowed([
'ue_4_27_2'
'ue_5_0_1'
])
param gameEngine string = 'ue_4_27_2'
@description('Select Operating System')
@allowed([
'win10'
'ws2019'
])
param osType string = 'win10'
@description('Select Virtual Machine Skew')
@allowed([
'Standard_NC4as_T4_v3'
'Standard_NC8as_T4_v3'
'Standard_NC16as_T4_v3'
'Standard_NC64as_T4_v3'
'Standard_NV6'
'Standard_NV12'
'Standard_NV24'
'Standard_NV12s_v3'
'Standard_NV24s_v3'
'Standard_NV48s_v3'
])
param vmSize string = 'Standard_NV12s_v3'
@description('Administrator Login for access')
param administratorLogin string
@description('Administrator Password for access')
@secure()
param passwordAdministratorLogin string
@description('Remote Access technology')
@allowed([
'RDP'
'Teradici'
'Parsec'
])
param remoteAccessTechnology string = 'RDP'
But... even given the new option for a parameters file, I still find the syntex for parameters to be extremely bloated, because of all the annotations that are allowed. Even if each annotation collapses to a single line, the rate of lines per parameters is still always greater then 1:1. (meaning if I add one parameter, it adds at least 3 lines to my file if I include description and new line)
The bicep formatter already collapses code after the "=". I would be nice to leverage this syntex for parameters too. Particularly with some hopes in the future where parameter types can be more advanced.
(the collapse would be even more perfect, if instead of '...' we showed the preview of the text on the single line, as well as collapse that extra '}' in with the rest, but was going to make that its own request)
I also do not think it is likely that this issue will be solved as first requested, but improving how parameters are defined could resolve it. #4184
[Idea]
Don't generate parameter in parameter files if default value is function like,
param par_instance_number string = substring((uniqueString(subscription().id)),0,2)
param par_base_name string = substring((subscription().subscriptionId),0,4)
[Idea]
Don't generate parameter in parameter files if default value is function like,
param par_instance_number string = substring((uniqueString(subscription().id)),0,2) param par_base_name string = substring((subscription().subscriptionId),0,4)
Or create them commented out to simplify use if someone wants to override?
Super excited to see this being worked on. Currently, parameters make my bicep files look TERRIBLE, taking up dozens up dozens of lines at the top of my files. Great start here! Do I understand this correct that I will be able to convert my bicep file to having a seperate file for my parameters?
I'm not sure whether this was the true intent of the parameters file option in Bicep, but it raises an interesting point around another value add we could get from Bicep.
Terraform (sorry, not sorry) uses the concept of a "root module" whereby all files within the root module directory are evaluated as a whole when determining what to deploy. This allows developers to break apart code into multiple files. A common pattern is to have a file per resource type, or a file for specific groups of variables, etc. This makes the code easier to maintain for large deployments.
Taking the idea from @dciborow, it would be awesome if Bicep would allow the compilation of a deployment from multiple files. This could enable re-use of code without having to formally make it a "module".
Why might you want to do this? Each Bicep module translates to an ARM "deployment". Each ARM deployment can take a while to start, resulting in unnecessary provisioning delays (especially when no changes are needed). But more importantly, delays in replication across the platform (eventual consistency) can also make it problematic when deploying dependent resources across multiple deployments. This can result in failed deployments despite using a "valid" template, resulting in a poor user experience.
Similar to my idea above of allowing "parameter chaining", making use of the using
concept could also allow a primary Bicep template to reference other Bicep templates to include as part of the final ARM template and allow resources "sourced from modules" to be included within a single ARM deployment.
Modules can then be used for more specific scenarios like when a change of deployment scope is needed, or for parallel deployment of batches of the same group of resources, etc.
@krowlandson -- I think the scenario you are describing is covered in #363. Can you confirm?
@mimachniak -- we cannot allow non-deterministic functions in the parameters file because we need to be able to generate a JSON parameters file with only hardcoded, static values. Also, FWIW, can't parameters like this be a variable in the template itself? Do you want the parameter to always be that value or would that depend on who is deploying the bicep file?
@krowlandson Kevin Rowlandson FTE -- I think the scenario you are describing is covered in #363. Can you confirm?
Certainly seems so @alex-frankel...
I think the only difference would be that #363 implies that Bicep evaluates "all files in the specified directory" (which is aligned to the Terraform approach) whilst I was suggesting that using
could explicitly pull multiple Bicep files into a single deployment template, offering greater flexibility and control over which files to combine (and from where).
Both seem valid scenarios.
Here are the features we're proposing for the first official release (combination of the "Summer" & "MVP" section - with some MVP pieces cut out). Most of the "Summer" work has already been completed, which is why it's not included here.
Is bicepparams available for testing with a feature flag in bicepconfig.json?
@stephaniezyen / @Usman0111 -- do we have an easy way to test this out yet? I know at one point it required building the extension from source, but not sure if that is still the case.
@akata72 we will enable the vs code extension to provide intellisense for .bicepparam
files in v0.16 release so you should be able to use them with a feature flag set in bicepconfig.json see instructions
< edit > I found this on the TODO list ✅ </ edit >
Any plan for: convert json param file to bicepparam file?
A decompile for json param.
Thank you for all the effort. You are doing a really great job making Bicep truly awesome! I'm using bicep since its very first announcement and it's only been getting better and better.
Creating parameter files in bicep format is certainly an interesting feature which will make the whole bicep approach more consistent. And speaking of consistency, as commented in the past community call:
<template-name>.json <-> <template-name>.parameters.json
<template-name>.bicep <-> <template-name>.parameters.bicep
I would appreciate if someone could elaborate what the rationale is behind the choice for an additional file extension.
As ARM does not (yet?) natively use bicep, it should be possible to both build and decompile Bicep parameter files the same way as it is for the templates (bicep build <template-name>.parameters.bicep
/ bicep decompile <template-name>.parameters.json
)
Being able to pass secrets is (as far as I can read above) already implemented. It could be a nice addition to be able to use some built-in functions like randomizers / environment() ...
Thank you again and keep the good work!
I would appreciate if someone could elaborate what the rationale is behind the choice for an additional file extension.
Value replacement is really hard with valid json. Example:
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"intValueParam": {
"value": ${env:something}
},
"otherIntValueParam": {
"value": ${referenceToSomeOtherParameterPassedByCLI}
}
}
}
I think this is the most obvious example. Some of the replacement can be done with current tolling using ReplaceTokens task but writing JSON-based parameter file is PITA because authoring tooling complains when supplied values does not match with paramter types and the JSON is not valid.
@JorgeDios -- to put it simply, the rules are different for what is valid bicepparam
syntax vs what is valid bicep
syntax. For ARM templates, while the template and parameter files both used the .json
file extension, they were distinguished by the $schema
property being specific to each case. Using a different file extension essentially serves the same purpose without having to clutter the actual file contents.
For those that would prefer everything be a .bicep
file extension, can you help us understand what the benefit is? Everything being JSON was helpful in that there are many JSON parsing libraries, but there are no .bicep
or .bicepparam
parsing libraries other than what we ship with the language service, so it is not obvious to me what the benefit is.
I would like to see a tooling to extract parameter values from bicepparams at some point. Use case:
@alex-frankel -- Thank you for the clear and concise clarification. I totally understand now why it has been chosen to use a new file extension.
To me, it was a matter of uniformity. The whole purpose of a file extension is to indicate the file format so the parser / system knows how to process it. I was therefore assuming that the bicep format would be enriched to identify what was being declared as parameter input.
However, if I understand you correctly, a different approach is implemented: a bicepparam
will be using a similar but different syntax that the one used by bicep
(templates). Using a different extension will indicate the system / parser which set of rules to apply to interpret it.
A matter of taste / style, I guess. Or may be a way to reduce complexity of the overall bicep implementation... Anyhow, it is clear to me now, and based on the bicep's team track record, this will be probably the right thing to do.
Does it make sense to include the ability to include the description
in the bicepparam
file?
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"Prefix": {
"value": "AEU1",
"metadata": {
"description": "region prefix e.g. acu1 or aeu1"
}
}
}
}
@description('region prefix e.g. acu1 or aeu1')
param prefix = 'AEU1'
I like what I am reading here, but admittedly still consider myself a neophyte with Bicep. We do use objects as parameters, will this be covered with .bicepparam?
Does it make sense to include the ability to include the
description
in thebicepparam
file?{ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", "contentVersion": "1.0.0.0", "parameters": { "Prefix": { "value": "AEU1", "metadata": { "description": "region prefix e.g. acu1 or aeu1" } } } }
@description('region prefix e.g. acu1 or aeu1') param prefix = 'AEU1'
I had indeed the same question. We provide our ops teams with several parameter input files which are used in combination with parent modules calling child modules for resource deployment.
It would be very helpful to have the possibility to add descriptions to the parameter files because it will save the ops teams a lot of time. They don't need to go to check either the readme.md of the parent module or the parameter description in the parent module.
The parameter files now are quite hard to read because they consist of quite large sets of parameters. It's not always clear from the parameter name alone what the parameter is about. The ppl filling out the parameter files are usually also not into the details of the workings of the parent modules etc.
Not sure if this has already been considered but what would be really great is to reference secrets via key vault (similar to Azure Container Apps secrets references pointing to a secret URI in a key vault) and they get pulled out automatically during deployment. Arguably that would require ARM support but that would be the ultimate feature to avoid sprinkling secrets all over the place during deployments and having to take care to not accidentally leak them via logging, temp file artifacts or command line parameter snooping via ps
Key vault references is already supported by ARM/ JSON paramter files: https://learn.microsoft.com/en-us/azure/azure-resource-manager/templates/template-tutorial-use-key-vault and by Bicep: https://learn.microsoft.com/en-us/azure/azure-resource-manager/bicep/bicep-functions-resource#getsecret
There is a ticket (and PR) to provide getSecret()
in .bicepparams context: https://github.com/Azure/bicep/issues/10652
Hello, I am facing the following issue: I defined multiple parameters in the Bicep file, and one of the parameters has a validation (can be valueA or valueB). I want to pass a value for this parameter inline (calculate logic with powershell and decide what the value will be during runtime), while I have a parameter file as well (static values). If I define a parameter in the bicepparam file, and give it a blank value, and as well overwrite it inline, I get the error from the bicepparam file, that the value must be either valueA or valueB. If I leave out the parameter from the bicepparam file, validation fails because the parameter is not present. How do I go around this issue? @sydkar @jikuja
First Release: #9567
Bicep Parameter Files
Bicep Parameters has been one of our most requested features. During the summer, the Bicep team will be building a prototype of what this experience looks like, with the intention to ship the MVP described below if we get a positive reaction.
Goals
Non-Goals
Requirements
Summer
Basic Language Features
Syntax
param paramName = value
to set a parameter value from the Bicep templateusing 'path/filename.bicep'
to select which Bicep template file to point at in order to find available parameters//
or/**/
Compilation/CLI
Code Completion and Navigation
param
Example
MVP
Basic Language Features
Code Completion and Navigation
String Replacement and Expressions
${varName}
to do string replacement in parameter files${varName}
uniqueString()
andcontains()
to dynamically set a parameterresourceGroup().id
Environment Variables
Load Functions
loadFileAsBase64()
,loadTextContent()
, andloadJsonContent()
to bring in values from other filesBicep Parameter File Generation
.bicep
to Bicep parametersCompatibility with Current Tooling
Future Tasks
These features may require further investigation and we intend to spend more time to provide a detailed spec that reflects their functionality to the fullest extent. We would love to hear further feedback on these items!
Modular Parameters
import
directiveSetting Deployment Properties in Param Files
getSecret()
getSecret()
function in the parameter file to access Key Vault secretsOpen Questions
Appendix
support parameters files natively in bicep (399)