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 parameters files natively in bicep #399

Closed
alex-frankel opened this issue Aug 31, 2020 · 22 comments
Closed

support parameters files natively in bicep #399

alex-frankel opened this issue Aug 31, 2020 · 22 comments
Labels
enhancement New feature or request story: bicep parameters syntax Related to language syntax

Comments

@alex-frankel
Copy link
Collaborator

Parameters should be able to be specified natively in bicep. Not sure if this should be .bicep file extension or a dedicated extension for parameters (i.e. .bicepparam but not that long). Should aim to reduce verbosity in parameters files. Could look something like:

namePrefix = 'contoso'
location = 'eastus'
someObjectParam = {
  prop: 'value'
}
...
@alex-frankel alex-frankel added the enhancement New feature or request label Aug 31, 2020
@ghost ghost added the Needs: Triage 🔍 label Aug 31, 2020
@alex-frankel alex-frankel added the syntax Related to language syntax label Aug 31, 2020
@alex-frankel alex-frankel changed the title support parameters natively in bicep support parameters files natively in bicep Sep 3, 2020
@alex-frankel alex-frankel added this to the Committed Backlog milestone Oct 7, 2020
@slavizh
Copy link
Contributor

slavizh commented Oct 26, 2020

It would be great if you can have bicep file(s) and json parameter file and do a deployment directly using those. This way for those who have build already parameter files that are used by end users we can change our code from ARM Templates to bicep without having to ask our users to change their input. Will allow for smoother transition for us.

@benc-uk
Copy link

benc-uk commented Nov 5, 2020

Something to consider would be a plain YAML file, as it's such a prevalent format now for CI/CD tooling, and it's now things like Helm work helm install --values myparams.yaml

@MarcusFelling
Copy link
Collaborator

Support ARM param as first step #1278

@miqm
Copy link
Collaborator

miqm commented Jul 7, 2021

An idea - what if CLI (because it's more for CLI rather than bicep itself) supported params in yaml format instead json?

@alex-frankel
Copy link
Collaborator Author

Definitely something we could add, but first priorities will be #1278 and #512. After those we can explore if we need a new parameters file format.

@brwilkinson
Copy link
Collaborator

brwilkinson commented Jul 10, 2021

Came here to ask for myparam1.bicepparam file support.

This would allow for much cleaner param files, with the Bicep syntax, instead of JSON.

Also with support for multi line strings ''' syntax, this is a nice feature for storing data e.g. yaml.

I would recommend to also speak with the PowerShell team (I can ask if that is helpful?) to see if they can support the Bicep language by creating:
Import-BicepData, Export-BicepData OR likely better still ConvertFrom-Bicep, ConvertTo-Bicep

or ensure support is in: https://github.com/StefanIvemo/BicepPowerShell

That way you can programmatically take an object and convert it to a Bicep param file and this would also potentially allow for conversion from json to bicep, since PowerShell already has: ConvertFrom-Json, ConvertTo-Json.

Currently I store extra data in JSON outside of param files and inject them in as a dynamic Global parameter at deploy time, so I would read them in then convert the Bicep data file to a powershell object with 'ConvertFrom-Bicep'. That way I could move my data files to bicepparam files OR bicepdata files i.e. variables only.

@brwilkinson
Copy link
Collaborator

Also in relation to the parameter file, perhaps it could just be a (data) mydata.bicepd file.

Like a standard data format that just contains variables !? That match up with parameter names during a deployment.

I would prefer the bicep variable/object format than json or yaml. Then it can also contain those (json/yaml) types for values within when needed.

Also I think it's been discussed in the past, however would be interesting/useful to be able to run a deployment referencing multiple data files i.e. not just the current single parameter file. Then continue to support the dynamic parameters. Then they all just get merged as parameters values.

@adamdost-0
Copy link

The clean syntax and easy human readability in Bicep is amazing especially when it comes to doing educational sessions with those who aren't as familiar with just regular Infra-as-Code. If Bicep can reach parity with parameter file creation and make it in an easy human readable format it will definitely help accelerate adoption.

@anthony-c-martin
Copy link
Member

I wanted to share some of my (opinionated) thoughts on motivations to start the ball rolling on creating a bicep parameters file. I think there are a bunch of untapped things that we can improve about deployments by doing this work. I'd love to hear feedback and see if we can come up with some ideas for things we like/dislike.

Syntax shown below is just for illustration - I'm not proposing any of the naming/structure with these suggestions.

Linking to a Bicep file for better validation

In the following sample, we have actual values for parameters, enabling us to do much deeper type validation at development time. This means the difference between catching an issue when checking in code vs catching an issue when you try to deploy your code, which feels like a gap in the current experience.

  • deploy.bicepparam
    set param paramA = 'foo' // error here - mismatch in allowed value!
    set param paramB = 'hello' // error here - expected an object!
    
    deploy './main.bicep'
  • main.bicep
    @allowed([
      'bar'
    ])
    param paramA string
    param paramB object

Notes

  • It's important to introduce an explicit link between parameter file and deployment (the deploy './main.bicep' statement) to make this validation accurate. A problem that exists today with validation with the JSON-based parameters file is that accurately linking template & parameter files together for validation requires heuristics (naming conventions, folder location), so it's not always possible to get right.

Using simple language expressions

It's very common to want to link certain parameters together with ARM template expressions - currently this isn't possible and requires either repetition in the params file, or refactoring the Bicep file.

var baseName = 'prod'

set param kvName = '${baseName}-kv'
set param storageName = '${toLower(baseName)}${uniqueString(resourceGroup().id)}'

deploy './main.bicep'

Hierarchical params files

Often we have shared sets of params that we reuse across multiple files. To cut down on repetition, it would be nice to be able to share some of these parameters by combining files (e.g. the import './global.bicepparam' statement).

  • global.bicepparam
    set param globalSetting = 'foo'
  • prod.bicepparam
    import './global.bicepparam'
    
    set param prodSetting = 'bar'
    
    deploy './main.bicep'

Setting other deployment properties

Currently, az cli deployments look like this:

az deployment group create -f ./main.bicep -g my_rg -p @parameters.json

Or:

az deployment sub create -f ./main.bicep -l 'West US' -p @parameters.json

My ideal world would be an az cli command that looks like this:

az deployment create -f ./deploy.bicepparam

No location, no scope, no resource group, mode, name etc - I would love for this one file to be the source of all the instructions for the deployment. Today we have settings shared between the command itself (generally, hardcoded somewhere in the build/validate CD pipeline), and parameters.json. It would be nice to have one place to go for all this information, and reduce the ability to get things wrong with formatting mistakes.

set param myParam = 'foo'

deploy './main.bicep' {
  location: 'West US'
  mode: 'Incremental'
  name: 'deploy-prod'
  group: 'myRg'
}

Other potentials

Globals/defaults?

This is more of a half-baked thought, and I'm not totally sure I'm on board. We have discussed setting/reading globals to avoid the amount of parameter passing:

  • prod.bicepparam
    set global location = resourceGroup().location
    set global tags = {
      foo: 'bar'
    }
    
    deploy './main.bicep'
  • deeply/nested/file.bicep
    resource myResource '...' = {
      name: 'foo'
      location: globals.location
      tags: globals.tags
    }

Notes

  • I don't love this, because it makes it harder for us to do validation when editing deeply/nested/file.bicep (as there's no link to the parameters file setting the global), but I know it's a requested feature, and at least being able to compile the parameters file would allow us to catch issues at development time.

@slavizh
Copy link
Contributor

slavizh commented Oct 6, 2021

Some things to be considered:

  • Az PowerShell still have the notion of subscription context so probably Az PowerShell commands for deployment needs to ignore this context and being able to deploy based on param file content.
  • Should/Could Azure portal supports this parameter file format when you deploy ARM or Bicep deployment trough Portal?
  • Ability to convert from ARM parameters file to Bicep parameter file and vice versa?
  • What if you have one bicep solution that deploys at subscription level. Can you have one parameter file that deploys the solution to multiple subscriptions - similar to doing for in bicep? Same applies if you are doing management group or resource group level deployment of a solution.
  • what if you have some complex input parameter like array that contains objects which can contain mandatory or non-mandatory properties that could be strings, integers, more objects and arrays. Could you define also such kind of schema either as separate file or within the bicep deployment file so the bicep parameter file can verify against that schema?

@miqm
Copy link
Collaborator

miqm commented Oct 8, 2021

What about secure objects? Currently I pass them in command line. Will this be possible?

I also use multiple parameter files or even single parameters set from cmd to override some values when I do test deploys.

Also,do we need a separate syntax to define params? Can't we just use yaml to define paramters? I'd be nice if this would work with current json files.

Perhaps in the bicep param (or bicepproj or bcpdeploy?) file we could just specify 'entry point' and parameter file combinations for validation and UX.

@smokedlinq
Copy link

Would be nice to be able to reference an environment variable. In my workflows and pipelines I often use those to store parameters.

@majastrz
Copy link
Member

I really like the concept of capturing all the information needed to execute a deployment in a repeatable fashion!

Some questions

  • Could you have multiple deploy directives in the param file?
  • Unlike bicep files, the param file appears to be "executed" in order of directives in the file. I think that makes sense since invoking a deployment needs to be imperative. However, we need to make sure our justification to create a new imperative language is sufficient. One huge value add here is the deep integration with the Bicep type checking and validation, but is it enough?
  • I didn't see scope being set in the param file? Did I miss it?

Implementation comments:

  • The bicepparam file should have its own parser and semantic model. The language server support should be at parity with bicep file. Go to def, find refs, highlights, outline, rename symbol, etc. should all work as expected.

@asbjorn-wiik
Copy link

Hi all

So, while we wait for bicep to naitively support creating parameter files.
I've created this this wrapper that uses bicep to build the parameter file and then the script grabs the output and massage it in to a json parameter file :)
You can run your main.bicep file through it an get a json parameter file out, or you can write your parameter file as bicep and the script generates the json parameter file from that.

Hope you find it usefull

Kind regards,
Asbjørn Wiik

Create-JsonParameterFileFromBicepParameterFile.ps1

@uky2019
Copy link

uky2019 commented Nov 4, 2021

It would be really great if bicep files could have parameter file in bicep language syntax as I really miss the commenting and readability with using *.json parameter file, if you have 100 parameters in one file you get lost quickly.

@brwilkinson
Copy link
Collaborator

Adding a comment here in relation to having the ability to use Bicep format "data" files for input via loadtextcontent()

Requested via discussion: #5546

@rgerteis
Copy link

Had a similar request under #5546 and agreed with @brwilkinson to continue here as my ask was pretty much the same as the one here.

upvote on this one.

@jrobins-tfa
Copy link

Following the recent Bicep community call, I'm sharing a use case here for parameters per the request of the call leader. What I would like to be able to do is have string interpolation in parameter values. For example, in my Bicep template for an app gateway, there are a lot of elements that cross-reference each other. A backendHttpSetting has a value for a probe, which references another property of the gateway. This means that to get the resourceId for that probe, I need to call the resourceId function. I can do that in my template, but to do so, I have to explicitly spell out the entire section for the backendHttpSetting:

backendHttpSettingsCollection: [for backendHttpSetting in backendHttpSettingsCollectionParam : {
   name: backendHttpSetting.name
     ...
     probe: (contains(backendHttpSetting.properties, 'probe')) ? {
       id: '${resourceId('Microsoft.Network/applicationGateways',appGatewayName)}/probes/${backendHttpSetting.properties.probe.name}'
     } : null

If I could call the resourceId function in my parameter, or even reference the appGateway resource id to build the rest of the reference, that would mean I could just have the needed values in my parameter file, and this section of my gateway template would simplify to

backendHttpSettingsCollection: backendHttpSettingsCollectionParam

There are several other use cases I've come across, and this seems like a valuable thing to be able to do.

@nnellanspdl
Copy link

The Bicep PowerShell Module has a cmdlet called "New-BicepParameterFile". You pass a Bicep file to the cmdlet and it generates a standard ARM JSON parameters file based on the parameters that are defined in your Bicep file. Therefore, you can simply pass it a Bicep file that has nothing but "param" statements and it will generate a valid JSON parametes file for you.

@jongio
Copy link
Member

jongio commented Jun 16, 2022

Not a show stopper, as I have a workaround...but...

I would like to see this support env var replacements by default.

I'm doing this today:

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "name": {
      "value": "${AZURE_ENV_NAME}"
    },
    "location": {
      "value": "${AZURE_LOCATION}"
    },
    "imageName": {
      "value": "${SERVICE_API_IMAGE_NAME}"
    }
  }
}

Then at deploy time, doing my own replacement to a temp file, then passing that file to deployment command.

Ideally, bicepparam

set imageName string = ${SERVICE_API_IMAGE_NAME}

Would auto replace the values from current environment.

@StephenWeatherford
Copy link
Contributor

@Usman0111 Can this be closed?

@rgerteis
Copy link

@Usman0111 Can this be closed?

I’d vote yes

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request story: bicep parameters syntax Related to language syntax
Projects
None yet
Development

No branches or pull requests