-
Notifications
You must be signed in to change notification settings - Fork 731
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
Resource symbolic name #84
Comments
The first argument of the reference function is either a resourceName or resourceIdentifier according to https://docs.microsoft.com/en-us/azure/azure-resource-manager/templates/template-functions-resource#reference. If I have a resource with symbolic name I wonder if we could leave the reference function as-is and allow expressions to directly reference properties of the symbolic name. For example let's say we have a symbolic name
|
Also wonder if we could allow similar expressions for variables and parameters in the template (assuming they're not ambiguous). |
I think the design is determined by what do we position IL for down the road. My take is customers should no longer need to compose deployment in json directly once bicep reaches parity with current template language. Customers should simply focus on understanding and using bicep while ignoring its compiled outputs. With this in mind, the proposal is to make bicep translating logic simpler while leveraging as much as possible capabilities provided by current template language. Extending the existing reference function requires less changes on template engine side. The case that you mentioned is a very good one. I think it's solvable if bicep compiler generates the json as we have control over the validation and translation logic. As for simplifying how variables and parameters are referenced, totally with you on that, but I think we should embrace symbolic names and achieve consistent syntax in bicep rather than in IL. Btw, this would be a great topic to discuss for our design meeting. |
Updated proposal to include discuss feedback. |
Looks good and made me think of more questions 🙂. We have other places in the templates that accept "resource name or identifier". One example of that is the We also have a |
Yup, I realized the same thing today when prototyping symbolic names, will list all impacted functions when i got a better idea. Another annoying thing is deployment and template engines are tied with template v1 classes, so defining v2 counterparts means duplicating a heck lot of code simply because of different function signatures, which I am trying to avoid. The approach I am playing with is to change TemplateResource[] Resources property in Template to JProperty Default from Always, and adding a ResourcesV2 side-by-side.
I am debugging in ExpressionEngine to see how to make it understand symbolic names. |
You will probably need to customize the (de)serialization logic to make that work right. By default it will expect the symbolic names in a property called |
Updated compatibility with existing template pipeline section to cover proposed change to Added section for compilation outputs to specify contracts between bicep compilation and template engine. |
|
Thanks for your comments, Anthony, See response inline:
Yes, we need to publish new schemas for the resources format change.
Yes, I can see some customers would still hand-craft their json template leveraging the enhancement even if we encourage them to focus on bicep experience. We should definitely have the enhancement well documented, and also have validation logic in template engine to reject invalid usage.
Good catch! Corrected.
Yes, the goal is to have a consistent compilation output either when reference Thinking about 4. and 9. together, I think we should make 'Full' explicit in compilation outputs:
Yes, the nested resources array will also be changed to object allowing customers to specify symbolic names.
The question was discussed in prior meetings. A few reasons that we decided to overload
It does. If used in resource properties, a corresponding template reference is created; if in template outputs, a template output reference is created. For either case, deployment engine is able to sort out the dependency and populate output values in a same way it does for template v1.
Yes, we still allow referring to external resource via
Good catch, it should be symbolicName.properties.propertyName. See response to 4. |
Discussed latest discussion on this topic in #257 cc @lwang2016 Lei - one thing I'm not seeing in this issue is updating/overloading the e.g.:
Will
or the way I would write it today, which is
|
|
I see - I think this is another one that we'd like to special case. In this case, by using the resourceId() function as it's very commonly used in templates today. What do you think? |
I see what you mean. If we do this |
yeah, actually it shouldn't have the type as an argument. It should just be a single argument which is the symbolic name:
Today, resourceId requires two arguments, so we could overload this with an option with just one argument without being ambiguous |
Deployment service implementation is complete, and is undergoing internal testing before opening up publicly. Will leave this open to track the codegen implementation in Bicep. |
Things to consider:
|
Resource Symbolic Name
This article proposes a design for adding resource symbolic names to ARM template language in json.
Challenge
Bicep language makes ARM deployment composition simpler and more intuitive as compared to current template language in json, particulary in defining and referencing resource loops.
DSL compiler translates bicep files into an intermediate language in json that ARM template engine needs to understand as well in order to prepare for resource deployment. However this translation runs into challenges caused by template language's limited capability in referencing entities in resource arrays.
For example, a bicep file that creates multiple storage accounts and outputs their blob endpoints:
Notice Bicep outputs the blob endpoints easily because it can reference storage account resources using symbolic name
storageAccounts
and enumerate through entities by their symbolic namesstorageAccount
as well.A corresponding template snippet would look like:
Notice
outputs.blobEndpoints.value
, there's no easy way in template language to reference the array of storage accounts and their primary endpoints. This is becauseresources
property is defined as an array.Proposal
Change
resources
property type toobject
instead ofarray
. This allows asigning symbolic names via "<symbolic name>": "<resource declaration>" pairs. A resource's symbolic name represents its state at runtime.Extend template engine so that function
reference('<symbolic name>')
is able to retrieve resource state using its symbolic name.Above template snippet would then look like:
Compatibility with existing template pipeline
Existing template engine pipeline needs to be extended to support both current (v1) and the new template schema (v2).
Template function
reference
takes resource name or id as argument, it also needs to be updated to understand resource symbolic names. Consider a scenario in which a resource with symbolic name x and name y and another resource with symbolic name y and name x. Callingreference('x')
would be ambiguous because'x'
could either refer to the resource name or symbolic name.To eliminate the ambiguity, function
reference
takes symbolic name or resource id as argument for template v2. Template engine can easily tell if a template is v1 or v2 by checking theresources
JToken type, array for v1 and object for v2.Similarly,
dependsOn
function allows providing either resource name or resource id and the behavior is changed to support either symbolic name or resource id in the new schema.Current template pipeline has restrictions on certain template functions that they must be evaluated before calculating deployment dependencies in order to have a deterministic dependency graph. For example, resource condition must be evaluated to a boolean value to determine if a resource should be included in dependency; loop count must be evaluated to decide number of resources to be created in deployment.
To address the above restrictions, symbolic name in bicep will be compiled into separate template functions, one for template-phase evaluation the other for deployment-phase evaluation. We introduce a new template function
"[resource('symbolicName')]"
for template-phase evaluation, function properties must have values already specified in template. We keep"[reference('symbolicName')]"
to refer to deployment-phase evaluations.Symbolic Name Compilation Outputs
Scenarios:
Reference resource name
Bicep:
symbolicName.name
Json:
"[reference('symbolicName', 'Full').name]"
Reference resource property
Bicep:
symbolicName.properties.propertyName
Json:
"[reference('symbolicName').propertyName]"
Reference array of resources
Bicep:
arraySymbolicName.length
Json:
"[length(reference('arraySymbolicName'))]"
Reference an array item
Bicep:
arraySymbolicName[index].properties.propertyName
Json:
"[reference('arraySymbolicName')[copyIndex()].propertyName]"
Reference nested deployment outputs
Bicep:
deploymentSymbolicName.outputs.outputName.value
Json:
"[reference('deploymentSymbolicName', 'Full').outputs.outputName.value]"
dependsOn resource
Bicep:
dependsOn: [symbolicName1, symbolicName2]
Json:
"dependsOn": ["symbolicName1", "symbolicName2"]
The text was updated successfully, but these errors were encountered: