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 string interpolation in resource type string #413

Closed
slavizh opened this issue Sep 1, 2020 · 20 comments
Closed

Support string interpolation in resource type string #413

slavizh opened this issue Sep 1, 2020 · 20 comments
Labels
enhancement New feature or request

Comments

@slavizh
Copy link
Contributor

slavizh commented Sep 1, 2020

Is your feature request related to a problem? Please describe.
Allow defining RP API version as variable

When I try to do something like this:

var storageApiVersion ='2019-06-01'

resource stg 'Microsoft.Storage/storageAccounts@${storageApiVersion}' = {
  name: storageAccountName
  location: location
  kind: 'Storage'
  sku: {
    name: globalRedundancy ? 'Standard_GRS' : 'Standard_LRS' // if true --> GRS, else --> LRS
  }
}

It is not possible. I would like to define the API version for RP as variable. This is a common practice for us to define the API versions as variables for different resources. For example if we have two or more resources for storage accounts define we can easily switch the API version for them by just changing the variable. This also allows us to easily see the different API versions we use in a single template without having to scroll trough all resources.

@slavizh slavizh added the enhancement New feature or request label Sep 1, 2020
@ghost ghost added the Needs: Triage 🔍 label Sep 1, 2020
@alex-frankel
Copy link
Collaborator

@anthony-c-martin can we take care of this as part of #267?

@majastrz
Copy link
Member

majastrz commented Sep 1, 2020

@alex-frankel No, we need to implement constant folding for that.

@kuhlman-labs
Copy link

Is there any way to implement a :latest tag for the ApiVersion? Having to manage and track what version of an API each resource in a deployment is using can be a pain and I often see customers neglect that once they have live code.

@alex-frankel alex-frankel changed the title Allow defining RP API version as variable Support string interpolation in resource type string Sep 3, 2020
@alex-frankel
Copy link
Collaborator

@kuhlman-labs - latest is a dangerous version because you are leaving it to us to choose new versions for you when we don't know the impact of the change. It means a bicep file can start failing even if there were no code changes. If a customer were to decide never to touch an old apiVersion, they're code should never break as ARM APIs should never ship breaking changes to existing apiVersions. So even though the apiVersion is a bit confusing/verbose, it ultimately ends up with templates that are more stable for longer.

With modules, module authors will be able to choose an apiVersion and the end user of the module only will have to pick a version of a particular module (which will likely be semantically versioned instead of using a date string). That might help alleviate some of this pain.

We also are tracking issue #16 which would allow you to provide an apiVersion "mapping" file of some kind.

@slavizh
Copy link
Contributor Author

slavizh commented Sep 4, 2020

To add additional information. Certainly there are RPs where when version is changed there is not actual breaking change but there are a lot of RPs where for example new properties are added, default value for property is changed from one to another. Some like kubernetes have drastic changes which will result in failed deployment. These are some of the reasons why it is dangerous.

@kuhlman-labs
Copy link

@alex-frankel @slavizh Thank you for the responses. From my perspective, I would advocate for giving the ability to find breaking changes the the RP API to users as easily as possible for a few reasons. If you're running IaC in separate environments ideally you would want to find any breaking changes as early as possible in your dev environment by always running the latest APIs and then pinning API versions to higher level environments to ensure stability. I also think that finding breaking changes can signal to a user that there may be new features for a RP that they may otherwise never become aware of.

@arsenvlad
Copy link

Regarding apiVersions as variables: Just wanted to point out that the Best Practices document for ARM templates has a line that says "Variables must not be used for apiVersions. The apiVersion affects the shape of the resource and often cannot be updated without updating all the resources that use a particular version."

In addition, arm-ttk validation looks for apiVersions as explicit recent dates (and this is required for ARM templates that are used in Azure Marketplace publishing).

cc @bmoore-msft

@slavizh
Copy link
Contributor Author

slavizh commented Sep 8, 2020

@arsenvlad I would not consider many of those there best practices. These are more of quick start templates best practices because otherwise our bot will not be able to verify the templates properly.

@kuhlman-labs not sure how you build your solutions but when we build them we put specific version and release them as packages. If we have 'latest' and we publish those with latest as soon as new version is released that is breaking the solution will stop working for those or make unexpected changes. When you run something in dev for sure you would want to know also what is the latest version as there is no notification channel or something when versions are released for RPs, nor there is change log. It is always to test these on your own if they are not documented or if they are documented check the version and compare it to previous one.

@bmoore-msft
Copy link
Contributor

I do think we need a better way to manage apiVersions throughout a template but I don’t think string interpolation in the definition is the right way to go about it.

That string is your contract and the ability to reason over and manage that part of the declaration is pretty important, for humans and tooling. It will also lead to things like the implementation of “latest” and while I understand the initial reaction to dealing with apiVersions, no one is served over the long run by making an anti-pattern easy to implement.

I’m pretty sure all of us have been through a breaking change due to some version upgrade (not related to arm templates) that we weren’t expecting. Debugging this is rarely simple and never seems to happen at a convenient time ;))

With bicep we have a clean slate (more or less) to go think about a better way to deal with apiVersions, we should exhaust that first.

@arsenvlad @slavizh – re: the TTK - regardless of whether we agree on best practices, we should at least try to make sure the tool chain doesn’t contradict itself.

@slavizh
Copy link
Contributor Author

slavizh commented Sep 10, 2020

Would it be better if we have some special syntax for versions?
Like

using Microsoft.Compute/virtualMachines@2020-05-01
using Microsoft.Compute/virtualMachines/extensions@2019-07-01
using Microsoft.Storage/storageAccounts@2019-08-01

The downside will be that you need to define those. Additional code you need to enter. On the plus side you do not have to define those on resources. If you define them in resources it will override the one specified via using. On the plus side this can make the usage of versions easier for best practice implementation.

Any thoughts?

@alex-frankel
Copy link
Collaborator

What were you thinking the resource declaration would look like if I do the using statements? Feels like you need an alias of some kind:

using Microsoft.Compute/virtualMachines@2020-05-01 as vm

resource myVm vm = { ... }

@majastrz
Copy link
Member

@alex-frankel If we went down this path, we could have rules for choosing the default alias as well. For example, the default alias could be subnets on using Microsoft.Network/virtualNetworks/subnets@2019-06-01 unless another using has the subnets alias. In those cases, the as part would be mandatory.

@slavizh
Copy link
Contributor Author

slavizh commented Sep 11, 2020

Not bad idea for the 'as' option. This could also fulfill some requirements around aliases for RPs. I am not big fan of that idea but if folks want that we can shoot two birds with one stone. The 'as' part could allow you to use two different versions for the same RP although I have met such scenario only for one RP. The security one which in one RP version allows you to set resource with name default in other it does not.

@smokedlinq
Copy link

I love the idea of using ... as ... to shorten the resource definitions. What about using the as alias to reference a sub-resource type, e.g.

using Microsoft.Network/virtualNetwork@2019-06-01' 

resource network virtualNetwork = {
...
}

resource subnet virtualNetwork/subnet = {
...
}

If the sub-resource type needed a different version number take it from the resource definition, otherwise default to the version of the alias.

resource subnet virtualNetwork/subnet@2020-05-01 = {
...
}

@WhitWaldo
Copy link

I'd like to jump in here since I filed a duplicate of this and share my thoughts. I really like the idea of using ... as ... to both shorten the definitions, to eliminate typos in all these strings and generally shorten what I have to type to produce the desired effect.

To the point earlier that having a @latest or string interpolation might have undesired effects, I get that concern, but the current approach of just repeating these blocks of strings (especially several times even after loops are introduced) just isn't ideal, especially as I have to continue to maintain these scripts.

@bmoore-msft
Copy link
Contributor

@WhitWaldo - if you have the using ... as ... construct, doesn't the problem you describe re: @latest go away? I.e. you've defined it in one place?

@WhitWaldo
Copy link

WhitWaldo commented Oct 23, 2020

@bmoore-msft Exactly - I'm sorry, my response earlier wasn't as clear as I intended. Someone earlier had mentioned the use of @latest, but I prefer the use of using ... as ... more.

Using/as lets me put the number in a single place and says that if I need to use an older version for some particular resource, I'm easily able to. It's better than simply inserting the version in via string interpolation because it puts the entire string in a single place (resource + version). If I as the developer change it there, I can conceivably just use the IDE to find all the places I've used that variable and take responsibility for updating accordingly.

@bmoore-msft
Copy link
Contributor

Got it - thanks for clarifying...

(turns out that "latest" is actually a github username... sorry about all the "@ latest" in this thread)

@yks0000
Copy link

yks0000 commented Jun 21, 2022

Seems like stale issue. Commenting to know if there is an update on this i.e, how to have string interpolation in resource type string for defining apiVersion as variable. Checked #622, but no update there as well.

@alex-frankel
Copy link
Collaborator

I'd say the latest on this is still #622 for "aliasing" type strings, but #6641 is also relevant. I'm going to close this in favor of continuing to track w/ #622.

@ghost ghost locked as resolved and limited conversation to collaborators May 29, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

9 participants