radius-project / radius

Radius is a cloud-native, portable application platform that makes app development easier for teams building cloud-native apps.
https://radapp.io
Apache License 2.0
1.49k stars 96 forks source link

Support for AWS intrinsic functions in Bicep #6387

Open asilverman opened 2 years ago

asilverman commented 2 years ago

Overview of feature request

While trying to implement AWS Workshop: Decoupled Microservices I noticed that some of the Cloud Formation files used to deploy infrastructure are using AWS CloudFormation intrinsic functions (for example: see here)

Similar to Bicep functions, AWS CloudFormation intrinsic functions provide built-in logic that helps AWS IaaS authors to assign values to properties that are not available until runtime.

In order to improve the authoring experience of AWS Resources using Bicep, we should support (to the extent that it is technically possible) the use of intrinsic function as part of the AWS Bicep Extensibility Provider.

Acceptance criteria

Additional context

Tasks

rynowak commented 2 years ago

After looking at the list of functions it looks like we can group these into three categories:

rynowak commented 2 years ago

Support for provider level functions in Bicep extensibility is something we've discussed but haven't spent any cycles on yet. It feels like GetAZs will be important to have.

We're already using resource level functions in Radius. We'll have to work to do to merge this support upstream into mainline Bicep.

asilverman commented 2 years ago

10/26/222 Ari/Ryan meeting notes

Findings

In the current state all Bicep functions are contained within two namespaces - az and sys[^1]. These namespaces are implicitly loaded when authoring a Bicep manifest.

In contrast to az and sys, both Radius and AWS resources are exposed through dedicated extensibility provider namespaces, (radius and aws) that need to be explicitly defined before usage.

To decide on the design for support of functions in the aws provider it helps to understand how the functions defined in sys and az are processed by the Bicep language server and Bicep compiler as well as where and how they are evaluated.

Function signatures (symbols) available in sys (for example join or split) are recognized by the Bicep language server and compiler per their definition in the Bicep.Core.Semantics.Namespaces namespace. An example is the function concat .

The code excerpt below builds the function symbol so that the Bicep compiler and language server recognizes it as a valid function, notice how concat doesn't define a .WithReturnResultsBuilder decorator because it is a builtin ARM template function (see docs here) so its evaluated

 yield return new FunctionOverloadBuilder("concat")
                .WithReturnType(LanguageConstants.Array)
                .WithGenericDescription(ConcatDescription)
                .WithDescription("Combines multiple arrays and returns the concatenated array.")
                .WithVariableParameter("arg", LanguageConstants.Array, minimumCount: 1, "The array for concatenation")
                .Build();

[^1]: Namespace for functions section of Bicep docs