diff --git a/sdk/provisioning/Azure.Provisioning/src/Resource.cs b/sdk/provisioning/Azure.Provisioning/src/Resource.cs
index 2116dffad2e0..3358f7b94abd 100644
--- a/sdk/provisioning/Azure.Provisioning/src/Resource.cs
+++ b/sdk/provisioning/Azure.Provisioning/src/Resource.cs
@@ -160,17 +160,14 @@ private protected void AssignParameter(object instance, string propertyName, Par
/// The name of the output.
/// The instance which contains the property for the output.
/// The property name to output.
+ /// The expression from the lambda
/// Is the output literal.
/// Is the output secure.
/// The .
/// If the is not found on the resources properties.
- private protected Output AddOutput(string name, object instance, string propertyName, bool isLiteral = false, bool isSecure = false)
+ private protected Output AddOutput(string name, object instance, string propertyName, string expression, bool isLiteral = false, bool isSecure = false)
{
- string? reference = GetReference(instance.GetType(), ResourceData.GetType(), propertyName, Name.ToCamelCase());
-
- if (reference is null)
- throw new ArgumentException(nameof(propertyName), $"{propertyName} was not found in the property tree for {ResourceData.GetType().Name}");
- var result = new Output(name, reference, Scope, isLiteral, isSecure);
+ var result = new Output(name, $"{Name}.{expression}", Scope, isLiteral, isSecure);
Scope.AddOutput(result);
return result;
}
diff --git a/sdk/provisioning/Azure.Provisioning/src/ResourceOfT.cs b/sdk/provisioning/Azure.Provisioning/src/ResourceOfT.cs
index cedfb4a7766d..8890b4037eeb 100644
--- a/sdk/provisioning/Azure.Provisioning/src/ResourceOfT.cs
+++ b/sdk/provisioning/Azure.Provisioning/src/ResourceOfT.cs
@@ -2,6 +2,7 @@
// Licensed under the MIT License.
using System;
+using System.Linq;
using System.Linq.Expressions;
using Azure.Core;
@@ -46,7 +47,7 @@ protected Resource(IConstruct scope, Resource? parent, string resourceName, Reso
///
public void AssignParameter(Expression> propertySelector, Parameter parameter)
{
- (object instance, string name) = EvaluateLambda(propertySelector);
+ (object instance, string name, string expression) = EvaluateLambda(propertySelector);
AssignParameter(instance, name, parameter);
}
@@ -60,47 +61,64 @@ public void AssignParameter(Expression> propertySelector, Param
/// The .
public Output AddOutput(Expression> propertySelector, string outputName, bool isLiteral = false, bool isSecure = false)
{
- (object instance, string name) = EvaluateLambda(propertySelector);
- return AddOutput(outputName, instance, name, isLiteral, isSecure);
+ (object instance, string name, string expression) = EvaluateLambda(propertySelector);
+
+ return AddOutput(outputName, instance, name, expression, isLiteral, isSecure);
}
- private (object Instance, string PropertyName) EvaluateLambda(Expression> propertySelector)
+ private (object Instance, string PropertyName, string Expression) EvaluateLambda(Expression> propertySelector)
{
ParameterExpression? root = null;
Expression? body = null;
string? name = null;
+ string expression = string.Empty;
if (propertySelector is LambdaExpression lambda)
{
root = lambda.Parameters[0];
if (lambda.Body is MemberExpression member)
{
+ GetBicepExpression(member, ref expression);
body = member.Expression;
name = member.Member.Name;
}
else if (lambda.Body is UnaryExpression { NodeType: ExpressionType.Convert, Operand: MemberExpression member2 })
{
+ GetBicepExpression(member2, ref expression);
body = member2.Expression;
name = member2.Member.Name;
}
- else if (lambda.Body is IndexExpression { Arguments.Count: 1 } indexer)
- {
- body = indexer.Object;
- name = Expression.Lambda(indexer.Arguments[0], root).Compile().DynamicInvoke(Properties) as string;
- }
- else if (lambda.Body is MethodCallExpression { Method.Name: "get_Item", Arguments.Count: 1 } call)
+ else
{
- body = call.Object;
- name = Expression.Lambda(call.Arguments[0], root).Compile().DynamicInvoke(Properties) as string;
+ throw new InvalidOperationException("Invalid expression type.");
}
}
-
- if (body is null || name is null || root is null)
+ else
{
- throw new NotSupportedException();
+ throw new InvalidOperationException("Invalid expression type.");
}
- object instance = Expression.Lambda(body, root).Compile().DynamicInvoke(Properties)!;
- return (instance, name);
+ object instance = Expression.Lambda(body!, root).Compile().DynamicInvoke(Properties)!;
+ return (instance, name, expression);
+ }
+
+ private void GetBicepExpression(Expression expression, ref string result)
+ {
+ switch (expression)
+ {
+ case MemberExpression memberExpression:
+ var attrib = memberExpression.Member.GetCustomAttributes(false).FirstOrDefault(a => a.GetType().Name == "WirePathAttribute");
+ string nodeString = attrib?.ToString() ?? memberExpression.Member.Name.ToCamelCase();
+ result = result == string.Empty ? nodeString : $"{nodeString}.{result}";
+ if (memberExpression.Expression is not null)
+ {
+ GetBicepExpression(memberExpression.Expression, ref result);
+ }
+ break;
+ case ParameterExpression parameterExpression:
+ return; // we have reached the root
+ default:
+ throw new InvalidOperationException($"Unsupported expression type {expression.GetType().Name}");
+ }
}
}
}
diff --git a/sdk/provisioning/Azure.Provisioning/src/appconfiguration/AppConfigurationStore.cs b/sdk/provisioning/Azure.Provisioning/src/appconfiguration/AppConfigurationStore.cs
index c9cc184e744d..b657c4f03902 100644
--- a/sdk/provisioning/Azure.Provisioning/src/appconfiguration/AppConfigurationStore.cs
+++ b/sdk/provisioning/Azure.Provisioning/src/appconfiguration/AppConfigurationStore.cs
@@ -30,6 +30,7 @@ public AppConfigurationStore(IConstruct scope, string name = "store", string ver
location: location ?? Environment.GetEnvironmentVariable("AZURE_LOCATION") ?? AzureLocation.WestUS,
skuName: "free"))
{
+ AddOutput(store => store.Endpoint, $"{Name}_endpoint");
}
///
diff --git a/sdk/provisioning/Azure.Provisioning/src/storage/StorageAccount.cs b/sdk/provisioning/Azure.Provisioning/src/storage/StorageAccount.cs
index 1251924817d2..6a761b031fc0 100644
--- a/sdk/provisioning/Azure.Provisioning/src/storage/StorageAccount.cs
+++ b/sdk/provisioning/Azure.Provisioning/src/storage/StorageAccount.cs
@@ -58,16 +58,15 @@ protected override string GetAzureName(IConstruct scope, string resourceName)
{
continue;
}
- if (char.IsDigit(c) && !char.IsLower(c))
+ if (char.IsLetter(c))
{
- stringBuilder.Append(char.ToLower(c));
+ stringBuilder.Append(char.ToLowerInvariant(c));
}
else
{
stringBuilder.Append(c);
}
}
- stringBuilder.Append('-');
stringBuilder.Append(Guid.NewGuid().ToString("N"));
return stringBuilder.ToString(0, Math.Min(stringBuilder.Length, 24));
diff --git a/sdk/provisioning/Azure.Provisioning/tests/Infrastructure/AppConfiguration/main.bicep b/sdk/provisioning/Azure.Provisioning/tests/Infrastructure/AppConfiguration/main.bicep
index 48aeda971d69..086bbe72e453 100644
--- a/sdk/provisioning/Azure.Provisioning/tests/Infrastructure/AppConfiguration/main.bicep
+++ b/sdk/provisioning/Azure.Provisioning/tests/Infrastructure/AppConfiguration/main.bicep
@@ -5,7 +5,7 @@ resource resourceGroup_I6QNkoPsb 'Microsoft.Resources/resourceGroups@2023-07-01'
name: 'rg-TEST'
location: 'westus'
tags: {
- azd-env-name: 'TEST'
+ 'azd-env-name': 'TEST'
}
}
@@ -19,3 +19,5 @@ resource appConfigurationStore_sgecYnln3 'Microsoft.AppConfiguration/configurati
properties: {
}
}
+
+output appConfigurationStore_sgecYnln3_endpoint string = appConfigurationStore_sgecYnln3.properties.endpoint
diff --git a/sdk/provisioning/Azure.Provisioning/tests/Infrastructure/ResourceGroupOnly/main.bicep b/sdk/provisioning/Azure.Provisioning/tests/Infrastructure/ResourceGroupOnly/main.bicep
index 9eb894c2b3ff..c61a4b9e1bfc 100644
--- a/sdk/provisioning/Azure.Provisioning/tests/Infrastructure/ResourceGroupOnly/main.bicep
+++ b/sdk/provisioning/Azure.Provisioning/tests/Infrastructure/ResourceGroupOnly/main.bicep
@@ -5,6 +5,6 @@ resource resourceGroup_I6QNkoPsb 'Microsoft.Resources/resourceGroups@2023-07-01'
name: 'rg-TEST'
location: 'westus'
tags: {
- azd-env-name: 'TEST'
+ 'azd-env-name': 'TEST'
}
}
diff --git a/sdk/provisioning/Azure.Provisioning/tests/Infrastructure/StorageBlobDefaults/main.bicep b/sdk/provisioning/Azure.Provisioning/tests/Infrastructure/StorageBlobDefaults/main.bicep
index 0edd84b5ad46..efd8c4f974fd 100644
--- a/sdk/provisioning/Azure.Provisioning/tests/Infrastructure/StorageBlobDefaults/main.bicep
+++ b/sdk/provisioning/Azure.Provisioning/tests/Infrastructure/StorageBlobDefaults/main.bicep
@@ -5,13 +5,13 @@ resource resourceGroup_I6QNkoPsb 'Microsoft.Resources/resourceGroups@2023-07-01'
name: 'rg-TEST'
location: 'westus'
tags: {
- azd-env-name: 'TEST'
+ 'azd-env-name': 'TEST'
}
}
-resource storageAccount_SIHb28RDV 'Microsoft.Storage/storageAccounts@2022-09-01' = {
+resource storageAccount_8fTaUIzOg 'Microsoft.Storage/storageAccounts@2022-09-01' = {
scope: resourceGroup_I6QNkoPsb
- name: 'photoAcct-4f6f922c331347'
+ name: 'photoacct2af3506bedd4415'
location: 'westus'
sku: {
name: 'Premium_LRS'
@@ -21,8 +21,8 @@ resource storageAccount_SIHb28RDV 'Microsoft.Storage/storageAccounts@2022-09-01'
}
}
-resource blobService_lyt6uqODr 'Microsoft.Storage/storageAccounts/blobServices@2022-09-01' = {
- parent: storageAccount_SIHb28RDV
+resource blobService_1iUqwyvnt 'Microsoft.Storage/storageAccounts/blobServices@2022-09-01' = {
+ parent: storageAccount_8fTaUIzOg
name: 'default'
properties: {
cors: {
diff --git a/sdk/provisioning/Azure.Provisioning/tests/Infrastructure/StorageBlobDropDown/main.bicep b/sdk/provisioning/Azure.Provisioning/tests/Infrastructure/StorageBlobDropDown/main.bicep
index c6b29f0ddf3e..7994d65dcd58 100644
--- a/sdk/provisioning/Azure.Provisioning/tests/Infrastructure/StorageBlobDropDown/main.bicep
+++ b/sdk/provisioning/Azure.Provisioning/tests/Infrastructure/StorageBlobDropDown/main.bicep
@@ -5,13 +5,13 @@ resource resourceGroup_I6QNkoPsb 'Microsoft.Resources/resourceGroups@2023-07-01'
name: 'rg-TEST'
location: 'westus'
tags: {
- azd-env-name: 'TEST'
+ 'azd-env-name': 'TEST'
}
}
-resource storageAccount_bhaja5ROZ 'Microsoft.Storage/storageAccounts@2022-09-01' = {
+resource storageAccount_VpeHv8O32 'Microsoft.Storage/storageAccounts@2022-09-01' = {
scope: resourceGroup_I6QNkoPsb
- name: 'photoAcct-96a1eefb1ac845'
+ name: 'photoacct414ad12f6b9c4a2'
location: 'westus'
sku: {
name: 'Premium_LRS'
@@ -21,8 +21,8 @@ resource storageAccount_bhaja5ROZ 'Microsoft.Storage/storageAccounts@2022-09-01'
}
}
-resource blobService_PQ7aICJK8 'Microsoft.Storage/storageAccounts/blobServices@2022-09-01' = {
- parent: storageAccount_bhaja5ROZ
+resource blobService_6SRi2s6Pf 'Microsoft.Storage/storageAccounts/blobServices@2022-09-01' = {
+ parent: storageAccount_VpeHv8O32
name: 'default'
properties: {
cors: {
diff --git a/sdk/provisioning/Azure.Provisioning/tests/Infrastructure/WebSiteUsingL1/main.bicep b/sdk/provisioning/Azure.Provisioning/tests/Infrastructure/WebSiteUsingL1/main.bicep
index 962c6bbcbb0f..4ab9eac1108a 100644
--- a/sdk/provisioning/Azure.Provisioning/tests/Infrastructure/WebSiteUsingL1/main.bicep
+++ b/sdk/provisioning/Azure.Provisioning/tests/Infrastructure/WebSiteUsingL1/main.bicep
@@ -13,8 +13,8 @@ resource resourceGroup_I6QNkoPsb 'Microsoft.Resources/resourceGroups@2023-07-01'
name: 'rg-TEST'
location: 'westus'
tags: {
- azd-env-name: 'TEST'
- key: 'value'
+ 'azd-env-name': 'TEST'
+ 'key': 'value'
}
}
@@ -232,8 +232,8 @@ resource applicationSettingsResource_vEe46o8Zn 'Microsoft.Web/sites/config@2021-
parent: webSite_4pzZqR2OO
name: 'appsettings'
properties: {
- SCM_DO_BUILD_DURING_DEPLOYMENT: 'False'
- ENABLE_ORYX_BUILD: 'True'
+ 'SCM_DO_BUILD_DURING_DEPLOYMENT': 'False'
+ 'ENABLE_ORYX_BUILD': 'True'
}
}
diff --git a/sdk/provisioning/Azure.Provisioning/tests/Infrastructure/WebSiteUsingL2/main.bicep b/sdk/provisioning/Azure.Provisioning/tests/Infrastructure/WebSiteUsingL2/main.bicep
index 6edc46bfa65f..5211bdb4ea9f 100644
--- a/sdk/provisioning/Azure.Provisioning/tests/Infrastructure/WebSiteUsingL2/main.bicep
+++ b/sdk/provisioning/Azure.Provisioning/tests/Infrastructure/WebSiteUsingL2/main.bicep
@@ -13,8 +13,8 @@ resource resourceGroup_I6QNkoPsb 'Microsoft.Resources/resourceGroups@2023-07-01'
name: 'rg-TEST'
location: 'westus'
tags: {
- azd-env-name: 'TEST'
- key: 'value'
+ 'azd-env-name': 'TEST'
+ 'key': 'value'
}
}
diff --git a/sdk/provisioning/Azure.Provisioning/tests/Infrastructure/WebSiteUsingL2/resources/TestBackEndWebSite/TestBackEndWebSite.bicep b/sdk/provisioning/Azure.Provisioning/tests/Infrastructure/WebSiteUsingL2/resources/TestBackEndWebSite/TestBackEndWebSite.bicep
index f92d15b10452..5bf70fec31e9 100644
--- a/sdk/provisioning/Azure.Provisioning/tests/Infrastructure/WebSiteUsingL2/resources/TestBackEndWebSite/TestBackEndWebSite.bicep
+++ b/sdk/provisioning/Azure.Provisioning/tests/Infrastructure/WebSiteUsingL2/resources/TestBackEndWebSite/TestBackEndWebSite.bicep
@@ -34,7 +34,7 @@ resource applicationSettingsResource_vEe46o8Zn 'Microsoft.Web/sites/config@2021-
parent: webSite_4pzZqR2OO
name: 'appsettings'
properties: {
- SCM_DO_BUILD_DURING_DEPLOYMENT: 'False'
- ENABLE_ORYX_BUILD: 'True'
+ 'SCM_DO_BUILD_DURING_DEPLOYMENT': 'False'
+ 'ENABLE_ORYX_BUILD': 'True'
}
}
diff --git a/sdk/provisioning/Azure.Provisioning/tests/Infrastructure/WebSiteUsingL3/main.bicep b/sdk/provisioning/Azure.Provisioning/tests/Infrastructure/WebSiteUsingL3/main.bicep
index ef77e05ab324..a4ee26f64267 100644
--- a/sdk/provisioning/Azure.Provisioning/tests/Infrastructure/WebSiteUsingL3/main.bicep
+++ b/sdk/provisioning/Azure.Provisioning/tests/Infrastructure/WebSiteUsingL3/main.bicep
@@ -13,8 +13,8 @@ resource resourceGroup_I6QNkoPsb 'Microsoft.Resources/resourceGroups@2023-07-01'
name: 'rg-TEST'
location: 'westus'
tags: {
- azd-env-name: 'TEST'
- key: 'value'
+ 'azd-env-name': 'TEST'
+ 'key': 'value'
}
}
diff --git a/sdk/provisioning/Azure.Provisioning/tests/Infrastructure/WebSiteUsingL3/resources/TestBackEndWebSite/TestBackEndWebSite.bicep b/sdk/provisioning/Azure.Provisioning/tests/Infrastructure/WebSiteUsingL3/resources/TestBackEndWebSite/TestBackEndWebSite.bicep
index f92d15b10452..5bf70fec31e9 100644
--- a/sdk/provisioning/Azure.Provisioning/tests/Infrastructure/WebSiteUsingL3/resources/TestBackEndWebSite/TestBackEndWebSite.bicep
+++ b/sdk/provisioning/Azure.Provisioning/tests/Infrastructure/WebSiteUsingL3/resources/TestBackEndWebSite/TestBackEndWebSite.bicep
@@ -34,7 +34,7 @@ resource applicationSettingsResource_vEe46o8Zn 'Microsoft.Web/sites/config@2021-
parent: webSite_4pzZqR2OO
name: 'appsettings'
properties: {
- SCM_DO_BUILD_DURING_DEPLOYMENT: 'False'
- ENABLE_ORYX_BUILD: 'True'
+ 'SCM_DO_BUILD_DURING_DEPLOYMENT': 'False'
+ 'ENABLE_ORYX_BUILD': 'True'
}
}
diff --git a/sdk/provisioning/Azure.Provisioning/tests/Infrastructure/WebSiteUsingL3/resources/TestWebSiteWithSqlBackEnd/TestWebSiteWithSqlBackEnd.bicep b/sdk/provisioning/Azure.Provisioning/tests/Infrastructure/WebSiteUsingL3/resources/TestWebSiteWithSqlBackEnd/TestWebSiteWithSqlBackEnd.bicep
index 18109bc3e303..5de221b11774 100644
--- a/sdk/provisioning/Azure.Provisioning/tests/Infrastructure/WebSiteUsingL3/resources/TestWebSiteWithSqlBackEnd/TestWebSiteWithSqlBackEnd.bicep
+++ b/sdk/provisioning/Azure.Provisioning/tests/Infrastructure/WebSiteUsingL3/resources/TestWebSiteWithSqlBackEnd/TestWebSiteWithSqlBackEnd.bicep
@@ -22,7 +22,7 @@ resource keyVault_CRoMbemLF 'Microsoft.KeyVault/vaults@2023-02-01' = {
name: 'kv-TEST'
location: 'westus'
tags: {
- key: 'value'
+ 'key': 'value'
}
properties: {
tenantId: '00000000-0000-0000-0000-000000000000'
diff --git a/sdk/provisioning/Azure.Provisioning/tests/ProvisioningTests.cs b/sdk/provisioning/Azure.Provisioning/tests/ProvisioningTests.cs
index a25c56c90093..d8ab7312a499 100644
--- a/sdk/provisioning/Azure.Provisioning/tests/ProvisioningTests.cs
+++ b/sdk/provisioning/Azure.Provisioning/tests/ProvisioningTests.cs
@@ -37,7 +37,7 @@ public void WebSiteUsingL1()
WebSite frontEnd = new WebSite(infra, "frontEnd", appServicePlan, WebSiteRuntime.Node, "18-lts");
var frontEndPrincipalId = frontEnd.AddOutput(
- website => website.Identity.PrincipalId,
+ website => website.Identity.PrincipalId, //Identity.PrincipalId
"SERVICE_API_IDENTITY_PRINCIPAL_ID",
isSecure: true);