Skip to content

Commit

Permalink
Use tenant function and resourceGroup().location (#42257)
Browse files Browse the repository at this point in the history
* Use tenant function and resourceGroup().location

* PR fb

* remove find infra
  • Loading branch information
JoshLove-msft authored Feb 28, 2024
1 parent f0a29bc commit e7989a4
Show file tree
Hide file tree
Showing 22 changed files with 146 additions and 49 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,15 @@ public static partial class CdkExtensions
public static T? GetSingleResourceInScope<T>(this Azure.Provisioning.IConstruct construct) where T : Azure.Provisioning.Resource { throw null; }
public static T? GetSingleResource<T>(this Azure.Provisioning.IConstruct construct) where T : Azure.Provisioning.Resource { throw null; }
}
public partial class Configuration
{
public Configuration() { }
public bool UsePromptMode { get { throw null; } set { } }
}
public abstract partial class Construct : Azure.Provisioning.IConstruct
{
protected Construct(Azure.Provisioning.IConstruct? scope, string name, Azure.Provisioning.ConstructScope constructScope = Azure.Provisioning.ConstructScope.ResourceGroup, System.Guid? tenantId = default(System.Guid?), System.Guid? subscriptionId = default(System.Guid?), string? envName = null, Azure.Provisioning.ResourceManager.ResourceGroup? resourceGroup = null) { }
public Azure.Provisioning.Configuration? Configuration { get { throw null; } }
public Azure.Provisioning.ConstructScope ConstructScope { get { throw null; } }
public string EnvironmentName { get { throw null; } }
public string Name { get { throw null; } }
Expand All @@ -34,6 +40,7 @@ public enum ConstructScope
}
public partial interface IConstruct
{
Azure.Provisioning.Configuration? Configuration { get; }
Azure.Provisioning.ConstructScope ConstructScope { get; }
string EnvironmentName { get; }
string Name { get; }
Expand All @@ -52,7 +59,7 @@ public partial interface IConstruct
}
public abstract partial class Infrastructure : Azure.Provisioning.Construct
{
public Infrastructure(Azure.Provisioning.ConstructScope constructScope = Azure.Provisioning.ConstructScope.Subscription, System.Guid? tenantId = default(System.Guid?), System.Guid? subscriptionId = default(System.Guid?), string? envName = null, bool useAnonymousResourceGroup = false) : base (default(Azure.Provisioning.IConstruct), default(string), default(Azure.Provisioning.ConstructScope), default(System.Guid?), default(System.Guid?), default(string), default(Azure.Provisioning.ResourceManager.ResourceGroup)) { }
public Infrastructure(Azure.Provisioning.ConstructScope constructScope = Azure.Provisioning.ConstructScope.Subscription, System.Guid? tenantId = default(System.Guid?), System.Guid? subscriptionId = default(System.Guid?), string? envName = null, Azure.Provisioning.Configuration? configuration = null) : base (default(Azure.Provisioning.IConstruct), default(string), default(Azure.Provisioning.ConstructScope), default(System.Guid?), default(System.Guid?), default(string), default(Azure.Provisioning.ResourceManager.ResourceGroup)) { }
public void Build(string? outputPath = null) { }
}
public partial class Output
Expand Down Expand Up @@ -95,6 +102,7 @@ public abstract partial class Resource<T> : Azure.Provisioning.Resource where T
public T Properties { get { throw null; } }
public Azure.Provisioning.Output AddOutput(System.Linq.Expressions.Expression<System.Func<T, object?>> propertySelector, string outputName, bool isLiteral = false, bool isSecure = false) { throw null; }
public void AssignParameter(System.Linq.Expressions.Expression<System.Func<T, object?>> propertySelector, Azure.Provisioning.Parameter parameter) { }
public void AssignProperty(System.Linq.Expressions.Expression<System.Func<T, object?>> propertySelector, string propertyValue) { }
}
}
namespace Azure.Provisioning.AppConfiguration
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,15 @@ public static partial class CdkExtensions
public static T? GetSingleResourceInScope<T>(this Azure.Provisioning.IConstruct construct) where T : Azure.Provisioning.Resource { throw null; }
public static T? GetSingleResource<T>(this Azure.Provisioning.IConstruct construct) where T : Azure.Provisioning.Resource { throw null; }
}
public partial class Configuration
{
public Configuration() { }
public bool UsePromptMode { get { throw null; } set { } }
}
public abstract partial class Construct : Azure.Provisioning.IConstruct
{
protected Construct(Azure.Provisioning.IConstruct? scope, string name, Azure.Provisioning.ConstructScope constructScope = Azure.Provisioning.ConstructScope.ResourceGroup, System.Guid? tenantId = default(System.Guid?), System.Guid? subscriptionId = default(System.Guid?), string? envName = null, Azure.Provisioning.ResourceManager.ResourceGroup? resourceGroup = null) { }
public Azure.Provisioning.Configuration? Configuration { get { throw null; } }
public Azure.Provisioning.ConstructScope ConstructScope { get { throw null; } }
public string EnvironmentName { get { throw null; } }
public string Name { get { throw null; } }
Expand All @@ -34,6 +40,7 @@ public enum ConstructScope
}
public partial interface IConstruct
{
Azure.Provisioning.Configuration? Configuration { get; }
Azure.Provisioning.ConstructScope ConstructScope { get; }
string EnvironmentName { get; }
string Name { get; }
Expand All @@ -52,7 +59,7 @@ public partial interface IConstruct
}
public abstract partial class Infrastructure : Azure.Provisioning.Construct
{
public Infrastructure(Azure.Provisioning.ConstructScope constructScope = Azure.Provisioning.ConstructScope.Subscription, System.Guid? tenantId = default(System.Guid?), System.Guid? subscriptionId = default(System.Guid?), string? envName = null, bool useAnonymousResourceGroup = false) : base (default(Azure.Provisioning.IConstruct), default(string), default(Azure.Provisioning.ConstructScope), default(System.Guid?), default(System.Guid?), default(string), default(Azure.Provisioning.ResourceManager.ResourceGroup)) { }
public Infrastructure(Azure.Provisioning.ConstructScope constructScope = Azure.Provisioning.ConstructScope.Subscription, System.Guid? tenantId = default(System.Guid?), System.Guid? subscriptionId = default(System.Guid?), string? envName = null, Azure.Provisioning.Configuration? configuration = null) : base (default(Azure.Provisioning.IConstruct), default(string), default(Azure.Provisioning.ConstructScope), default(System.Guid?), default(System.Guid?), default(string), default(Azure.Provisioning.ResourceManager.ResourceGroup)) { }
public void Build(string? outputPath = null) { }
}
public partial class Output
Expand Down Expand Up @@ -95,6 +102,7 @@ public abstract partial class Resource<T> : Azure.Provisioning.Resource where T
public T Properties { get { throw null; } }
public Azure.Provisioning.Output AddOutput(System.Linq.Expressions.Expression<System.Func<T, object?>> propertySelector, string outputName, bool isLiteral = false, bool isSecure = false) { throw null; }
public void AssignParameter(System.Linq.Expressions.Expression<System.Func<T, object?>> propertySelector, Azure.Provisioning.Parameter parameter) { }
public void AssignProperty(System.Linq.Expressions.Expression<System.Func<T, object?>> propertySelector, string propertyValue) { }
}
}
namespace Azure.Provisioning.AppConfiguration
Expand Down
18 changes: 18 additions & 0 deletions sdk/provisioning/Azure.Provisioning/src/Configuration.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

namespace Azure.Provisioning
{
/// <summary>
/// Configuration for the provisioning.
/// </summary>
#pragma warning disable AZC0012 // Avoid single word type names
public class Configuration
#pragma warning restore AZC0012 // Avoid single word type names
{
/// <summary>
/// Whether to use prompt mode.
/// </summary>
public bool UsePromptMode { get; set; }
}
}
13 changes: 13 additions & 0 deletions sdk/provisioning/Azure.Provisioning/src/Construct.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,19 @@ public abstract class Construct : IConstruct
public Tenant Root { get; }
/// <inheritdoc/>
public ConstructScope ConstructScope { get; }
/// <inheritdoc/>
public Configuration? Configuration
{
get
{
return Scope == null ? _configuration : Scope.Configuration;
}
internal set
{
_configuration = value;
}
}
private Configuration? _configuration;

/// <summary>
/// Initializes a new instance of the <see cref="Construct"/> class.
Expand Down
5 changes: 5 additions & 0 deletions sdk/provisioning/Azure.Provisioning/src/IConstruct.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ public interface IConstruct
/// </summary>
public Subscription? Subscription { get; }

/// <summary>
/// Gets the configuration for the construct.
/// </summary>
public Configuration? Configuration { get; }

/// <summary>
/// Gets the parent of the construct.
/// </summary>
Expand Down
8 changes: 3 additions & 5 deletions sdk/provisioning/Azure.Provisioning/src/Infrastructure.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,13 @@ public abstract class Infrastructure : Construct
/// <param name="tenantId">The tenant id to use. If not passed in will try to load from AZURE_TENANT_ID environment variable.</param>
/// <param name="subscriptionId">The subscription id to use. If not passed, the subscription will be loaded from the deployment context.</param>
/// <param name="envName">The environment name to use. If not passed in will try to load from AZURE_ENV_NAME environment variable.</param>
/// <param name="useAnonymousResourceGroup">Whether to use a single anonymous resource group. When deploying the resource group will need to be provided.</param>
public Infrastructure(ConstructScope constructScope = ConstructScope.Subscription, Guid? tenantId = null, Guid? subscriptionId = null, string? envName = null, bool useAnonymousResourceGroup = false)
/// <param name="configuration">The configuration for the infrastructure.</param>
public Infrastructure(ConstructScope constructScope = ConstructScope.Subscription, Guid? tenantId = null, Guid? subscriptionId = null, string? envName = null, Configuration? configuration = null)
: base(null, "default", constructScope, tenantId, subscriptionId, envName ?? Environment.GetEnvironmentVariable("AZURE_ENV_NAME") ?? throw new Exception("No environment variable found named 'AZURE_ENV_NAME'"), resourceGroup: null)
{
UseAnonymousResourceGroup = useAnonymousResourceGroup;
Configuration = configuration;
}

internal bool UseAnonymousResourceGroup { get; }

/// <summary>
/// Converts the infrastructure to Bicep files.
/// </summary>
Expand Down
12 changes: 0 additions & 12 deletions sdk/provisioning/Azure.Provisioning/src/ModuleConstruct.cs
Original file line number Diff line number Diff line change
Expand Up @@ -254,18 +254,6 @@ private static void WriteLines(int depth, BinaryData data, MemoryStream stream,
{
start++;
}
line = line.Slice(start);
int end = line.IndexOf(':');
if (end > 0)
{
// foo: 1
// foo: 'something.url'
string name = line.Slice(0, end).ToString();
if (resource.ParameterOverrides.TryGetValue(name, out var value))
{
lineToWrite = $"{new string(' ', start)}{name}: {value}";
}
}
stream.WriteLine($"{indent}{lineToWrite}");
}
}
Expand Down
28 changes: 28 additions & 0 deletions sdk/provisioning/Azure.Provisioning/src/Resource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
using Azure.Provisioning.ResourceManager;
using Azure.Provisioning.Resources;
using Azure.ResourceManager;
using Azure.ResourceManager.Models;

namespace Azure.Provisioning
{
Expand All @@ -25,6 +26,8 @@ public abstract class Resource : IPersistableModel<Resource>
{
internal Dictionary<object, Dictionary<string, Parameter>> ParameterOverrides { get; }

private Dictionary<object, Dictionary<string, string>> PropertyOverrides { get; }

private IList<Resource> Dependencies { get; }

internal void AddDependency(Resource resource)
Expand Down Expand Up @@ -85,6 +88,7 @@ protected Resource(IConstruct scope, Resource? parent, string resourceName, Reso
ResourceData = createProperties(azureName);
Version = version;
ParameterOverrides = new Dictionary<object, Dictionary<string, Parameter>>();
PropertyOverrides = new Dictionary<object, Dictionary<string, string>>();
Dependencies = new List<Resource>();
ResourceType = resourceType;
Id = Parent is null
Expand Down Expand Up @@ -161,6 +165,18 @@ private protected void AssignParameter(object instance, string propertyName, Par
Parameters.Add(parameter);
}

private protected void AssignProperty(object instance, string propertyName, string propertyValue)
{
if (PropertyOverrides.TryGetValue(instance, out var overrides))
{
overrides[propertyName] = propertyValue;
}
else
{
PropertyOverrides.Add(instance, new Dictionary<string, string> { { propertyName, propertyValue } });
}
}

/// <summary>
/// Adds an output to the resource.
/// </summary>
Expand Down Expand Up @@ -245,6 +261,18 @@ private BinaryData SerializeModule(ModelReaderWriterOptions options)
}
bicepOptions.ParameterOverrides.Add(parameter.Key, dict);
}
foreach (var propertyOverride in PropertyOverrides)
{
if (!bicepOptions.ParameterOverrides.TryGetValue(propertyOverride.Key, out var dict))
{
dict = new Dictionary<string, string>();
bicepOptions.ParameterOverrides.Add(propertyOverride.Key, dict);
}
foreach (var kvp in propertyOverride.Value)
{
dict.Add(kvp.Key, kvp.Value);
}
}
var data = ModelReaderWriter.Write(ResourceData, bicepOptions).ToMemory();

#if NET6_0_OR_GREATER
Expand Down
34 changes: 32 additions & 2 deletions sdk/provisioning/Azure.Provisioning/src/ResourceOfT.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
using System.Linq;
using System.Linq.Expressions;
using Azure.Core;
using Azure.Provisioning.ResourceManager;
using Azure.ResourceManager.Models;

namespace Azure.Provisioning
{
Expand Down Expand Up @@ -33,10 +35,24 @@ public abstract class Resource<T> : Resource
/// <param name="resourceType">The resourceType.</param>
/// <param name="version">The version.</param>
/// <param name="createProperties">Lambda to create the ARM properties.</param>
protected Resource(IConstruct scope, Resource? parent, string resourceName, ResourceType resourceType, string version, Func<string, T> createProperties)
: base(scope, parent, resourceName, resourceType, version, (name) => createProperties(name))
protected Resource(
IConstruct scope,
Resource? parent,
string resourceName,
ResourceType resourceType,
string version,
Func<string, T> createProperties)
: base(scope, parent, resourceName, resourceType, version, name => createProperties(name))
{
Properties = (T)ResourceData;

// Resources that have a non-RG parent do not require a location value
if (scope.Configuration?.UsePromptMode == true && Parent is ResourceGroup)
{
// We can't use the lambda overload because not all of the T's will inherit from TrackedResourceData
// TODO we may need to add a protected LocationSelector property in the future if there are exceptions to the rule
AssignProperty(Properties, "Location", $"{ResourceGroup.AnonymousResourceGroupName}.location");
}
}

/// <summary>
Expand All @@ -51,6 +67,18 @@ public void AssignParameter(Expression<Func<T, object?>> propertySelector, Param
AssignParameter(instance, name, parameter);
}

/// <summary>
///
/// </summary>
/// <param name="propertySelector"></param>
/// <param name="propertyValue"></param>
/// <exception cref="NotSupportedException"></exception>
public void AssignProperty(Expression<Func<T, object?>> propertySelector, string propertyValue)
{
(object instance, string name, string expression) = EvaluateLambda(propertySelector);
AssignProperty(instance, name, propertyValue);
}

/// <summary>
/// Adds an output to the resource.
/// </summary>
Expand Down Expand Up @@ -113,6 +141,8 @@ private void GetBicepExpression(Expression expression, ref string result)
GetBicepExpression(memberExpression.Expression, ref result);
}
break;
case UnaryExpression unaryExpression:
break;
case MethodCallExpression methodCallExpression:
break; // skip
case ParameterExpression parameterExpression:
Expand Down
5 changes: 4 additions & 1 deletion sdk/provisioning/Azure.Provisioning/src/keyvault/KeyVault.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ public KeyVault(IConstruct scope, ResourceGroup? parent = default, string name =
resourceType: ResourceTypeName,
location: location ?? Environment.GetEnvironmentVariable("AZURE_LOCATION") ?? AzureLocation.WestUS,
properties: ArmKeyVaultModelFactory.KeyVaultProperties(
tenantId: scope.Root.Properties.TenantId!.Value,
sku: new KeyVaultSku(KeyVaultSkuFamily.A, KeyVaultSkuName.Standard),
accessPolicies: Environment.GetEnvironmentVariable("AZURE_PRINCIPAL_ID") is not null ? new List<KeyVaultAccessPolicy>()
{
Expand All @@ -47,6 +46,10 @@ public KeyVault(IConstruct scope, ResourceGroup? parent = default, string name =
enableRbacAuthorization: true)))
{
AddOutput(kv => kv.Properties.VaultUri, "vaultUri");
if (scope.Root.Properties.TenantId == Guid.Empty)
{
AssignProperty(kv => kv.Properties.TenantId, "tenant()");
}
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public static ResourceGroup AddResourceGroup(this IConstruct construct)
throw new InvalidOperationException("ResourceGroup already exists on the construct");
}

return new ResourceGroup(construct, name: construct is Infrastructure { UseAnonymousResourceGroup: true } ? ResourceGroup.AnonymousResourceGroupName : "rg");
return new ResourceGroup(construct, name: construct.Configuration?.UsePromptMode == true ? ResourceGroup.AnonymousResourceGroupName : "rg");
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,7 @@ public class SqlDatabase : Resource<SqlDatabaseData>
public SqlDatabase(IConstruct scope, SqlServer? parent = null, string name = "db", string version = "2022-08-01-preview", AzureLocation? location = default)
: base(scope, parent, name, ResourceTypeName, version, (name) => ArmSqlModelFactory.SqlDatabaseData(
name: name,
resourceType: ResourceTypeName,
location: location ?? Environment.GetEnvironmentVariable("AZURE_LOCATION") ?? AzureLocation.WestUS))
resourceType: ResourceTypeName))
{
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ resource keyVault_j1ww9730M 'Microsoft.KeyVault/vaults@2023-02-01' = {
name: 'kv-TEST'
location: 'westus'
properties: {
tenantId: '00000000-0000-0000-0000-000000000000'
tenantId: tenant()
sku: {
name: 'standard'
family: 'A'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@

resource storageAccount_NHn0GuaqX 'Microsoft.Storage/storageAccounts@2022-09-01' = {
name: 'photoacct84d98ba67edc4e3'
resource storageAccount_hWQR13jUf 'Microsoft.Storage/storageAccounts@2022-09-01' = {
name: 'photoacct71d9792260684fd'
location: 'westus'
sku: {
name: 'Premium_LRS'
Expand All @@ -10,8 +10,8 @@ resource storageAccount_NHn0GuaqX 'Microsoft.Storage/storageAccounts@2022-09-01'
}
}

resource blobService_58OA4T8kA 'Microsoft.Storage/storageAccounts/blobServices@2022-09-01' = {
parent: storageAccount_NHn0GuaqX
resource blobService_UnN8ydpj5 'Microsoft.Storage/storageAccounts/blobServices@2022-09-01' = {
parent: storageAccount_hWQR13jUf
name: 'default'
properties: {
}
Expand Down
Loading

0 comments on commit e7989a4

Please sign in to comment.